From 397e4963bd2ae796999aaa3f8bfbbed63d9c6089 Mon Sep 17 00:00:00 2001 From: Aman Harwara Date: Tue, 19 Oct 2021 21:37:47 +0530 Subject: [PATCH] feat: Update notes list options menu to new design (#687) feat: Implement initial Menu component functionality. --- app/assets/icons/ic-arrows-sort-down.svg | 5 + app/assets/icons/ic-arrows-sort-up.svg | 5 + app/assets/javascripts/app.ts | 2 + app/assets/javascripts/components/Icon.tsx | 4 + .../components/NotesListOptionsMenu.tsx | 244 ++++++++++++++++++ app/assets/javascripts/components/Switch.tsx | 2 + .../javascripts/components/menu/Menu.tsx | 132 ++++++++++ .../javascripts/components/menu/MenuItem.tsx | 111 ++++++++ .../javascripts/views/notes/notes-view.pug | 71 +---- .../javascripts/views/notes/notes_view.ts | 20 +- app/assets/stylesheets/_sn.scss | 20 ++ 11 files changed, 550 insertions(+), 66 deletions(-) create mode 100644 app/assets/icons/ic-arrows-sort-down.svg create mode 100644 app/assets/icons/ic-arrows-sort-up.svg create mode 100644 app/assets/javascripts/components/NotesListOptionsMenu.tsx create mode 100644 app/assets/javascripts/components/menu/Menu.tsx create mode 100644 app/assets/javascripts/components/menu/MenuItem.tsx diff --git a/app/assets/icons/ic-arrows-sort-down.svg b/app/assets/icons/ic-arrows-sort-down.svg new file mode 100644 index 00000000000..b7793bb2537 --- /dev/null +++ b/app/assets/icons/ic-arrows-sort-down.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/assets/icons/ic-arrows-sort-up.svg b/app/assets/icons/ic-arrows-sort-up.svg new file mode 100644 index 00000000000..ddb85688f73 --- /dev/null +++ b/app/assets/icons/ic-arrows-sort-up.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/assets/javascripts/app.ts b/app/assets/javascripts/app.ts index 09ae253cb65..ddd208fabe3 100644 --- a/app/assets/javascripts/app.ts +++ b/app/assets/javascripts/app.ts @@ -64,6 +64,7 @@ import { IconDirective } from './components/Icon'; import { NoteTagsContainerDirective } from './components/NoteTagsContainer'; import { PreferencesDirective } from './preferences'; import { AppVersion, IsWebPlatform } from '@/version'; +import { NotesListOptionsDirective } from './components/NotesListOptionsMenu'; import { PurchaseFlowDirective } from './purchaseFlow'; import { QuickSettingsMenuDirective } from './components/QuickSettingsMenu'; @@ -164,6 +165,7 @@ const startApplication: StartApplication = async function startApplication( .directive('multipleSelectedNotesPanel', MultipleSelectedNotesDirective) .directive('notesContextMenu', NotesContextMenuDirective) .directive('notesOptionsPanel', NotesOptionsPanelDirective) + .directive('notesListOptionsMenu', NotesListOptionsDirective) .directive('icon', IconDirective) .directive('noteTagsContainer', NoteTagsContainerDirective) .directive('preferences', PreferencesDirective) diff --git a/app/assets/javascripts/components/Icon.tsx b/app/assets/javascripts/components/Icon.tsx index 051ac9c1921..0ccc69b60ca 100644 --- a/app/assets/javascripts/components/Icon.tsx +++ b/app/assets/javascripts/components/Icon.tsx @@ -48,11 +48,15 @@ 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 ArrowsSortUpIcon from '../../icons/ic-arrows-sort-up.svg'; +import ArrowsSortDownIcon from '../../icons/ic-arrows-sort-down.svg'; import { toDirective } from './utils'; import { FunctionalComponent } from 'preact'; const ICONS = { + 'arrows-sort-up': ArrowsSortUpIcon, + 'arrows-sort-down': ArrowsSortDownIcon, lock: LockIcon, eye: EyeIcon, 'eye-off': EyeOffIcon, diff --git a/app/assets/javascripts/components/NotesListOptionsMenu.tsx b/app/assets/javascripts/components/NotesListOptionsMenu.tsx new file mode 100644 index 00000000000..1d22e14f2f0 --- /dev/null +++ b/app/assets/javascripts/components/NotesListOptionsMenu.tsx @@ -0,0 +1,244 @@ +import { WebApplication } from '@/ui_models/application'; +import { CollectionSort, PrefKey } from '@standardnotes/snjs'; +import { observer } from 'mobx-react-lite'; +import { FunctionComponent } from 'preact'; +import { useState } from 'preact/hooks'; +import { Icon } from './Icon'; +import { Menu } from './menu/Menu'; +import { MenuItem, MenuItemSeparator, MenuItemType } from './menu/MenuItem'; +import { toDirective } from './utils'; + +type Props = { + application: WebApplication; + setShowMenuFalse: () => void; +}; + +export const NotesListOptionsMenu: FunctionComponent = observer( + ({ setShowMenuFalse, application }) => { + const menuClassName = + 'sn-dropdown sn-dropdown--animated min-w-70 overflow-y-auto \ +border-1 border-solid border-gray-300 text-sm z-index-dropdown-menu \ +flex flex-col py-2 bottom-0 left-2 absolute'; + const [sortBy, setSortBy] = useState(() => + application.getPreference(PrefKey.SortNotesBy, CollectionSort.CreatedAt) + ); + const [sortReverse, setSortReverse] = useState(() => + application.getPreference(PrefKey.SortNotesReverse, false) + ); + const [hidePreview, setHidePreview] = useState(() => + application.getPreference(PrefKey.NotesHideNotePreview, false) + ); + const [hideDate, setHideDate] = useState(() => + application.getPreference(PrefKey.NotesHideDate, false) + ); + const [hideTags, setHideTags] = useState(() => + application.getPreference(PrefKey.NotesHideTags, true) + ); + const [hidePinned, setHidePinned] = useState(() => + application.getPreference(PrefKey.NotesHidePinned, false) + ); + const [showArchived, setShowArchived] = useState(() => + application.getPreference(PrefKey.NotesShowArchived, false) + ); + const [showTrashed, setShowTrashed] = useState(() => + application.getPreference(PrefKey.NotesShowTrashed, false) + ); + const [hideProtected, setHideProtected] = useState(() => + application.getPreference(PrefKey.NotesHideProtected, false) + ); + + const toggleSortReverse = () => { + application.setPreference(PrefKey.SortNotesReverse, !sortReverse); + setSortReverse(!sortReverse); + }; + + const toggleSortBy = (sort: CollectionSort) => { + if (sortBy === sort) { + toggleSortReverse(); + } else { + setSortBy(sort); + application.setPreference(PrefKey.SortNotesBy, sort); + } + }; + + const toggleSortByDateModified = () => { + toggleSortBy(CollectionSort.UpdatedAt); + }; + + const toggleSortByCreationDate = () => { + toggleSortBy(CollectionSort.CreatedAt); + }; + + const toggleSortByTitle = () => { + toggleSortBy(CollectionSort.Title); + }; + + const toggleHidePreview = () => { + setHidePreview(!hidePreview); + application.setPreference(PrefKey.NotesHideNotePreview, !hidePreview); + }; + + const toggleHideDate = () => { + setHideDate(!hideDate); + application.setPreference(PrefKey.NotesHideDate, !hideDate); + }; + + const toggleHideTags = () => { + setHideTags(!hideTags); + application.setPreference(PrefKey.NotesHideTags, !hideTags); + }; + + const toggleHidePinned = () => { + setHidePinned(!hidePinned); + application.setPreference(PrefKey.NotesHidePinned, !hidePinned); + }; + + const toggleShowArchived = () => { + setShowArchived(!showArchived); + application.setPreference(PrefKey.NotesShowArchived, !showArchived); + }; + + const toggleShowTrashed = () => { + setShowTrashed(!showTrashed); + application.setPreference(PrefKey.NotesShowTrashed, !showTrashed); + }; + + const toggleHideProtected = () => { + setHideProtected(!hideProtected); + application.setPreference(PrefKey.NotesHideProtected, !hideProtected); + }; + + return ( +
+ +
+ Sort by +
+ +
+ Date modified + {sortBy === CollectionSort.UpdatedAt ? ( + sortReverse ? ( + + ) : ( + + ) + ) : null} +
+
+ +
+ Creation date + {sortBy === CollectionSort.CreatedAt ? ( + sortReverse ? ( + + ) : ( + + ) + ) : null} +
+
+ +
+ Title + {sortBy === CollectionSort.Title ? ( + sortReverse ? ( + + ) : ( + + ) + ) : null} +
+
+ +
+ View +
+ +
Show note preview
+
+ + Show date + + + Show tags + +
+
+ Other +
+ + Show pinned notes + + + Show protected notes + + + Show archived notes + + + Show trashed notes + +
+
+ ); + } +); + +export const NotesListOptionsDirective = toDirective( + NotesListOptionsMenu, + { + setShowMenuFalse: '=', + state: '&', + } +); diff --git a/app/assets/javascripts/components/Switch.tsx b/app/assets/javascripts/components/Switch.tsx index 49da00dc94d..06b5a28815c 100644 --- a/app/assets/javascripts/components/Switch.tsx +++ b/app/assets/javascripts/components/Switch.tsx @@ -13,6 +13,7 @@ export type SwitchProps = HTMLProps & { onChange: (checked: boolean) => void; className?: string; children?: ComponentChildren; + role?: string; }; export const Switch: FunctionalComponent = ( @@ -24,6 +25,7 @@ export const Switch: FunctionalComponent = ( return (