Skip to content

Commit 7ce7eb3

Browse files
joewinkeclaude
andcommitted
feature(jat-fq7dx): Add /open-tasks route with spreadsheet view and Change Project context menu
New /open-tasks page shows all open tasks across projects in a data-table with resizable/reorderable/hideable columns, inline due date editing, and a full right-click context menu (Launch, View Details, Change Status/Priority, Assign to Epic, Change Project, Duplicate, Close, Delete). Propagated the "Change Project" submenu to TasksOpen and TasksActive context menus so tasks can be moved between projects from any task view. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 928952b commit 7ce7eb3

File tree

6 files changed

+2376
-20
lines changed

6 files changed

+2376
-20
lines changed

ide/src/lib/components/Sidebar.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
function getGroupItems(groupId: NavGroup) {
4949
const debugMode = getDebugMode();
5050
return unifiedNavConfig.navItems.filter((item) => {
51-
if (!debugMode && (item.id === 'mobile' || item.id === 'mobilenew')) return false;
51+
if (!debugMode && (item.id === 'mobile' || item.id === 'mobilenew' || item.id === 'open-tasks' || item.id === 'clients')) return false;
5252
return item.category === groupId;
5353
});
5454
}

ide/src/lib/components/sessions/TasksActive.svelte

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,7 @@
10681068
let ctxVisible = $state(false);
10691069
let ctxStatusSubmenuOpen = $state(false);
10701070
let ctxStateSubmenuOpen = $state(false);
1071+
let ctxProjectSubmenuOpen = $state(false);
10711072
10721073
function handleContextMenu(session: TmuxSession, event: MouseEvent) {
10731074
if (session.type !== 'agent') return;
@@ -1089,12 +1090,14 @@
10891090
ctxVisible = true;
10901091
ctxStatusSubmenuOpen = false;
10911092
ctxStateSubmenuOpen = false;
1093+
ctxProjectSubmenuOpen = false;
10921094
}
10931095
10941096
function closeCtxMenu() {
10951097
ctxVisible = false;
10961098
ctxStatusSubmenuOpen = false;
10971099
ctxStateSubmenuOpen = false;
1100+
ctxProjectSubmenuOpen = false;
10981101
}
10991102
11001103
// Close context menu on click outside or Escape
@@ -1176,6 +1179,26 @@
11761179
}
11771180
}
11781181
1182+
const ctxAllProjectNames = $derived.by(() => {
1183+
const set = new Set<string>();
1184+
for (const [, task] of agentTasks) set.add(task.id.split('-')[0]);
1185+
return [...set].sort();
1186+
});
1187+
1188+
async function ctxChangeProject(taskId: string, newProject: string) {
1189+
closeCtxMenu();
1190+
try {
1191+
const response = await fetch(`/api/tasks/${taskId}`, {
1192+
method: 'PUT',
1193+
headers: { 'Content-Type': 'application/json' },
1194+
body: JSON.stringify({ project: newProject }),
1195+
});
1196+
if (!response.ok) console.error('Failed to change project');
1197+
} catch (err) {
1198+
console.error('Failed to change project:', err);
1199+
}
1200+
}
1201+
11791202
// Cleanup on destroy
11801203
import { onDestroy } from 'svelte';
11811204
onDestroy(() => {
@@ -2191,7 +2214,7 @@
21912214
>
21922215
<!-- View Details -->
21932216
{#if ctxData.task}
2194-
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }} onclick={() => { const id = ctxData!.task!.id; closeCtxMenu(); onViewTask?.(id); ctxData = null; }}>
2217+
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }} onclick={() => { const id = ctxData!.task!.id; closeCtxMenu(); onViewTask?.(id); ctxData = null; }}>
21952218
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
21962219
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
21972220
<circle cx="12" cy="12" r="3" />
@@ -2201,7 +2224,7 @@
22012224
{/if}
22022225

22032226
<!-- Attach Terminal -->
2204-
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }} onclick={() => { const name = ctxData!.session.name; closeCtxMenu(); handleAttachSession(name); ctxData = null; }}>
2227+
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }} onclick={() => { const name = ctxData!.session.name; closeCtxMenu(); handleAttachSession(name); ctxData = null; }}>
22052228
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
22062229
<polyline points="4 17 10 11 4 5" />
22072230
<line x1="12" y1="19" x2="20" y2="19" />
@@ -2216,7 +2239,7 @@
22162239
<!-- svelte-ignore a11y_no_static_element_interactions -->
22172240
<div
22182241
class="active-context-submenu-container"
2219-
onmouseenter={() => { ctxStatusSubmenuOpen = true; ctxStateSubmenuOpen = false; }}
2242+
onmouseenter={() => { ctxStatusSubmenuOpen = true; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }}
22202243
onmouseleave={() => { ctxStatusSubmenuOpen = false; }}
22212244
>
22222245
<button class="active-context-menu-item active-context-menu-item-has-submenu">
@@ -2259,7 +2282,7 @@
22592282
<!-- svelte-ignore a11y_no_static_element_interactions -->
22602283
<div
22612284
class="active-context-submenu-container"
2262-
onmouseenter={() => { ctxStateSubmenuOpen = true; ctxStatusSubmenuOpen = false; }}
2285+
onmouseenter={() => { ctxStateSubmenuOpen = true; ctxStatusSubmenuOpen = false; ctxProjectSubmenuOpen = false; }}
22632286
onmouseleave={() => { ctxStateSubmenuOpen = false; }}
22642287
>
22652288
<button class="active-context-menu-item active-context-menu-item-has-submenu">
@@ -2301,9 +2324,49 @@
23012324
{/if}
23022325
</div>
23032326

2327+
<!-- Change Project (submenu) -->
2328+
{#if ctxData.task}
2329+
<!-- svelte-ignore a11y_no_static_element_interactions -->
2330+
<div
2331+
class="active-context-submenu-container"
2332+
onmouseenter={() => { ctxProjectSubmenuOpen = true; ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }}
2333+
onmouseleave={() => { ctxProjectSubmenuOpen = false; }}
2334+
>
2335+
<button class="active-context-menu-item active-context-menu-item-has-submenu">
2336+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2337+
<path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2z" />
2338+
<path d="M22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z" />
2339+
</svg>
2340+
<span>Change Project</span>
2341+
<svg class="active-context-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2342+
<polyline points="9 18 15 12 9 6" />
2343+
</svg>
2344+
</button>
2345+
{#if ctxProjectSubmenuOpen}
2346+
<div class="active-context-submenu active-context-submenu-project">
2347+
{#each ctxAllProjectNames as proj}
2348+
{@const currentProject = ctxData!.task!.id.split('-')[0]}
2349+
<button
2350+
class="active-context-menu-item {currentProject === proj ? 'active-context-menu-item-active' : ''}"
2351+
onclick={() => ctxChangeProject(ctxData!.task!.id, proj)}
2352+
>
2353+
<span class="active-status-dot" style="background: {projectColors[proj] || getProjectColorReactive(proj + '-x') || 'oklch(0.65 0.15 250)'};"></span>
2354+
<span>{proj}</span>
2355+
{#if currentProject === proj}
2356+
<svg class="active-context-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
2357+
<polyline points="20 6 9 17 4 12" />
2358+
</svg>
2359+
{/if}
2360+
</button>
2361+
{/each}
2362+
</div>
2363+
{/if}
2364+
</div>
2365+
{/if}
2366+
23042367
<!-- Duplicate -->
23052368
{#if ctxData.task}
2306-
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }} onclick={() => ctxDuplicateTask(ctxData!.task!)}>
2369+
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }} onclick={() => ctxDuplicateTask(ctxData!.task!)}>
23072370
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
23082371
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
23092372
<path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" />
@@ -2315,7 +2378,7 @@
23152378
<div class="active-context-menu-divider"></div>
23162379

23172380
<!-- Interrupt -->
2318-
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }} onclick={async () => {
2381+
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }} onclick={async () => {
23192382
const name = ctxData!.session.name;
23202383
closeCtxMenu();
23212384
ctxData = null;
@@ -2334,7 +2397,7 @@
23342397

23352398
<!-- Pause -->
23362399
{#if ctxData.task}
2337-
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }} onclick={async () => {
2400+
<button class="active-context-menu-item" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }} onclick={async () => {
23382401
const d = ctxData!;
23392402
closeCtxMenu();
23402403
ctxData = null;
@@ -2366,7 +2429,7 @@
23662429

23672430
<!-- Complete -->
23682431
{#if ctxData.task}
2369-
<button class="active-context-menu-item active-context-menu-item-success" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }} onclick={async () => {
2432+
<button class="active-context-menu-item active-context-menu-item-success" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }} onclick={async () => {
23702433
const d = ctxData!;
23712434
closeCtxMenu();
23722435
ctxData = null;
@@ -2404,7 +2467,7 @@
24042467
<div class="active-context-menu-divider"></div>
24052468

24062469
<!-- Kill Session -->
2407-
<button class="active-context-menu-item active-context-menu-item-danger" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; }} onclick={async () => {
2470+
<button class="active-context-menu-item active-context-menu-item-danger" onmouseenter={() => { ctxStatusSubmenuOpen = false; ctxStateSubmenuOpen = false; ctxProjectSubmenuOpen = false; }} onclick={async () => {
24082471
const d = ctxData!;
24092472
closeCtxMenu();
24102473
ctxData = null;
@@ -3112,6 +3175,11 @@
31123175
animation: activeCtxIn 0.1s ease;
31133176
}
31143177
3178+
.active-context-submenu-project {
3179+
max-height: 300px;
3180+
overflow-y: auto;
3181+
}
3182+
31153183
/* Delay row exit animation so avatar flip-out plays first */
31163184
.exit-delayed {
31173185
animation-delay: 0.25s;

ide/src/lib/components/sessions/TasksOpen.svelte

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,7 @@
11271127
let statusSubmenuOpen = $state(false);
11281128
let prioritySubmenuOpen = $state(false);
11291129
let epicSubmenuOpen = $state(false);
1130+
let projectSubmenuOpen = $state(false);
11301131
let epics = $state<Epic[]>([]);
11311132
let epicsLoading = $state(false);
11321133
let showCreateEpic = $state(false);
@@ -1175,13 +1176,15 @@
11751176
statusSubmenuOpen = false;
11761177
prioritySubmenuOpen = false;
11771178
epicSubmenuOpen = false;
1179+
projectSubmenuOpen = false;
11781180
}
11791181
11801182
function closeContextMenu() {
11811183
ctxVisible = false;
11821184
statusSubmenuOpen = false;
11831185
prioritySubmenuOpen = false;
11841186
epicSubmenuOpen = false;
1187+
projectSubmenuOpen = false;
11851188
showCreateEpic = false;
11861189
newEpicTitle = '';
11871190
// Note: ctxTask is intentionally NOT cleared so the DOM persists
@@ -1387,6 +1390,29 @@
13871390
}
13881391
}
13891392
1393+
// All unique project names for "Change Project" submenu
1394+
const allProjectNames = $derived.by(() => {
1395+
const set = new Set<string>();
1396+
for (const t of tasks) set.add(getProjectFromTaskId(t.id));
1397+
return [...set].sort();
1398+
});
1399+
1400+
async function handleChangeProject(taskId: string, newProject: string) {
1401+
closeContextMenu();
1402+
try {
1403+
const response = await fetch(`/api/tasks/${taskId}`, {
1404+
method: 'PUT',
1405+
headers: { 'Content-Type': 'application/json' },
1406+
body: JSON.stringify({ project: newProject }),
1407+
});
1408+
if (response.ok) {
1409+
onRetry();
1410+
}
1411+
} catch (err) {
1412+
console.error('Failed to change project:', err);
1413+
}
1414+
}
1415+
13901416
async function handleDuplicateTask(task: Task) {
13911417
closeContextMenu();
13921418
const projectName = getProjectFromTaskId(task.id);
@@ -1997,7 +2023,7 @@
19972023
onkeydown={(e) => e.stopPropagation()}
19982024
>
19992025
<!-- Launch -->
2000-
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }} onclick={() => { const t = ctxTask!; closeContextMenu(); onSpawnTask(t); ctxTask = null; }}>
2026+
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }} onclick={() => { const t = ctxTask!; closeContextMenu(); onSpawnTask(t); ctxTask = null; }}>
20012027
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
20022028
<path d="M12 2C12 2 8 6 8 12C8 15 9 17 10 18L10 21C10 21.5 10.5 22 11 22H13C13.5 22 14 21.5 14 21L14 18C15 17 16 15 16 12C16 6 12 2 12 2Z" />
20032029
<circle cx="12" cy="10" r="2" />
@@ -2007,7 +2033,7 @@
20072033

20082034
<!-- Resume (only for tasks with a resumable session) -->
20092035
{#if ctxTask.assignee || resumableTasks.has(ctxTask.id)}
2010-
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }} onclick={() => { const t = ctxTask!; handleResumeTask(t); ctxTask = null; }} disabled={resumingTaskId === ctxTask.id}>
2036+
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }} onclick={() => { const t = ctxTask!; handleResumeTask(t); ctxTask = null; }} disabled={resumingTaskId === ctxTask.id}>
20112037
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
20122038
<path d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.347a1.125 1.125 0 0 1 0 1.972l-11.54 6.347a1.125 1.125 0 0 1-1.667-.986V5.653Z" />
20132039
</svg>
@@ -2016,7 +2042,7 @@
20162042
{/if}
20172043

20182044
<!-- View Details -->
2019-
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }} onclick={() => { const id = ctxTask!.id; closeContextMenu(); onTaskClick(id); ctxTask = null; }}>
2045+
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }} onclick={() => { const id = ctxTask!.id; closeContextMenu(); onTaskClick(id); ctxTask = null; }}>
20202046
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
20212047
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
20222048
<circle cx="12" cy="12" r="3" />
@@ -2026,7 +2052,7 @@
20262052

20272053
<!-- Reply (integrated tasks from ingest — feedback widget, Supabase, Telegram, Slack, etc.) -->
20282054
{#if isIntegratedTask(ctxTask)}
2029-
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }} onclick={() => { const t = ctxTask!; closeContextMenu(); openReplyModal(t); }}>
2055+
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }} onclick={() => { const t = ctxTask!; closeContextMenu(); openReplyModal(t); }}>
20302056
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
20312057
<path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" />
20322058
</svg>
@@ -2040,7 +2066,7 @@
20402066
<!-- svelte-ignore a11y_no_static_element_interactions -->
20412067
<div
20422068
class="task-context-menu-submenu-container"
2043-
onmouseenter={() => { statusSubmenuOpen = true; prioritySubmenuOpen = false; epicSubmenuOpen = false; }}
2069+
onmouseenter={() => { statusSubmenuOpen = true; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }}
20442070
onmouseleave={() => { statusSubmenuOpen = false; }}
20452071
>
20462072
<button class="task-context-menu-item task-context-menu-item-has-submenu">
@@ -2082,7 +2108,7 @@
20822108
<!-- svelte-ignore a11y_no_static_element_interactions -->
20832109
<div
20842110
class="task-context-menu-submenu-container"
2085-
onmouseenter={() => { prioritySubmenuOpen = true; statusSubmenuOpen = false; epicSubmenuOpen = false; }}
2111+
onmouseenter={() => { prioritySubmenuOpen = true; statusSubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }}
20862112
onmouseleave={() => { prioritySubmenuOpen = false; }}
20872113
>
20882114
<button class="task-context-menu-item task-context-menu-item-has-submenu">
@@ -2124,7 +2150,7 @@
21242150
<!-- svelte-ignore a11y_no_static_element_interactions -->
21252151
<div
21262152
class="task-context-menu-submenu-container"
2127-
onmouseenter={() => { epicSubmenuOpen = true; statusSubmenuOpen = false; prioritySubmenuOpen = false; if (ctxTask) { const p = getProjectFromTaskId(ctxTask.id); fetchEpics(p); } }}
2153+
onmouseenter={() => { epicSubmenuOpen = true; statusSubmenuOpen = false; prioritySubmenuOpen = false; projectSubmenuOpen = false; if (ctxTask) { const p = getProjectFromTaskId(ctxTask.id); fetchEpics(p); } }}
21282154
onmouseleave={() => { epicSubmenuOpen = false; }}
21292155
>
21302156
<button class="task-context-menu-item task-context-menu-item-has-submenu">
@@ -2193,10 +2219,48 @@
21932219
{/if}
21942220
</div>
21952221

2222+
<!-- Change Project (submenu) -->
2223+
<!-- svelte-ignore a11y_no_static_element_interactions -->
2224+
<div
2225+
class="task-context-menu-submenu-container"
2226+
onmouseenter={() => { projectSubmenuOpen = true; statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }}
2227+
onmouseleave={() => { projectSubmenuOpen = false; }}
2228+
>
2229+
<button class="task-context-menu-item task-context-menu-item-has-submenu">
2230+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2231+
<path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2z" />
2232+
<path d="M22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z" />
2233+
</svg>
2234+
<span>Change Project</span>
2235+
<svg class="task-context-menu-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
2236+
<polyline points="9 18 15 12 9 6" />
2237+
</svg>
2238+
</button>
2239+
{#if projectSubmenuOpen}
2240+
<div class="task-context-submenu task-context-submenu-project">
2241+
{#each allProjectNames as proj}
2242+
{@const currentProject = getProjectFromTaskId(ctxTask!.id)}
2243+
<button
2244+
class="task-context-menu-item {currentProject === proj ? 'task-context-menu-item-active' : ''}"
2245+
onclick={() => handleChangeProject(ctxTask!.id, proj)}
2246+
>
2247+
<span class="task-status-dot" style="background: {projectColors[proj] || getProjectColor(proj + '-x')};"></span>
2248+
<span>{proj}</span>
2249+
{#if currentProject === proj}
2250+
<svg class="task-context-menu-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
2251+
<polyline points="20 6 9 17 4 12" />
2252+
</svg>
2253+
{/if}
2254+
</button>
2255+
{/each}
2256+
</div>
2257+
{/if}
2258+
</div>
2259+
21962260
<div class="task-context-menu-divider"></div>
21972261

21982262
<!-- Duplicate -->
2199-
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }} onclick={() => handleDuplicateTask(ctxTask!)}>
2263+
<button class="task-context-menu-item" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }} onclick={() => handleDuplicateTask(ctxTask!)}>
22002264
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
22012265
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
22022266
<path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" />
@@ -2205,7 +2269,7 @@
22052269
</button>
22062270

22072271
<!-- Close Task -->
2208-
<button class="task-context-menu-item task-context-menu-item-danger" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }} onclick={() => handleChangeStatus(ctxTask!.id, 'closed')}>
2272+
<button class="task-context-menu-item task-context-menu-item-danger" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }} onclick={() => handleChangeStatus(ctxTask!.id, 'closed')}>
22092273
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
22102274
<circle cx="12" cy="12" r="10" />
22112275
<line x1="15" y1="9" x2="9" y2="15" />
@@ -2215,7 +2279,7 @@
22152279
</button>
22162280

22172281
<!-- Delete Task -->
2218-
<button class="task-context-menu-item task-context-menu-item-danger" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; }} onclick={() => handleDeleteTask(ctxTask!.id)}>
2282+
<button class="task-context-menu-item task-context-menu-item-danger" onmouseenter={() => { statusSubmenuOpen = false; prioritySubmenuOpen = false; epicSubmenuOpen = false; projectSubmenuOpen = false; }} onclick={() => handleDeleteTask(ctxTask!.id)}>
22192283
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
22202284
<polyline points="3 6 5 6 21 6" />
22212285
<path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2" />
@@ -3013,6 +3077,11 @@
30133077
overflow-y: auto;
30143078
}
30153079
3080+
.task-context-submenu-project {
3081+
max-height: 300px;
3082+
overflow-y: auto;
3083+
}
3084+
30163085
/* Chevron for submenu indicators */
30173086
.task-context-menu-chevron {
30183087
width: 12px !important;

0 commit comments

Comments
 (0)