From b85c65a841cef1c7866ee6857df9a83788fd1971 Mon Sep 17 00:00:00 2001 From: dralkh Date: Thu, 9 Oct 2025 09:29:59 +0300 Subject: [PATCH] feat(settings): add granular data clearing options --- .gitignore | 5 ++ main.js | 79 ++++++++++++++++++++++++++---- styles.css | 8 +++ styles/settings.css | 11 +++++ ui/settings-tab.ts | 115 +++++++++++++++++++++++++++++++++++++------- 5 files changed, 190 insertions(+), 28 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d828444 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules/.bin/acorn +node_modules +.kilocode +opencode.json diff --git a/main.js b/main.js index 0d0bdb1..827ea7f 100644 --- a/main.js +++ b/main.js @@ -7467,7 +7467,7 @@ var SpaceforgeSettingTab = class extends import_obsidian19.PluginSettingTab { }; const createActionButtons = () => { const actionsContainer = containerEl.createEl("div", { cls: "sf-settings-actions" }); - const exportBtn = actionsContainer.createEl("button", { text: "Export all data" }); + const exportBtn = actionsContainer.createEl("button", { text: "Export all data", cls: "sf-btn sf-btn-primary" }); exportBtn.addEventListener("click", () => { var _a, _b, _c, _d, _e, _f, _g, _h, _i; const pluginStateToExport = { @@ -7508,7 +7508,7 @@ var SpaceforgeSettingTab = class extends import_obsidian19.PluginSettingTab { document.body.removeChild(a); new import_obsidian19.Notice("All plugin data exported successfully"); }); - const importBtn = actionsContainer.createEl("button", { text: "Import all data" }); + const importBtn = actionsContainer.createEl("button", { text: "Import all data", cls: "sf-btn sf-btn-primary" }); importBtn.addEventListener("click", () => { const input = document.createElement("input"); input.type = "file"; @@ -7545,7 +7545,7 @@ var SpaceforgeSettingTab = class extends import_obsidian19.PluginSettingTab { }; input.click(); }); - const resetBtn = actionsContainer.createEl("button", { text: "Reset to defaults" }); + const resetBtn = actionsContainer.createEl("button", { text: "Reset to defaults", cls: "sf-btn sf-btn-warning" }); resetBtn.addEventListener("click", async () => { var _a, _b, _c; const confirmed = confirm("Are you sure you want to reset all plugin data (settings and state) to defaults? This cannot be undone."); @@ -7567,12 +7567,12 @@ var SpaceforgeSettingTab = class extends import_obsidian19.PluginSettingTab { new import_obsidian19.Notice("All plugin data reset to defaults."); } }); - const clearScheduleBtn = actionsContainer.createEl("button", { - text: "Clear all schedule data", - cls: "sf-button-danger" - // Optional: Add a class for dangerous actions + const clearReviewsBtn = actionsContainer.createEl("button", { + text: "Clear all reviews", + cls: "sf-btn sf-btn-danger" + // Use existing danger button styling }); - clearScheduleBtn.addEventListener("click", async () => { + clearReviewsBtn.addEventListener("click", async () => { var _a; const confirmed = confirm("Are you sure you want to clear all review schedules, history, and session data? This action cannot be undone."); if (confirmed) { @@ -7592,11 +7592,70 @@ var SpaceforgeSettingTab = class extends import_obsidian19.PluginSettingTab { this.plugin.events.emit("sidebar-update"); } await this.plugin.savePluginData(); - new import_obsidian19.Notice("All schedule data cleared successfully."); + new import_obsidian19.Notice("All review data cleared successfully."); this.display(); (_a = this.plugin.getSidebarView()) == null ? void 0 : _a.refresh(); } catch (error) { - new import_obsidian19.Notice("Failed to clear schedule data. Check console for details."); + new import_obsidian19.Notice("Failed to clear review data. Check console for details."); + } + } + }); + const clearEventsBtn = actionsContainer.createEl("button", { + text: "Clear all events", + cls: "sf-btn sf-btn-danger" + }); + clearEventsBtn.addEventListener("click", async () => { + var _a; + const confirmed = confirm("Are you sure you want to clear all calendar events? This action cannot be undone."); + if (confirmed) { + try { + this.plugin.pluginState.calendarEvents = { ...DEFAULT_PLUGIN_STATE_DATA.calendarEvents }; + if (this.plugin.calendarEventService) { + this.plugin.calendarEventService.initialize([]); + } + await this.plugin.savePluginData(); + new import_obsidian19.Notice("All calendar events cleared successfully."); + this.display(); + (_a = this.plugin.getSidebarView()) == null ? void 0 : _a.refresh(); + } catch (error) { + new import_obsidian19.Notice("Failed to clear calendar events. Check console for details."); + } + } + }); + const clearAllBtn = actionsContainer.createEl("button", { + text: "Clear all data", + cls: "sf-btn sf-btn-danger" + }); + clearAllBtn.addEventListener("click", async () => { + var _a, _b, _c, _d; + const confirmed = confirm("Are you sure you want to clear ALL plugin data (reviews, events, MCQs, Pomodoro state)? This action cannot be undone."); + if (confirmed) { + try { + this.plugin.pluginState = JSON.parse(JSON.stringify(DEFAULT_PLUGIN_STATE_DATA)); + this.plugin.reviewScheduleService.schedules = this.plugin.pluginState.schedules; + this.plugin.reviewHistoryService.history = this.plugin.pluginState.history; + this.plugin.reviewSessionService.reviewSessions = this.plugin.pluginState.reviewSessions; + this.plugin.mcqService.mcqSets = this.plugin.pluginState.mcqSets; + this.plugin.mcqService.mcqSessions = this.plugin.pluginState.mcqSessions; + this.plugin.reviewScheduleService.customNoteOrder = this.plugin.pluginState.customNoteOrder; + this.plugin.reviewScheduleService.lastLinkAnalysisTimestamp = (_a = this.plugin.pluginState.lastLinkAnalysisTimestamp) != null ? _a : null; + if (this.plugin.calendarEventService) { + this.plugin.calendarEventService.initialize([]); + } + (_b = this.plugin.pomodoroService) == null ? void 0 : _b.onSettingsChanged(); + (_c = this.plugin.pomodoroService) == null ? void 0 : _c.reinitializeTimerFromState(); + if (this.plugin.reviewController) { + await this.plugin.reviewController.updateTodayNotes(); + } + if (this.plugin.events) { + this.plugin.events.emit("sidebar-update"); + } + await this.plugin.savePluginData(); + new import_obsidian19.Notice("All plugin data cleared successfully."); + this.display(); + (_d = this.plugin.getSidebarView()) == null ? void 0 : _d.refresh(); + } catch (error) { + new import_obsidian19.Notice("Failed to clear all data. Check console for details."); } } }); diff --git a/styles.css b/styles.css index b9f9288..86e5fbf 100644 --- a/styles.css +++ b/styles.css @@ -663,6 +663,14 @@ button.disabled:hover { opacity: 0.9; transform: translateY(-1px); } +.sf-settings-actions .sf-btn { + flex: 1; + min-width: 120px; +} +.sf-settings-actions .sf-btn:hover { + opacity: 0.9; + transform: translateY(-1px); +} .sf-info-box { background-color: var(--sf-bg-secondary); padding: var(--sf-space-md); diff --git a/styles/settings.css b/styles/settings.css index decf6da..c6dc290 100644 --- a/styles/settings.css +++ b/styles/settings.css @@ -106,6 +106,17 @@ transform: translateY(-1px); } +/* Ensure button classes work properly in settings actions */ +.sf-settings-actions .sf-btn { + flex: 1; + min-width: 120px; +} + +.sf-settings-actions .sf-btn:hover { + opacity: 0.9; + transform: translateY(-1px); +} + .sf-info-box { background-color: var(--sf-bg-secondary); padding: var(--sf-space-md); diff --git a/ui/settings-tab.ts b/ui/settings-tab.ts index 2f7795c..0e770b2 100644 --- a/ui/settings-tab.ts +++ b/ui/settings-tab.ts @@ -82,7 +82,7 @@ export class SpaceforgeSettingTab extends PluginSettingTab { const actionsContainer = containerEl.createEl('div', { cls: 'sf-settings-actions' }); // Export all data button - const exportBtn = actionsContainer.createEl('button', { text: 'Export all data' }); + const exportBtn = actionsContainer.createEl('button', { text: 'Export all data', cls: 'sf-btn sf-btn-primary' }); exportBtn.addEventListener('click', () => { // Construct the full plugin data for export const pluginStateToExport = { @@ -127,7 +127,7 @@ export class SpaceforgeSettingTab extends PluginSettingTab { }); // Import all data button - const importBtn = actionsContainer.createEl('button', { text: 'Import all data' }); + const importBtn = actionsContainer.createEl('button', { text: 'Import all data', cls: 'sf-btn sf-btn-primary' }); importBtn.addEventListener('click', () => { const input = document.createElement('input'); input.type = 'file'; @@ -181,7 +181,7 @@ export class SpaceforgeSettingTab extends PluginSettingTab { }); // Reset to defaults button - const resetBtn = actionsContainer.createEl('button', { text: 'Reset to defaults' }); + const resetBtn = actionsContainer.createEl('button', { text: 'Reset to defaults', cls: 'sf-btn sf-btn-warning' }); resetBtn.addEventListener('click', async () => { const confirmed = confirm('Are you sure you want to reset all plugin data (settings and state) to defaults? This cannot be undone.'); @@ -214,12 +214,12 @@ export class SpaceforgeSettingTab extends PluginSettingTab { } }); - // Clear Schedule Data button - const clearScheduleBtn = actionsContainer.createEl('button', { - text: 'Clear all schedule data', - cls: 'sf-button-danger' // Optional: Add a class for dangerous actions + // Clear Reviews Data button + const clearReviewsBtn = actionsContainer.createEl('button', { + text: 'Clear all reviews', + cls: 'sf-btn sf-btn-danger' // Use existing danger button styling }); - clearScheduleBtn.addEventListener('click', async () => { + clearReviewsBtn.addEventListener('click', async () => { const confirmed = confirm('Are you sure you want to clear all review schedules, history, and session data? This action cannot be undone.'); if (confirmed) { try { @@ -228,8 +228,6 @@ export class SpaceforgeSettingTab extends PluginSettingTab { this.plugin.pluginState.history = [...DEFAULT_PLUGIN_STATE_DATA.history]; this.plugin.pluginState.reviewSessions = { ...DEFAULT_PLUGIN_STATE_DATA.reviewSessions }; this.plugin.pluginState.customNoteOrder = [...DEFAULT_PLUGIN_STATE_DATA.customNoteOrder]; - // Potentially mcqSets and mcqSessions if they are tied to notes that might be unscheduled - // For now, focusing on explicit schedule data as requested. // Update services this.plugin.reviewScheduleService.schedules = this.plugin.pluginState.schedules; @@ -246,24 +244,105 @@ export class SpaceforgeSettingTab extends PluginSettingTab { if (this.plugin.events) { this.plugin.events.emit('sidebar-update'); } - - // If mcq data should also be cleared when schedules are cleared: - // this.plugin.pluginState.mcqSets = { ...DEFAULT_PLUGIN_STATE_DATA.mcqSets }; - // this.plugin.pluginState.mcqSessions = { ...DEFAULT_PLUGIN_STATE_DATA.mcqSessions }; - // this.plugin.mcqService.mcqSets = this.plugin.pluginState.mcqSets; - // this.plugin.mcqService.mcqSessions = this.plugin.pluginState.mcqSessions; // Save the cleared data first await this.plugin.savePluginData(); - new Notice('All schedule data cleared successfully.'); + new Notice('All review data cleared successfully.'); // Then refresh UI elements this.display(); // Refresh settings UI this.plugin.getSidebarView()?.refresh(); } catch (error) { - new Notice('Failed to clear schedule data. Check console for details.'); + new Notice('Failed to clear review data. Check console for details.'); + } + } + }); + + // Clear Events Data button + const clearEventsBtn = actionsContainer.createEl('button', { + text: 'Clear all events', + cls: 'sf-btn sf-btn-danger' + }); + clearEventsBtn.addEventListener('click', async () => { + const confirmed = confirm('Are you sure you want to clear all calendar events? This action cannot be undone.'); + if (confirmed) { + try { + // Reset calendar events in pluginState + this.plugin.pluginState.calendarEvents = { ...DEFAULT_PLUGIN_STATE_DATA.calendarEvents }; + + // Update calendar service if it exists + if (this.plugin.calendarEventService) { + this.plugin.calendarEventService.initialize([]); + } + + // Save the cleared data + await this.plugin.savePluginData(); + + new Notice('All calendar events cleared successfully.'); + + // Then refresh UI elements + this.display(); // Refresh settings UI + this.plugin.getSidebarView()?.refresh(); + + } catch (error) { + new Notice('Failed to clear calendar events. Check console for details.'); + } + } + }); + + // Clear All Data button + const clearAllBtn = actionsContainer.createEl('button', { + text: 'Clear all data', + cls: 'sf-btn sf-btn-danger' + }); + clearAllBtn.addEventListener('click', async () => { + const confirmed = confirm('Are you sure you want to clear ALL plugin data (reviews, events, MCQs, Pomodoro state)? This action cannot be undone.'); + if (confirmed) { + try { + // Reset all plugin state to defaults + this.plugin.pluginState = JSON.parse(JSON.stringify(DEFAULT_PLUGIN_STATE_DATA)); + + // Update all services + this.plugin.reviewScheduleService.schedules = this.plugin.pluginState.schedules; + this.plugin.reviewHistoryService.history = this.plugin.pluginState.history; + this.plugin.reviewSessionService.reviewSessions = this.plugin.pluginState.reviewSessions; + this.plugin.mcqService.mcqSets = this.plugin.pluginState.mcqSets; + this.plugin.mcqService.mcqSessions = this.plugin.pluginState.mcqSessions; + this.plugin.reviewScheduleService.customNoteOrder = this.plugin.pluginState.customNoteOrder; + this.plugin.reviewScheduleService.lastLinkAnalysisTimestamp = this.plugin.pluginState.lastLinkAnalysisTimestamp ?? null; + + // Update calendar service if it exists + if (this.plugin.calendarEventService) { + this.plugin.calendarEventService.initialize([]); + } + + // Update Pomodoro service + this.plugin.pomodoroService?.onSettingsChanged(); + this.plugin.pomodoroService?.reinitializeTimerFromState(); + + // Explicitly update the review controller's state + if (this.plugin.reviewController) { + await this.plugin.reviewController.updateTodayNotes(); + } + + // Emit an event that the sidebar might be listening to + if (this.plugin.events) { + this.plugin.events.emit('sidebar-update'); + } + + // Save the cleared data + await this.plugin.savePluginData(); + + new Notice('All plugin data cleared successfully.'); + + // Then refresh UI elements + this.display(); // Refresh settings UI + this.plugin.getSidebarView()?.refresh(); + + } catch (error) { + new Notice('Failed to clear all data. Check console for details.'); } } });