From 288f276d6151ab29ce78fa216078462e624b789c Mon Sep 17 00:00:00 2001 From: steeven Date: Thu, 4 Apr 2024 20:23:26 +0200 Subject: [PATCH] first implementation of the main.ts file: settings tab --- main.ts | 294 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 200 insertions(+), 94 deletions(-) diff --git a/main.ts b/main.ts index 2d07212..f61ccdd 100644 --- a/main.ts +++ b/main.ts @@ -1,134 +1,240 @@ -import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian'; +import test from "node:test"; +import { + App, + ButtonComponent, + Editor, + MarkdownEditView, + MarkdownView, + Modal, + Notice, + Plugin, + PluginSettingTab, + Setting, + setIcon, +} from "obsidian"; -// Remember to rename these classes and interfaces! - -interface MyPluginSettings { +interface BudgetSettings { mySetting: string; } -const DEFAULT_SETTINGS: MyPluginSettings = { - mySetting: 'default' -} +const DEFAULT_SETTINGS: BudgetSettings = { + mySetting: "default", +}; -export default class MyPlugin extends Plugin { - settings: MyPluginSettings; +export default class budgetPlugin extends Plugin { + settings: BudgetSettings | "test" = DEFAULT_SETTINGS; async onload() { - await this.loadSettings(); - - // This creates an icon in the left ribbon. - const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => { - // Called when the user clicks the icon. - new Notice('This is a notice!'); - }); - // Perform additional things with the ribbon - ribbonIconEl.addClass('my-plugin-ribbon-class'); - - // This adds a status bar item to the bottom of the app. Does not work on mobile apps. - const statusBarItemEl = this.addStatusBarItem(); - statusBarItemEl.setText('Status Bar Text'); - - // This adds a simple command that can be triggered anywhere - this.addCommand({ - id: 'open-sample-modal-simple', - name: 'Open sample modal (simple)', - callback: () => { - new SampleModal(this.app).open(); - } - }); - // This adds an editor command that can perform some operation on the current editor instance - this.addCommand({ - id: 'sample-editor-command', - name: 'Sample editor command', - editorCallback: (editor: Editor, view: MarkdownView) => { - console.log(editor.getSelection()); - editor.replaceSelection('Sample Editor Command'); - } - }); - // This adds a complex command that can check whether the current state of the app allows execution of the command - this.addCommand({ - id: 'open-sample-modal-complex', - name: 'Open sample modal (complex)', - checkCallback: (checking: boolean) => { - // Conditions to check - const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView); - if (markdownView) { - // If checking is true, we're simply "checking" if the command can be run. - // If checking is false, then we want to actually perform the operation. - if (!checking) { - new SampleModal(this.app).open(); + console.log(this.settings); + ///// starting the app + // addRibbon icon + const ribbonIconEl = this.addRibbonIcon( + "dollar-sign", + "New Expense", + (evt: MouseEvent) => { + new Notice("New Expense Modal"); + // need to start modal + new ExpenseModal( + this.app, + ( + expenseAmount, + expenseCategory, + expenseAccount, + expenseValue + ) => { + new Notice( + `${expenseAmount}, ${expenseCategory}, ${expenseAccount}, ${expenseValue}` + ); } + ).open(); - // This command will only show up in Command Palette when the check function returns true - return true; - } + // need to set active md file to budget + console.log("Debug: trigger new expense modal from ribbon"); } - }); - - // This adds a settings tab so the user can configure various aspects of the plugin - this.addSettingTab(new SampleSettingTab(this.app, this)); - - // If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin) - // Using this function will automatically remove the event listener when this plugin is disabled. - this.registerDomEvent(document, 'click', (evt: MouseEvent) => { - console.log('click', evt); - }); - - // When registering intervals, this function will automatically clear the interval when the plugin is disabled. - this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000)); + ); + // Adds a setting tag so the user ca configure the aspects of the plugin + this.addSettingTab(new ExpenseSettingTab(this.app, this)); } - onunload() { + onunload(): void {} + async loadSettings(): Promise { + this.settings = Object.assign( + {}, + DEFAULT_SETTINGS, + await this.loadData() + ); } - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } - - async saveSettings() { + async saveSettings(): Promise { await this.saveData(this.settings); } } -class SampleModal extends Modal { - constructor(app: App) { +export class ExpenseModal extends Modal { + expenseAmount: string = "120"; + expenseCategory: string; + expenseAccount: string = "cash"; + expenseValue: string = "basics"; + + onSubmit: ( + expenseAmount: string, + expenseCategory: string, + expenseAccount: string, + expenseValue: string + ) => void; + + constructor( + app: App, + onSubmit: ( + expenseAmount: string, + expenseCategory: string, + expenseAccount: string, + expenseValue: string + ) => void + ) { super(app); + this.onSubmit = onSubmit; } onOpen() { - const {contentEl} = this; - contentEl.setText('Woah!'); - } + const { contentEl } = this; + contentEl.createEl("h1", { text: "Enter new Expense" }); + new Setting(contentEl).setName("Amount").addText((text) => + text.onChange((value) => { + this.expenseAmount = value; + }) + ); + + // move this to the setting + const category = [ + { categoryId: 1, categoryName: "Eat", categoryIcon: "carrot" }, + { + categoryId: 2, + categoryName: "Home", + categoryIcon: "home", + }, + { + categoryId: 3, + categoryName: "Leisure", + categoryIcon: "armchair", + }, + { + categoryId: 4, + categoryName: "Beauty", + categoryIcon: "glasses", + }, + { + categoryId: 5, + categoryName: "Holidays", + categoryIcon: "caravan", + }, + { + categoryId: 6, + categoryName: "Transport", + categoryIcon: "car", + }, + ]; + + const categorySetting = new Setting(contentEl).setName("Category"); + category.forEach((c) => { + const setting = categorySetting.addButton((btn: ButtonComponent) => + btn + .setButtonText(c.categoryName) + .setIcon(c.categoryIcon) + .setTooltip(c.categoryName) + .onClick(() => { + this.expenseCategory = c.categoryName; + new Notice(`Selected Category: ${c.categoryName}`); + btn.setCta(); + }) + ); + }); + + new Setting(contentEl).setName("Account").addText((text) => + text.onChange((value = "cash") => { + this.expenseAccount = value; + }) + ); + + new Setting(contentEl).setName("Rating").addText((text) => + text.onChange((value) => { + this.expenseValue = value; + }) + ); + + new Setting(contentEl).addButton((btn) => + btn + .setButtonText("Submit") + .setCta() + .onClick(() => { + this.close(); + this.onSubmit( + this.expenseAmount, + this.expenseCategory, + this.expenseAccount, + this.expenseValue + ); + const file = this.app.workspace.getActiveFile(); + if (file) { + console.log("Debug: active file", file.basename); + const editor = + this.app.workspace.getActiveViewOfType( + MarkdownView + ); + if (editor) { + console.log("Debug: active editor", 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} | ${this.expenseAmount} | ${this.expenseCategory} | ${this.expenseAccount} | ${this.expenseValue} | \n` + ); + } + } else { + console.log("Debug: no active file"); + } + }) + ); + } onClose() { - const {contentEl} = this; + let { contentEl } = this; contentEl.empty(); } } -class SampleSettingTab extends PluginSettingTab { - plugin: MyPlugin; +class ExpenseSettingTab extends PluginSettingTab { + plugin: budgetPlugin; - constructor(app: App, plugin: MyPlugin) { + constructor(app: App, plugin: budgetPlugin) { super(app, plugin); this.plugin = plugin; } display(): void { - const {containerEl} = this; - + const { containerEl } = this; + console.log(this.plugin.settings); containerEl.empty(); new Setting(containerEl) - .setName('Setting #1') - .setDesc('It\'s a secret') - .addText(text => text - .setPlaceholder('Enter your secret') - .setValue(this.plugin.settings.mySetting) - .onChange(async (value) => { - this.plugin.settings.mySetting = value; - await this.plugin.saveSettings(); - })); + .setName("MySetting.settings") + .setDesc("Category 1") + .addText((text) => + text + .setPlaceholder("First setting = categories") + .setValue(this.plugin.settings.mySetting) + .onChange(async (value) => { + this.plugin.settings.mySetting = value; + await this.plugin.saveSettings(); + console.log("Secret: " + value); + }) + ); } }