2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-05-09 03:03:41 +00:00
Files
InvenTree/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx
T
github-actions[bot] d1354fc147 [plugin] Render tables (#11733) (#11737)
* Move useFilterSet state to the @lib

* Refactor useTable hook into @lib

* Refactor string helper functions

* Refactor constructFormUrl func

* Refactor Boundary component

* Refactor StoredTableState

* More refactoring

* Refactor CopyButton and CopyableCell

* Pass table render func to plugins

* Provide internal wrapper function, while allowing the "api" and "navigate" functions to be provided by the caller

* Adds <InvenTreeTable /> component which is exposed to plugins

* Update frontend versioning

* Update docs

* Handle condition where UI does not provide table rendering function

* Move queryFilters out of custom state

* Fix exported type

* Extract searchParams

- Cannot be used outside of router component
- Only provide when the table is generated internally

* Bump UI version

* Fix for right-click context menu

- Function needs to be defined with the context menu provider

(cherry picked from commit 23f43ffd33)

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
2026-04-13 20:43:40 +10:00

239 lines
5.9 KiB
TypeScript

import { t } from '@lingui/core/macro';
import { type ReactNode, useCallback, useMemo, useState } from 'react';
import { AddItemButton } from '@lib/components/AddItemButton';
import {
type RowAction,
RowDeleteAction,
RowDuplicateAction,
RowEditAction
} from '@lib/components/RowActions';
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import useTable from '@lib/hooks/UseTable';
import type { TableFilter } from '@lib/types/Filters';
import type { TableColumn } from '@lib/types/Tables';
import { useManufacturerPartFields } from '../../forms/CompanyForms';
import {
useCreateApiFormModal,
useDeleteApiFormModal,
useEditApiFormModal
} from '../../hooks/UseForm';
import { useUserState } from '../../states/UserState';
import {
CompanyColumn,
DescriptionColumn,
IPNColumn,
LinkColumn,
PartColumn
} from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
/*
* Construct a table listing manufacturer parts
*/
export function ManufacturerPartTable({
manufacturerId,
partId
}: Readonly<{
manufacturerId?: number;
partId?: number;
}>): ReactNode {
const tableId: string = useMemo(() => {
let tId = 'manufacturer-part';
if (manufacturerId) {
tId += '-manufacturer';
}
if (partId) {
tId += '-part';
}
return tId;
}, [manufacturerId, partId]);
const initialFilters = useMemo(() => {
const filters: TableFilter[] = [];
if (!manufacturerId) {
filters.push({
name: 'manufacturer_active',
value: 'true'
});
}
if (!partId) {
filters.push({
name: 'part_active',
value: 'true'
});
}
return filters;
}, [manufacturerId, partId]);
const table = useTable(tableId, {
initialFilters: initialFilters
});
const user = useUserState();
// Construct table columns for this table
const tableColumns: TableColumn[] = useMemo(() => {
return [
PartColumn({
switchable: !!partId
}),
IPNColumn({}),
{
accessor: 'manufacturer',
sortable: true,
render: (record: any) => (
<CompanyColumn company={record?.manufacturer_detail} />
)
},
{
accessor: 'MPN',
title: t`MPN`,
sortable: true,
copyable: true
},
DescriptionColumn({}),
LinkColumn({})
];
}, [partId]);
const manufacturerPartFields = useManufacturerPartFields();
const [selectedPart, setSelectedPart] = useState<any>(undefined);
const createManufacturerPart = useCreateApiFormModal({
url: ApiEndpoints.manufacturer_part_list,
title: t`Add Manufacturer Part`,
fields: manufacturerPartFields,
table: table,
initialData: {
manufacturer: manufacturerId,
part: partId
},
keepOpenOption: true
});
const editManufacturerPart = useEditApiFormModal({
url: ApiEndpoints.manufacturer_part_list,
pk: selectedPart?.pk,
title: t`Edit Manufacturer Part`,
fields: useMemo(() => manufacturerPartFields, [manufacturerPartFields]),
table: table
});
const duplicateManufacturerPart = useCreateApiFormModal({
url: ApiEndpoints.manufacturer_part_list,
title: t`Add Manufacturer Part`,
fields: useMemo(() => manufacturerPartFields, [manufacturerPartFields]),
table: table,
initialData: {
...selectedPart
}
});
const deleteManufacturerPart = useDeleteApiFormModal({
url: ApiEndpoints.manufacturer_part_list,
pk: selectedPart?.pk,
title: t`Delete Manufacturer Part`,
table: table
});
const tableFilters: TableFilter[] = useMemo(() => {
return [
{
name: 'part_active',
label: t`Active Part`,
description: t`Show manufacturer parts for active internal parts.`,
type: 'boolean'
},
{
name: 'manufacturer_active',
label: t`Active Manufacturer`,
active: !manufacturerId,
description: t`Show manufacturer parts for active manufacturers.`,
type: 'boolean'
}
];
}, [manufacturerId]);
const tableActions = useMemo(() => {
const can_add =
user.hasAddRole(UserRoles.purchase_order) &&
user.hasAddRole(UserRoles.part);
return [
<AddItemButton
key='add-manufacturer-part'
tooltip={t`Add Manufacturer Part`}
onClick={() => createManufacturerPart.open()}
hidden={!can_add}
/>
];
}, [user]);
const rowActions = useCallback(
(record: any): RowAction[] => {
return [
RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order),
onClick: () => {
setSelectedPart(record);
editManufacturerPart.open();
}
}),
RowDuplicateAction({
hidden: !user.hasAddRole(UserRoles.purchase_order),
onClick: () => {
setSelectedPart(record);
duplicateManufacturerPart.open();
}
}),
RowDeleteAction({
hidden: !user.hasDeleteRole(UserRoles.purchase_order),
onClick: () => {
setSelectedPart(record);
deleteManufacturerPart.open();
}
})
];
},
[user]
);
return (
<>
{createManufacturerPart.modal}
{duplicateManufacturerPart.modal}
{editManufacturerPart.modal}
{deleteManufacturerPart.modal}
<InvenTreeTable
url={apiUrl(ApiEndpoints.manufacturer_part_list)}
tableState={table}
columns={tableColumns}
props={{
params: {
part: partId,
manufacturer: manufacturerId,
part_detail: true,
manufacturer_detail: true
},
enableDownload: true,
rowActions: rowActions,
tableActions: tableActions,
tableFilters: tableFilters,
modelType: ModelType.manufacturerpart
}}
/>
</>
);
}