[PUI] Part parameter table (#6599)

* Refactor for PartTable

* Skeleton for ParametricPartTable

* Implement parametric part table

* Table updates
This commit is contained in:
Oliver 2024-02-28 17:43:36 +11:00 committed by GitHub
parent a2a7b60d41
commit 820d7c6a15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 145 additions and 23 deletions

View File

@ -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: <IconListDetails />,
content: <PlaceholderPanel />
content: <ParametricPartTable categoryId={id} />
}
],
[category, id]

View File

@ -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: <IconInfoCircle />,
content: <PlaceholderPanel />
icon: <IconInfoCircle />
},
{
name: 'tracking',
label: t`Stock Tracking`,
icon: <IconHistory />,
content: <PlaceholderPanel />
icon: <IconHistory />
},
{
name: 'allocations',
label: t`Allocations`,
icon: <IconBookmark />,
content: <PlaceholderPanel />,
hidden:
!stockitem?.part_detail?.salable && !stockitem?.part_detail?.component
},

View File

@ -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 (
<TableHoverCard
value={parameter.data}
extra={extra}
title={t`Internal Units`}
/>
);
}
};
});
}, [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 (
<InvenTreeTable
url={apiUrl(ApiEndpoints.part_list)}
tableState={table}
columns={tableColumns}
props={{
enableDownload: false,
params: {
category: categoryId,
cascade: true,
category_detail: true,
parameters: true
},
onRowClick: (record) => {
if (record.pk) {
navigate(getDetailUrl(ModelType.part, record.pk));
}
}
}}
/>
);
}

View File

@ -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 <YesNoButton value={record.data} />;
}
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 (
<TableHoverCard
value={record.data}
extra={extra}
title={t`Internal Units`}
/>
);
}
},
{

View File

@ -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 (
<Thumbnail
src={record.thumbnail || record.image}
alt={record.name}
text={record.full_name}
/>
);
}
render: (record: any) => PartColumn(record)
},
{
accessor: 'IPN',