From a0f90b2204f604f449eb9902dce82085a89ba35b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 30 Jun 2026 09:39:08 +0000 Subject: [PATCH] Launch preview drawer directly from tables --- .../src/states/PreviewDrawerState.tsx | 14 ++++++++-- src/frontend/src/tables/InvenTreeTable.tsx | 28 +++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/frontend/src/states/PreviewDrawerState.tsx b/src/frontend/src/states/PreviewDrawerState.tsx index 29488ce97a..8e7fc84c29 100644 --- a/src/frontend/src/states/PreviewDrawerState.tsx +++ b/src/frontend/src/states/PreviewDrawerState.tsx @@ -4,9 +4,13 @@ import { create } from 'zustand'; interface PreviewDrawerStateProps { isOpen: boolean; modelType?: ModelType; - id?: number; + id?: number | string; instance?: any; - openPreview: (modelType: ModelType, id: number, instance?: any) => void; + openPreview: ( + modelType: ModelType, + id: number | string, + instance?: any + ) => void; closePreview: () => void; } @@ -17,7 +21,11 @@ export const usePreviewDrawerState = create()( id: undefined, instance: undefined, - openPreview: (modelType: ModelType, id: number, instance?: any) => { + openPreview: ( + modelType: ModelType, + id: number | string, + instance?: any + ) => { set({ modelType, id, instance, isOpen: true }); }, diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx index 29ac6661cc..b6b1981f4c 100644 --- a/src/frontend/src/tables/InvenTreeTable.tsx +++ b/src/frontend/src/tables/InvenTreeTable.tsx @@ -5,7 +5,7 @@ import { ModelInformationDict } from '@lib/enums/ModelInformation'; import { resolveItem } from '@lib/functions/Conversion'; import { cancelEvent } from '@lib/functions/Events'; import { mapFields } from '@lib/functions/Forms'; -import { getDetailUrl } from '@lib/functions/Navigation'; +import { eventModified, getDetailUrl } from '@lib/functions/Navigation'; import { navigateToLink } from '@lib/functions/Navigation'; import { useStoredTableState } from '@lib/states/StoredTableState'; import type { TableFilter } from '@lib/types/Filters'; @@ -37,6 +37,7 @@ import { useApi } from '../contexts/ApiContext'; import { extractAvailableFields } from '../functions/forms'; import { showApiErrorMessage } from '../functions/notifications'; import { useLocalState } from '../states/LocalState'; +import { usePreviewDrawerState } from '../states/PreviewDrawerState'; import { useUserSettingsState } from '../states/SettingsStates'; import { ColumnFilterPopover } from './FilterSelectDrawer'; import InvenTreeTableHeader from './InvenTreeTableHeader'; @@ -700,6 +701,18 @@ export function InvenTreeTableInternal>({ tableState.setRecords(tableData ?? apiData ?? []); }, [tableData, apiData]); + const previewDrawer = usePreviewDrawerState(); + + // Callback to display "preview" view for a row (if available) + const showRowPreview = useCallback( + (pk: string | number) => { + if (tableProps.modelType && pk) { + previewDrawer.openPreview(tableProps.modelType, Number(pk)); + } + }, + [tableProps.modelType] + ); + // Callback when a cell is clicked const handleCellClick = useCallback( ({ @@ -732,7 +745,12 @@ export function InvenTreeTableInternal>({ cancelEvent(event); // If a model type is provided, navigate to the detail view for that model const url = getDetailUrl(tableProps.modelType, pk); - navigateToLink(url, navigate, event); + + if (eventModified(event as any)) { + navigateToLink(url, navigate, event); + } else { + showRowPreview(pk); + } } } }, @@ -796,7 +814,11 @@ export function InvenTreeTableInternal>({ icon: , onClick: (event: any) => { cancelEvent(event); - navigateToLink(url, navigate, event); + if (eventModified(event as any)) { + navigateToLink(url, navigate, event); + } else { + showRowPreview(pk); + } } }); }