[PUI] Tables (#6357)

* Cleanup SupplierPartTable

* Show PurchaseOrder table on SupplierPart page

* Perform edit actions as PATCH requests

* Implement ManufacturerPartParameter table

* Fix link

* supplier part link fix

* Revert code which introduced bug

* Remove unused import
This commit is contained in:
Oliver 2024-01-29 17:51:29 +11:00 committed by GitHub
parent 0f7d385755
commit 9a215f97f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 143 additions and 9 deletions

View File

@ -0,0 +1,96 @@
import { t } from '@lingui/macro';
import { useCallback, useMemo } from 'react';
import { ApiPaths } from '../../../enums/ApiEndpoints';
import { UserRoles } from '../../../enums/Roles';
import { useManufacturerPartParameterFields } from '../../../forms/CompanyForms';
import { openDeleteApiForm, openEditApiForm } from '../../../functions/forms';
import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState';
import { useUserState } from '../../../states/UserState';
import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions';
export default function ManufacturerPartParameterTable({
params
}: {
params: any;
}) {
const table = useTable('manufacturer-part-parameter');
const user = useUserState();
const tableColumns: TableColumn[] = useMemo(() => {
return [
{
accessor: 'name',
title: t`Name`,
sortable: true,
switchable: false
},
{
accessor: 'value',
title: t`Value`,
sortable: true,
switchable: false
},
{
accessor: 'units',
title: t`Units`,
sortable: false,
switchable: true
}
];
}, []);
const fields = useManufacturerPartParameterFields();
const rowActions = useCallback(
(record: any) => {
return [
RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order),
onClick: () => {
openEditApiForm({
url: ApiPaths.manufacturer_part_parameter_list,
pk: record.pk,
title: t`Edit Parameter`,
fields: fields,
onFormSuccess: table.refreshTable,
successMessage: t`Parameter updated`
});
}
}),
RowDeleteAction({
hidden: !user.hasDeleteRole(UserRoles.purchase_order),
onClick: () => {
record.pk &&
openDeleteApiForm({
url: ApiPaths.manufacturer_part_parameter_list,
pk: record.pk,
title: t`Delete Parameter`,
onFormSuccess: table.refreshTable,
successMessage: t`Parameter deleted`,
preFormWarning: t`Are you sure you want to delete this parameter?`
});
}
})
];
},
[user]
);
return (
<InvenTreeTable
url={apiUrl(ApiPaths.manufacturer_part_parameter_list)}
tableState={table}
columns={tableColumns}
props={{
params: {
...params
},
rowActions: rowActions
}}
/>
);
}

View File

@ -48,11 +48,13 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
render: (record: any) => {
let supplier = record?.supplier_detail ?? {};
return (
return supplier?.pk ? (
<Thumbnail
src={supplier?.thumbnail ?? supplier.image}
text={supplier.name}
/>
) : (
'-'
);
}
},
@ -70,11 +72,13 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
render: (record: any) => {
let manufacturer = record?.manufacturer_detail ?? {};
return (
return manufacturer?.pk ? (
<Thumbnail
src={manufacturer?.thumbnail ?? manufacturer.image}
text={manufacturer.name}
/>
) : (
'-'
);
}
},

View File

@ -68,6 +68,7 @@ export enum ApiPaths {
supplier_part_list = 'api-supplier-part-list',
manufacturer_part_list = 'api-manufacturer-part-list',
manufacturer_part_attachment_list = 'api-manufacturer-part-attachment-list',
manufacturer_part_parameter_list = 'api-manufacturer-part-parameter-list',
address_list = 'api-address-list',
contact_list = 'api-contact-list',

View File

@ -95,6 +95,18 @@ export function useManufacturerPartFields() {
}, []);
}
export function useManufacturerPartParameterFields() {
return useMemo(() => {
const fields: ApiFormFieldSet = {
name: {},
value: {},
units: {}
};
return fields;
}, []);
}
/**
* Field set for editing a company instance
*/

View File

@ -64,6 +64,11 @@ export function extractAvailableFields(
method = method.toUpperCase();
// PATCH method is supported, but metadata is provided via PUT
if (method === 'PATCH') {
method = 'PUT';
}
if (!(method in actions)) {
// Missing method - this means user does not have appropriate permission
permissionDenied();
@ -290,7 +295,7 @@ export function openEditApiForm(props: OpenApiFormProps) {
let editProps: OpenApiFormProps = {
...props,
fetchInitialData: props.fetchInitialData ?? true,
method: 'PUT'
method: 'PATCH'
};
openModalApiForm(editProps);

View File

@ -12,6 +12,7 @@ import { useParams } from 'react-router-dom';
import { PageDetail } from '../../components/nav/PageDetail';
import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
import { AttachmentTable } from '../../components/tables/general/AttachmentTable';
import ManufacturerPartParameterTable from '../../components/tables/purchasing/ManufacturerPartParameterTable';
import { SupplierPartTable } from '../../components/tables/purchasing/SupplierPartTable';
import { ApiPaths } from '../../enums/ApiEndpoints';
import { useInstance } from '../../hooks/UseInstance';
@ -39,7 +40,14 @@ export default function ManufacturerPartDetail() {
{
name: 'parameters',
label: t`Parameters`,
icon: <IconList />
icon: <IconList />,
content: manufacturerPart?.pk ? (
<ManufacturerPartParameterTable
params={{ manufacturer_part: manufacturerPart.pk }}
/>
) : (
<Skeleton />
)
},
{
name: 'suppliers',
@ -78,7 +86,7 @@ export default function ManufacturerPartDetail() {
},
{
name: manufacturerPart?.manufacturer_detail?.name ?? t`Manufacturer`,
url: `/company/manufacturer/${manufacturerPart?.manufacturer_detail?.id}/`
url: `/purchasing/manufacturer/${manufacturerPart?.manufacturer_detail?.pk}/`
}
];
}, [manufacturerPart]);

View File

@ -1,5 +1,5 @@
import { t } from '@lingui/macro';
import { LoadingOverlay, Stack } from '@mantine/core';
import { LoadingOverlay, Skeleton, Stack } from '@mantine/core';
import {
IconCurrencyDollar,
IconInfoCircle,
@ -11,6 +11,7 @@ import { useParams } from 'react-router-dom';
import { PageDetail } from '../../components/nav/PageDetail';
import { PanelGroup, PanelType } from '../../components/nav/PanelGroup';
import { PurchaseOrderTable } from '../../components/tables/purchasing/PurchaseOrderTable';
import { ApiPaths } from '../../enums/ApiEndpoints';
import { useInstance } from '../../hooks/UseInstance';
@ -42,7 +43,12 @@ export default function SupplierPartDetail() {
{
name: 'purchaseorders',
label: t`Purchase Orders`,
icon: <IconShoppingCart />
icon: <IconShoppingCart />,
content: supplierPart?.pk ? (
<PurchaseOrderTable params={{ supplier_part: supplierPart.pk }} />
) : (
<Skeleton />
)
},
{
name: 'pricing',
@ -50,7 +56,7 @@ export default function SupplierPartDetail() {
icon: <IconCurrencyDollar />
}
];
}, []);
}, [supplierPart]);
const breadcrumbs = useMemo(() => {
return [
@ -60,7 +66,7 @@ export default function SupplierPartDetail() {
},
{
name: supplierPart?.supplier_detail?.name ?? t`Supplier`,
url: `/company/supplier/${supplierPart?.supplier_detail?.pk ?? ''}`
url: `/purchasing/supplier/${supplierPart?.supplier_detail?.pk ?? ''}`
}
];
}, [supplierPart]);

View File

@ -185,6 +185,8 @@ export function apiEndpoint(path: ApiPaths): string {
return 'company/part/manufacturer/';
case ApiPaths.manufacturer_part_attachment_list:
return 'company/part/manufacturer/attachment/';
case ApiPaths.manufacturer_part_parameter_list:
return 'company/part/manufacturer/parameter/';
case ApiPaths.stock_item_list:
return 'stock/';
case ApiPaths.stock_tracking_list: