Documents fixes for three UX issues: - Unclear notification message format - Settings section collapsing on toggle - Broken filter controls in history modal Co-Authored-By: Claude <noreply@anthropic.com>
5.8 KiB
5.8 KiB
Notification UI Improvements Design
Date: 2025-10-26 Status: Approved for implementation
Overview
Improve the MCP plugin's notification system to address three key UX issues:
- Unclear notification message format
- Settings section collapsing when toggling notifications on/off
- Broken filter controls in notification history modal
Problem Statement
Issue 1: Notification Message Clarity
Current format: 🔧 MCP: tool_name({ params })
- Not immediately clear this is a tool call
- Parameters on same line make long notifications hard to read
- "MCP:" prefix is too terse
Issue 2: Settings Section Collapse
When toggling "Enable notifications" on/off:
- The entire settings page re-renders via
this.display() - This collapses the "UI Notifications" detail section
- Poor UX - user loses their place in settings
Issue 3: Modal Filter Bugs
In the notification history modal:
- Tool filter input box doesn't accept text input
- Success/Error dropdown doesn't show selected option visually
- Root cause:
applyFilters()callsthis.onOpen()which destroys/recreates all DOM elements
Design Decisions
1. Notification Message Format
Chosen approach: Multi-line format with explicit "MCP Tool Called" label
Format:
📖 MCP Tool Called: read_note
path: "daily/2025-01-15.md"
Rationale:
- First line clearly identifies this as an MCP tool call
- Tool name prominently displayed
- Parameters on separate line improve readability
- Works within Obsidian's Notice component (supports newlines)
Implementation:
- Modify
NotificationManager.formatArgs()to return parameter string without wrapping parens - Update message construction:
${icon} MCP Tool Called: ${toolName}\n${argsStr} - When
showParametersis false:${icon} MCP Tool Called: ${toolName}(no newline) - Maintain existing truncation: 30 chars for parameter values, 50 for JSON fallback
2. Settings Section - Prevent Collapse
Chosen approach: Targeted subsection update
Strategy:
- Store reference to notification detail element during initial render
- Create helper method to update only notification section content
- Preserve
openstate of detail element - Avoid full page re-render on toggle
Implementation:
- Add instance variable:
private notificationDetailsEl: HTMLDetailsElement | null = null - Store reference when creating notification section in
display() - Create
updateNotificationSection()method:- Clear content of detail element (not the element itself)
- Rebuild child settings
- Preserve
openattribute
- Replace
this.display()in toggle handler with targeted update
Benefits:
- Better UX - maintains user context
- More efficient - doesn't re-render entire page
- Extensible pattern for other collapsible sections
3. Modal Filter Controls
Chosen approach: Use Obsidian Setting components + eliminate re-render on filter
Current problems:
- Raw HTML elements (
createEl('input'),createEl('select')) applyFilters()→onOpen()→contentEl.empty()destroys all DOM- Loses focus, input values, selected states
Solution:
- Use Obsidian
Settingcomponent for filter controls - Filter state already stored in instance variables (
filterTool,filterType) - Refactor update logic:
createFilters()- builds filters once using Setting componentsupdateHistoryList()- updates only list container with filtered resultsupdateResultsCount()- updates only count element
- Store references to list container and count element
applyFilters()calls targeted update methods, NOTonOpen()
Benefits:
- Setting components properly handle input/select state
- No DOM destruction during filtering
- Consistent with Obsidian UI patterns
- Better performance - only updates what changed
Files to Modify
src/ui/notifications.ts
- Update
showToolCall()message format - Modify
formatArgs()to return unwrapped parameter string
src/settings.ts
- Add
notificationDetailsElinstance variable - Store reference in
display()when creating notification section - Create
updateNotificationSection()helper method - Replace
this.display()call in toggle handler
src/ui/notification-history.ts
- Add instance variables for DOM references:
listContainerEl: HTMLElement | nullcountEl: HTMLElement | null
- Refactor
createFilters()to use Setting components - Create
updateHistoryList()method - Create
updateResultsCount()method - Update
applyFilters()to call targeted update methods
Success Criteria
- Notifications display with clear "MCP Tool Called:" label and multi-line format
- Toggling "Enable notifications" keeps the UI Notifications section open
- Tool filter input accepts text and filters list in real-time
- Success/Error dropdown shows selected option and filters correctly
- No regressions in existing notification functionality
Testing Plan
-
Notification format:
- Enable notifications with parameters shown
- Trigger various MCP tools (read_note, search, etc.)
- Verify multi-line format with "MCP Tool Called:" label
- Test with parameters disabled - should show single line
-
Settings collapse:
- Open UI Notifications section
- Toggle "Enable notifications" off
- Verify section remains open
- Toggle back on, verify section still open
-
Modal filters:
- Open notification history modal
- Type in tool filter box - verify text appears and list filters
- Select different options in Success/Error dropdown - verify selection shows and list filters
- Test combinations of filters
- Verify results count updates correctly
Future Enhancements (Out of Scope)
- Notification batching/grouping for rapid tool calls
- Clickable notifications that open relevant notes
- Export history to note file (not just clipboard)
- Filter by date/time range in history modal