Skip to content

Commit

Permalink
chore: better UI for creating notes from forms
Browse files Browse the repository at this point in the history
  • Loading branch information
danielo515 committed Dec 11, 2023
1 parent 4653ee6 commit 6c8355d
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 34 deletions.
17 changes: 10 additions & 7 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import * as E from "fp-ts/Either";
import { pipe } from "fp-ts/function";
import * as A from "fp-ts/Array"
import { settingsStore } from "./store/store";
import { FormPickerModal } from "./suggesters/FormPickerModal";
import { O } from "@std";
import { executeTemplate } from "./core/template/templateParser";
import { NewNoteModal } from "./suggesters/NewNoteModal";
import { file_exists } from "./utils/files";

type ViewType = typeof EDIT_FORM_VIEW | typeof MANAGE_FORMS_VIEW;

Expand Down Expand Up @@ -203,11 +204,11 @@ export default class ModalFormPlugin extends Plugin {
* @param name the name of the note, without the extension
* @returns a unique name for the note, full path including the extension
*/
getUniqueNoteName(name: string): string {
getUniqueNoteName(name: string, destinationFolder?: string): string {
const defaultNotesFolder = this.app.fileManager.getNewFileParent('', 'note.md')
let destinationPath = `${defaultNotesFolder.path}/${name}.md`
let destinationPath = `${destinationFolder || defaultNotesFolder.path}/${name}.md`
let i = 1;
while (this.app.vault.getAbstractFileByPath(destinationPath)) {
while (file_exists(destinationPath, this.app)) {
destinationPath = `${defaultNotesFolder.path}/${name}-${i}.md`
i++;
}
Expand All @@ -232,12 +233,14 @@ export default class ModalFormPlugin extends Plugin {
return O.none;
})
)
const onFormSelected = async (form: FormWithTemplate) => {
const onFormSelected = async (form: FormWithTemplate, noteName: string, destinationFolder: string) => {
const formData = await this.api.openForm(form);
const newNoteFullPath = this.getUniqueNoteName(form.name);
const newNoteFullPath = this.getUniqueNoteName(noteName, destinationFolder);
this.app.vault.create(newNoteFullPath, executeTemplate(form.template, formData.getData()))
}
const picker = new FormPickerModal(this.app, formsWithTemplates, onFormSelected);
const picker = new NewNoteModal(this.app, formsWithTemplates, ({ form, folder, noteName }) => {
onFormSelected(form, noteName, folder)
});
picker.open();
}

Expand Down
84 changes: 84 additions & 0 deletions src/suggesters/NewNoteModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { App, Modal, Setting } from "obsidian";
import { FormWithTemplate } from "src/core/formDefinition";
import { FolderSuggest } from "./suggestFolder";
import { GenericSuggest } from "./suggestGeneric";
import { log_notice } from "src/utils/Log";

interface OnSelectArgs {
form: FormWithTemplate
folder: string
noteName: string
}

const formSuggester = (app: App, input: HTMLInputElement, forms: FormWithTemplate[], onChange: (form: FormWithTemplate) => void) => new GenericSuggest<FormWithTemplate>(
app,
input,
new Set(forms),
{
getSuggestions: (inputStr, forms) => {
return forms.filter((form) => form.name.toLowerCase().contains(inputStr))
},
renderSuggestion: (form, el) => {
el.setText(form.name)
},
selectSuggestion: (form) => {
onChange(form)
return form.name
}
}
)

export class NewNoteModal extends Modal {
constructor(app: App, private forms: FormWithTemplate[], protected onSelected: (args: OnSelectArgs) => void) {
super(app);
}

onOpen() {
let destinationFolder = ''
let form: FormWithTemplate
let noteName = ''
const { contentEl } = this;
// h1 is a title
contentEl.createEl('h1', { text: 'New Note from form' })

// picker of existing forms
new Setting(contentEl).addSearch((element) => {
formSuggester(this.app, element.inputEl, this.forms, (value) => {
form = value
})
}).setDesc('Pick a form')
// picker for destination folder
new Setting(contentEl).addSearch((element) => {
new FolderSuggest(element.inputEl, this.app)
element.onChange((value) => {
destinationFolder = value
})
}).setName('Destination folder')
new Setting(contentEl).addText((element) => {
element.onChange((value) => {
noteName = value
})
}).setName('Note name');
// button to create new form
new Setting(contentEl).addButton((element) => {
element.setButtonText('Create new note')
element.onClick(() => {
if (!form || !destinationFolder.trim() || !noteName.trim()) {
log_notice('Missing fields', 'Please fill all the fields')
return
}
this.close()
this.onSelected({
form,
folder: destinationFolder.trim(),
noteName: noteName.trim(),
})
})
})
}

onClose() {
const { contentEl } = this;
contentEl.empty();
}
}
27 changes: 0 additions & 27 deletions src/suggesters/suggestArray.ts

This file was deleted.

8 changes: 8 additions & 0 deletions src/utils/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,11 @@ export function get_tfiles_from_folder(folder_str: string, app: App): Either<Fol
}
))
}

export function file_exists(file_str: string, app: App): boolean {
return pipe(
normalizePath(file_str),
(path) => app.vault.getAbstractFileByPath(path),
(value) => value !== null
)
}

0 comments on commit 6c8355d

Please sign in to comment.