diff --git a/app/assets/icons/ic-authenticator.svg b/app/assets/icons/ic-authenticator.svg index e8dd720cf..9a1193919 100644 --- a/app/assets/icons/ic-authenticator.svg +++ b/app/assets/icons/ic-authenticator.svg @@ -1,4 +1,3 @@ - - - \ No newline at end of file + + + diff --git a/app/assets/icons/ic-code.svg b/app/assets/icons/ic-code.svg index 79df4be8d..4a871e270 100644 --- a/app/assets/icons/ic-code.svg +++ b/app/assets/icons/ic-code.svg @@ -1,4 +1,3 @@ - - - \ No newline at end of file + + + diff --git a/app/assets/icons/ic-lock-filled.svg b/app/assets/icons/ic-lock-filled.svg deleted file mode 100644 index a71db2794..000000000 --- a/app/assets/icons/ic-lock-filled.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/app/assets/icons/ic-markdown.svg b/app/assets/icons/ic-markdown.svg index 1efac5876..bceed54b3 100644 --- a/app/assets/icons/ic-markdown.svg +++ b/app/assets/icons/ic-markdown.svg @@ -1,4 +1,3 @@ - - - \ No newline at end of file + + + diff --git a/app/assets/icons/ic-notes.svg b/app/assets/icons/ic-notes.svg deleted file mode 100644 index ece661333..000000000 --- a/app/assets/icons/ic-notes.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/assets/icons/ic-pin-filled.svg b/app/assets/icons/ic-pin-filled.svg deleted file mode 100644 index 4e5ae92a5..000000000 --- a/app/assets/icons/ic-pin-filled.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/app/assets/icons/ic-spreadsheets.svg b/app/assets/icons/ic-spreadsheets.svg index 2566d69bb..70f175be2 100644 --- a/app/assets/icons/ic-spreadsheets.svg +++ b/app/assets/icons/ic-spreadsheets.svg @@ -1,4 +1,3 @@ - - - \ No newline at end of file + + + diff --git a/app/assets/icons/ic-tasks.svg b/app/assets/icons/ic-tasks.svg index c6b89554f..0f8ef0587 100644 --- a/app/assets/icons/ic-tasks.svg +++ b/app/assets/icons/ic-tasks.svg @@ -1,4 +1,3 @@ - - - \ No newline at end of file + + + diff --git a/app/assets/icons/ic-text-paragraph.svg b/app/assets/icons/ic-text-paragraph.svg index 376e8ad46..4f43cdc0c 100644 --- a/app/assets/icons/ic-text-paragraph.svg +++ b/app/assets/icons/ic-text-paragraph.svg @@ -1,3 +1,4 @@ - - - \ No newline at end of file + + + + \ No newline at end of file diff --git a/app/assets/icons/ic-text-rich.svg b/app/assets/icons/ic-text-rich.svg index d895ca8c4..87f57dd41 100644 --- a/app/assets/icons/ic-text-rich.svg +++ b/app/assets/icons/ic-text-rich.svg @@ -1,4 +1,3 @@ - - \ No newline at end of file + + diff --git a/app/assets/icons/ic-trash-filled.svg b/app/assets/icons/ic-trash-filled.svg deleted file mode 100644 index 63f9575bf..000000000 --- a/app/assets/icons/ic-trash-filled.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/app/assets/javascripts/app.ts b/app/assets/javascripts/app.ts index bd5d4e066..2d1762e8d 100644 --- a/app/assets/javascripts/app.ts +++ b/app/assets/javascripts/app.ts @@ -20,32 +20,23 @@ declare global { } } -import { ComponentViewDirective } from '@/components/ComponentView'; -import { NavigationDirective } from '@/components/Navigation'; -import { PinNoteButtonDirective } from '@/components/PinNoteButton'; -import { IsWebPlatform, WebAppVersion } from '@/version'; -import { - ApplicationGroupView, - ApplicationView, ChallengeModal, - FooterView, NoteGroupViewDirective, - NoteViewDirective -} from '@/views'; import { SNLog } from '@standardnotes/snjs'; import angular from 'angular'; -import { AccountMenuDirective } from './components/AccountMenu'; -import { ConfirmSignoutDirective } from './components/ConfirmSignoutModal'; -import { IconDirective } from './components/Icon'; -import { MultipleSelectedNotesDirective } from './components/MultipleSelectedNotes'; -import { NoAccountWarningDirective } from './components/NoAccountWarning'; -import { NotesContextMenuDirective } from './components/NotesContextMenu'; -import { NotesListOptionsDirective } from './components/NotesListOptionsMenu'; -import { NotesOptionsPanelDirective } from './components/NotesOptionsPanel'; -import { NotesViewDirective } from './components/NotesView'; -import { NoteTagsContainerDirective } from './components/NoteTagsContainer'; -import { ProtectedNoteOverlayDirective } from './components/ProtectedNoteOverlay'; -import { QuickSettingsMenuDirective } from './components/QuickSettingsMenu/QuickSettingsMenu'; -import { SearchOptionsDirective } from './components/SearchOptions'; -import { SessionsModalDirective } from './components/SessionsModal'; +import { configRoutes } from './routes'; + +import { ApplicationGroup } from './ui_models/application_group'; +import { AccountSwitcher } from './views/account_switcher/account_switcher'; + +import { + ApplicationGroupView, + ApplicationView, + NoteGroupViewDirective, + NoteViewDirective, + TagsView, + FooterView, + ChallengeModal, +} from '@/views'; + import { autofocus, clickOutside, @@ -55,31 +46,49 @@ import { infiniteScroll, lowercase, selectOnFocus, - snEnter + snEnter, } from './directives/functional'; + import { ActionsMenu, EditorMenu, - HistoryMenu, InputModal, MenuRow, PanelResizer, PasswordWizard, PermissionsModal, RevisionPreviewModal, - SyncResolutionMenu + HistoryMenu, + SyncResolutionMenu, } from './directives/views'; + import { trusted } from './filters'; -import { PreferencesDirective } from './preferences'; -import { PurchaseFlowDirective } from './purchaseFlow'; -import { configRoutes } from './routes'; -import { Bridge } from './services/bridge'; +import { isDev } from './utils'; import { BrowserBridge } from './services/browserBridge'; import { startErrorReporting } from './services/errorReporting'; import { StartApplication } from './startApplication'; -import { ApplicationGroup } from './ui_models/application_group'; -import { isDev } from './utils'; -import { AccountSwitcher } from './views/account_switcher/account_switcher'; +import { Bridge } from './services/bridge'; +import { SessionsModalDirective } from './components/SessionsModal'; +import { NoAccountWarningDirective } from './components/NoAccountWarning'; +import { ProtectedNoteOverlayDirective } from './components/ProtectedNoteOverlay'; +import { SearchOptionsDirective } from './components/SearchOptions'; +import { AccountMenuDirective } from './components/AccountMenu'; +import { ConfirmSignoutDirective } from './components/ConfirmSignoutModal'; +import { MultipleSelectedNotesDirective } from './components/MultipleSelectedNotes'; +import { NotesContextMenuDirective } from './components/NotesContextMenu'; +import { NotesOptionsPanelDirective } from './components/NotesOptionsPanel'; +import { IconDirective } from './components/Icon'; +import { NoteTagsContainerDirective } from './components/NoteTagsContainer'; +import { PreferencesDirective } from './preferences'; +import { WebAppVersion, IsWebPlatform } from '@/version'; +import { NotesListOptionsDirective } from './components/NotesListOptionsMenu'; +import { PurchaseFlowDirective } from './purchaseFlow'; +import { QuickSettingsMenuDirective } from './components/QuickSettingsMenu/QuickSettingsMenu'; +import { ComponentViewDirective } from '@/components/ComponentView'; +import { TagsListDirective } from '@/components/TagsList'; +import { NotesViewDirective } from './components/NotesView'; +import { PinNoteButtonDirective } from '@/components/PinNoteButton'; +import { TagsSectionDirective } from './components/Tags/TagsSection'; function reloadHiddenFirefoxTab(): boolean { /** @@ -134,6 +143,7 @@ const startApplication: StartApplication = async function startApplication( .directive('applicationView', () => new ApplicationView()) .directive('noteGroupView', () => new NoteGroupViewDirective()) .directive('noteView', () => new NoteViewDirective()) + .directive('tagsView', () => new TagsView()) .directive('footerView', () => new FooterView()); // Directives - Functional @@ -178,7 +188,8 @@ const startApplication: StartApplication = async function startApplication( .directive('notesListOptionsMenu', NotesListOptionsDirective) .directive('icon', IconDirective) .directive('noteTagsContainer', NoteTagsContainerDirective) - .directive('navigation', NavigationDirective) + .directive('tagsList', TagsListDirective) + .directive('tagsSection', TagsSectionDirective) .directive('preferences', PreferencesDirective) .directive('purchaseFlow', PurchaseFlowDirective) .directive('notesView', NotesViewDirective) diff --git a/app/assets/javascripts/components/AutocompleteTagResult.tsx b/app/assets/javascripts/components/AutocompleteTagResult.tsx index d732541af..84bb150ac 100644 --- a/app/assets/javascripts/components/AutocompleteTagResult.tsx +++ b/app/assets/javascripts/components/AutocompleteTagResult.tsx @@ -21,9 +21,6 @@ export const AutocompleteTagResult = observer( const tagResultRef = useRef(null); - const title = tagResult.title; - const prefixTitle = appState.noteTags.getPrefixTitle(tagResult); - const onTagOptionClick = async (tag: SNTag) => { await appState.noteTags.addTagToActiveNote(tag); appState.noteTags.clearAutocompleteSearch(); @@ -89,10 +86,9 @@ export const AutocompleteTagResult = observer( > - {prefixTitle && {prefixTitle}} {autocompleteSearchQuery === '' - ? title - : title + ? tagResult.title + : tagResult.title .split(new RegExp(`(${autocompleteSearchQuery})`, 'gi')) .map((substring, index) => ( void; }; -type ListboxButtonProps = DropdownItem & { +type ListboxButtonProps = { + icon?: IconType; + value: string | null; + label: string; isExpanded: boolean; }; @@ -34,13 +36,12 @@ const CustomDropdownButton: FunctionComponent = ({ label, isExpanded, icon, - iconClassName = '', }) => ( <>
{icon ? (
- +
) : null}
{label}
@@ -84,13 +85,11 @@ export const Dropdown: FunctionComponent = ({ children={({ value, label, isExpanded }) => { const current = items.find((item) => item.value === value); const icon = current ? current?.icon : null; - const iconClassName = current ? current?.iconClassName : null; return CustomDropdownButton({ - value: value ? value : label.toLowerCase(), + value, label, isExpanded, ...(icon ? { icon } : null), - ...(iconClassName ? { iconClassName } : null), }); }} /> @@ -105,10 +104,7 @@ export const Dropdown: FunctionComponent = ({ > {item.icon ? (
- +
) : null}
{item.label}
diff --git a/app/assets/javascripts/components/Icon.tsx b/app/assets/javascripts/components/Icon.tsx index 6d5b6d3bc..96eee992f 100644 --- a/app/assets/javascripts/components/Icon.tsx +++ b/app/assets/javascripts/components/Icon.tsx @@ -3,9 +3,7 @@ import PencilOffIcon from '../../icons/ic-pencil-off.svg'; import PlainTextIcon from '../../icons/ic-text-paragraph.svg'; import RichTextIcon from '../../icons/ic-text-rich.svg'; import TrashIcon from '../../icons/ic-trash.svg'; -import TrashFilledIcon from '../../icons/ic-trash-filled.svg'; import PinIcon from '../../icons/ic-pin.svg'; -import PinFilledIcon from '../../icons/ic-pin-filled.svg'; import UnpinIcon from '../../icons/ic-pin-off.svg'; import ArchiveIcon from '../../icons/ic-archive.svg'; import UnarchiveIcon from '../../icons/ic-unarchive.svg'; @@ -23,7 +21,6 @@ import AuthenticatorIcon from '../../icons/ic-authenticator.svg'; import SpreadsheetsIcon from '../../icons/ic-spreadsheets.svg'; import TasksIcon from '../../icons/ic-tasks.svg'; import MarkdownIcon from '../../icons/ic-markdown.svg'; -import NotesIcon from '../../icons/ic-notes.svg'; import CodeIcon from '../../icons/ic-code.svg'; import AccessibilityIcon from '../../icons/ic-accessibility.svg'; @@ -55,7 +52,6 @@ import ServerIcon from '../../icons/ic-server.svg'; import EyeIcon from '../../icons/ic-eye.svg'; import EyeOffIcon from '../../icons/ic-eye-off.svg'; import LockIcon from '../../icons/ic-lock.svg'; -import LockFilledIcon from '../../icons/ic-lock-filled.svg'; import ArrowsSortUpIcon from '../../icons/ic-arrows-sort-up.svg'; import ArrowsSortDownIcon from '../../icons/ic-arrows-sort-down.svg'; import WindowIcon from '../../icons/ic-window.svg'; @@ -70,11 +66,9 @@ import { FunctionalComponent } from 'preact'; const ICONS = { 'menu-arrow-down-alt': MenuArrowDownAlt, 'menu-arrow-right': MenuArrowRight, - notes: NotesIcon, 'arrows-sort-up': ArrowsSortUpIcon, 'arrows-sort-down': ArrowsSortDownIcon, lock: LockIcon, - 'lock-filled': LockFilledIcon, eye: EyeIcon, 'eye-off': EyeOffIcon, server: ServerIcon, @@ -95,9 +89,7 @@ const ICONS = { spreadsheets: SpreadsheetsIcon, tasks: TasksIcon, trash: TrashIcon, - 'trash-filled': TrashFilledIcon, pin: PinIcon, - 'pin-filled': PinFilledIcon, unpin: UnpinIcon, archive: ArchiveIcon, unarchive: UnarchiveIcon, @@ -138,22 +130,11 @@ export type IconType = keyof typeof ICONS; type Props = { type: IconType; className?: string; - ariaLabel?: string; }; -export const Icon: FunctionalComponent = ({ - type, - className = '', - ariaLabel, -}) => { +export const Icon: FunctionalComponent = ({ type, className = '' }) => { const IconComponent = ICONS[type]; - return ( - - ); + return ; }; export const IconDirective = toDirective(Icon, { diff --git a/app/assets/javascripts/components/Navigation.tsx b/app/assets/javascripts/components/Navigation.tsx deleted file mode 100644 index b3e5dcfd4..000000000 --- a/app/assets/javascripts/components/Navigation.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { ComponentView } from '@/components/ComponentView'; -import { PanelResizer } from '@/components/PanelResizer'; -import { SmartTagsSection } from '@/components/Tags/SmartTagsSection'; -import { TagsSection } from '@/components/Tags/TagsSection'; -import { toDirective } from '@/components/utils'; -import { - PanelSide, - ResizeFinishCallback, -} from '@/directives/views/panelResizer'; -import { WebApplication } from '@/ui_models/application'; -import { PANEL_NAME_NAVIGATION } from '@/views/constants'; -import { PrefKey } from '@standardnotes/snjs'; -import { observer } from 'mobx-react-lite'; -import { FunctionComponent } from 'preact'; -import { useCallback, useEffect, useMemo, useState } from 'preact/hooks'; -import { PremiumModalProvider } from './Premium'; - -type Props = { - application: WebApplication; -}; - -export const Navigation: FunctionComponent = observer( - ({ application }) => { - const appState = useMemo(() => application.getAppState(), [application]); - const componentViewer = appState.foldersComponentViewer; - const enableNativeSmartTagsFeature = - appState.features.enableNativeSmartTagsFeature; - const [panelRef, setPanelRef] = useState(null); - - useEffect(() => { - const elem = document.querySelector( - 'navigation' - ) as HTMLDivElement | null; - setPanelRef(elem); - }, [setPanelRef]); - - const onCreateNewTag = useCallback(() => { - appState.tags.createNewTemplate(); - }, [appState]); - - const panelResizeFinishCallback: ResizeFinishCallback = useCallback( - (_lastWidth, _lastLeft, _isMaxWidth, isCollapsed) => { - appState.noteTags.reloadTagsContainerMaxWidth(); - appState.panelDidResize(PANEL_NAME_NAVIGATION, isCollapsed); - }, - [appState] - ); - - const panelWidthEventCallback = useCallback(() => { - appState.noteTags.reloadTagsContainerMaxWidth(); - }, [appState]); - - return ( - -
- {componentViewer ? ( -
-
- -
-
- ) : ( -
-
-
-
- Views -
- {!enableNativeSmartTagsFeature && ( -
-
- -
-
- )} -
-
-
-
- - -
-
-
- )} - {panelRef && ( - - )} -
-
- ); - } -); - -export const NavigationDirective = toDirective(Navigation); diff --git a/app/assets/javascripts/components/NoteTag.tsx b/app/assets/javascripts/components/NoteTag.tsx index 372f6017e..91dc12aba 100644 --- a/app/assets/javascripts/components/NoteTag.tsx +++ b/app/assets/javascripts/components/NoteTag.tsx @@ -10,9 +10,7 @@ type Props = { }; export const NoteTag = observer(({ appState, tag }: Props) => { - const noteTags = appState.noteTags; - - const { autocompleteInputFocused, focusedTagUuid, tags } = noteTags; + const { autocompleteInputFocused, focusedTagUuid, tags } = appState.noteTags; const [showDeleteButton, setShowDeleteButton] = useState(false); const [tagClicked, setTagClicked] = useState(false); @@ -20,10 +18,6 @@ export const NoteTag = observer(({ appState, tag }: Props) => { const tagRef = useRef(null); - const title = tag.title; - const prefixTitle = noteTags.getPrefixTitle(tag); - const longTitle = noteTags.getLongTitle(tag); - const deleteTag = () => { appState.noteTags.focusPreviousTag(tag); appState.noteTags.removeTagFromActiveNote(tag); @@ -38,7 +32,7 @@ export const NoteTag = observer(({ appState, tag }: Props) => { const onTagClick = (event: MouseEvent) => { if (tagClicked && event.target !== deleteTagRef.current) { setTagClicked(false); - appState.selectedTag = tag; + appState.setSelectedTag(tag); } else { setTagClicked(true); } @@ -103,12 +97,10 @@ export const NoteTag = observer(({ appState, tag }: Props) => { onFocus={onFocus} onBlur={onBlur} tabIndex={getTabIndex()} - title={longTitle} > - {prefixTitle && {prefixTitle}} - {title} + {tag.title} {showDeleteButton && (