feat: add migration pref pane (#825)
* feat: add migration pane * style: clean imports * removeme: beta version * fix: do no show dropzone when tag has no parent * fix: hide the Folders toggle * fix: hide migrations option when user has no folders * fix: add delimiter on Folders mark * removeme: bump beta * fix: remove component viewer for tag folders * removeme: bump beta * chore(deps): snjs
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { ComponentView } from '@/components/ComponentView';
|
||||
import { SmartTagsSection } from '@/components/Tags/SmartTagsSection';
|
||||
import { TagsSection } from '@/components/Tags/TagsSection';
|
||||
import { WebApplication } from '@/ui_models/application';
|
||||
@@ -6,13 +5,7 @@ import { PANEL_NAME_NAVIGATION } from '@/views/constants';
|
||||
import { ApplicationEvent, PrefKey } from '@standardnotes/snjs';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { FunctionComponent } from 'preact';
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'preact/hooks';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'preact/hooks';
|
||||
import { PremiumModalProvider } from './Premium';
|
||||
import {
|
||||
PanelSide,
|
||||
@@ -28,7 +21,6 @@ type Props = {
|
||||
export const Navigation: FunctionComponent<Props> = observer(
|
||||
({ application }) => {
|
||||
const appState = useMemo(() => application.getAppState(), [application]);
|
||||
const componentViewer = appState.foldersComponentViewer;
|
||||
const enableNativeSmartTagsFeature =
|
||||
appState.features.enableNativeSmartTagsFeature;
|
||||
const [ref, setRef] = useState<HTMLDivElement | null>();
|
||||
@@ -72,42 +64,30 @@ export const Navigation: FunctionComponent<Props> = observer(
|
||||
data-aria-label="Navigation"
|
||||
ref={setRef}
|
||||
>
|
||||
{componentViewer ? (
|
||||
<div className="component-view-container">
|
||||
<div className="component-view">
|
||||
<ComponentView
|
||||
componentViewer={componentViewer}
|
||||
application={application}
|
||||
appState={appState}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div id="navigation-content" className="content">
|
||||
<div className="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 id="navigation-content" className="content">
|
||||
<div className="section-title-bar">
|
||||
<div className="section-title-bar-header">
|
||||
<div className="sk-h3 title">
|
||||
<span className="sk-bold">Views</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="scrollable">
|
||||
<SmartTagsSection appState={appState} />
|
||||
<TagsSection appState={appState} />
|
||||
{!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">
|
||||
<SmartTagsSection appState={appState} />
|
||||
<TagsSection appState={appState} />
|
||||
</div>
|
||||
</div>
|
||||
{ref && (
|
||||
<PanelResizer
|
||||
collapsable={true}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import {
|
||||
ComponentArea,
|
||||
ContentType,
|
||||
FeatureIdentifier,
|
||||
SNComponent,
|
||||
SNTheme,
|
||||
} from '@standardnotes/snjs';
|
||||
@@ -107,10 +108,11 @@ export const QuickSettingsMenu: FunctionComponent<MenuProps> = observer(
|
||||
const reloadToggleableComponents = useCallback(() => {
|
||||
const toggleableComponents = (
|
||||
application.getDisplayableItems(ContentType.Component) as SNComponent[]
|
||||
).filter((component) =>
|
||||
[ComponentArea.EditorStack, ComponentArea.TagsList].includes(
|
||||
component.area
|
||||
)
|
||||
).filter(
|
||||
(component) =>
|
||||
[ComponentArea.EditorStack, ComponentArea.TagsList].includes(
|
||||
component.area
|
||||
) && component.identifier !== FeatureIdentifier.FoldersComponent
|
||||
);
|
||||
setToggleableComponents(toggleableComponents);
|
||||
}, [application]);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { Icon } from '@/components/Icon';
|
||||
import { usePremiumModal } from '@/components/Premium';
|
||||
import {
|
||||
FeaturesState,
|
||||
TAG_FOLDERS_FEATURE_NAME,
|
||||
} from '@/ui_models/app_state/features_state';
|
||||
import { FeaturesState } from '@/ui_models/app_state/features_state';
|
||||
import { TagsState } from '@/ui_models/app_state/tags_state';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useDrop } from 'react-dnd';
|
||||
@@ -22,8 +19,8 @@ export const RootTagDropZone: React.FC<Props> = observer(
|
||||
const [{ isOver, canDrop }, dropRef] = useDrop<DropItem, void, DropProps>(
|
||||
() => ({
|
||||
accept: ItemTypes.TAG,
|
||||
canDrop: () => {
|
||||
return true;
|
||||
canDrop: (item) => {
|
||||
return tagsState.hasParent(item.uuid);
|
||||
},
|
||||
drop: (item) => {
|
||||
tagsState.assignParent(item.uuid, undefined);
|
||||
|
||||
@@ -52,7 +52,7 @@ export const TagsSectionTitle: FunctionComponent<Props> = observer(
|
||||
className="ml-1 sk-bold color-grey-2 cursor-pointer"
|
||||
onClick={showPremiumAlert}
|
||||
>
|
||||
Folders
|
||||
· Folders
|
||||
</label>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
@@ -91,22 +91,27 @@ type ListElementProps = {
|
||||
};
|
||||
|
||||
export const MenuItemListElement: FunctionComponent<ListElementProps> =
|
||||
forwardRef(({ children, isFirstMenuItem }: ListElementProps, ref: Ref<HTMLLIElement>) => {
|
||||
const child = children as VNode<unknown>;
|
||||
forwardRef(
|
||||
(
|
||||
{ children, isFirstMenuItem }: ListElementProps,
|
||||
ref: Ref<HTMLLIElement>
|
||||
) => {
|
||||
const child = children as VNode<unknown>;
|
||||
|
||||
return (
|
||||
<li className="list-style-none" role="none" ref={ref}>
|
||||
{{
|
||||
...child,
|
||||
props: {
|
||||
...(child.props ? { ...child.props } : {}),
|
||||
...(child.type === MenuItem
|
||||
? {
|
||||
tabIndex: isFirstMenuItem ? 0 : -1,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
}}
|
||||
</li>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<li className="list-style-none" role="none" ref={ref}>
|
||||
{{
|
||||
...child,
|
||||
props: {
|
||||
...(child.props ? { ...child.props } : {}),
|
||||
...(child.type === MenuItem
|
||||
? {
|
||||
tabIndex: isFirstMenuItem ? 0 : -1,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
}}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user