From d208648ba49cb8674b48b0f3f1eca9bfb9aed5ad Mon Sep 17 00:00:00 2001 From: Danielo Rodriguez Date: Thu, 12 Dec 2024 13:40:32 +0100 Subject: [PATCH] feat(input): you can define a parent folder on the folder input fixes [Feature request] Designate "Parent Folder" for narrowing folder search options with Folder Type Fields #305 --- .../.obsidian/plugins/modal-form/data.json | 17 +++++++---------- src/core/input/InputDefinitionSchema.ts | 1 + src/suggesters/suggestFolder.ts | 19 ++++++++++++------- src/views/FormBuilder.svelte | 8 +++++++- src/views/components/Form/InputFolder.svelte | 11 +++++++++-- src/views/components/Form/RenderField.svelte | 7 ++++++- .../components/InputBuilderFolder.svelte | 11 ++++------- 7 files changed, 46 insertions(+), 28 deletions(-) diff --git a/EXAMPLE_VAULT/.obsidian/plugins/modal-form/data.json b/EXAMPLE_VAULT/.obsidian/plugins/modal-form/data.json index 2c037e5f..4ea22e3a 100644 --- a/EXAMPLE_VAULT/.obsidian/plugins/modal-form/data.json +++ b/EXAMPLE_VAULT/.obsidian/plugins/modal-form/data.json @@ -343,31 +343,28 @@ { "title": "Frontmatter example", "name": "frontmatter", - "version": "1", "fields": [ { "name": "title", "label": "", "description": "", + "isRequired": false, "input": { "type": "text", - "allowUnknownValues": false, "hidden": false - }, - "isRequired": false + } }, { "name": "tags", "label": "", "description": "", + "isRequired": false, "input": { - "type": "tag", - "allowUnknownValues": false, - "hidden": false - }, - "isRequired": false + "type": "tag" + } } - ] + ], + "version": "1" } ] } \ No newline at end of file diff --git a/src/core/input/InputDefinitionSchema.ts b/src/core/input/InputDefinitionSchema.ts index 08310725..5d78da9f 100644 --- a/src/core/input/InputDefinitionSchema.ts +++ b/src/core/input/InputDefinitionSchema.ts @@ -68,6 +68,7 @@ export const InputNoteFromFolderSchema = object({ }); export const InputFolderSchema = object({ type: literal("folder"), + parentFolder: optional(string([toTrimmed()])), // TODO: allow exclude option }); export const InputDataviewSourceSchema = object({ diff --git a/src/suggesters/suggestFolder.ts b/src/suggesters/suggestFolder.ts index db12e45c..b7203f5c 100644 --- a/src/suggesters/suggestFolder.ts +++ b/src/suggesters/suggestFolder.ts @@ -2,25 +2,30 @@ import { AbstractInputSuggest, App, TAbstractFile, TFolder } from "obsidian"; export class FolderSuggest extends AbstractInputSuggest { - constructor( public inputEl: HTMLInputElement, public app: App, + private parentFolder?: string, ) { super(app, inputEl); } + getSuggestions(inputStr: string): TFolder[] { const abstractFiles = this.app.vault.getAllLoadedFiles(); const lowerCaseInputStr = inputStr.toLowerCase(); const folders: TFolder[] = abstractFiles.reduce((acc, folder: TAbstractFile) => { - if ( - folder instanceof TFolder && - folder.path.toLowerCase().contains(lowerCaseInputStr) - ) { - acc.push(folder) + if (!(folder instanceof TFolder)) return acc; + + const folderPath = folder.path.toLowerCase(); + const matchesInput = folderPath.contains(lowerCaseInputStr); + const matchesParent = + !this.parentFolder || folderPath.startsWith(this.parentFolder.toLowerCase()); + + if (matchesInput && matchesParent) { + acc.push(folder); } - return acc + return acc; }, [] as TFolder[]); return folders; diff --git a/src/views/FormBuilder.svelte b/src/views/FormBuilder.svelte index 7e25ea05..0b03dcbc 100644 --- a/src/views/FormBuilder.svelte +++ b/src/views/FormBuilder.svelte @@ -17,9 +17,9 @@ import FormRow from "./components/FormRow.svelte"; import InputBuilderDataview from "./components/inputBuilderDataview.svelte"; import InputBuilderDocumentBlock from "./components/InputBuilderDocumentBlock.svelte"; + import InputBuilderFile from "./components/InputBuilderFile.svelte"; import InputFolder from "./components/InputBuilderFolder.svelte"; import InputBuilderImage from "./components/InputBuilderImage.svelte"; - import InputBuilderFile from "./components/InputBuilderFile.svelte"; import InputBuilderSelect from "./components/InputBuilderSelect.svelte"; import Tabs from "./components/Tabs.svelte"; import TemplateEditor from "./components/TemplateEditor.svelte"; @@ -349,6 +349,12 @@ bind:folder={field.input.folder} notifyChange={onChange} /> + {:else if field.input.type === "folder"} + {:else if field.input.type === "dataview"} ; + export let parentFolder: string | undefined; export let app: App; let search_: SearchComponent | undefined; function customizer(setting: Setting) { setting.addSearch((component) => { - new FolderSuggest(component.inputEl, app); + new FolderSuggest(component.inputEl, app, parentFolder); search_ = component; component.onChange((v) => { - $value = v; + $value = v.trim(); }); }); + setting.infoEl.appendChild( + createSpan({ + cls: "setting-item-description", + text: parentFolder ? `Searching in: ${parentFolder}` : "", + }), + ); } $: if (search_) { search_.setValue($value as string); diff --git a/src/views/components/Form/RenderField.svelte b/src/views/components/Form/RenderField.svelte index df5a0b14..9e78312a 100644 --- a/src/views/components/Form/RenderField.svelte +++ b/src/views/components/Form/RenderField.svelte @@ -56,7 +56,12 @@ {:else if definition.input.type === "toggle"} {:else if definition.input.type === "folder"} - + {:else if definition.input.type === "dataview"} {:else if definition.input.type === "note"} diff --git a/src/views/components/InputBuilderFolder.svelte b/src/views/components/InputBuilderFolder.svelte index 536c8f38..43ddc2e7 100644 --- a/src/views/components/InputBuilderFolder.svelte +++ b/src/views/components/InputBuilderFolder.svelte @@ -5,17 +5,17 @@ * This component is just to select a folder, not notes inside the folder */ export let index: number; - export let folder: string = ""; + export let folder: string | undefined; // This is just used to notify the parent component that the value has changed // it is useful for example to persis the intermediary state of the form export let notifyChange: () => void; function searchFolder(element: HTMLElement) { new Setting(element).addSearch((search) => { search.setPlaceholder("Select a folder"); - search.setValue(folder); + search.setValue(folder || ""); new FolderSuggest(search.inputEl, app); search.onChange((value) => { - folder = value; + folder = value.trim() || undefined; notifyChange(); }); }); @@ -24,10 +24,7 @@ -