import { PluginSettingTab, Setting } from "obsidian"; import type { App } from "obsidian"; import type BeaverCalendarPlugin from "./main"; export type ViewMode = "list" | "calendar"; export type GroupBy = "sphere" | "project" | "status" | "due"; export type SortBy = "manual" | "priority" | "due"; export interface BeaverCalendarSettings { boardsFolder: string; archiveFolder: string; view: ViewMode; groupBy: GroupBy; listSort: SortBy; calendarSort: SortBy; showDone: boolean; includeArchive: boolean; railCollapsed: boolean; undatedCollapsed: boolean; /** The lane the last task was written into, so the composer opens there. */ lastLanePath: string; lastLaneProject: string; } export const DEFAULT_SETTINGS: BeaverCalendarSettings = { boardsFolder: "Boards", archiveFolder: "archive", view: "list", groupBy: "sphere", listSort: "due", calendarSort: "priority", showDone: false, includeArchive: false, railCollapsed: false, undatedCollapsed: false, lastLanePath: "", lastLaneProject: "", }; export function normalizeFolder(value: string): string { return value.trim().replace(/^\/+/u, "").replace(/\/+$/u, ""); } export class BeaverCalendarSettingsTab extends PluginSettingTab { constructor( app: App, private readonly plugin: BeaverCalendarPlugin, ) { super(app, plugin); } display(): void { const { containerEl } = this; containerEl.empty(); new Setting(containerEl) .setName("Boards folder") .setDesc( "Every markdown file in this folder is a sphere, and every second-level heading inside it is a project.", ) .addText((text) => text .setPlaceholder("Boards") .setValue(this.plugin.settings.boardsFolder) .onChange(async (value) => { this.plugin.settings.boardsFolder = normalizeFolder(value); await this.plugin.saveSettings(); await this.plugin.store.reloadAll(); }), ); new Setting(containerEl) .setName("Archive folder") .setDesc( "A subfolder mirroring the boards folder, where the archive command " + "puts completed tasks: a board at Boards/work.md archives into " + "Boards/archive/work.md, itself a Kanban board with the same lanes. " + "The command also lifts a board's old *** archive section in there.", ) .addText((text) => text .setPlaceholder("archive") .setValue(this.plugin.settings.archiveFolder) .onChange(async (value) => { this.plugin.settings.archiveFolder = normalizeFolder(value) || "archive"; await this.plugin.saveSettings(); await this.plugin.store.reloadAll(); }), ); new Setting(containerEl) .setName("Include the archive") .setDesc( "Widen the show-completed toggle to reach archived tasks - both the " + "archive folder and whatever still sits below a board's *** " + "separator. With this off, show-completed only reveals completed " + "tasks still in their lanes. Archived tasks carry an Archive badge " + "instead of a project one.", ) .addToggle((toggle) => toggle .setValue(this.plugin.settings.includeArchive) .onChange(async (value) => { this.plugin.settings.includeArchive = value; this.plugin.store.includeArchive = value; await this.plugin.saveSettings(); }), ); new Setting(containerEl) .setName("Show completed") .setDesc("Completed tasks are hidden from the list and the calendar by default.") .addToggle((toggle) => toggle .setValue(this.plugin.settings.showDone) .onChange(async (value) => { this.plugin.settings.showDone = value; this.plugin.store.showDone = value; await this.plugin.saveSettings(); }), ); } }