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/docs/blog/posts/modal form showcase.md b/docs/blog/posts/modal form showcase.md new file mode 100644 index 00000000..14f2758d --- /dev/null +++ b/docs/blog/posts/modal form showcase.md @@ -0,0 +1,25 @@ +--- +title: Modal form showcase thread +Author: Danielo +date: 2024-12-12 +tags: announcement +--- + +Hello everyone. + +I've created this thread so people can share their awesome workflows using modal forms. + +A lot of times people that open feature requests mention they need such feature to complete their workflow, or that such feature will make their workflow simpler, and then they mention what their workflow is about and then blow my mind. + +I saw other plugins also have similar threads, so I decided to create this one to encourage people to share their forms and how are they using them. + +Anyone is free to provide their experiences however they want, but here are some suggestions that I think will make each post even more useful for everyone: + +- Start the thread with a summary of the workflow or the problem you are solving. +- If you can, export your form as a JSON file and share it in the thread using a code block. This will make it easier for others to use your form. +- If you can, share a screenshot of your form. This will make it easier for others to understand what your form looks like and makes it a lot more engaging. +- If you are calling the form from a template, please share the template as well in another code block. +- If you are okay about including your post as part of the example vault on modal form repository, please say so, then others just looking at the plugin repository can see your example. + +And that's all. +I'm very excited about seeing all the different workflows and how you use modal forms, and I hope this will be a great way to share and learn from each other. 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 @@ -