diff --git a/src/frontend/src/pages/part/CategoryDetail.tsx b/src/frontend/src/pages/part/CategoryDetail.tsx index 32664a5ff9..938fe0356e 100644 --- a/src/frontend/src/pages/part/CategoryDetail.tsx +++ b/src/frontend/src/pages/part/CategoryDetail.tsx @@ -8,13 +8,14 @@ import { import { useMemo, useState } from 'react'; import { useParams } from 'react-router-dom'; -import { PlaceholderPanel } from '../../components/items/Placeholder'; import { PageDetail } from '../../components/nav/PageDetail'; import { PanelGroup, PanelType } from '../../components/nav/PanelGroup'; import { PartCategoryTree } from '../../components/nav/PartCategoryTree'; import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { useInstance } from '../../hooks/UseInstance'; +import ParametricPartTable from '../../tables/part/ParametricPartTable'; import { PartCategoryTable } from '../../tables/part/PartCategoryTable'; +import { PartParameterTable } from '../../tables/part/PartParameterTable'; import { PartListTable } from '../../tables/part/PartTable'; /** @@ -70,7 +71,7 @@ export default function CategoryDetail({}: {}) { name: 'parameters', label: t`Parameters`, icon: , - content: + content: } ], [category, id] diff --git a/src/frontend/src/pages/stock/StockDetail.tsx b/src/frontend/src/pages/stock/StockDetail.tsx index 468aad4ea0..4901bf20ed 100644 --- a/src/frontend/src/pages/stock/StockDetail.tsx +++ b/src/frontend/src/pages/stock/StockDetail.tsx @@ -29,7 +29,6 @@ import { UnlinkBarcodeAction, ViewBarcodeAction } from '../../components/items/ActionDropdown'; -import { PlaceholderPanel } from '../../components/items/Placeholder'; import { PageDetail } from '../../components/nav/PageDetail'; import { PanelGroup, PanelType } from '../../components/nav/PanelGroup'; import { StockLocationTree } from '../../components/nav/StockLocationTree'; @@ -69,20 +68,17 @@ export default function StockDetail() { { name: 'details', label: t`Details`, - icon: , - content: + icon: }, { name: 'tracking', label: t`Stock Tracking`, - icon: , - content: + icon: }, { name: 'allocations', label: t`Allocations`, icon: , - content: , hidden: !stockitem?.part_detail?.salable && !stockitem?.part_detail?.component }, diff --git a/src/frontend/src/tables/part/ParametricPartTable.tsx b/src/frontend/src/tables/part/ParametricPartTable.tsx new file mode 100644 index 0000000000..c655f351b2 --- /dev/null +++ b/src/frontend/src/tables/part/ParametricPartTable.tsx @@ -0,0 +1,122 @@ +import { t } from '@lingui/macro'; +import { useQuery } from '@tanstack/react-query'; +import { useMemo } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { api } from '../../App'; +import { ApiEndpoints } from '../../enums/ApiEndpoints'; +import { ModelType } from '../../enums/ModelType'; +import { getDetailUrl } from '../../functions/urls'; +import { useTable } from '../../hooks/UseTable'; +import { apiUrl } from '../../states/ApiState'; +import { useUserState } from '../../states/UserState'; +import { TableColumn } from '../Column'; +import { DescriptionColumn, PartColumn } from '../ColumnRenderers'; +import { InvenTreeTable } from '../InvenTreeTable'; +import { TableHoverCard } from '../TableHoverCard'; + +export default function ParametricPartTable({ + categoryId +}: { + categoryId?: any; +}) { + const table = useTable('parametric-parts'); + const user = useUserState(); + const navigate = useNavigate(); + + const categoryParmeters = useQuery({ + queryKey: ['category-parameters', categoryId], + queryFn: async () => { + return api + .get(apiUrl(ApiEndpoints.part_parameter_template_list), { + params: { + category: categoryId + } + }) + .then((response) => response.data) + .catch((_error) => []); + }, + refetchOnMount: true + }); + + const parameterColumns: TableColumn[] = useMemo(() => { + let data = categoryParmeters.data ?? []; + + return data.map((template: any) => { + return { + accessor: `parameter_${template.pk}`, + title: template.name, + sortable: true, + render: (record: any) => { + // Find matching template parameter + let parameter = record.parameters?.find( + (p: any) => p.template == template.pk + ); + + if (!parameter) { + return '-'; + } + + let extra: any[] = []; + + if ( + template.units && + parameter.data_numeric && + parameter.data_numeric != parameter.data + ) { + extra.push(`${parameter.data_numeric} [${template.units}]`); + } + + return ( + + ); + } + }; + }); + }, [categoryParmeters.data]); + + const tableColumns: TableColumn[] = useMemo(() => { + const partColumns: TableColumn[] = [ + { + accessor: 'name', + sortable: true, + switchable: false, + noWrap: true, + render: (record: any) => PartColumn(record) + }, + DescriptionColumn({}), + { + accessor: 'IPN', + sortable: true + } + ]; + + return [...partColumns, ...parameterColumns]; + }, [parameterColumns]); + + return ( + { + if (record.pk) { + navigate(getDetailUrl(ModelType.part, record.pk)); + } + } + }} + /> + ); +} diff --git a/src/frontend/src/tables/part/PartParameterTable.tsx b/src/frontend/src/tables/part/PartParameterTable.tsx index d9f6ce4f4e..a598cf885a 100644 --- a/src/frontend/src/tables/part/PartParameterTable.tsx +++ b/src/frontend/src/tables/part/PartParameterTable.tsx @@ -19,6 +19,7 @@ import { TableColumn } from '../Column'; import { DescriptionColumn, PartColumn } from '../ColumnRenderers'; import { InvenTreeTable } from '../InvenTreeTable'; import { RowDeleteAction, RowEditAction } from '../RowActions'; +import { TableHoverCard } from '../TableHoverCard'; /** * Construct a table listing parameters for a given part @@ -65,13 +66,23 @@ export function PartParameterTable({ partId }: { partId: any }) { return ; } - if (record.data_numeric) { - // TODO: Numeric data + let extra: any[] = []; + + if ( + template.units && + record.data_numeric && + record.data_numeric != record.data + ) { + extra.push(`${record.data_numeric} [${template.units}]`); } - // TODO: Units - - return record.data; + return ( + + ); } }, { diff --git a/src/frontend/src/tables/part/PartTable.tsx b/src/frontend/src/tables/part/PartTable.tsx index 7616e7c977..49dc743f66 100644 --- a/src/frontend/src/tables/part/PartTable.tsx +++ b/src/frontend/src/tables/part/PartTable.tsx @@ -17,7 +17,7 @@ import { useTable } from '../../hooks/UseTable'; import { apiUrl } from '../../states/ApiState'; import { useUserState } from '../../states/UserState'; import { TableColumn } from '../Column'; -import { DescriptionColumn, LinkColumn } from '../ColumnRenderers'; +import { DescriptionColumn, LinkColumn, PartColumn } from '../ColumnRenderers'; import { TableFilter } from '../Filter'; import { InvenTreeTable, InvenTreeTableProps } from '../InvenTreeTable'; import { TableHoverCard } from '../TableHoverCard'; @@ -31,15 +31,7 @@ function partTableColumns(): TableColumn[] { accessor: 'name', sortable: true, noWrap: true, - render: function (record: any) { - return ( - - ); - } + render: (record: any) => PartColumn(record) }, { accessor: 'IPN',