Files
portainer/app/react/docker/stacks/ItemView/StackContainersDatatable.tsx
agent_coder f379e8057e fix(stacks): keep stack breadcrumb on container Quick Actions
The stack container list reuses the shared containers datatable, whose
Quick Actions column linked to the global docker.containers.container.*
states with only {id,nodeName}. Clicking Logs/Stats/Console/Inspect/Attach
from within a stack therefore jumped to the global route and collapsed the
breadcrumb to "Containers > <name> > Logs", losing the stack trail that
PR #7 added.

Thread the current stack route params (via RowContext) down to
ContainerQuickActions so, when rendered inside a stack, its links target the
stack-scoped docker.stacks.stack.container.* sub-tab states (reusing #7's
buildStackContainerLinkParams / STACK_CONTAINER_STATE_NAME helpers). The
global containers list and service tasks pass no stack params and keep the
global links unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 18:52:44 +03:00

106 lines
3.8 KiB
TypeScript

import { Box } from 'lucide-react';
import { useCurrentStateAndParams } from '@uirouter/react';
import { ContainerListViewModel } from '@/react/docker/containers/types';
import { createStore } from '@/react/docker/containers/ListView/ContainersDatatable/datatable-store';
import { useColumns } from '@/react/docker/containers/ListView/ContainersDatatable/columns';
import { ContainersDatatableActions } from '@/react/docker/containers/ListView/ContainersDatatable/ContainersDatatableActions';
import { ContainersDatatableSettings } from '@/react/docker/containers/ListView/ContainersDatatable/ContainersDatatableSettings';
import { useShowGPUsColumn } from '@/react/docker/containers/utils';
import { useCurrentEnvironment } from '@/react/hooks/useCurrentEnvironment';
import { Datatable, Table } from '@@/datatables';
import {
buildAction,
QuickActionsSettings,
} from '@@/datatables/QuickActionsSettings';
import {
ColumnVisibilityMenu,
getColumnVisibilityState,
} from '@@/datatables/ColumnVisibilityMenu';
import { TableSettingsProvider } from '@@/datatables/useTableSettings';
import { useTableState } from '@@/datatables/useTableState';
import { RowProvider } from '../../containers/ListView/ContainersDatatable/RowContext';
import { useComposeStackContainers } from './useComposeStackContainers';
const storageKey = 'stack-containers';
const settingsStore = createStore(storageKey);
const actions = [
buildAction('logs', 'Logs'),
buildAction('inspect', 'Inspect'),
buildAction('stats', 'Stats'),
buildAction('exec', 'Console'),
buildAction('attach', 'Attach'),
];
export interface Props {
stackName: string;
}
export function StackContainersDatatable({ stackName }: Props) {
const environmentQuery = useCurrentEnvironment();
const tableState = useTableState(settingsStore, storageKey);
// Current stack route params, forwarded to the Quick Actions column so it can
// link to the stack-scoped container sub-tab states and keep the stack trail.
const { params: stackRouteParams } = useCurrentStateAndParams();
const isGPUsColumnVisible = useShowGPUsColumn(environmentQuery.data);
const columns = useColumns(false, isGPUsColumnVisible);
const containersQuery = useComposeStackContainers(
{ environmentId: environmentQuery.data?.Id, stackName },
{
autoRefreshRate: tableState.autoRefreshRate * 1000,
}
);
if (!environmentQuery.data) {
return null;
}
const environment = environmentQuery.data;
return (
<RowProvider context={{ environment, stackRouteParams }}>
<TableSettingsProvider settings={settingsStore}>
<Datatable
title="Containers"
titleIcon={Box}
settingsManager={tableState}
columns={columns}
renderTableActions={(selectedRows) => (
<ContainersDatatableActions
selectedItems={selectedRows}
isAddActionVisible={false}
endpointId={environment.Id}
/>
)}
initialTableState={getColumnVisibilityState(tableState.hiddenColumns)}
data-cy="stack-containers-datatable"
renderTableSettings={(tableInstance) => (
<>
<ColumnVisibilityMenu<ContainerListViewModel>
table={tableInstance}
onChange={(hiddenColumns) => {
tableState.setHiddenColumns(hiddenColumns);
}}
value={tableState.hiddenColumns}
/>
<Table.SettingsMenu
quickActions={<QuickActionsSettings actions={actions} />}
>
<ContainersDatatableSettings settings={tableState} />
</Table.SettingsMenu>
</>
)}
dataset={containersQuery.data || []}
isLoading={!containersQuery.data}
/>
</TableSettingsProvider>
</RowProvider>
);
}