InvenTree/src/frontend/src/tables/part/PartParameterTable.tsx

225 lines
6.0 KiB
TypeScript

import { t } from '@lingui/macro';
import { Alert, Stack, Text } from '@mantine/core';
import { IconLock } from '@tabler/icons-react';
import { useCallback, useMemo, useState } from 'react';
import { AddItemButton } from '../../components/buttons/AddItemButton';
import { YesNoButton } from '../../components/buttons/YesNoButton';
import { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { UserRoles } from '../../enums/Roles';
import { usePartParameterFields } from '../../forms/PartForms';
import {
useCreateApiFormModal,
useDeleteApiFormModal,
useEditApiFormModal
} from '../../hooks/UseForm';
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 { RowDeleteAction, RowEditAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard';
/**
* Construct a table listing parameters for a given part
*/
export function PartParameterTable({
partId,
partLocked
}: {
partId: any;
partLocked?: boolean;
}) {
const table = useTable('part-parameters');
const user = useUserState();
const tableColumns: TableColumn[] = useMemo(() => {
return [
{
accessor: 'part',
sortable: true,
render: (record: any) => PartColumn(record?.part_detail)
},
{
accessor: 'part_detail.IPN',
sortable: false,
switchable: true
},
{
accessor: 'template_detail.name',
switchable: false,
sortable: true,
ordering: 'name',
render: (record) => {
let variant = String(partId) != String(record.part);
return (
<Text style={{ fontStyle: variant ? 'italic' : 'inherit' }}>
{record.template_detail?.name}
</Text>
);
}
},
DescriptionColumn({
accessor: 'template_detail.description'
}),
{
accessor: 'data',
switchable: false,
sortable: true,
render: (record) => {
let template = record.template_detail;
if (template?.checkbox) {
return <YesNoButton value={record.data} />;
}
let extra: any[] = [];
if (
template.units &&
record.data_numeric &&
record.data_numeric != record.data
) {
extra.push(`${record.data_numeric} [${template.units}]`);
}
return (
<TableHoverCard
value={record.data}
extra={extra}
title={t`Internal Units`}
/>
);
}
},
{
accessor: 'template_detail.units',
ordering: 'units',
sortable: true
}
];
}, [partId]);
const partParameterFields: ApiFormFieldSet = usePartParameterFields();
const newParameter = useCreateApiFormModal({
url: ApiEndpoints.part_parameter_list,
title: t`New Part Parameter`,
fields: useMemo(() => ({ ...partParameterFields }), [partParameterFields]),
focus: 'template',
initialData: {
part: partId
},
table: table
});
const [selectedParameter, setSelectedParameter] = useState<
number | undefined
>(undefined);
const editParameter = useEditApiFormModal({
url: ApiEndpoints.part_parameter_list,
pk: selectedParameter,
title: t`Edit Part Parameter`,
focus: 'data',
fields: useMemo(() => ({ ...partParameterFields }), [partParameterFields]),
table: table
});
const deleteParameter = useDeleteApiFormModal({
url: ApiEndpoints.part_parameter_list,
pk: selectedParameter,
title: t`Delete Part Parameter`,
table: table
});
// Callback for row actions
const rowActions = useCallback(
(record: any) => {
// Actions not allowed for "variant" rows
if (String(partId) != String(record.part)) {
return [];
}
return [
RowEditAction({
tooltip: t`Edit Part Parameter`,
hidden: partLocked || !user.hasChangeRole(UserRoles.part),
onClick: () => {
setSelectedParameter(record.pk);
editParameter.open();
}
}),
RowDeleteAction({
tooltip: t`Delete Part Parameter`,
hidden: partLocked || !user.hasDeleteRole(UserRoles.part),
onClick: () => {
setSelectedParameter(record.pk);
deleteParameter.open();
}
})
];
},
[partId, partLocked, user]
);
// Custom table actions
const tableActions = useMemo(() => {
return [
<AddItemButton
key="add-parameter"
hidden={partLocked || !user.hasAddRole(UserRoles.part)}
tooltip={t`Add parameter`}
onClick={() => newParameter.open()}
/>
];
}, [partLocked, user]);
return (
<>
{newParameter.modal}
{editParameter.modal}
{deleteParameter.modal}
<Stack gap="xs">
{partLocked && (
<Alert
title={t`Part is Locked`}
color="red"
icon={<IconLock />}
p="xs"
>
<Text>{t`Part parameters cannot be edited, as the part is locked`}</Text>
</Alert>
)}
<InvenTreeTable
url={apiUrl(ApiEndpoints.part_parameter_list)}
tableState={table}
columns={tableColumns}
props={{
rowActions: rowActions,
enableDownload: true,
tableActions: tableActions,
tableFilters: [
{
name: 'include_variants',
label: t`Include Variants`,
type: 'boolean'
}
],
params: {
part: partId,
template_detail: true,
part_detail: true
}
}}
/>
</Stack>
</>
);
}