From bacee666f184d37f591fc41a310aced98cd3586c Mon Sep 17 00:00:00 2001 From: Pujit Mehrotra Date: Tue, 14 Oct 2025 15:46:06 -0400 Subject: [PATCH] fix: context menu --- web/src/components/Common/BaseTreeTable.vue | 24 ++++- .../Docker/DockerContainerManagement.vue | 3 +- .../DockerContainerOverview.standalone.vue | 17 ---- .../Docker/DockerContainersTable.vue | 88 +++++++++++++++++-- web/src/composables/useContainerActions.ts | 17 ++-- 5 files changed, 109 insertions(+), 40 deletions(-) diff --git a/web/src/components/Common/BaseTreeTable.vue b/web/src/components/Common/BaseTreeTable.vue index db66a9815..a419af722 100644 --- a/web/src/components/Common/BaseTreeTable.vue +++ b/web/src/components/Common/BaseTreeTable.vue @@ -44,6 +44,10 @@ const emit = defineEmits<{ e: 'row:select', payload: { id: string; type: string; name: string; selected: boolean; meta?: T } ): void; + ( + e: 'row:contextmenu', + payload: { id: string; type: string; name: string; meta?: T; event: MouseEvent } + ): void; (e: 'row:drop', payload: DropEvent): void; (e: 'update:selectedIds', value: string[]): void; }>(); @@ -147,7 +151,7 @@ function toArray(value: unknown | unknown[]): unknown[] { return value !== undefined && value !== null ? [value] : []; } -function getRowSearchValues(row: TreeRow): string[] { +function getRowSearchValues(row: TreeRow): string[] { const values: unknown[] = []; if (props.searchableKeys?.length) { @@ -178,7 +182,7 @@ function getRowSearchValues(row: TreeRow): string[] { .filter((str) => str.trim().length); } -function rowMatchesTerm(row: TreeRow, term: string): boolean { +function rowMatchesTerm(row: TreeRow, term: string): boolean { if (!term) return true; return getRowSearchValues(row) @@ -186,7 +190,7 @@ function rowMatchesTerm(row: TreeRow, term: string): boolean { .some((value) => value.includes(term)); } -function filterRowsByTerm(rows: TreeRow[], term: string): TreeRow[] { +function filterRowsByTerm(rows: TreeRow[], term: string): TreeRow[] { if (!term) { return rows; } @@ -284,6 +288,18 @@ function wrapCellWithRow(row: { original: TreeRow; depth?: number }, cellCont } : undefined, onDragend: props.enableDragDrop ? handleDragEnd : undefined, + onContextmenu: (e: MouseEvent) => { + const target = e.target as HTMLElement | null; + if ( + target && + target.closest('input,button,textarea,a,[role=checkbox],[role=button],[data-stop-row-click]') + ) { + return; + } + e.preventDefault(); + const r = row.original; + emit('row:contextmenu', { id: r.id, type: r.type, name: r.name, meta: r.meta, event: e }); + }, }, [cellContent] ); @@ -428,7 +444,7 @@ defineExpose({ ; + const nextQuery: LocationQueryRaw = { ...route!.query }; if (nextId) nextQuery[ROUTE_QUERY_KEY] = nextId; else delete nextQuery[ROUTE_QUERY_KEY]; diff --git a/web/src/components/Docker/DockerContainerOverview.standalone.vue b/web/src/components/Docker/DockerContainerOverview.standalone.vue index 31ca876ab..b9dfc75f4 100644 --- a/web/src/components/Docker/DockerContainerOverview.standalone.vue +++ b/web/src/components/Docker/DockerContainerOverview.standalone.vue @@ -1,22 +1,5 @@