Skip to content

Mode Selector: Add export/import buttons to popover for quick mode managementΒ #6320

@hannesrudolph

Description

@hannesrudolph

What specific problem does this solve?

Users who frequently work with custom modes need to access export/import functionality quickly, but currently must navigate away from their active chat to the dedicated Modes view. This interrupts their workflow and requires multiple clicks.

Who is affected: Power users who create and share custom modes regularly
When this happens: When users want to export a mode they just created or import a mode while in an active chat session
Current behavior: Users must click "Manage Modes" β†’ navigate to Modes view β†’ find the mode β†’ use export/import buttons there
Expected behavior: Users can export/import modes directly from the mode selector popover without leaving their current context
Impact: Saves 3-4 clicks and ~10-15 seconds per export/import operation, keeping users in their workflow

Additional context (optional)

The export/import functionality already exists in the main Modes view (ModesView.tsx) and works well. This request is to replicate that same functionality in the mode selector popover for quicker access.

How should this be solved? (REQUIRED if contributing, optional otherwise)

Add export and import buttons to the mode selector popover (ModeSelector.tsx) that replicate the existing functionality from ModesView.tsx:

  1. Add UI buttons: Place export/import icons in the popover header or as action buttons for each mode
  2. Reuse existing logic: Copy the state management (isExporting, isImporting, showImportDialog) and message handlers from ModesView
  3. Maintain consistency: Use the same icons, tooltips, and behavior as the main Modes view
  4. Handle state locally: Each component instance manages its own loading states independently

The implementation leverages the existing backend handlers (exportMode and importMode in webviewMessageHandler.ts) without any backend changes needed.

How will we know it works? (Acceptance Criteria - REQUIRED if contributing, optional otherwise)

Given I have the mode selector popover open
When I click the export button for a mode
Then a file dialog opens to save the mode as JSON
And the button shows a loading state during export
And I receive the exported file with the mode configuration
But the popover doesn't close unexpectedly

Given I have the mode selector popover open
When I click the import button
Then an import dialog appears
And I can paste mode JSON or upload a file
And clicking "Import" adds the mode to my list
And the new mode appears immediately in the selector
But invalid JSON shows an appropriate error message

Technical considerations (REQUIRED if contributing, optional otherwise)

  • Implementation approach: Copy the export/import logic from ModesView.tsx (lines 51-53 for state, 91-137 for handlers) to ModeSelector.tsx
  • No backend changes needed: The vscode.postMessage handlers for exportMode and importMode already exist and work
  • Component isolation: Each component instance (ModesView and ModeSelector) maintains its own state
  • UI constraints: The popover has limited space, so button placement needs careful consideration
  • Import dialog: Can reuse the existing ImportModeDialog component

Trade-offs and risks (REQUIRED if contributing, optional otherwise)

Chosen approach: Duplicate the state and handlers in ModeSelector

  • Pro: Simple, maintains component independence
  • Pro: No shared state complexity
  • Con: Some code duplication (~50 lines)

Alternative considered: Extract shared state to a context/hook

  • Pro: DRY principle
  • Con: Adds complexity for a small feature
  • Con: Requires refactoring both components

Risks:

  • UI clutter: Adding buttons to the popover might make it feel cramped
  • State sync: If a mode is imported in one place, it won't immediately show in the other without a refresh
  • Edge case: Importing a mode with a duplicate slug needs the same error handling as ModesView

πŸ” Comprehensive Issue Scoping

Root Cause / Implementation Target

The mode selector popover (ModeSelector.tsx) lacks quick access to export/import functionality that already exists in the main Modes view. Users must navigate away from their current context to manage modes, disrupting their workflow.

Affected Components

  • Primary Files:

    • webview-ui/src/components/chat/ModeSelector.tsx (lines 1-406): Add export/import buttons and state management
    • webview-ui/src/components/modes/ImportModeDialog.tsx (lines 1-139): Reuse existing import dialog component
  • Secondary Impact:

    • No backend changes needed - handlers already exist in src/core/webview/webviewMessageHandler.ts
    • No API changes - uses existing message protocol
    • CSS may need minor adjustments for button placement

Current Implementation Analysis

The export/import functionality in ModesView.tsx (lines 91-137) works by:

  1. Maintaining local state for isExporting, isImporting, and showImportDialog
  2. Sending vscode.postMessage with type exportMode (includes mode data)
  3. Sending vscode.postMessage with type importMode (includes imported mode JSON)
  4. The backend handles file operations and returns success/error responses

Proposed Implementation

Step 1: Add state variables to ModeSelector

  • File: webview-ui/src/components/chat/ModeSelector.tsx
  • Changes: Add after line 50:
    const [isExporting, setIsExporting] = useState<string | null>(null);
    const [isImporting, setIsImporting] = useState(false);
    const [showImportDialog, setShowImportDialog] = useState(false);
  • Rationale: Local state management for loading indicators and dialog visibility

Step 2: Copy export/import handlers

  • File: webview-ui/src/components/chat/ModeSelector.tsx
  • Changes: Add the handleExportMode and handleImportMode functions from ModesView.tsx
  • Rationale: Reuse proven logic that already integrates with the backend

Step 3: Add UI buttons

  • File: webview-ui/src/components/chat/ModeSelector.tsx
  • Changes: Add export button for each mode and import button in popover header
  • Rationale: Consistent with ModesView UI patterns

Step 4: Integrate ImportModeDialog

  • File: webview-ui/src/components/chat/ModeSelector.tsx
  • Changes: Add ImportModeDialog component with appropriate props
  • Rationale: Reuse existing, tested dialog component

Code Architecture Considerations

  • Follow existing patterns from ModesView for consistency
  • Maintain component isolation - no shared state needed
  • Use existing VSCode message protocol
  • Preserve existing keyboard navigation and accessibility

Testing Requirements

  • Unit Tests:
    • Test export button triggers message with correct mode data
    • Test import button shows dialog
    • Test loading states during operations
  • Edge Cases:
    • Test importing mode with duplicate slug
    • Test importing invalid JSON
    • Test export during mode switching

Performance Impact

  • Expected performance change: Neutral
  • No additional API calls or data fetching
  • Minimal DOM additions (2-3 buttons per mode)

Security Considerations

  • No new security concerns - uses existing validated message handlers
  • Import validation already handled by backend
  • No direct file system access from frontend

Migration Strategy

Not applicable - purely additive feature

Rollback Plan

Feature can be removed by reverting the ModeSelector.tsx changes without affecting existing functionality

Dependencies and Breaking Changes

  • External dependencies affected: None
  • API contract changes: None
  • Breaking changes for users: None

Metadata

Metadata

Assignees

Labels

Issue - In ProgressSomeone is actively working on this. Should link to a PR soon.enhancementNew feature or requestproposal

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions