2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 19:46:46 +00:00

[PUI] table fixes (#6764)

* Impove link rendering in attachment table

* Add "updateRecord" hook for useTable

* Refactoring

Make use of new table.updateRecord method

* Refactor model row clicks

- Just need to provide a model type

* Fix BuildLineTable

* Re-add required imports

* Remove hard-coded paths
This commit is contained in:
Oliver 2024-03-20 21:56:32 +11:00 committed by GitHub
parent 08c0953eb7
commit 0cb4e8ec1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 99 additions and 104 deletions

View File

@ -20,6 +20,7 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
import { InvenTreeIcon, InvenTreeIconType } from '../../functions/icons'; import { InvenTreeIcon, InvenTreeIconType } from '../../functions/icons';
import { getDetailUrl } from '../../functions/urls'; import { getDetailUrl } from '../../functions/urls';
import { base_url } from '../../main';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
import { useGlobalSettingsState } from '../../states/SettingsState'; import { useGlobalSettingsState } from '../../states/SettingsState';
import { ProgressBar } from '../items/ProgressBar'; import { ProgressBar } from '../items/ProgressBar';
@ -292,7 +293,7 @@ function TableAnchorValue(props: FieldProps) {
<Suspense fallback={<Skeleton width={200} height={20} radius="xl" />}> <Suspense fallback={<Skeleton width={200} height={20} radius="xl" />}>
{make_link ? ( {make_link ? (
<Anchor <Anchor
href={`/platform${detailUrl}`} href={`/${base_url}${detailUrl}`}
target={data?.external ? '_blank' : undefined} target={data?.external ? '_blank' : undefined}
rel={data?.external ? 'noreferrer noopener' : undefined} rel={data?.external ? 'noreferrer noopener' : undefined}
> >

View File

@ -1,5 +1,5 @@
import { Group, Text } from '@mantine/core'; import { Anchor, Group, Text } from '@mantine/core';
import { IconPhoto } from '@tabler/icons-react'; import { IconLink, IconPhoto } from '@tabler/icons-react';
import { import {
IconFile, IconFile,
IconFileTypeCsv, IconFileTypeCsv,
@ -50,14 +50,20 @@ export function attachmentIcon(attachment: string): ReactNode {
* @param attachment : string - The attachment filename * @param attachment : string - The attachment filename
*/ */
export function AttachmentLink({ export function AttachmentLink({
attachment attachment,
external
}: { }: {
attachment: string; attachment: string;
external?: boolean;
}): ReactNode { }): ReactNode {
let text = external ? attachment : attachment.split('/').pop();
return ( return (
<Group position="left" spacing="sm"> <Group position="left" spacing="sm">
{attachmentIcon(attachment)} {external ? <IconLink /> : attachmentIcon(attachment)}
<Text>{attachment.split('/').pop()}</Text> <Anchor href={attachment} target="_blank" rel="noopener noreferrer">
{text}
</Anchor>
</Group> </Group>
); );
} }

View File

@ -80,7 +80,7 @@ export function editAttachment({
model: string; model: string;
pk: number; pk: number;
attachmentType: 'file' | 'link'; attachmentType: 'file' | 'link';
callback?: () => void; callback?: (record: any) => void;
}) { }) {
let formFields: ApiFormFieldSet = { let formFields: ApiFormFieldSet = {
link: {}, link: {},

View File

@ -34,6 +34,7 @@ export type TableState = {
setPage: (page: number) => void; setPage: (page: number) => void;
records: any[]; records: any[];
setRecords: (records: any[]) => void; setRecords: (records: any[]) => void;
updateRecord: (record: any) => void;
}; };
/** /**
@ -95,6 +96,25 @@ export function useTable(tableName: string): TableState {
// Table records // Table records
const [records, setRecords] = useState<any[]>([]); const [records, setRecords] = useState<any[]>([]);
// Update a single record in the table, by primary key value
const updateRecord = useCallback(
(record: any) => {
let _records = [...records];
// Find the matching record in the table
const index = _records.findIndex((r) => r.pk === record.pk);
if (index >= 0) {
_records[index] = record;
} else {
_records.push(record);
}
setRecords(_records);
},
[records]
);
return { return {
tableKey, tableKey,
refreshTable, refreshTable,
@ -115,6 +135,7 @@ export function useTable(tableName: string): TableState {
page, page,
setPage, setPage,
records, records,
setRecords setRecords,
updateRecord
}; };
} }

View File

@ -21,13 +21,17 @@ import {
DataTableSortStatus DataTableSortStatus
} from 'mantine-datatable'; } from 'mantine-datatable';
import { Fragment, useCallback, useEffect, useMemo, useState } from 'react'; import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { api } from '../App'; import { api } from '../App';
import { ActionButton } from '../components/buttons/ActionButton'; import { ActionButton } from '../components/buttons/ActionButton';
import { ButtonMenu } from '../components/buttons/ButtonMenu'; import { ButtonMenu } from '../components/buttons/ButtonMenu';
import { ApiFormFieldSet } from '../components/forms/fields/ApiFormField'; import { ApiFormFieldSet } from '../components/forms/fields/ApiFormField';
import { ModelType } from '../enums/ModelType';
import { extractAvailableFields, mapFields } from '../functions/forms'; import { extractAvailableFields, mapFields } from '../functions/forms';
import { getDetailUrl } from '../functions/urls';
import { TableState } from '../hooks/UseTable'; import { TableState } from '../hooks/UseTable';
import { base_url } from '../main';
import { useLocalState } from '../states/LocalState'; import { useLocalState } from '../states/LocalState';
import { TableColumn } from './Column'; import { TableColumn } from './Column';
import { TableColumnSelect } from './ColumnSelect'; import { TableColumnSelect } from './ColumnSelect';
@ -62,6 +66,7 @@ const defaultPageSize: number = 25;
* @param rowActions : (record: any) => RowAction[] - Callback function to generate row actions * @param rowActions : (record: any) => RowAction[] - Callback function to generate row actions
* @param onRowClick : (record: any, index: number, event: any) => void - Callback function when a row is clicked * @param onRowClick : (record: any, index: number, event: any) => void - Callback function when a row is clicked
* @param onCellClick : (event: any, record: any, recordIndex: number, column: any, columnIndex: number) => void - Callback function when a cell is clicked * @param onCellClick : (event: any, record: any, recordIndex: number, column: any, columnIndex: number) => void - Callback function when a cell is clicked
* @param modelType: ModelType - The model type for the table
*/ */
export type InvenTreeTableProps<T = any> = { export type InvenTreeTableProps<T = any> = {
params?: any; params?: any;
@ -85,6 +90,7 @@ export type InvenTreeTableProps<T = any> = {
rowActions?: (record: T) => RowAction[]; rowActions?: (record: T) => RowAction[];
onRowClick?: (record: T, index: number, event: any) => void; onRowClick?: (record: T, index: number, event: any) => void;
onCellClick?: DataTableCellClickHandler<T>; onCellClick?: DataTableCellClickHandler<T>;
modelType?: ModelType;
}; };
/** /**
@ -125,6 +131,8 @@ export function InvenTreeTable<T = any>({
const { getTableColumnNames, setTableColumnNames } = useLocalState(); const { getTableColumnNames, setTableColumnNames } = useLocalState();
const [fieldNames, setFieldNames] = useState<Record<string, string>>({}); const [fieldNames, setFieldNames] = useState<Record<string, string>>({});
const navigate = useNavigate();
// Construct table filters - note that we can introspect filter labels from column names // Construct table filters - note that we can introspect filter labels from column names
const filters: TableFilter[] = useMemo(() => { const filters: TableFilter[] = useMemo(() => {
return ( return (
@ -501,6 +509,29 @@ export function InvenTreeTable<T = any>({
}); });
}, [tableState.selectedRecords]); }, [tableState.selectedRecords]);
// Callback when a row is clicked
const handleRowClick = useCallback(
(record: any, index: number, event: any) => {
if (props.onRowClick) {
// If a custom row click handler is provided, use that
props.onRowClick(record, index, event);
} else if (tableProps.modelType && record?.pk) {
// If a model type is provided, navigate to the detail view for that model
let url = getDetailUrl(tableProps.modelType, record.pk);
// Should it be opened in a new tab?
if (event?.ctrlKey || event?.shiftKey || event?.buttons & 0x04) {
// Open in a new tab
window.open(`/${base_url}{url}`, '_blank', 'noreferrer');
} else {
// Navigate internally
navigate(url);
}
}
},
[props.onRowClick]
);
return ( return (
<> <>
{tableProps.enableFilters && (filters.length ?? 0) > 0 && ( {tableProps.enableFilters && (filters.length ?? 0) > 0 && (
@ -622,7 +653,7 @@ export function InvenTreeTable<T = any>({
noRecordsText={missingRecordsText} noRecordsText={missingRecordsText}
records={tableState.records} records={tableState.records}
columns={dataColumns} columns={dataColumns}
onRowClick={tableProps.onRowClick} onRowClick={handleRowClick}
onCellClick={tableProps.onCellClick} onCellClick={tableProps.onCellClick}
defaultColumnProps={{ defaultColumnProps={{
noWrap: true, noWrap: true,

View File

@ -16,7 +16,6 @@ import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { bomItemFields } from '../../forms/BomForms'; import { bomItemFields } from '../../forms/BomForms';
import { openDeleteApiForm, openEditApiForm } from '../../functions/forms'; import { openDeleteApiForm, openEditApiForm } from '../../functions/forms';
import { getDetailUrl } from '../../functions/urls';
import { useTable } from '../../hooks/UseTable'; import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
@ -55,11 +54,9 @@ export function BomTable({
partId: number; partId: number;
params?: any; params?: any;
}) { }) {
const navigate = useNavigate();
const user = useUserState(); const user = useUserState();
const table = useTable('bom'); const table = useTable('bom');
const navigate = useNavigate();
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
return [ return [
@ -355,8 +352,7 @@ export function BomTable({
sub_part_detail: true sub_part_detail: true
}, },
tableFilters: tableFilters, tableFilters: tableFilters,
onRowClick: (row) => modelType: ModelType.part,
navigate(getDetailUrl(ModelType.part, row.sub_part)),
rowActions: rowActions rowActions: rowActions
}} }}
/> />

View File

@ -1,11 +1,9 @@
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { PartHoverCard } from '../../components/images/Thumbnail'; import { PartHoverCard } from '../../components/images/Thumbnail';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
import { getDetailUrl } from '../../functions/urls';
import { useTable } from '../../hooks/UseTable'; import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -23,8 +21,6 @@ export function UsedInTable({
partId: number; partId: number;
params?: any; params?: any;
}) { }) {
const navigate = useNavigate();
const table = useTable('usedin'); const table = useTable('usedin');
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
@ -87,7 +83,7 @@ export function UsedInTable({
sub_part_detail: true sub_part_detail: true
}, },
tableFilters: tableFilters, tableFilters: tableFilters,
onRowClick: (row) => navigate(getDetailUrl(ModelType.part, row.part)) modelType: ModelType.part
}} }}
/> />
); );

View File

@ -178,7 +178,7 @@ export function BuildOrderTable({
}, },
tableActions: tableActions, tableActions: tableActions,
tableFilters: tableFilters, tableFilters: tableFilters,
onRowClick: (row) => navigate(getDetailUrl(ModelType.build, row.pk)) modelType: ModelType.build
}} }}
/> />
</> </>

View File

@ -134,7 +134,7 @@ export function AddressTable({
pk: selectedAddress, pk: selectedAddress,
title: t`Edit Address`, title: t`Edit Address`,
fields: addressFields, fields: addressFields,
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const deleteAddress = useDeleteApiFormModal({ const deleteAddress = useDeleteApiFormModal({

View File

@ -6,6 +6,7 @@ import { useNavigate } from 'react-router-dom';
import { AddItemButton } from '../../components/buttons/AddItemButton'; import { AddItemButton } from '../../components/buttons/AddItemButton';
import { Thumbnail } from '../../components/images/Thumbnail'; import { Thumbnail } from '../../components/images/Thumbnail';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { companyFields } from '../../forms/CompanyForms'; import { companyFields } from '../../forms/CompanyForms';
import { useCreateApiFormModal } from '../../hooks/UseForm'; import { useCreateApiFormModal } from '../../hooks/UseForm';

View File

@ -72,7 +72,7 @@ export function ContactTable({
pk: selectedContact, pk: selectedContact,
title: t`Edit Contact`, title: t`Edit Contact`,
fields: contactFields, fields: contactFields,
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const newContact = useCreateApiFormModal({ const newContact = useCreateApiFormModal({

View File

@ -34,8 +34,7 @@ function attachmentTableColumns(): TableColumn[] {
if (record.attachment) { if (record.attachment) {
return <AttachmentLink attachment={record.attachment} />; return <AttachmentLink attachment={record.attachment} />;
} else if (record.link) { } else if (record.link) {
// TODO: Custom renderer for links return <AttachmentLink attachment={record.link} external />;
return record.link;
} else { } else {
return '-'; return '-';
} }
@ -121,7 +120,9 @@ export function AttachmentTable({
model: model, model: model,
pk: record.pk, pk: record.pk,
attachmentType: record.attachment ? 'file' : 'link', attachmentType: record.attachment ? 'file' : 'link',
callback: table.refreshTable callback: (record: any) => {
table.updateRecord(record);
}
}); });
} }
}) })

View File

@ -4,7 +4,6 @@ import { useHover } from '@mantine/hooks';
import { IconEdit } from '@tabler/icons-react'; import { IconEdit } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { api } from '../../App'; import { api } from '../../App';
import { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField'; import { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
@ -12,7 +11,6 @@ import { YesNoButton } from '../../components/items/YesNoButton';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { getDetailUrl } from '../../functions/urls';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useEditApiFormModal useEditApiFormModal
@ -99,7 +97,6 @@ export default function ParametricPartTable({
}) { }) {
const table = useTable('parametric-parts'); const table = useTable('parametric-parts');
const user = useUserState(); const user = useUserState();
const navigate = useNavigate();
const categoryParmeters = useQuery({ const categoryParmeters = useQuery({
queryKey: ['category-parameters', categoryId], queryKey: ['category-parameters', categoryId],
@ -289,11 +286,7 @@ export default function ParametricPartTable({
category_detail: true, category_detail: true,
parameters: true parameters: true
}, },
onRowClick: (record) => { modelType: ModelType.part
if (record.pk) {
navigate(getDetailUrl(ModelType.part, record.pk));
}
}
}} }}
/> />
</> </>

View File

@ -95,7 +95,7 @@ export function PartCategoryTable({ parentId }: { parentId?: any }) {
pk: selectedCategory, pk: selectedCategory,
title: t`Edit Part Category`, title: t`Edit Part Category`,
fields: partCategoryFields({}), fields: partCategoryFields({}),
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const tableActions = useMemo(() => { const tableActions = useMemo(() => {
@ -143,8 +143,7 @@ export function PartCategoryTable({ parentId }: { parentId?: any }) {
tableFilters: tableFilters, tableFilters: tableFilters,
tableActions: tableActions, tableActions: tableActions,
rowActions: rowActions, rowActions: rowActions,
onRowClick: (record) => modelType: ModelType.partcategory
navigate(getDetailUrl(ModelType.partcategory, record.pk))
}} }}
/> />
</> </>

View File

@ -96,7 +96,7 @@ export default function PartParameterTemplateTable() {
pk: selectedTemplate, pk: selectedTemplate,
title: t`Edit Parameter Template`, title: t`Edit Parameter Template`,
fields: partParameterTemplateFields, fields: partParameterTemplateFields,
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const deleteTemplate = useDeleteApiFormModal({ const deleteTemplate = useDeleteApiFormModal({

View File

@ -4,7 +4,6 @@ import { ReactNode, useMemo } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { AddItemButton } from '../../components/buttons/AddItemButton'; import { AddItemButton } from '../../components/buttons/AddItemButton';
import { Thumbnail } from '../../components/images/Thumbnail';
import { formatPriceRange } from '../../defaults/formatters'; import { formatPriceRange } from '../../defaults/formatters';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
@ -268,8 +267,8 @@ export function PartListTable({ props }: { props: InvenTreeTableProps }) {
const tableFilters = useMemo(() => partTableFilters(), []); const tableFilters = useMemo(() => partTableFilters(), []);
const table = useTable('part-list'); const table = useTable('part-list');
const navigate = useNavigate();
const user = useUserState(); const user = useUserState();
const navigate = useNavigate();
const newPart = useCreateApiFormModal({ const newPart = useCreateApiFormModal({
url: ApiEndpoints.part_list, url: ApiEndpoints.part_list,
@ -305,14 +304,13 @@ export function PartListTable({ props }: { props: InvenTreeTableProps }) {
props={{ props={{
...props, ...props,
enableDownload: true, enableDownload: true,
modelType: ModelType.part,
tableFilters: tableFilters, tableFilters: tableFilters,
tableActions: tableActions, tableActions: tableActions,
params: { params: {
...props.params, ...props.params,
category_detail: true category_detail: true
}, }
onRowClick: (record) =>
navigate(getDetailUrl(ModelType.part, record.pk))
}} }}
/> />
</> </>

View File

@ -134,7 +134,7 @@ export default function PartTestTemplateTable({ partId }: { partId: number }) {
pk: selectedTest, pk: selectedTest,
title: t`Edit Test Template`, title: t`Edit Test Template`,
fields: partTestTemplateFields, fields: partTestTemplateFields,
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const deleteTestTemplate = useDeleteApiFormModal({ const deleteTestTemplate = useDeleteApiFormModal({

View File

@ -1,6 +1,5 @@
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { ReactNode, useCallback, useMemo } from 'react'; import { ReactNode, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { AddItemButton } from '../../components/buttons/AddItemButton'; import { AddItemButton } from '../../components/buttons/AddItemButton';
import { Thumbnail } from '../../components/images/Thumbnail'; import { Thumbnail } from '../../components/images/Thumbnail';
@ -9,8 +8,6 @@ import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { useManufacturerPartFields } from '../../forms/CompanyForms'; import { useManufacturerPartFields } from '../../forms/CompanyForms';
import { openDeleteApiForm, openEditApiForm } from '../../functions/forms'; import { openDeleteApiForm, openEditApiForm } from '../../functions/forms';
import { notYetImplemented } from '../../functions/notifications';
import { getDetailUrl } from '../../functions/urls';
import { useCreateApiFormModal } from '../../hooks/UseForm'; import { useCreateApiFormModal } from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable'; import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
@ -27,7 +24,6 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
const table = useTable('manufacturerparts'); const table = useTable('manufacturerparts');
const user = useUserState(); const user = useUserState();
const navigate = useNavigate();
// Construct table columns for this table // Construct table columns for this table
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
@ -139,11 +135,7 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
}, },
rowActions: rowActions, rowActions: rowActions,
tableActions: tableActions, tableActions: tableActions,
onRowClick: (record: any) => { modelType: ModelType.manufacturerpart
if (record?.pk) {
navigate(getDetailUrl(ModelType.manufacturerpart, record.pk));
}
}
}} }}
/> />
</> </>

View File

@ -2,7 +2,6 @@ import { t } from '@lingui/macro';
import { Text } from '@mantine/core'; import { Text } from '@mantine/core';
import { IconSquareArrowRight } from '@tabler/icons-react'; import { IconSquareArrowRight } from '@tabler/icons-react';
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { ActionButton } from '../../components/buttons/ActionButton'; import { ActionButton } from '../../components/buttons/ActionButton';
import { AddItemButton } from '../../components/buttons/AddItemButton'; import { AddItemButton } from '../../components/buttons/AddItemButton';
@ -16,7 +15,6 @@ import {
usePurchaseOrderLineItemFields, usePurchaseOrderLineItemFields,
useReceiveLineItems useReceiveLineItems
} from '../../forms/PurchaseOrderForms'; } from '../../forms/PurchaseOrderForms';
import { getDetailUrl } from '../../functions/urls';
import { import {
useCreateApiFormModal, useCreateApiFormModal,
useDeleteApiFormModal, useDeleteApiFormModal,
@ -52,7 +50,6 @@ export function PurchaseOrderLineItemTable({
}) { }) {
const table = useTable('purchase-order-line-item'); const table = useTable('purchase-order-line-item');
const navigate = useNavigate();
const user = useUserState(); const user = useUserState();
const [singleRecord, setSingeRecord] = useState(null); const [singleRecord, setSingeRecord] = useState(null);
@ -291,11 +288,7 @@ export function PurchaseOrderLineItemTable({
}, },
rowActions: rowActions, rowActions: rowActions,
tableActions: tableActions, tableActions: tableActions,
onRowClick: (row: any) => { modelType: ModelType.supplierpart
if (row.part) {
navigate(getDetailUrl(ModelType.supplierpart, row.part));
}
}
}} }}
/> />
</> </>

View File

@ -138,11 +138,7 @@ export function PurchaseOrderTable({
}, },
tableFilters: tableFilters, tableFilters: tableFilters,
tableActions: tableActions, tableActions: tableActions,
onRowClick: (row: any) => { modelType: ModelType.purchaseorder
if (row.pk) {
navigate(getDetailUrl(ModelType.purchaseorder, row.pk));
}
}
}} }}
/> />
</> </>

View File

@ -1,7 +1,6 @@
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Text } from '@mantine/core'; import { Text } from '@mantine/core';
import { ReactNode, useCallback, useMemo } from 'react'; import { ReactNode, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { AddItemButton } from '../../components/buttons/AddItemButton'; import { AddItemButton } from '../../components/buttons/AddItemButton';
import { Thumbnail } from '../../components/images/Thumbnail'; import { Thumbnail } from '../../components/images/Thumbnail';
@ -10,7 +9,6 @@ import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { useSupplierPartFields } from '../../forms/CompanyForms'; import { useSupplierPartFields } from '../../forms/CompanyForms';
import { openDeleteApiForm, openEditApiForm } from '../../functions/forms'; import { openDeleteApiForm, openEditApiForm } from '../../functions/forms';
import { getDetailUrl } from '../../functions/urls';
import { useCreateApiFormModal } from '../../hooks/UseForm'; import { useCreateApiFormModal } from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable'; import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
@ -34,7 +32,6 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
const table = useTable('supplierparts'); const table = useTable('supplierparts');
const user = useUserState(); const user = useUserState();
const navigate = useNavigate();
// Construct table columns for this table // Construct table columns for this table
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
@ -232,11 +229,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
}, },
rowActions: rowActions, rowActions: rowActions,
tableActions: tableActions, tableActions: tableActions,
onRowClick: (record: any) => { modelType: ModelType.supplierpart
if (record?.pk) {
navigate(getDetailUrl(ModelType.supplierpart, record.pk));
}
}
}} }}
/> />
</> </>

View File

@ -1,6 +1,5 @@
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { AddItemButton } from '../../components/buttons/AddItemButton'; import { AddItemButton } from '../../components/buttons/AddItemButton';
import { Thumbnail } from '../../components/images/Thumbnail'; import { Thumbnail } from '../../components/images/Thumbnail';
@ -8,7 +7,6 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles'; import { UserRoles } from '../../enums/Roles';
import { notYetImplemented } from '../../functions/notifications'; import { notYetImplemented } from '../../functions/notifications';
import { getDetailUrl } from '../../functions/urls';
import { useTable } from '../../hooks/UseTable'; import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
@ -36,8 +34,6 @@ export function ReturnOrderTable({ params }: { params?: any }) {
const table = useTable('return-orders'); const table = useTable('return-orders');
const user = useUserState(); const user = useUserState();
const navigate = useNavigate();
const tableFilters: TableFilter[] = useMemo(() => { const tableFilters: TableFilter[] = useMemo(() => {
return [ return [
{ {
@ -115,11 +111,7 @@ export function ReturnOrderTable({ params }: { params?: any }) {
}, },
tableFilters: tableFilters, tableFilters: tableFilters,
tableActions: tableActions, tableActions: tableActions,
onRowClick: (row: any) => { modelType: ModelType.returnorder
if (row.pk) {
navigate(getDetailUrl(ModelType.returnorder, row.pk));
}
}
}} }}
/> />
); );

View File

@ -136,11 +136,7 @@ export function SalesOrderTable({
}, },
tableFilters: tableFilters, tableFilters: tableFilters,
tableActions: tableActions, tableActions: tableActions,
onRowClick: (row: any) => { modelType: ModelType.salesorder
if (row.pk) {
navigate(getDetailUrl(ModelType.salesorder, row.pk));
}
}
}} }}
/> />
</> </>

View File

@ -59,7 +59,7 @@ export default function CustomUnitsTable() {
pk: selectedUnit, pk: selectedUnit,
title: t`Edit Custom Unit`, title: t`Edit Custom Unit`,
fields: customUnitsFields(), fields: customUnitsFields(),
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const deleteUnit = useDeleteApiFormModal({ const deleteUnit = useDeleteApiFormModal({

View File

@ -53,7 +53,7 @@ export default function ProjectCodeTable() {
pk: selectedProjectCode, pk: selectedProjectCode,
title: t`Edit Project Code`, title: t`Edit Project Code`,
fields: projectCodeFields(), fields: projectCodeFields(),
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const deleteProjectCode = useDeleteApiFormModal({ const deleteProjectCode = useDeleteApiFormModal({

View File

@ -1,9 +1,7 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType'; import { ModelType } from '../../enums/ModelType';
import { getDetailUrl } from '../../functions/urls';
import { useTable } from '../../hooks/UseTable'; import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState'; import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
@ -18,7 +16,6 @@ export default function InstalledItemsTable({
}) { }) {
const table = useTable('stock_item_install'); const table = useTable('stock_item_install');
const user = useUserState(); const user = useUserState();
const navigate = useNavigate();
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
return [ return [
@ -60,11 +57,7 @@ export default function InstalledItemsTable({
columns={tableColumns} columns={tableColumns}
props={{ props={{
tableActions: tableActions, tableActions: tableActions,
onRowClick: (record: any) => { modelType: ModelType.stockitem,
if (record.pk) {
navigate(getDetailUrl(ModelType.stockitem, record.pk));
}
},
params: { params: {
belongs_to: parentId, belongs_to: parentId,
part_detail: true part_detail: true

View File

@ -509,8 +509,7 @@ export function StockItemTable({ params = {} }: { params?: any }) {
enableSelection: true, enableSelection: true,
tableFilters: tableFilters, tableFilters: tableFilters,
tableActions: tableActions, tableActions: tableActions,
onRowClick: (record) => modelType: ModelType.stockitem,
navigate(getDetailUrl(ModelType.stockitem, record.pk)),
params: { params: {
...params, ...params,
part_detail: true, part_detail: true,

View File

@ -105,7 +105,7 @@ export function StockLocationTable({ parentId }: { parentId?: any }) {
pk: selectedLocation, pk: selectedLocation,
title: t`Edit Stock Location`, title: t`Edit Stock Location`,
fields: stockLocationFields({}), fields: stockLocationFields({}),
onFormSuccess: table.refreshTable onFormSuccess: (record: any) => table.updateRecord(record)
}); });
const tableActions = useMemo(() => { const tableActions = useMemo(() => {
@ -153,9 +153,7 @@ export function StockLocationTable({ parentId }: { parentId?: any }) {
tableFilters: tableFilters, tableFilters: tableFilters,
tableActions: tableActions, tableActions: tableActions,
rowActions: rowActions, rowActions: rowActions,
onRowClick: (record) => { modelType: ModelType.stocklocation
navigate(getDetailUrl(ModelType.stocklocation, record.pk));
}
}} }}
/> />
</> </>