From 6135f7c708526efd445a5a08c348624367e86633 Mon Sep 17 00:00:00 2001 From: Bill Date: Tue, 28 Oct 2025 23:11:30 -0400 Subject: [PATCH] refactor: extract inline styles from notification-history to CSS Moved 36 inline style assignments from notification-history.ts to CSS classes in styles.css following the mcp-* naming pattern. This improves maintainability and separates presentation from logic. Changes: - Created CSS classes for all static styles (mcp-history-filters, mcp-history-count, mcp-history-list, mcp-history-empty, mcp-history-entry, mcp-history-entry-header, mcp-history-entry-header-meta, mcp-history-entry-args, mcp-history-entry-error, mcp-history-actions) - Created dynamic state classes for conditional styling (mcp-history-entry-border, mcp-history-entry-title-success, mcp-history-entry-title-error) - Updated notification-history.ts to use CSS classes via addClass() instead of inline style assignments - Retained only truly dynamic styles (borderBottom conditional, color conditional) as class toggles All tests pass (716/716), build succeeds. --- src/ui/notification-history.ts | 48 ++++---------------- styles.css | 82 ++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 39 deletions(-) diff --git a/src/ui/notification-history.ts b/src/ui/notification-history.ts index b220603..a9a4135 100644 --- a/src/ui/notification-history.ts +++ b/src/ui/notification-history.ts @@ -50,7 +50,6 @@ export class NotificationHistoryModal extends Modal { */ private createFilters(containerEl: HTMLElement): void { const filterContainer = containerEl.createDiv({ cls: 'mcp-history-filters' }); - filterContainer.style.marginBottom = '16px'; // Tool name filter using Setting component new Setting(filterContainer) @@ -80,9 +79,6 @@ export class NotificationHistoryModal extends Modal { // Results count this.countEl = filterContainer.createDiv({ cls: 'mcp-history-count' }); - this.countEl.style.marginTop = '8px'; - this.countEl.style.fontSize = '0.9em'; - this.countEl.style.color = 'var(--text-muted)'; this.updateResultsCount(); } @@ -91,11 +87,6 @@ export class NotificationHistoryModal extends Modal { */ private createHistoryListContainer(containerEl: HTMLElement): void { this.listContainerEl = containerEl.createDiv({ cls: 'mcp-history-list' }); - this.listContainerEl.style.maxHeight = '400px'; - this.listContainerEl.style.overflowY = 'auto'; - this.listContainerEl.style.marginBottom = '16px'; - this.listContainerEl.style.border = '1px solid var(--background-modifier-border)'; - this.listContainerEl.style.borderRadius = '4px'; // Initial render this.updateHistoryList(); @@ -112,36 +103,31 @@ export class NotificationHistoryModal extends Modal { if (this.filteredHistory.length === 0) { const emptyEl = this.listContainerEl.createDiv({ cls: 'mcp-history-empty' }); - emptyEl.style.padding = '24px'; - emptyEl.style.textAlign = 'center'; - emptyEl.style.color = 'var(--text-muted)'; emptyEl.textContent = 'No entries found'; return; } this.filteredHistory.forEach((entry, index) => { const entryEl = this.listContainerEl!.createDiv({ cls: 'mcp-history-entry' }); - entryEl.style.padding = '12px'; - entryEl.style.borderBottom = index < this.filteredHistory.length - 1 - ? '1px solid var(--background-modifier-border)' - : 'none'; + + // Add border class to all entries except the last one + if (index < this.filteredHistory.length - 1) { + entryEl.addClass('mcp-history-entry-border'); + } // Header row const headerEl = entryEl.createDiv({ cls: 'mcp-history-entry-header' }); - headerEl.style.display = 'flex'; - headerEl.style.justifyContent = 'space-between'; - headerEl.style.marginBottom = '8px'; // Tool name and status const titleEl = headerEl.createDiv(); const statusIcon = entry.success ? '✅' : '❌'; const toolName = titleEl.createEl('strong', { text: `${statusIcon} ${entry.toolName}` }); - toolName.style.color = entry.success ? 'var(--text-success)' : 'var(--text-error)'; + + // Add dynamic color class based on success/error + toolName.addClass(entry.success ? 'mcp-history-entry-title-success' : 'mcp-history-entry-title-error'); // Timestamp and duration - const metaEl = headerEl.createDiv(); - metaEl.style.fontSize = '0.85em'; - metaEl.style.color = 'var(--text-muted)'; + const metaEl = headerEl.createDiv({ cls: 'mcp-history-entry-header-meta' }); const timestamp = new Date(entry.timestamp).toLocaleTimeString(); const durationStr = entry.duration ? ` • ${entry.duration}ms` : ''; metaEl.textContent = `${timestamp}${durationStr}`; @@ -149,25 +135,12 @@ export class NotificationHistoryModal extends Modal { // Arguments if (entry.args && Object.keys(entry.args).length > 0) { const argsEl = entryEl.createDiv({ cls: 'mcp-history-entry-args' }); - argsEl.style.fontSize = '0.85em'; - argsEl.style.fontFamily = 'monospace'; - argsEl.style.backgroundColor = 'var(--background-secondary)'; - argsEl.style.padding = '8px'; - argsEl.style.borderRadius = '4px'; - argsEl.style.marginBottom = '8px'; - argsEl.style.overflowX = 'auto'; argsEl.textContent = JSON.stringify(entry.args, null, 2); } // Error message if (!entry.success && entry.error) { const errorEl = entryEl.createDiv({ cls: 'mcp-history-entry-error' }); - errorEl.style.fontSize = '0.85em'; - errorEl.style.color = 'var(--text-error)'; - errorEl.style.backgroundColor = 'var(--background-secondary)'; - errorEl.style.padding = '8px'; - errorEl.style.borderRadius = '4px'; - errorEl.style.fontFamily = 'monospace'; errorEl.textContent = entry.error; } }); @@ -186,9 +159,6 @@ export class NotificationHistoryModal extends Modal { */ private createActions(containerEl: HTMLElement): void { const actionsContainer = containerEl.createDiv({ cls: 'mcp-history-actions' }); - actionsContainer.style.display = 'flex'; - actionsContainer.style.gap = '8px'; - actionsContainer.style.justifyContent = 'flex-end'; // Export button const exportButton = actionsContainer.createEl('button', { text: 'Export to Clipboard' }); diff --git a/styles.css b/styles.css index 9fdd033..e680c13 100644 --- a/styles.css +++ b/styles.css @@ -151,3 +151,85 @@ .mcp-config-button { margin-bottom: 12px; } + +/* Notification History Modal */ +.mcp-notification-history-modal { + /* Base modal styling handled by Obsidian */ +} + +.mcp-history-filters { + margin-bottom: 16px; +} + +.mcp-history-count { + margin-top: 8px; + font-size: 0.9em; + color: var(--text-muted); +} + +.mcp-history-list { + max-height: 400px; + overflow-y: auto; + margin-bottom: 16px; + border: 1px solid var(--background-modifier-border); + border-radius: 4px; +} + +.mcp-history-empty { + padding: 24px; + text-align: center; + color: var(--text-muted); +} + +.mcp-history-entry { + padding: 12px; +} + +.mcp-history-entry-header { + display: flex; + justify-content: space-between; + margin-bottom: 8px; +} + +.mcp-history-entry-header-meta { + font-size: 0.85em; + color: var(--text-muted); +} + +.mcp-history-entry-args { + font-size: 0.85em; + font-family: monospace; + background-color: var(--background-secondary); + padding: 8px; + border-radius: 4px; + margin-bottom: 8px; + overflow-x: auto; +} + +.mcp-history-entry-error { + font-size: 0.85em; + color: var(--text-error); + background-color: var(--background-secondary); + padding: 8px; + border-radius: 4px; + font-family: monospace; +} + +.mcp-history-actions { + display: flex; + gap: 8px; + justify-content: flex-end; +} + +/* Dynamic state classes */ +.mcp-history-entry-border { + border-bottom: 1px solid var(--background-modifier-border); +} + +.mcp-history-entry-title-success { + color: var(--text-success); +} + +.mcp-history-entry-title-error { + color: var(--text-error); +}