Files
standardnotes-app-web/app/assets/javascripts/components/Navigation.tsx
Laurent Senta c3772e06b4 feat: native smart tags (#782)
* feat: introduce native smart tags

* feat: introduce react navigation

* feat: render smart tag special cases

* feat: add create tag & all count

* feat: move components to react + mobx

* fix: workaround issue with snjs

* feat: nice smart tag icons in experimental

* feat: add back components

* fix: typo on all tags

* feat: add panel resizer + simplif code

* fix: panel resize size & refresh

* fix: auto select all notes

* style: remove legacy tag view

* style: remove legacy directives

* fix: select tag from note view

* feat: WIP smart tag rename

* fix: template checks

* fix: user can create new notes

* panel: init width

* fix: panel resizer ref

* fix: update with new component viewer

* fix: use fixed isTemplateItem & fixed findItems

* refactor: rename tags panel into navigation

* style: remove TODOs that are ok

* feat: smart tag premium check with premium service

* refactor: multi-select variables for debuggability

* fix: clean deinit code

* fix: prevent trigger tag changes event for the same uuid

* fix: typings

* fix: use minimal state

* style: remove dead code

* style: long variable names

* refactor: move magic string to module

* fix: use smart filter feature

* refactor: add task id in todo
2022-01-04 14:02:58 +01:00

118 lines
4.1 KiB
TypeScript

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<Props> = observer(
({ application }) => {
const appState = useMemo(() => application.getAppState(), [application]);
const componentViewer = appState.foldersComponentViewer;
const enableNativeSmartTagsFeature =
appState.features.enableNativeSmartTagsFeature;
const [panelRef, setPanelRef] = useState<HTMLDivElement | null>(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 (
<PremiumModalProvider state={appState.features}>
<div
id="tags-column"
ref={setPanelRef}
className="sn-component section tags"
data-aria-label="Tags"
>
{componentViewer ? (
<div className="component-view-container">
<div className="component-view">
<ComponentView
componentViewer={componentViewer}
application={application}
appState={appState}
/>
</div>
</div>
) : (
<div id="tags-content" className="content">
<div className="tags-title-section section-title-bar">
<div className="section-title-bar-header">
<div className="sk-h3 title">
<span className="sk-bold">Views</span>
</div>
{!enableNativeSmartTagsFeature && (
<div
className="sk-button sk-secondary-contrast wide"
onClick={onCreateNewTag}
title="Create a new tag"
>
<div className="sk-label">
<i className="icon ion-plus add-button" />
</div>
</div>
)}
</div>
</div>
<div className="scrollable">
<div className="infinite-scroll">
<SmartTagsSection appState={appState} />
<TagsSection appState={appState} />
</div>
</div>
</div>
)}
{panelRef && (
<PanelResizer
application={application}
collapsable={true}
defaultWidth={150}
panel={panelRef}
prefKey={PrefKey.TagsPanelWidth}
side={PanelSide.Right}
resizeFinishCallback={panelResizeFinishCallback}
widthEventCallback={panelWidthEventCallback}
/>
)}
</div>
</PremiumModalProvider>
);
}
);
export const NavigationDirective = toDirective<Props>(Navigation);