* 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
118 lines
4.1 KiB
TypeScript
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);
|