From a97fa797b494cd3f8f195023e707a71be00ae24e Mon Sep 17 00:00:00 2001 From: Al0cam Date: Sat, 25 Oct 2025 20:02:46 +0200 Subject: [PATCH] feat: add collapse of rule lists --- Settings/ExclusionSection.ts | 27 ++++++++++++++------------- Settings/MovingRuleSection.ts | 22 ++++++++++++---------- Settings/Settings.ts | 16 +++++++++++++--- Settings/SettingsTab.ts | 17 +++++++++++++++-- Settings/TagSection.ts | 23 +++++++++++++---------- 5 files changed, 67 insertions(+), 38 deletions(-) diff --git a/Settings/ExclusionSection.ts b/Settings/ExclusionSection.ts index 058f1ed..b6845e6 100644 --- a/Settings/ExclusionSection.ts +++ b/Settings/ExclusionSection.ts @@ -2,20 +2,25 @@ import { ExclusionRule } from "Models/ExclusionRule"; import type AutoMoverPlugin from "main"; import { Setting } from "obsidian"; -export function exclusionSection( - containerEl: HTMLElement, - plugin: AutoMoverPlugin, - display: () => void, -) { +export function exclusionSection(containerEl: HTMLElement, plugin: AutoMoverPlugin, display: () => void) { /** * Header for excluded folders */ const exclusionRuleContainer = containerEl.createDiv({ cls: "moving_rules_container", }); - new Setting(exclusionRuleContainer).setName("Exclusion rules").setHeading(); - const exclusionList = exclusionRuleContainer.createDiv({ + // Class used from obdsidian's css for consistency + const exclusionRuleDetails = exclusionRuleContainer.createEl("details", {}); + exclusionRuleDetails.createEl("summary", { text: "Exclusion rules", cls: ["setting-item-heading"] }); + + exclusionRuleDetails.open = !plugin.settings.collapseSections.exclusionRules; + exclusionRuleDetails.addEventListener("toggle", async () => { + plugin.settings.collapseSections.exclusionRules = !exclusionRuleDetails.open; + await plugin.saveData(plugin.settings); + }); + + const exclusionList = exclusionRuleDetails.createDiv({ cls: "rule_list", }); const exclusionHeader = exclusionList.createDiv({ @@ -45,9 +50,7 @@ export function exclusionSection( cls: "rule_input", }).onchange = (e) => { exclusion.regex = (e.target as HTMLInputElement).value; - plugin.settings.exclusionRules.map((ef) => - ef === exclusion ? exclusion : ef, - ); + plugin.settings.exclusionRules.map((ef) => (ef === exclusion ? exclusion : ef)); plugin.saveData(plugin.settings); }; @@ -65,9 +68,7 @@ export function exclusionSection( cls: "rule_button rule_button_remove", }); deleteExclusionButton.addEventListener("click", () => { - plugin.settings.exclusionRules = plugin.settings.exclusionRules.filter( - (r) => r !== exclusion, - ); + plugin.settings.exclusionRules = plugin.settings.exclusionRules.filter((r) => r !== exclusion); display(); }); } diff --git a/Settings/MovingRuleSection.ts b/Settings/MovingRuleSection.ts index e40054e..fd6c76d 100644 --- a/Settings/MovingRuleSection.ts +++ b/Settings/MovingRuleSection.ts @@ -2,11 +2,7 @@ import AutoMoverPlugin from "main"; import { MovingRule } from "Models/MovingRule"; import { Setting } from "obsidian"; -export default function movingRuleSection( - containerEl: HTMLElement, - plugin: AutoMoverPlugin, - display: () => void, -) { +export default function movingRuleSection(containerEl: HTMLElement, plugin: AutoMoverPlugin, display: () => void) { /** * Header of the rules */ @@ -14,9 +10,17 @@ export default function movingRuleSection( cls: "moving_rules_container", }); - new Setting(movingRulesContainer).setName("Moving rules").setHeading(); + // Class used from obdsidian's css for consistency + const movingRuleDetails = movingRulesContainer.createEl("details", {}); + movingRuleDetails.createEl("summary", { text: "Moving rules", cls: ["setting-item-heading"] }); - const ruleList = movingRulesContainer.createDiv({ cls: "rule_list" }); + movingRuleDetails.open = !plugin.settings.collapseSections.movingRules; + movingRuleDetails.addEventListener("toggle", async () => { + plugin.settings.collapseSections.movingRules = !movingRuleDetails.open; + await plugin.saveData(plugin.settings); + }); + + const ruleList = movingRuleDetails.createDiv({ cls: "rule_list" }); const ruleHeader = ruleList.createDiv({ cls: "rule margig_right" }); ruleHeader.createEl("p", { text: "Search criteria (string or regex)", @@ -72,9 +76,7 @@ export default function movingRuleSection( cls: "rule_button rule_button_remove", }); deleteRuleButton.addEventListener("click", () => { - plugin.settings.movingRules = plugin.settings.movingRules.filter( - (r) => r !== rule, - ); + plugin.settings.movingRules = plugin.settings.movingRules.filter((r) => r !== rule); display(); }); } diff --git a/Settings/Settings.ts b/Settings/Settings.ts index 547d1fe..0d30fe7 100644 --- a/Settings/Settings.ts +++ b/Settings/Settings.ts @@ -10,6 +10,12 @@ export interface AutoMoverSettings { tagRules: MovingRule[]; automaticMoving: boolean; timer: number | null; // in miliseconds + collapseSections: { + tutorial: boolean; + movingRules: boolean; + exclusionRules: boolean; + tagRules: boolean; + }; } export const DEFAULT_SETTINGS: Partial = { @@ -20,10 +26,14 @@ export const DEFAULT_SETTINGS: Partial = { tagRules: [], automaticMoving: false, timer: null, + collapseSections: { + tutorial: false, + movingRules: false, + exclusionRules: false, + tagRules: false, + }, }; -function loadSettings( - AutoMoverPlugin: AutoMoverPlugin, -): Partial { +function loadSettings(AutoMoverPlugin: AutoMoverPlugin): Partial { return Object.assign({}, DEFAULT_SETTINGS, AutoMoverPlugin.loadData()); } diff --git a/Settings/SettingsTab.ts b/Settings/SettingsTab.ts index 5f46b6f..bf8f319 100644 --- a/Settings/SettingsTab.ts +++ b/Settings/SettingsTab.ts @@ -5,6 +5,7 @@ import { type App, PluginSettingTab, Setting } from "obsidian"; import { exclusionSection } from "./ExclusionSection"; import movingRuleSection from "./MovingRuleSection"; import { tagSection } from "./TagSection"; +import { groupCollapsed } from "console"; export class SettingsTab extends PluginSettingTab { plugin: AutoMoverPlugin; @@ -102,11 +103,23 @@ export class SettingsTab extends PluginSettingTab { const tutorialContainer = containerEl.createDiv({ cls: "moving_rules_container", }); - new Setting(tutorialContainer).setName("Tutorial").setHeading(); + + // Class used from obdsidian's css for consistency + const tutorialDetails = tutorialContainer.createEl("details", {}); + tutorialDetails.createEl("summary", { text: "Tutorial", cls: ["setting-item-heading"] }); + + tutorialDetails.open = !this.plugin.settings.collapseSections.tutorial; + tutorialDetails.addEventListener("toggle", async () => { + this.plugin.settings.collapseSections.tutorial = !tutorialDetails.open; + await this.plugin.saveData(this.plugin.settings); + }); + + const tutorialDetailsContainer = tutorialDetails.createDiv({}); + /** * Rule description and tutorial */ - const description = tutorialContainer.createDiv(); + const description = tutorialDetailsContainer.createDiv(); description.createSpan({ text: "This plugin allows you to move files to a specified folder based on the file name.", diff --git a/Settings/TagSection.ts b/Settings/TagSection.ts index caed175..8866e94 100644 --- a/Settings/TagSection.ts +++ b/Settings/TagSection.ts @@ -2,20 +2,25 @@ import { MovingRule } from "Models/MovingRule"; import * as obsidian from "obsidian"; import type AutoMoverPlugin from "main"; -export function tagSection( - containerEl: HTMLElement, - plugin: AutoMoverPlugin, - display: () => void, -) { +export function tagSection(containerEl: HTMLElement, plugin: AutoMoverPlugin, display: () => void) { /** * Header for excluded folders */ const tagRuleContainer = containerEl.createDiv({ cls: "moving_rules_container", }); - new obsidian.Setting(tagRuleContainer).setName("Tag rules").setHeading(); - const tagList = tagRuleContainer.createDiv({ + // Class used from obdsidian's css for consistency + const tagRuleDetails = tagRuleContainer.createEl("details", {}); + tagRuleDetails.createEl("summary", { text: "Tag rules", cls: ["setting-item-heading"] }); + + tagRuleDetails.open = !plugin.settings.collapseSections.tagRules; + tagRuleDetails.addEventListener("toggle", async () => { + plugin.settings.collapseSections.tagRules = !tagRuleDetails.open; + await plugin.saveData(plugin.settings); + }); + + const tagList = tagRuleDetails.createDiv({ cls: "rule_list", }); const tagHeader = tagList.createDiv({ @@ -71,9 +76,7 @@ export function tagSection( cls: "rule_button rule_button_remove", }); deleteRuleButton.addEventListener("click", () => { - plugin.settings.tagRules = plugin.settings.tagRules.filter( - (r) => r !== rule, - ); + plugin.settings.tagRules = plugin.settings.tagRules.filter((r) => r !== rule); display(); }); }