obsidian-sample-plugin/expenseModal.ts

211 lines
5.3 KiB
TypeScript

// this modal opens a new modal to add a new expense and write it down on the budgetMarkdownFile
import {
App,
Modal,
Notice,
ButtonComponent,
MarkdownView,
Setting,
} from "obsidian";
import budgetPlugin from "./main";
import { DEFAULT_SETTINGS } from "./main";
export class ExpenseModal extends Modal {
plugin: budgetPlugin = DEFAULT_SETTINGS;
expenseAmount: string;
expenseAccount: string;
expenseCategory: string;
expenseValue: string;
onSubmit: (
expenseAmount: string,
expenseCategory: string,
expenseAccount: string,
expenseValue: string
) => void;
constructor(
app: App,
plugin: budgetPlugin,
onSubmit: (
expenseAmount: string,
expenseCategory: string,
expenseAccount: string,
expenseValue: string
) => void
) {
super(app);
this.plugin = plugin;
this.onSubmit = onSubmit;
}
async onOpen() {
const { contentEl } = this;
contentEl.createEl("h1", { text: "Enter new Expense" });
// get the data from the plugin settings
const pluginData = await this.plugin.loadData();
// create a currency formatter
// to do : get regional settings from obsidian
const formatter = new Intl.NumberFormat("fr-FR", {
style: "currency",
currency: pluginData.currency,
});
// input field for the expense amount
new Setting(contentEl).setName("Amount").addText((text) =>
text.onChange((value) => {
// convert comma to dot (need to check this if internationalizing)
if (value.includes(",")) {
value = value.replace(",", ".");
}
this.expenseAmount = value;
})
);
// focus on the input field expense
const inputElement = contentEl.querySelector("input");
if (inputElement) {
inputElement.focus();
}
// create category button with icon and tooltip
const categorySetting = new Setting(contentEl).setName("Category");
let selectedButton: ButtonComponent | null = null;
Object.entries(pluginData.expenseCategories).forEach(
([key, value]: [string, { icon: string; name: string }]) => {
categorySetting.addButton((btn: ButtonComponent) =>
btn
.setButtonText(key)
.setIcon(value.icon)
.setTooltip(value.name)
.onClick(() => {
// remove the cta from the previous button
if (selectedButton) {
selectedButton.removeCta();
}
selectedButton = btn;
this.expenseCategory = value.name;
new Notice(`Selected Category: ${value.name}`);
btn.setCta();
})
);
}
);
// create account button with icon and tooltip
const accountSetting = new Setting(contentEl).setName("Account");
let selectedButton2: ButtonComponent | null = null;
Object.entries(pluginData.expenseAccounts).forEach(
([key, value]: [string, { icon: string; name: string }]) => {
accountSetting.addButton((btn: ButtonComponent) =>
btn
.setButtonText(key)
.setIcon(value.icon)
.setTooltip(value.name)
.onClick(() => {
// remove the cta from the previous button
if (selectedButton2) {
selectedButton2.removeCta();
}
selectedButton2 = btn;
this.expenseAccount = value.name;
new Notice(`Selected Account: ${value.name}`);
btn.setCta();
})
);
}
);
const valueSetting = new Setting(contentEl).setName("Value");
let selectedButton3: ButtonComponent | null = null;
Object.entries(pluginData.expenseValues).forEach(
([key, value]: [string, { icon: string; name: string }]) => {
valueSetting.addButton((btn: ButtonComponent) =>
btn
.setButtonText(key)
.setIcon(value.icon)
.setTooltip(value.name)
.onClick(() => {
// remove the cta from the previous button
if (selectedButton3) {
selectedButton3.removeCta();
}
selectedButton3 = btn;
this.expenseValue = value.name;
new Notice(`Selected Value: ${value.name}`);
btn.setCta();
})
);
}
);
// submit button
new Setting(contentEl).addButton((btn) =>
btn
.setButtonText("Submit")
.setCta()
.onClick(() => {
// check if all fields are filled
if (
this.expenseAmount &&
this.expenseCategory &&
this.expenseAccount &&
this.expenseValue
) {
new Notice("Expense added");
this.close();
this.onSubmit(
this.expenseAmount,
this.expenseCategory,
this.expenseAccount,
this.expenseValue
);
const file = this.app.workspace.getActiveFile();
if (file) {
const editor =
this.app.workspace.getActiveViewOfType(
MarkdownView
);
if (editor) {
// get today date and format YYYY-MM-DD
const today = new Date();
const todayFormatted = today
.toISOString()
.split("T")[0];
// move the cursor on start of line 3
editor.editor.setCursor(2, 0);
// insert the new expense on line 3
editor.editor.replaceSelection(
`| ${todayFormatted} | ${formatter.format(
Number(this.expenseAmount)
)} | ${this.expenseCategory} | ${
this.expenseAccount
} | ${this.expenseValue} | \n`
);
}
} else {
console.log("Debug: no active file");
}
} else {
new Notice("Please fill all the fields");
return;
}
})
);
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
}