diff --git a/apps/todo/apps/web/src/lib/components/board-views/ViewEditorModal.svelte b/apps/todo/apps/web/src/lib/components/board-views/ViewEditorModal.svelte new file mode 100644 index 000000000..ca4020e79 --- /dev/null +++ b/apps/todo/apps/web/src/lib/components/board-views/ViewEditorModal.svelte @@ -0,0 +1,1162 @@ + + +{#if open} + + +{/if} + + diff --git a/apps/todo/apps/web/src/lib/components/board-views/ViewSelector.svelte b/apps/todo/apps/web/src/lib/components/board-views/ViewSelector.svelte index e25bc48f0..e7aeb6740 100644 --- a/apps/todo/apps/web/src/lib/components/board-views/ViewSelector.svelte +++ b/apps/todo/apps/web/src/lib/components/board-views/ViewSelector.svelte @@ -5,9 +5,15 @@ views: LocalBoardView[]; activeViewId: string | null; onSelect: (viewId: string) => void; + onCreate?: () => void; + onEdit?: (view: LocalBoardView) => void; } - let { views, activeViewId, onSelect }: Props = $props(); + let { views, activeViewId, onSelect, onCreate, onEdit }: Props = $props(); + + // Context menu state + let contextMenuViewId = $state(null); + let contextMenuPos = $state({ x: 0, y: 0 }); // Map icon names to simple SVG representations const iconMap: Record = { @@ -15,10 +21,48 @@ 'grid-four': 'M3 3h8v8H3zM13 3h8v8h-8zM3 13h8v8H3zM13 13h8v8h-8z', flag: 'M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1zM4 22v-7', folders: 'M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z', - calendar: 'M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z', + calendar: + 'M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z', + list: 'M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01', + star: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z', + tag: 'M20.59 13.41l-7.17 7.17a2 2 0 01-2.83 0L2 12V2h10l8.59 8.59a2 2 0 010 2.82zM7 7h.01', + clock: 'M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 6v6l4 2', + target: + 'M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 18a6 6 0 100-12 6 6 0 000 12zM12 14a2 2 0 100-4 2 2 0 000 4z', + lightning: 'M13 2L3 14h9l-1 10 10-12h-9l1-10z', + heart: + 'M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z', }; + + function handleContextMenu(e: MouseEvent, view: LocalBoardView) { + e.preventDefault(); + e.stopPropagation(); + contextMenuViewId = view.id; + contextMenuPos = { x: e.clientX, y: e.clientY }; + } + + function handleMoreClick(e: MouseEvent, view: LocalBoardView) { + e.stopPropagation(); + const rect = (e.currentTarget as HTMLElement).getBoundingClientRect(); + contextMenuViewId = view.id; + contextMenuPos = { x: rect.left, y: rect.bottom + 4 }; + } + + function handleEditClick() { + const view = views.find((v) => v.id === contextMenuViewId); + contextMenuViewId = null; + if (view && onEdit) { + onEdit(view); + } + } + + function closeContextMenu() { + contextMenuViewId = null; + } + +
@@ -28,6 +72,7 @@ class="view-pill" class:active={activeViewId === view.id} onclick={() => onSelect(view.id)} + oncontextmenu={(e) => handleContextMenu(e, view)} > {#if view.icon && iconMap[view.icon]} {view.icon} {/if} {view.name} + + {#if activeViewId === view.id && onEdit} + + {/if} {/each} + + {#if onCreate} + + {/if}
+ +{#if contextMenuViewId} + +{/if} + diff --git a/apps/todo/apps/web/src/lib/components/board-views/index.ts b/apps/todo/apps/web/src/lib/components/board-views/index.ts index 02b1199ff..745e5c418 100644 --- a/apps/todo/apps/web/src/lib/components/board-views/index.ts +++ b/apps/todo/apps/web/src/lib/components/board-views/index.ts @@ -4,3 +4,4 @@ export { default as KanbanLayout } from './KanbanLayout.svelte'; export { default as GridLayout } from './GridLayout.svelte'; export { default as BoardViewRenderer } from './BoardViewRenderer.svelte'; export { default as ViewSelector } from './ViewSelector.svelte'; +export { default as ViewEditorModal } from './ViewEditorModal.svelte'; diff --git a/apps/todo/apps/web/src/routes/(app)/kanban/+page.svelte b/apps/todo/apps/web/src/routes/(app)/kanban/+page.svelte index 0b855d608..af2558acd 100644 --- a/apps/todo/apps/web/src/routes/(app)/kanban/+page.svelte +++ b/apps/todo/apps/web/src/routes/(app)/kanban/+page.svelte @@ -1,8 +1,10 @@