Unified Card Editor with Drag-and-Drop Support
Resolved 💬 3 comments Opened Oct 16, 2025 by chooglygit Closed Jan 8, 2026
Summary
Enhance the dashboard card editor to provide a unified, contextual editing experience while maintaining drag-and-drop reordering functionality.
Current Implementation (Issue #537)
✅ Successfully implemented:
- Clickable preview cards open unified editor modal
- Single modal with tabs: Basic Settings | Categories & Metrics | Responsive Spans | Styling | Tooltips | Preview
- Styling tab: Icon picker, font customization, optional color scales
- Tooltips tab: View all metric tooltips and formulas for the card
- Removed scattered tooltip info buttons for cleaner UI
Problem
The current implementation has a UX conflict:
- Cards are clickable to open the editor (good for quick access)
- Drag-and-drop for reordering is still needed (currently uses grip handle)
- Need to ensure clicking opens the correct card's editor (contextual)
Requirements
1. Contextual Card Editing
- ✅ Clicking on a card should open that specific card's editor
- ✅ Modal should show the correct card's properties, metrics, styling, and tooltips
- Verify that card ID, categories, and all properties are correctly loaded
2. Drag-and-Drop Reordering
- Users need to reorder cards in the dashboard layout
- Current grip handle (⋮⋮) approach should be preserved or enhanced
- Drag-and-drop should NOT trigger the card editor modal
- Visual feedback during drag operation
3. Clear Interaction Patterns
Option A: Separate drag handle and clickable area
- Keep grip handle for dragging only
- Rest of card is clickable to edit
- Clear visual distinction
Option B: Modifier key for drag vs click
- Click card → Opens editor
- Click + drag from grip handle → Reorders card
- Already partially implemented
Suggested Implementation
Verify Contextual Editing
Ensure that when clicking a card, the modal receives:
- Correct card object with all properties
- Correct card index in the array
- Proper card ID for styling updates via Zustand
Maintain Drag-and-Drop
Current implementation in DashboardLayoutViewer.tsx:
SortableCardItemcomponent wraps each card- Grip handle has
{...attributes} {...listeners}for drag DndContextandSortableContextmanage reorderinghandleCardDragEndupdates card order
Potential conflict:
- CardPreview now has
onClick={onEdit} - This might interfere with drag operations if not properly separated
Solution
Ensure drag handle area and click-to-edit area are distinct:
// Grip handle area - for dragging only
<HStack {...attributes} {...listeners} cursor="grab">
<FaGripVertical />
// Card info display
</HStack>
// Preview area - for clicking to edit
<CardPreview onCardClick={onEdit} />
Testing Checklist
- [ ] Click on different preview cards and verify correct card loads in editor
- [ ] Verify card ID, categories, metrics show correctly in modal
- [ ] Test styling tab updates the correct card
- [ ] Test tooltips tab shows metrics from the clicked card
- [ ] Drag cards by grip handle to reorder without opening editor
- [ ] Verify card order persists after drag-and-drop
- [ ] Save changes and verify correct card is updated in database
- [ ] Test with multiple cards of different types (categoryGroup, featureContext, etc.)
Acceptance Criteria
- ✅ Clicking on a preview card opens editor for that specific card
- ✅ All tabs (Basic, Metrics, Spans, Styling, Tooltips, Preview) show correct card data
- ✅ Drag-and-drop by grip handle reorders cards without opening editor
- ✅ Visual feedback distinguishes drag handle from clickable areas
- ✅ Card order changes persist through save workflow
- ✅ No interference between drag and click interactions
Related Issues
- #537 - Dashboard Card Styling Customization (completed)
- #536 - Draft-Save Workflow with Version Control (completed)
- #524 - Dashboard Layout WYSIWYG Preview (completed)
Implementation Notes
- Already have
SortableCardItemwith drag-and-drop - Already have
CardPreviewwith click handler - Need to verify contextual data flow (card object → modal)
- May need to adjust event propagation to prevent conflicts
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗