feat(clipper): Added default tag setting to clipper
This commit is contained in:
@@ -42,6 +42,7 @@ export enum PrefKey {
|
|||||||
DarkMode = 'darkMode',
|
DarkMode = 'darkMode',
|
||||||
DefaultEditorIdentifier = 'defaultEditorIdentifier',
|
DefaultEditorIdentifier = 'defaultEditorIdentifier',
|
||||||
MomentsDefaultTagUuid = 'momentsDefaultTagUuid',
|
MomentsDefaultTagUuid = 'momentsDefaultTagUuid',
|
||||||
|
ClipperDefaultTagUuid = 'clipperDefaultTagUuid',
|
||||||
SystemViewPreferences = 'systemViewPreferences',
|
SystemViewPreferences = 'systemViewPreferences',
|
||||||
SuperNoteExportFormat = 'superNoteExportFormat',
|
SuperNoteExportFormat = 'superNoteExportFormat',
|
||||||
AuthenticatorNames = 'authenticatorNames',
|
AuthenticatorNames = 'authenticatorNames',
|
||||||
@@ -111,6 +112,7 @@ export type PrefValue = {
|
|||||||
[PrefKey.DarkMode]: boolean
|
[PrefKey.DarkMode]: boolean
|
||||||
[PrefKey.DefaultEditorIdentifier]: EditorIdentifier
|
[PrefKey.DefaultEditorIdentifier]: EditorIdentifier
|
||||||
[PrefKey.MomentsDefaultTagUuid]: string | undefined
|
[PrefKey.MomentsDefaultTagUuid]: string | undefined
|
||||||
|
[PrefKey.ClipperDefaultTagUuid]: string | undefined
|
||||||
[PrefKey.SystemViewPreferences]: Partial<Record<SystemViewId, TagPreferences>>
|
[PrefKey.SystemViewPreferences]: Partial<Record<SystemViewId, TagPreferences>>
|
||||||
[PrefKey.SuperNoteExportFormat]: 'json' | 'md' | 'html'
|
[PrefKey.SuperNoteExportFormat]: 'json' | 'md' | 'html'
|
||||||
[PrefKey.AuthenticatorNames]: string
|
[PrefKey.AuthenticatorNames]: string
|
||||||
|
|||||||
@@ -15,11 +15,14 @@ import { confirmDialog } from '@standardnotes/ui-services'
|
|||||||
import {
|
import {
|
||||||
ApplicationEvent,
|
ApplicationEvent,
|
||||||
ContentType,
|
ContentType,
|
||||||
|
DecryptedItem,
|
||||||
FeatureIdentifier,
|
FeatureIdentifier,
|
||||||
FeatureStatus,
|
FeatureStatus,
|
||||||
NoteContent,
|
NoteContent,
|
||||||
NoteType,
|
NoteType,
|
||||||
|
PrefKey,
|
||||||
SNNote,
|
SNNote,
|
||||||
|
SNTag,
|
||||||
} from '@standardnotes/snjs'
|
} from '@standardnotes/snjs'
|
||||||
import { addToast, ToastType } from '@standardnotes/toast'
|
import { addToast, ToastType } from '@standardnotes/toast'
|
||||||
import { getSuperJSONFromClipPayload } from './getSuperJSONFromClipHTML'
|
import { getSuperJSONFromClipPayload } from './getSuperJSONFromClipHTML'
|
||||||
@@ -28,6 +31,11 @@ import { PremiumFeatureIconClass, PremiumFeatureIconName } from '../Icon/Premium
|
|||||||
import Button from '../Button/Button'
|
import Button from '../Button/Button'
|
||||||
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
|
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
|
||||||
import { useStateRef } from '@/Hooks/useStateRef'
|
import { useStateRef } from '@/Hooks/useStateRef'
|
||||||
|
import usePreference from '@/Hooks/usePreference'
|
||||||
|
import { createLinkFromItem } from '@/Utils/Items/Search/createLinkFromItem'
|
||||||
|
import ItemSelectionDropdown from '../ItemSelectionDropdown/ItemSelectionDropdown'
|
||||||
|
import LinkedItemBubble from '../LinkedItems/LinkedItemBubble'
|
||||||
|
import StyledTooltip from '../StyledTooltip/StyledTooltip'
|
||||||
|
|
||||||
const Header = () => (
|
const Header = () => (
|
||||||
<div className="flex items-center border-b border-border p-1 px-3 py-2 text-base font-semibold text-info-contrast">
|
<div className="flex items-center border-b border-border p-1 px-3 py-2 text-base font-semibold text-info-contrast">
|
||||||
@@ -79,6 +87,30 @@ const ClipperView = ({
|
|||||||
})
|
})
|
||||||
}, [application])
|
}, [application])
|
||||||
|
|
||||||
|
const defaultTagId = usePreference<string>(PrefKey.ClipperDefaultTagUuid)
|
||||||
|
const [defaultTag, setDefaultTag] = useState<SNTag | undefined>()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!defaultTagId) {
|
||||||
|
setDefaultTag(undefined)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const tag = application.items.findItem(defaultTagId) as SNTag | undefined
|
||||||
|
setDefaultTag(tag)
|
||||||
|
}, [defaultTagId, application])
|
||||||
|
|
||||||
|
const selectTag = useCallback(
|
||||||
|
(tag: DecryptedItem) => {
|
||||||
|
void application.setPreference(PrefKey.ClipperDefaultTagUuid, tag.uuid)
|
||||||
|
},
|
||||||
|
[application],
|
||||||
|
)
|
||||||
|
|
||||||
|
const unselectTag = useCallback(async () => {
|
||||||
|
void application.setPreference(PrefKey.ClipperDefaultTagUuid, undefined)
|
||||||
|
}, [application])
|
||||||
|
|
||||||
const [menuPane, setMenuPane] = useState<AccountMenuPane>()
|
const [menuPane, setMenuPane] = useState<AccountMenuPane>()
|
||||||
|
|
||||||
const activateRegisterPane = useCallback(() => {
|
const activateRegisterPane = useCallback(() => {
|
||||||
@@ -167,18 +199,24 @@ const ClipperView = ({
|
|||||||
references: [],
|
references: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
void application.items.insertItem(note).then((note) => {
|
const insertedNote = await application.items.insertItem(note)
|
||||||
setClippedNote(note as SNNote)
|
|
||||||
addToast({
|
if (defaultTag) {
|
||||||
type: ToastType.Success,
|
await application.linkingController.linkItems(insertedNote, defaultTag)
|
||||||
message: 'Note clipped successfully',
|
}
|
||||||
})
|
|
||||||
void application.sync.sync()
|
setClippedNote(insertedNote as SNNote)
|
||||||
|
|
||||||
|
addToast({
|
||||||
|
type: ToastType.Success,
|
||||||
|
message: 'Note clipped successfully',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
void application.sync.sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
void createNoteFromClip()
|
void createNoteFromClip()
|
||||||
}, [application.items, application.sync, clipPayload, isEntitledRef])
|
}, [application.items, application.linkingController, application.sync, clipPayload, defaultTag, isEntitledRef])
|
||||||
|
|
||||||
const upgradePlan = useCallback(async () => {
|
const upgradePlan = useCallback(async () => {
|
||||||
if (hasSubscription) {
|
if (hasSubscription) {
|
||||||
@@ -309,6 +347,34 @@ const ClipperView = ({
|
|||||||
>
|
>
|
||||||
Select elements to clip
|
Select elements to clip
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<div className="border-t border-border px-3 py-3 text-base text-foreground">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="font-medium">Default tag:</div>
|
||||||
|
{defaultTag && (
|
||||||
|
<StyledTooltip label="Remove default tag" gutter={2}>
|
||||||
|
<button className="rounded-full p-1 hover:bg-contrast hover:text-info" onClick={unselectTag}>
|
||||||
|
<Icon type="clear-circle-filled" />
|
||||||
|
</button>
|
||||||
|
</StyledTooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{defaultTag && (
|
||||||
|
<div>
|
||||||
|
<LinkedItemBubble
|
||||||
|
className="m-1 mr-2"
|
||||||
|
link={createLinkFromItem(defaultTag, 'linked')}
|
||||||
|
unlinkItem={unselectTag}
|
||||||
|
isBidirectional={false}
|
||||||
|
inlineFlex={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ItemSelectionDropdown
|
||||||
|
onSelection={selectTag}
|
||||||
|
placeholder="Select tag to save clipped notes to..."
|
||||||
|
contentTypes={[ContentType.Tag]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="border-t border-border px-3 pt-3 pb-1 text-base text-foreground">
|
<div className="border-t border-border px-3 pt-3 pb-1 text-base text-foreground">
|
||||||
<div>You're signed in as:</div>
|
<div>You're signed in as:</div>
|
||||||
<div className="wrap my-0.5 font-bold">{user.email}</div>
|
<div className="wrap my-0.5 font-bold">{user.email}</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user