Skip to content

Commit

Permalink
Merge pull request #201 from danielo515/feat/edit-form-command
Browse files Browse the repository at this point in the history
Feat/edit form command
  • Loading branch information
danielo515 authored Jan 6, 2024
2 parents f131c37 + cf7bc4f commit 72c164c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 65 deletions.
31 changes: 10 additions & 21 deletions src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ModalFormPlugin from "./main";
import { ModalFormError } from "./utils/ModalFormError";
import { FormModal } from "./FormModal";
import { log_error, log_notice } from "./utils/Log";
import * as std from "@std";

type pickOption = { pick: string[] };
type omitOption = { omit: string[] };
Expand All @@ -21,6 +22,7 @@ function isOmitOption(opts: limitOptions): opts is omitOption {
}

export class API {
std = std;
/**
* Constructor for the API class
* @param {App} app - The application instance
Expand All @@ -29,17 +31,14 @@ export class API {
constructor(
private app: App,
private plugin: ModalFormPlugin,
) { }
) {}

/**
* Opens a modal form with the provided form definition
* @param {FormDefinition} formDefinition - The form definition to use
* @returns {Promise<FormResult>} - A promise that resolves with the form result
*/
openModalForm(
formDefinition: FormDefinition,
options?: FormOptions,
): Promise<FormResult> {
openModalForm(formDefinition: FormDefinition, options?: FormOptions): Promise<FormResult> {
return new Promise((resolve) => {
new FormModal(this.app, formDefinition, resolve, options).open();
});
Expand All @@ -49,14 +48,12 @@ export class API {
}

private getFormByName(name: string): FormDefinition | undefined {
const form = this.plugin.settings?.formDefinitions.find(
(form) => form.name === name,
);
const form = this.plugin.settings?.formDefinitions.find((form) => form.name === name);
if (form instanceof MigrationError) {
log_notice(
"🚫 The form you tried to load has an invalid format",
`The form "${name}" has an invalid format.` +
`We tried to automatically convert it but it failed, please fix it manually in the forms manager.
`We tried to automatically convert it but it failed, please fix it manually in the forms manager.
`,
);
return undefined;
Expand All @@ -76,9 +73,7 @@ export class API {
if (formDefinition) {
return this.openModalForm(formDefinition, options);
} else {
const error = new ModalFormError(
`Form definition ${name} not found`,
);
const error = new ModalFormError(`Form definition ${name} not found`);
log_error(error);
return Promise.reject(error);
}
Expand All @@ -92,16 +87,12 @@ export class API {
const omit = opts.omit;
newFormDefinition = {
...formDefinition,
fields: formDefinition.fields.filter(
(field) => !omit.includes(field.name),
),
fields: formDefinition.fields.filter((field) => !omit.includes(field.name)),
};
} else if (isPickOption(opts)) {
newFormDefinition = {
...formDefinition,
fields: formDefinition.fields.filter((field) =>
opts.pick.includes(field.name),
),
fields: formDefinition.fields.filter((field) => opts.pick.includes(field.name)),
};
} else {
throw new ModalFormError(
Expand All @@ -111,9 +102,7 @@ export class API {
}
return this.openModalForm(newFormDefinition);
} else {
const error = new ModalFormError(
`Form definition ${name} not found`,
);
const error = new ModalFormError(`Form definition ${name} not found`);
log_error(error);
return Promise.reject(error);
}
Expand Down
2 changes: 1 addition & 1 deletion src/FormModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class FormModal extends Modal {
const name = definition.label || definition.name;
const required = definition.isRequired ?? false;
const fieldBase = new Setting(contentEl)
.setName(`${name} ${required ? "*" : ""}`)
.setName(`${name} ${required ? "*" : ""}`.trim())
.setDesc(definition.description);
// This intermediary constants are necessary so typescript can narrow down the proper types.
// without them, you will have to use the whole access path (definition.input.folder),
Expand Down
78 changes: 35 additions & 43 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,12 @@ import {
getDefaultSettings,
} from "src/core/settings";
import { log_error, log_notice } from "./utils/Log";
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 { O } from "@std";
import { O, pipe, E, A } from "@std";
import { executeTemplate } from "./core/template/templateParser";
import { NewNoteModal } from "./suggesters/NewNoteModal";
import { file_exists } from "./utils/files";
import { FormPickerModal } from "./suggesters/FormPickerModal";

type ViewType = typeof EDIT_FORM_VIEW | typeof MANAGE_FORMS_VIEW;

Expand Down Expand Up @@ -61,7 +59,7 @@ function notifyMigrationErrors(errors: MigrationError[]) {
// This is the plugin entrypoint
export default class ModalFormPlugin extends Plugin {
public settings: ModalFormSettings | undefined;
private unsubscribeSettingsStore: () => void = () => { };
private unsubscribeSettingsStore: () => void = () => {};
// This things will be setup in the onload function rather than constructor
public api!: PublicAPI;

Expand All @@ -84,9 +82,7 @@ export default class ModalFormPlugin extends Plugin {
// then if you save another form you will unexpectedly save the mutated form too.
// Maybe we could instead do a deep copy instead, but until this proven to be a bottleneck I will leave it like this.
const savedSettings = await this.getSettings();
const formDefinition = savedSettings.formDefinitions.find(
(form) => form.name === formName,
);
const formDefinition = savedSettings.formDefinitions.find((form) => form.name === formName);
if (!formDefinition) {
throw new ModalFormError(`Form ${formName} not found`);
}
Expand All @@ -107,14 +103,10 @@ export default class ModalFormPlugin extends Plugin {

async activateView(viewType: ViewType, state?: FormDefinition) {
const { workspace } = this.app;
let leaf: WorkspaceLeaf | undefined =
workspace.getLeavesOfType(viewType)[0];
let leaf: WorkspaceLeaf | undefined = workspace.getLeavesOfType(viewType)[0];
if (leaf) {
console.info("found leaf, no reason to create a new one");
} else if (
Platform.isMobile ||
this.settings?.editorPosition === "mainView"
) {
} else if (Platform.isMobile || this.settings?.editorPosition === "mainView") {
leaf = this.app.workspace.getLeaf("tab");
} else if (this.settings?.editorPosition === "right") {
leaf = this.app.workspace.getRightLeaf(false);
Expand Down Expand Up @@ -142,11 +134,10 @@ export default class ModalFormPlugin extends Plugin {
const [migrationIsNeeded, settings] = pipe(
parseSettings(data),
E.map((settings): [boolean, ModalFormSettings] => {
const migrationIsNeeded =
settings.formDefinitions.some(formNeedsMigration);
const { right: formDefinitions, left: errors } = A.partitionMap(
migrateToLatest,
)(settings.formDefinitions);
const migrationIsNeeded = settings.formDefinitions.some(formNeedsMigration);
const { right: formDefinitions, left: errors } = A.partitionMap(migrateToLatest)(
settings.formDefinitions,
);
notifyParsingErrors(errors);
const validSettings: ModalFormSettings = {
...settings,
Expand Down Expand Up @@ -175,8 +166,8 @@ export default class ModalFormPlugin extends Plugin {

attachShortcutToGlobalWindow() {
if (!this.settings) {
log_error(new ModalFormError("Settings not loaded yet"))
return
log_error(new ModalFormError("Settings not loaded yet"));
return;
}
const globalNamespace = this.settings.globalNamespace;
if (this.settings?.attachShortcutToGlobalWindow) {
Expand All @@ -190,6 +181,13 @@ export default class ModalFormPlugin extends Plugin {
await this.saveSettings();
}

get validFormDefinitions(): FormDefinition[] {
return pipe(
this.settings!.formDefinitions,
A.filterMap((form) => (form instanceof MigrationError ? O.none : O.some(form))),
);
}

async onload() {
const settings = await this.getSettings();
if (settings.formDefinitions.length === 0) {
Expand All @@ -203,14 +201,8 @@ export default class ModalFormPlugin extends Plugin {
});
this.api = new API(this.app, this);
this.attachShortcutToGlobalWindow();
this.registerView(
EDIT_FORM_VIEW,
(leaf) => new EditFormView(leaf, this),
);
this.registerView(
MANAGE_FORMS_VIEW,
(leaf) => new ManageFormsView(leaf, this),
);
this.registerView(EDIT_FORM_VIEW, (leaf) => new EditFormView(leaf, this));
this.registerView(MANAGE_FORMS_VIEW, (leaf) => new ManageFormsView(leaf, this));

// This creates an icon in the left ribbon.
this.addRibbonIcon("documents", "Edit forms", (evt: MouseEvent) => {
Expand Down Expand Up @@ -239,6 +231,16 @@ export default class ModalFormPlugin extends Plugin {
},
});

this.addCommand({
id: "edit-form",
name: "Edit form",
callback: async () => {
new FormPickerModal(this.app, this.validFormDefinitions, (formToEdit) => {
this.activateView(EDIT_FORM_VIEW, formToEdit);
}).open();
},
});

// This adds a settings tab so the user can configure various aspects of the plugin
this.addSettingTab(new ModalFormSettingTab(this.app, this));
}
Expand All @@ -250,13 +252,9 @@ export default class ModalFormPlugin extends Plugin {
* @returns a unique name for the note, full path including the extension
*/
getUniqueNoteName(name: string, destinationFolder?: string): string {
const defaultNotesFolder = this.app.fileManager.getNewFileParent(
"",
"note.md",
);
const defaultNotesFolder = this.app.fileManager.getNewFileParent("", "note.md");
function makePath(name: string, folder?: string, suffix?: number) {
return `${folder || defaultNotesFolder.path}/${name}${suffix ? "-" + suffix : ""
}.md`;
return `${folder || defaultNotesFolder.path}/${name}${suffix ? "-" + suffix : ""}.md`;
}
let destinationPath = makePath(name, destinationFolder);
let i = 1;
Expand Down Expand Up @@ -291,14 +289,8 @@ export default class ModalFormPlugin extends Plugin {
destinationFolder: string,
) => {
const formData = await this.api.openForm(form);
const newNoteFullPath = this.getUniqueNoteName(
noteName,
destinationFolder,
);
const noteContent = executeTemplate(
form.template.parsedTemplate,
formData.getData(),
);
const newNoteFullPath = this.getUniqueNoteName(noteName, destinationFolder);
const noteContent = executeTemplate(form.template.parsedTemplate, formData.getData());
console.log("new note content", noteContent);
this.app.vault.create(newNoteFullPath, noteContent);
};
Expand Down

0 comments on commit 72c164c

Please sign in to comment.