diff --git a/src/frontend/lib/types/Tables.tsx b/src/frontend/lib/types/Tables.tsx index f6d2f82803..ba0675e285 100644 --- a/src/frontend/lib/types/Tables.tsx +++ b/src/frontend/lib/types/Tables.tsx @@ -173,6 +173,7 @@ export type RowViewProps = RowAction & RowModelProps; * @param barcodeActions : any[] - List of barcode actions * @param tableFilters : TableFilter[] - List of custom filters * @param tableActions : any[] - List of custom action groups + * @param detailAction: boolean - Enable detail action for each row (default = true) * @param dataFormatter : (data: any) => any - Callback function to reformat data returned by server (if not in default format) * @param rowActions : (record: any) => RowAction[] - Callback function to generate row actions * @param onRowClick : (record: any, index: number, event: any) => void - Callback function when a row is clicked @@ -204,6 +205,7 @@ export type InvenTreeTableProps = { rowExpansion?: DataTableRowExpansionProps; dataFormatter?: (data: any) => any; rowActions?: (record: T) => RowAction[]; + detailAction?: boolean; onRowClick?: (record: T, index: number, event: any) => void; onCellClick?: DataTableCellClickHandler; modelType?: ModelType; diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx index 8335c9840f..d262348d82 100644 --- a/src/frontend/src/tables/InvenTreeTable.tsx +++ b/src/frontend/src/tables/InvenTreeTable.tsx @@ -1,4 +1,5 @@ import { RowActions } from '@lib/components/RowActions'; +import { ModelInformationDict } from '@lib/enums/ModelInformation'; import { resolveItem } from '@lib/functions/Conversion'; import { cancelEvent } from '@lib/functions/Events'; import { getDetailUrl } from '@lib/functions/Navigation'; @@ -678,14 +679,24 @@ export function InvenTreeTable>({ })); } - if (props.modelType) { + if (props.modelType && props.detailAction !== false) { // Add action to navigate to the detail view const accessor = props.modelField ?? 'pk'; const pk = resolveItem(record, accessor); const url = getDetailUrl(props.modelType, pk); + + const model: string | undefined = + ModelInformationDict[props.modelType]?.label?.(); + + let detailsText: string = t`View details`; + + if (!!model) { + detailsText = t`View ${model}`; + } + items.push({ key: 'detail', - title: t`View details`, + title: detailsText, icon: , onClick: (event: any) => { cancelEvent(event); diff --git a/src/frontend/src/tables/build/BuildLineTable.tsx b/src/frontend/src/tables/build/BuildLineTable.tsx index b32e768e24..36e0e6db0b 100644 --- a/src/frontend/src/tables/build/BuildLineTable.tsx +++ b/src/frontend/src/tables/build/BuildLineTable.tsx @@ -957,6 +957,7 @@ export default function BuildLineTable({ enableSelection: true, enableLabels: true, modelType: ModelType.buildline, + detailAction: false, onCellClick: () => {}, rowExpansion: rowExpansion }} diff --git a/src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx b/src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx index 96ac375258..e67a0ee171 100644 --- a/src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx +++ b/src/frontend/src/tables/sales/SalesOrderAllocationTable.tsx @@ -5,7 +5,8 @@ import { ActionButton } from '@lib/components/ActionButton'; import { type RowAction, RowDeleteAction, - RowEditAction + RowEditAction, + RowViewAction } from '@lib/components/RowActions'; import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import { ModelType } from '@lib/enums/ModelType'; @@ -15,6 +16,7 @@ import type { TableFilter } from '@lib/types/Filters'; import type { StockOperationProps } from '@lib/types/Forms'; import type { TableColumn } from '@lib/types/Tables'; import { IconTruckDelivery } from '@tabler/icons-react'; +import { useNavigate } from 'react-router-dom'; import { formatDate } from '../../defaults/formatters'; import { useSalesOrderAllocationFields } from '../../forms/SalesOrderForms'; import { @@ -61,6 +63,7 @@ export default function SalesOrderAllocationTable({ modelField?: string; }>) { const user = useUserState(); + const navigate = useNavigate(); const tableId = useMemo(() => { let id = 'salesorderallocations'; @@ -221,13 +224,13 @@ export default function SalesOrderAllocationTable({ // Do not allow "shipped" items to be manipulated const isShipped = !!record.shipment_detail?.shipment_date; - if (isShipped || !allowEdit) { - return []; - } - return [ RowEditAction({ tooltip: t`Edit Allocation`, + hidden: + isShipped || + !allowEdit || + !user.hasChangeRole(UserRoles.sales_order), onClick: () => { setSelectedAllocation(record.pk); setSelectedShipment(record.shipment); @@ -236,14 +239,26 @@ export default function SalesOrderAllocationTable({ }), RowDeleteAction({ tooltip: t`Delete Allocation`, + hidden: + isShipped || + !allowEdit || + !user.hasDeleteRole(UserRoles.sales_order), onClick: () => { setSelectedAllocation(record.pk); deleteAllocation.open(); } + }), + RowViewAction({ + tooltip: t`View Shipment`, + title: t`View Shipment`, + hidden: !record.shipment || !!shipmentId, + modelId: record.shipment, + modelType: ModelType.salesordershipment, + navigate: navigate }) ]; }, - [allowEdit, user] + [allowEdit, shipmentId, user] ); const stockOperationProps: StockOperationProps = useMemo(() => {