feat: option to toggle adding note to all parent folders (#937)
This commit is contained in:
@@ -22,22 +22,25 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => {
|
|||||||
} = appState.noteTags;
|
} = appState.noteTags;
|
||||||
|
|
||||||
const [dropdownVisible, setDropdownVisible] = useState(false);
|
const [dropdownVisible, setDropdownVisible] = useState(false);
|
||||||
const [dropdownMaxHeight, setDropdownMaxHeight] =
|
const [dropdownMaxHeight, setDropdownMaxHeight] = useState<number | 'auto'>(
|
||||||
useState<number | 'auto'>('auto');
|
'auto'
|
||||||
|
);
|
||||||
|
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const [closeOnBlur] = useCloseOnBlur(containerRef as any, (visible: boolean) => {
|
const [closeOnBlur] = useCloseOnBlur(containerRef, (visible: boolean) => {
|
||||||
setDropdownVisible(visible);
|
setDropdownVisible(visible);
|
||||||
appState.noteTags.clearAutocompleteSearch();
|
appState.noteTags.clearAutocompleteSearch();
|
||||||
});
|
});
|
||||||
|
|
||||||
const showDropdown = () => {
|
const showDropdown = () => {
|
||||||
const { clientHeight } = document.documentElement;
|
const { clientHeight } = document.documentElement;
|
||||||
const inputRect = inputRef.current!.getBoundingClientRect();
|
const inputRect = inputRef.current?.getBoundingClientRect();
|
||||||
setDropdownMaxHeight(clientHeight - inputRect.bottom - 32 * 2);
|
if (inputRect) {
|
||||||
setDropdownVisible(true);
|
setDropdownMaxHeight(clientHeight - inputRect.bottom - 32 * 2);
|
||||||
|
setDropdownVisible(true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSearchQueryChange = (event: Event) => {
|
const onSearchQueryChange = (event: Event) => {
|
||||||
@@ -93,7 +96,7 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (autocompleteInputFocused) {
|
if (autocompleteInputFocused) {
|
||||||
inputRef.current!.focus();
|
inputRef.current?.focus();
|
||||||
}
|
}
|
||||||
}, [appState.noteTags, autocompleteInputFocused]);
|
}, [appState.noteTags, autocompleteInputFocused]);
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ export const Defaults: FunctionComponent<Props> = ({ application }) => {
|
|||||||
application.getPreference(PrefKey.EditorSpellcheck, true)
|
application.getPreference(PrefKey.EditorSpellcheck, true)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [addNoteToParentFolders, setAddNoteToParentFolders] = useState(() =>
|
||||||
|
application.getPreference(PrefKey.NoteAddToParentFolders, true)
|
||||||
|
);
|
||||||
|
|
||||||
const toggleSpellcheck = () => {
|
const toggleSpellcheck = () => {
|
||||||
setSpellcheck(!spellcheck);
|
setSpellcheck(!spellcheck);
|
||||||
application.getAppState().toggleGlobalSpellcheck();
|
application.getAppState().toggleGlobalSpellcheck();
|
||||||
@@ -148,6 +152,28 @@ export const Defaults: FunctionComponent<Props> = ({ application }) => {
|
|||||||
</div>
|
</div>
|
||||||
<Switch onChange={toggleSpellcheck} checked={spellcheck} />
|
<Switch onChange={toggleSpellcheck} checked={spellcheck} />
|
||||||
</div>
|
</div>
|
||||||
|
<HorizontalSeparator classes="mt-5 mb-3" />
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<Subtitle>
|
||||||
|
Add all parent tags when adding a nested tag to a note
|
||||||
|
</Subtitle>
|
||||||
|
<Text>
|
||||||
|
When enabled, adding a nested tag to a note will automatically add
|
||||||
|
all associated parent tags.
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
<Switch
|
||||||
|
onChange={() => {
|
||||||
|
application.setPreference(
|
||||||
|
PrefKey.NoteAddToParentFolders,
|
||||||
|
!addNoteToParentFolders
|
||||||
|
);
|
||||||
|
setAddNoteToParentFolders(!addNoteToParentFolders);
|
||||||
|
}}
|
||||||
|
checked={addNoteToParentFolders}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</PreferencesSegment>
|
</PreferencesSegment>
|
||||||
</PreferencesGroup>
|
</PreferencesGroup>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
import { ElementIds } from '@/element_ids';
|
import { ElementIds } from '@/element_ids';
|
||||||
import { ContentType, SNNote, SNTag, UuidString } from '@standardnotes/snjs';
|
import { ApplicationEvent } from '@standardnotes/snjs';
|
||||||
|
import {
|
||||||
|
ContentType,
|
||||||
|
PrefKey,
|
||||||
|
SNNote,
|
||||||
|
SNTag,
|
||||||
|
UuidString,
|
||||||
|
} from '@standardnotes/snjs';
|
||||||
import { action, computed, makeObservable, observable } from 'mobx';
|
import { action, computed, makeObservable, observable } from 'mobx';
|
||||||
import { WebApplication } from '../application';
|
import { WebApplication } from '../application';
|
||||||
import { AppState } from './app_state';
|
import { AppState } from './app_state';
|
||||||
@@ -13,6 +20,7 @@ export class NoteTagsState {
|
|||||||
focusedTagUuid: UuidString | undefined = undefined;
|
focusedTagUuid: UuidString | undefined = undefined;
|
||||||
tags: SNTag[] = [];
|
tags: SNTag[] = [];
|
||||||
tagsContainerMaxWidth: number | 'auto' = 0;
|
tagsContainerMaxWidth: number | 'auto' = 0;
|
||||||
|
addNoteToParentFolders: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private application: WebApplication,
|
private application: WebApplication,
|
||||||
@@ -41,10 +49,24 @@ export class NoteTagsState {
|
|||||||
setTagsContainerMaxWidth: action,
|
setTagsContainerMaxWidth: action,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.addNoteToParentFolders = application.getPreference(
|
||||||
|
PrefKey.NoteAddToParentFolders,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
appEventListeners.push(
|
appEventListeners.push(
|
||||||
application.streamItems(ContentType.Tag, () => {
|
application.streamItems(ContentType.Tag, () => {
|
||||||
this.reloadTags();
|
this.reloadTags();
|
||||||
})
|
}),
|
||||||
|
application.addSingleEventObserver(
|
||||||
|
ApplicationEvent.PreferencesChanged,
|
||||||
|
async () => {
|
||||||
|
this.addNoteToParentFolders = application.getPreference(
|
||||||
|
PrefKey.NoteAddToParentFolders,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +202,11 @@ export class NoteTagsState {
|
|||||||
const { activeNote } = this;
|
const { activeNote } = this;
|
||||||
|
|
||||||
if (activeNote) {
|
if (activeNote) {
|
||||||
await this.application.addTagHierarchyToNote(activeNote, tag);
|
await this.application.items.addTagToNote(
|
||||||
|
activeNote,
|
||||||
|
tag,
|
||||||
|
this.addNoteToParentFolders
|
||||||
|
);
|
||||||
this.application.sync.sync();
|
this.application.sync.sync();
|
||||||
this.reloadTags();
|
this.reloadTags();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
"@standardnotes/filepicker": "1.10.0",
|
"@standardnotes/filepicker": "1.10.0",
|
||||||
"@standardnotes/settings": "1.13.1",
|
"@standardnotes/settings": "1.13.1",
|
||||||
"@standardnotes/sncrypto-web": "1.8.0",
|
"@standardnotes/sncrypto-web": "1.8.0",
|
||||||
"@standardnotes/snjs": "2.86.4",
|
"@standardnotes/snjs": "2.87.0",
|
||||||
"@zip.js/zip.js": "^2.4.7",
|
"@zip.js/zip.js": "^2.4.7",
|
||||||
"mobx": "^6.5.0",
|
"mobx": "^6.5.0",
|
||||||
"mobx-react-lite": "^3.3.0",
|
"mobx-react-lite": "^3.3.0",
|
||||||
|
|||||||
@@ -2491,10 +2491,10 @@
|
|||||||
buffer "^6.0.3"
|
buffer "^6.0.3"
|
||||||
libsodium-wrappers "^0.7.9"
|
libsodium-wrappers "^0.7.9"
|
||||||
|
|
||||||
"@standardnotes/snjs@2.86.4":
|
"@standardnotes/snjs@2.87.0":
|
||||||
version "2.86.4"
|
version "2.87.0"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.86.4.tgz#d0cc9d1e1e890d192bf252b19f06775902bfc6f0"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.87.0.tgz#7bccd49a365e6b8e2fe081798cfd9b899e8d39d1"
|
||||||
integrity sha512-Cp9nQ7a+Tjr/PVp72+qAgOaDetjyItuc9SwvnsPp4SlKku4KtCsIRQODPZfpF9ifxV/QIii+ZQbqk2ankHUQ0g==
|
integrity sha512-qvQhLFDtTYilG3nskdPklW1v8UTALTPX8fEjaVlH3+INlWFVR+yu9/Cwvyfkg6kqal6YTG/kG/tfDpRsLOTCxQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/applications" "^1.2.3"
|
"@standardnotes/applications" "^1.2.3"
|
||||||
"@standardnotes/auth" "^3.17.8"
|
"@standardnotes/auth" "^3.17.8"
|
||||||
|
|||||||
Reference in New Issue
Block a user