mirror of
https://github.com/inventree/InvenTree.git
synced 2025-12-16 09:18:10 +00:00
Implement more parametric tables:
- ManufacturerPart - SupplierPart - Fixes and enhancements
This commit is contained in:
@@ -23,8 +23,10 @@ import SegmentedControlPanel from '../../components/panels/SegmentedControlPanel
|
|||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
import { CompanyTable } from '../../tables/company/CompanyTable';
|
import { CompanyTable } from '../../tables/company/CompanyTable';
|
||||||
import ParametricCompanyTable from '../../tables/company/ParametricCompanyTable';
|
import ParametricCompanyTable from '../../tables/company/ParametricCompanyTable';
|
||||||
|
import ManufacturerPartParametricTable from '../../tables/purchasing/ManufacturerPartParametricTable';
|
||||||
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
|
import { ManufacturerPartTable } from '../../tables/purchasing/ManufacturerPartTable';
|
||||||
import { PurchaseOrderTable } from '../../tables/purchasing/PurchaseOrderTable';
|
import { PurchaseOrderTable } from '../../tables/purchasing/PurchaseOrderTable';
|
||||||
|
import SupplierPartParametricTable from '../../tables/purchasing/SupplierPartParametricTable';
|
||||||
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
|
import { SupplierPartTable } from '../../tables/purchasing/SupplierPartTable';
|
||||||
|
|
||||||
export default function PurchasingIndex() {
|
export default function PurchasingIndex() {
|
||||||
@@ -45,6 +47,17 @@ export default function PurchasingIndex() {
|
|||||||
defaultValue: 'table'
|
defaultValue: 'table'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [manufacturerPartsView, setManufacturerPartsView] =
|
||||||
|
useLocalStorage<string>({
|
||||||
|
key: 'manufacturer-parts-view',
|
||||||
|
defaultValue: 'table'
|
||||||
|
});
|
||||||
|
|
||||||
|
const [supplierPartsView, setSupplierPartsView] = useLocalStorage<string>({
|
||||||
|
key: 'supplier-parts-view',
|
||||||
|
defaultValue: 'table'
|
||||||
|
});
|
||||||
|
|
||||||
const panels = useMemo(() => {
|
const panels = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
SegmentedControlPanel({
|
SegmentedControlPanel({
|
||||||
@@ -103,12 +116,27 @@ export default function PurchasingIndex() {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
{
|
SegmentedControlPanel({
|
||||||
name: 'supplier-parts',
|
name: 'supplier-parts',
|
||||||
label: t`Supplier Parts`,
|
label: t`Supplier Parts`,
|
||||||
icon: <IconPackageExport />,
|
icon: <IconPackageExport />,
|
||||||
content: <SupplierPartTable />
|
selection: supplierPartsView,
|
||||||
},
|
onChange: setSupplierPartsView,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'table',
|
||||||
|
label: t`Table View`,
|
||||||
|
icon: <IconTable />,
|
||||||
|
content: <SupplierPartTable />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'parametric',
|
||||||
|
label: t`Parametric View`,
|
||||||
|
icon: <IconListDetails />,
|
||||||
|
content: <SupplierPartParametricTable />
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}),
|
||||||
SegmentedControlPanel({
|
SegmentedControlPanel({
|
||||||
name: 'manufacturer',
|
name: 'manufacturer',
|
||||||
label: t`Manufacturers`,
|
label: t`Manufacturers`,
|
||||||
@@ -137,14 +165,36 @@ export default function PurchasingIndex() {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
{
|
SegmentedControlPanel({
|
||||||
name: 'manufacturer-parts',
|
name: 'manufacturer-parts',
|
||||||
label: t`Manufacturer Parts`,
|
label: t`Manufacturer Parts`,
|
||||||
icon: <IconBuildingWarehouse />,
|
icon: <IconBuildingWarehouse />,
|
||||||
content: <ManufacturerPartTable />
|
selection: manufacturerPartsView,
|
||||||
}
|
onChange: setManufacturerPartsView,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'table',
|
||||||
|
label: t`Table View`,
|
||||||
|
icon: <IconTable />,
|
||||||
|
content: <ManufacturerPartTable />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'parametric',
|
||||||
|
label: t`Parametric View`,
|
||||||
|
icon: <IconListDetails />,
|
||||||
|
content: <ManufacturerPartParametricTable />
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
];
|
];
|
||||||
}, [user, manufacturerView, purchaseOrderView, supplierView]);
|
}, [
|
||||||
|
user,
|
||||||
|
manufacturerPartsView,
|
||||||
|
manufacturerView,
|
||||||
|
purchaseOrderView,
|
||||||
|
supplierPartsView,
|
||||||
|
supplierView
|
||||||
|
]);
|
||||||
|
|
||||||
if (!user.isLoggedIn() || !user.hasViewRole(UserRoles.purchase_order)) {
|
if (!user.isLoggedIn() || !user.hasViewRole(UserRoles.purchase_order)) {
|
||||||
return <PermissionDenied />;
|
return <PermissionDenied />;
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import { cancelEvent } from '@lib/functions/Events';
|
|||||||
import {
|
import {
|
||||||
ApiEndpoints,
|
ApiEndpoints,
|
||||||
type ApiFormFieldSet,
|
type ApiFormFieldSet,
|
||||||
ModelType,
|
type ModelType,
|
||||||
|
RowViewAction,
|
||||||
UserRoles,
|
UserRoles,
|
||||||
YesNoButton,
|
YesNoButton,
|
||||||
apiUrl,
|
apiUrl,
|
||||||
@@ -15,6 +16,7 @@ import type { TableColumn } from '@lib/types/Tables';
|
|||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { Group } from '@mantine/core';
|
import { Group } from '@mantine/core';
|
||||||
import { useHover } from '@mantine/hooks';
|
import { useHover } from '@mantine/hooks';
|
||||||
|
import { IconCirclePlus } from '@tabler/icons-react';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
import { type ReactNode, useCallback, useMemo, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
@@ -247,11 +249,11 @@ export default function ParametricDataTable({
|
|||||||
}, [parameterFilters]);
|
}, [parameterFilters]);
|
||||||
|
|
||||||
const [selectedInstance, setSelectedInstance] = useState<number>(-1);
|
const [selectedInstance, setSelectedInstance] = useState<number>(-1);
|
||||||
const [selectedTemplate, setSelectedTemplate] = useState<number>(-1);
|
const [selectedTemplate, setSelectedTemplate] = useState<number | null>(null);
|
||||||
const [selectedParameter, setSelectedParameter] = useState<number>(-1);
|
const [selectedParameter, setSelectedParameter] = useState<number>(-1);
|
||||||
|
|
||||||
const parameterFields: ApiFormFieldSet = useParameterFields({
|
const parameterFields: ApiFormFieldSet = useParameterFields({
|
||||||
modelType: ModelType.part,
|
modelType: modelType,
|
||||||
modelId: selectedInstance
|
modelId: selectedInstance
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -262,6 +264,16 @@ export default function ParametricDataTable({
|
|||||||
focus: 'data',
|
focus: 'data',
|
||||||
onFormSuccess: (parameter: any) => {
|
onFormSuccess: (parameter: any) => {
|
||||||
updateParameterRecord(selectedInstance, parameter);
|
updateParameterRecord(selectedInstance, parameter);
|
||||||
|
|
||||||
|
// Ensure that the parameter template is included in the table
|
||||||
|
const template = parameterTemplates.data.find(
|
||||||
|
(t: any) => t.pk == parameter.template
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!template) {
|
||||||
|
// Reload the parameter templates
|
||||||
|
parameterTemplates.refetch();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
initialData: {
|
initialData: {
|
||||||
part: selectedInstance,
|
part: selectedInstance,
|
||||||
@@ -374,6 +386,32 @@ export default function ParametricDataTable({
|
|||||||
return [...(customColumns || []), ...parameterColumns];
|
return [...(customColumns || []), ...parameterColumns];
|
||||||
}, [customColumns, parameterColumns]);
|
}, [customColumns, parameterColumns]);
|
||||||
|
|
||||||
|
const rowActions = useCallback(
|
||||||
|
(record: any) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: t`Add Parameter`,
|
||||||
|
icon: <IconCirclePlus />,
|
||||||
|
color: 'green',
|
||||||
|
hidden: !user.hasAddPermission(modelType),
|
||||||
|
onClick: () => {
|
||||||
|
setSelectedInstance(record.pk);
|
||||||
|
setSelectedTemplate(null);
|
||||||
|
addParameter.open();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RowViewAction({
|
||||||
|
title: t`View`,
|
||||||
|
modelType: modelType,
|
||||||
|
modelId: record.pk,
|
||||||
|
hidden: !user.hasViewPermission(modelType),
|
||||||
|
navigate: navigate
|
||||||
|
})
|
||||||
|
];
|
||||||
|
},
|
||||||
|
[modelType, user]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{addParameter.modal}
|
{addParameter.modal}
|
||||||
@@ -384,6 +422,7 @@ export default function ParametricDataTable({
|
|||||||
columns={tableColumns}
|
columns={tableColumns}
|
||||||
props={{
|
props={{
|
||||||
enableDownload: true,
|
enableDownload: true,
|
||||||
|
rowActions: rowActions,
|
||||||
tableFilters: tableFilters,
|
tableFilters: tableFilters,
|
||||||
params: {
|
params: {
|
||||||
...queryParams,
|
...queryParams,
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { ApiEndpoints, ModelType } from '@lib/index';
|
||||||
|
import type { TableFilter } from '@lib/types/Filters';
|
||||||
|
import type { TableColumn } from '@lib/types/Tables';
|
||||||
|
import { type ReactNode, useMemo } from 'react';
|
||||||
|
import ParametricDataTable from '../general/ParametricDataTable';
|
||||||
|
|
||||||
|
export default function ManufacturerPartParametricTable({
|
||||||
|
queryParams
|
||||||
|
}: {
|
||||||
|
queryParams?: Record<string, any>;
|
||||||
|
}): ReactNode {
|
||||||
|
const customColumns: TableColumn[] = useMemo(() => {
|
||||||
|
return [];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const customFilters: TableFilter[] = useMemo(() => {
|
||||||
|
return [];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ParametricDataTable
|
||||||
|
modelType={ModelType.manufacturerpart}
|
||||||
|
endpoint={ApiEndpoints.manufacturer_part_list}
|
||||||
|
customColumns={customColumns}
|
||||||
|
customFilters={customFilters}
|
||||||
|
queryParams={{
|
||||||
|
...queryParams,
|
||||||
|
part_detail: true,
|
||||||
|
manufacturer_detail: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { ApiEndpoints, ModelType } from '@lib/index';
|
||||||
|
import type { TableFilter } from '@lib/types/Filters';
|
||||||
|
import type { TableColumn } from '@lib/types/Tables';
|
||||||
|
import { t } from '@lingui/core/macro';
|
||||||
|
import { type ReactNode, useMemo } from 'react';
|
||||||
|
import { CompanyColumn, PartColumn } from '../ColumnRenderers';
|
||||||
|
import ParametricDataTable from '../general/ParametricDataTable';
|
||||||
|
|
||||||
|
export default function SupplierPartParametricTable({
|
||||||
|
queryParams
|
||||||
|
}: {
|
||||||
|
queryParams?: Record<string, any>;
|
||||||
|
}): ReactNode {
|
||||||
|
const customColumns: TableColumn[] = useMemo(() => {
|
||||||
|
return [
|
||||||
|
PartColumn({
|
||||||
|
switchable: false,
|
||||||
|
part: 'part_detail'
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
accessor: 'supplier',
|
||||||
|
sortable: true,
|
||||||
|
render: (record: any) => (
|
||||||
|
<CompanyColumn company={record?.supplier_detail} />
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessor: 'SKU',
|
||||||
|
title: t`Supplier Part`,
|
||||||
|
sortable: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const customFilters: TableFilter[] = useMemo(() => {
|
||||||
|
return [];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ParametricDataTable
|
||||||
|
modelType={ModelType.supplierpart}
|
||||||
|
endpoint={ApiEndpoints.supplier_part_list}
|
||||||
|
customColumns={customColumns}
|
||||||
|
customFilters={customFilters}
|
||||||
|
queryParams={{
|
||||||
|
...queryParams,
|
||||||
|
part_detail: true,
|
||||||
|
supplier_detail: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user