Add useTable hook (#6000)

* Add new hook - useTable

- Will replace useTableRefresh
- More extensible (further functionality to follow)
- Pass entire state through to final table
- Defined interface for return type

* Update BomTable

* Update UsedInTable

* Refactor attachment table

* Update remaining tables

* Clean StockItemTable

* Fix NotificationTable

* Remove unused import
This commit is contained in:
Oliver 2023-11-28 23:15:08 +11:00 committed by GitHub
parent c7bf1348e7
commit c3aeadda4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 160 additions and 168 deletions

View File

@ -9,6 +9,7 @@ import { DataTable, DataTableSortStatus } from 'mantine-datatable';
import { Fragment, useEffect, useMemo, useState } from 'react'; import { Fragment, useEffect, useMemo, useState } from 'react';
import { api } from '../../App'; import { api } from '../../App';
import { TableState } from '../../hooks/UseTable';
import { ButtonMenu } from '../buttons/ButtonMenu'; import { ButtonMenu } from '../buttons/ButtonMenu';
import { TableColumn } from './Column'; import { TableColumn } from './Column';
import { TableColumnSelect } from './ColumnSelect'; import { TableColumnSelect } from './ColumnSelect';
@ -25,8 +26,7 @@ const defaultPageSize: number = 25;
* Set of optional properties which can be passed to an InvenTreeTable component * Set of optional properties which can be passed to an InvenTreeTable component
* *
* @param params : any - Base query parameters * @param params : any - Base query parameters
* @param tableKey : string - Unique key for the table (used for local storage) * @param tableState : TableState - State manager for the table
* @param refreshId : string - Unique ID for the table (used to trigger a refresh)
* @param defaultSortColumn : string - Default column to sort by * @param defaultSortColumn : string - Default column to sort by
* @param noRecordsText : string - Text to display when no records are found * @param noRecordsText : string - Text to display when no records are found
* @param enableDownload : boolean - Enable download actions * @param enableDownload : boolean - Enable download actions
@ -92,18 +92,19 @@ const defaultInvenTreeTableProps: InvenTreeTableProps = {
*/ */
export function InvenTreeTable<T = any>({ export function InvenTreeTable<T = any>({
url, url,
tableKey, tableState,
columns, columns,
props props
}: { }: {
url: string; url: string;
tableKey: string; tableState: TableState;
columns: TableColumn<T>[]; columns: TableColumn<T>[];
props: InvenTreeTableProps<T>; props: InvenTreeTableProps<T>;
}) { }) {
// Use the first part of the table key as the table name // Use the first part of the table key as the table name
const tableName: string = useMemo(() => { const tableName: string = useMemo(() => {
return tableKey.split('-')[0]; let key = tableState?.tableKey ?? 'table';
return key.split('-')[0];
}, []); }, []);
// Build table properties based on provided props (and default props) // Build table properties based on provided props (and default props)
@ -411,14 +412,12 @@ export function InvenTreeTable<T = any>({
const [recordCount, setRecordCount] = useState<number>(0); const [recordCount, setRecordCount] = useState<number>(0);
/* /*
* Reload the table whenever the refetch changes * Reload the table whenever the tableKey changes
* this allows us to programmatically refresh the table * this allows us to programmatically refresh the table
*
* Implement this using the custom useTableRefresh hook
*/ */
useEffect(() => { useEffect(() => {
refetch(); refetch();
}, [tableKey, props.params]); }, [tableState?.tableKey, props.params]);
return ( return (
<> <>

View File

@ -12,7 +12,7 @@ import { ApiPaths } from '../../../enums/ApiEndpoints';
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 { useTableRefresh } from '../../../hooks/TableRefresh'; 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';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
@ -51,7 +51,7 @@ export function BomTable({
const user = useUserState(); const user = useUserState();
const { tableKey, refreshTable } = useTableRefresh('bom'); const table = useTable('bom');
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
return [ return [
@ -289,7 +289,7 @@ export function BomTable({
title: t`Edit Bom Item`, title: t`Edit Bom Item`,
fields: bomItemFields(), fields: bomItemFields(),
successMessage: t`Bom item updated`, successMessage: t`Bom item updated`,
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
} }
}) })
@ -305,7 +305,7 @@ export function BomTable({
pk: record.pk, pk: record.pk,
title: t`Delete Bom Item`, title: t`Delete Bom Item`,
successMessage: t`Bom item deleted`, successMessage: t`Bom item deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to remove this BOM item?`}</Text> <Text>{t`Are you sure you want to remove this BOM item?`}</Text>
) )
@ -322,7 +322,7 @@ export function BomTable({
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.bom_list)} url={apiUrl(ApiPaths.bom_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
params: { params: {

View File

@ -3,7 +3,7 @@ import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { ThumbnailHoverCard } from '../../images/Thumbnail'; import { ThumbnailHoverCard } from '../../images/Thumbnail';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -22,7 +22,7 @@ export function UsedInTable({
}) { }) {
const navigate = useNavigate(); const navigate = useNavigate();
const { tableKey } = useTableRefresh('usedin'); const table = useTable('usedin');
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
return [ return [
@ -86,7 +86,7 @@ export function UsedInTable({
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.bom_list)} url={apiUrl(ApiPaths.bom_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
params: { params: {

View File

@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom';
import { renderDate } from '../../../defaults/formatters'; import { renderDate } from '../../../defaults/formatters';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { ModelType } from '../../../enums/ModelType'; import { ModelType } from '../../../enums/ModelType';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { ThumbnailHoverCard } from '../../images/Thumbnail'; import { ThumbnailHoverCard } from '../../images/Thumbnail';
import { ProgressBar } from '../../items/ProgressBar'; import { ProgressBar } from '../../items/ProgressBar';
@ -128,12 +128,12 @@ export function BuildOrderTable({ params = {} }: { params?: any }) {
const navigate = useNavigate(); const navigate = useNavigate();
const { tableKey, refreshTable } = useTableRefresh('buildorder'); const table = useTable('buildorder');
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.build_order_list)} url={apiUrl(ApiPaths.build_order_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
enableDownload: true, enableDownload: true,

View File

@ -13,7 +13,7 @@ import {
deleteAttachment, deleteAttachment,
editAttachment editAttachment
} from '../../../forms/AttachmentForms'; } from '../../../forms/AttachmentForms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { AttachmentLink } from '../../items/AttachmentLink'; import { AttachmentLink } from '../../items/AttachmentLink';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -82,7 +82,7 @@ export function AttachmentTable({
pk: number; pk: number;
model: string; model: string;
}): ReactNode { }): ReactNode {
const { tableKey, refreshTable } = useTableRefresh(`${model}-attachments`); const table = useTable(`${model}-attachments`);
const tableColumns = useMemo(() => attachmentTableColumns(), []); const tableColumns = useMemo(() => attachmentTableColumns(), []);
@ -122,7 +122,7 @@ export function AttachmentTable({
model: model, model: model,
pk: record.pk, pk: record.pk,
attachmentType: record.attachment ? 'file' : 'link', attachmentType: record.attachment ? 'file' : 'link',
callback: refreshTable callback: table.refreshTable
}); });
} }
}) })
@ -136,7 +136,7 @@ export function AttachmentTable({
deleteAttachment({ deleteAttachment({
endpoint: endpoint, endpoint: endpoint,
pk: record.pk, pk: record.pk,
callback: refreshTable callback: table.refreshTable
}); });
} }
}) })
@ -162,7 +162,7 @@ export function AttachmentTable({
color: 'green' color: 'green'
}); });
refreshTable(); table.refreshTable();
return response; return response;
}) })
@ -192,7 +192,7 @@ export function AttachmentTable({
model: model, model: model,
pk: pk, pk: pk,
attachmentType: 'file', attachmentType: 'file',
callback: refreshTable callback: table.refreshTable
}); });
}} }}
> >
@ -211,7 +211,7 @@ export function AttachmentTable({
model: model, model: model,
pk: pk, pk: pk,
attachmentType: 'link', attachmentType: 'link',
callback: refreshTable callback: table.refreshTable
}); });
}} }}
> >
@ -230,7 +230,7 @@ export function AttachmentTable({
<InvenTreeTable <InvenTreeTable
key="attachment-table" key="attachment-table"
url={url} url={url}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
noRecordsText: t`No attachments found`, noRecordsText: t`No attachments found`,

View File

@ -4,7 +4,7 @@ import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
import { DescriptionColumn } from '../ColumnRenderers'; import { DescriptionColumn } from '../ColumnRenderers';
@ -21,7 +21,7 @@ export function CompanyTable({
params?: any; params?: any;
path?: string; path?: string;
}) { }) {
const { tableKey } = useTableRefresh('company'); const table = useTable('company');
const navigate = useNavigate(); const navigate = useNavigate();
@ -56,7 +56,7 @@ export function CompanyTable({
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.company_list)} url={apiUrl(ApiPaths.company_list)}
tableKey={tableKey} tableState={table}
columns={columns} columns={columns}
props={{ props={{
params: { params: {

View File

@ -2,6 +2,7 @@ import { t } from '@lingui/macro';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { TableState } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
@ -9,11 +10,11 @@ import { RowAction } from '../RowActions';
export function NotificationTable({ export function NotificationTable({
params, params,
tableKey, tableState,
actions actions
}: { }: {
params: any; params: any;
tableKey: string; tableState: TableState;
actions: (record: any) => RowAction[]; actions: (record: any) => RowAction[];
}) { }) {
const columns: TableColumn[] = useMemo(() => { const columns: TableColumn[] = useMemo(() => {
@ -42,7 +43,7 @@ export function NotificationTable({
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.notifications_list)} url={apiUrl(ApiPaths.notifications_list)}
tableKey={tableKey} tableState={tableState}
columns={columns} columns={columns}
props={{ props={{
rowActions: actions, rowActions: actions,

View File

@ -3,7 +3,7 @@ import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { DescriptionColumn } from '../ColumnRenderers'; import { DescriptionColumn } from '../ColumnRenderers';
@ -15,7 +15,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
export function PartCategoryTable({ params = {} }: { params?: any }) { export function PartCategoryTable({ params = {} }: { params?: any }) {
const navigate = useNavigate(); const navigate = useNavigate();
const { tableKey, refreshTable } = useTableRefresh('partcategory'); const table = useTable('partcategory');
const tableColumns: TableColumn[] = useMemo(() => { const tableColumns: TableColumn[] = useMemo(() => {
return [ return [
@ -42,7 +42,7 @@ export function PartCategoryTable({ params = {} }: { params?: any }) {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.category_list)} url={apiUrl(ApiPaths.category_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
enableDownload: true, enableDownload: true,

View File

@ -9,7 +9,7 @@ import {
openDeleteApiForm, openDeleteApiForm,
openEditApiForm openEditApiForm
} from '../../../functions/forms'; } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; 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';
import { AddItemButton } from '../../buttons/AddItemButton'; import { AddItemButton } from '../../buttons/AddItemButton';
@ -23,7 +23,7 @@ import { RowDeleteAction, RowEditAction } from '../RowActions';
* Construct a table listing parameters for a given part * Construct a table listing parameters for a given part
*/ */
export function PartParameterTable({ partId }: { partId: any }) { export function PartParameterTable({ partId }: { partId: any }) {
const { tableKey, refreshTable } = useTableRefresh('part-parameters'); const table = useTable('part-parameters');
const user = useUserState(); const user = useUserState();
@ -124,7 +124,7 @@ export function PartParameterTable({ partId }: { partId: any }) {
data: {} data: {}
}, },
successMessage: t`Part parameter updated`, successMessage: t`Part parameter updated`,
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
} }
}) })
@ -139,7 +139,7 @@ export function PartParameterTable({ partId }: { partId: any }) {
pk: record.pk, pk: record.pk,
title: t`Delete Part Parameter`, title: t`Delete Part Parameter`,
successMessage: t`Part parameter deleted`, successMessage: t`Part parameter deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to remove this parameter?`}</Text> <Text>{t`Are you sure you want to remove this parameter?`}</Text>
) )
@ -170,7 +170,7 @@ export function PartParameterTable({ partId }: { partId: any }) {
data: {} data: {}
}, },
successMessage: t`Part parameter added`, successMessage: t`Part parameter added`,
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
}, [partId]); }, [partId]);
@ -189,7 +189,7 @@ export function PartParameterTable({ partId }: { partId: any }) {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.part_parameter_list)} url={apiUrl(ApiPaths.part_parameter_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
rowActions: rowActions, rowActions: rowActions,

View File

@ -10,7 +10,7 @@ import {
openDeleteApiForm, openDeleteApiForm,
openEditApiForm openEditApiForm
} from '../../../functions/forms'; } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; 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';
import { AddItemButton } from '../../buttons/AddItemButton'; import { AddItemButton } from '../../buttons/AddItemButton';
@ -19,9 +19,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
import { RowDeleteAction, RowEditAction } from '../RowActions'; import { RowDeleteAction, RowEditAction } from '../RowActions';
export function PartParameterTemplateTable() { export function PartParameterTemplateTable() {
const { tableKey, refreshTable } = useTableRefresh( const table = useTable('part-parameter-templates');
'part-parameter-templates'
);
const user = useUserState(); const user = useUserState();
@ -67,7 +65,7 @@ export function PartParameterTemplateTable() {
title: t`Edit Parameter Template`, title: t`Edit Parameter Template`,
fields: partParameterTemplateFields(), fields: partParameterTemplateFields(),
successMessage: t`Parameter template updated`, successMessage: t`Parameter template updated`,
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
} }
}), }),
@ -79,7 +77,7 @@ export function PartParameterTemplateTable() {
pk: record.pk, pk: record.pk,
title: t`Delete Parameter Template`, title: t`Delete Parameter Template`,
successMessage: t`Parameter template deleted`, successMessage: t`Parameter template deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: <Text>{t`Remove parameter template`}</Text> preFormContent: <Text>{t`Remove parameter template`}</Text>
}); });
} }
@ -95,7 +93,7 @@ export function PartParameterTemplateTable() {
title: t`Create Parameter Template`, title: t`Create Parameter Template`,
fields: partParameterTemplateFields(), fields: partParameterTemplateFields(),
successMessage: t`Parameter template created`, successMessage: t`Parameter template created`,
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
}, []); }, []);
@ -112,7 +110,7 @@ export function PartParameterTemplateTable() {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.part_parameter_template_list)} url={apiUrl(ApiPaths.part_parameter_template_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
rowActions: rowActions, rowActions: rowActions,

View File

@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { shortenString } from '../../../functions/tables'; import { shortenString } from '../../../functions/tables';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -265,14 +265,14 @@ export function PartListTable({ props }: { props: InvenTreeTableProps }) {
const tableColumns = useMemo(() => partTableColumns(), []); const tableColumns = useMemo(() => partTableColumns(), []);
const tableFilters = useMemo(() => partTableFilters(), []); const tableFilters = useMemo(() => partTableFilters(), []);
const { tableKey, refreshTable } = useTableRefresh('part'); const table = useTable('part-list');
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.part_list)} url={apiUrl(ApiPaths.part_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
...props, ...props,

View File

@ -7,7 +7,7 @@ import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { UserRoles } from '../../../enums/Roles'; import { UserRoles } from '../../../enums/Roles';
import { openCreateApiForm, openDeleteApiForm } from '../../../functions/forms'; import { openCreateApiForm, openDeleteApiForm } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; 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';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
@ -19,7 +19,7 @@ import { RowDeleteAction } from '../RowActions';
* Construct a table listing related parts for a given part * Construct a table listing related parts for a given part
*/ */
export function RelatedPartTable({ partId }: { partId: number }): ReactNode { export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
const { tableKey, refreshTable } = useTableRefresh('relatedparts'); const table = useTable('relatedparts');
const navigate = useNavigate(); const navigate = useNavigate();
@ -80,7 +80,7 @@ export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
} }
}, },
successMessage: t`Related part added`, successMessage: t`Related part added`,
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
}, [partId]); }, [partId]);
@ -115,7 +115,7 @@ export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to remove this relationship?`}</Text> <Text>{t`Are you sure you want to remove this relationship?`}</Text>
), ),
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
} }
}) })
@ -127,7 +127,7 @@ export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.related_part_list)} url={apiUrl(ApiPaths.related_part_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
params: { params: {

View File

@ -11,7 +11,7 @@ import { useCallback, useMemo } from 'react';
import { api } from '../../../App'; import { api } from '../../../App';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { StylishText } from '../../items/StylishText'; import { StylishText } from '../../items/StylishText';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -49,7 +49,7 @@ function PluginIcon(plugin: any) {
* Table displaying list of available plugins * Table displaying list of available plugins
*/ */
export function PluginListTable({ props }: { props: InvenTreeTableProps }) { export function PluginListTable({ props }: { props: InvenTreeTableProps }) {
const { tableKey, refreshTable } = useTableRefresh('plugin'); const table = useTable('plugin');
const pluginTableColumns: TableColumn[] = useMemo( const pluginTableColumns: TableColumn[] = useMemo(
() => [ () => [
@ -147,7 +147,7 @@ export function PluginListTable({ props }: { props: InvenTreeTableProps }) {
api api
.patch(url, { active: active }) .patch(url, { active: active })
.then(() => { .then(() => {
refreshTable(); table.refreshTable();
notifications.hide(id); notifications.hide(id);
notifications.show({ notifications.show({
title: t`Plugin updated`, title: t`Plugin updated`,
@ -203,7 +203,7 @@ export function PluginListTable({ props }: { props: InvenTreeTableProps }) {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.plugin_list)} url={apiUrl(ApiPaths.plugin_list)}
tableKey={tableKey} tableState={table}
columns={pluginTableColumns} columns={pluginTableColumns}
props={{ props={{
...props, ...props,

View File

@ -8,7 +8,7 @@ import { ApiPaths } from '../../../enums/ApiEndpoints';
import { UserRoles } from '../../../enums/Roles'; import { UserRoles } from '../../../enums/Roles';
import { purchaseOrderLineItemFields } from '../../../forms/PurchaseOrderForms'; import { purchaseOrderLineItemFields } from '../../../forms/PurchaseOrderForms';
import { openCreateApiForm, openEditApiForm } from '../../../functions/forms'; import { openCreateApiForm, openEditApiForm } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; 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';
import { ActionButton } from '../../buttons/ActionButton'; import { ActionButton } from '../../buttons/ActionButton';
@ -39,9 +39,7 @@ export function PurchaseOrderLineItemTable({
orderId: number; orderId: number;
params?: any; params?: any;
}) { }) {
const { tableKey, refreshTable } = useTableRefresh( const table = useTable('purchase-order-line-item');
'purchase-order-line-item'
);
const user = useUserState(); const user = useUserState();
@ -75,7 +73,7 @@ export function PurchaseOrderLineItemTable({
pk: record.pk, pk: record.pk,
title: t`Edit Line Item`, title: t`Edit Line Item`,
fields: fields, fields: fields,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Line item updated` successMessage: t`Line item updated`
}); });
} }
@ -226,7 +224,7 @@ export function PurchaseOrderLineItemTable({
create: true, create: true,
orderId: orderId orderId: orderId
}), }),
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Line item added` successMessage: t`Line item added`
}); });
}, [orderId]); }, [orderId]);
@ -251,7 +249,7 @@ export function PurchaseOrderLineItemTable({
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.purchase_order_line_list)} url={apiUrl(ApiPaths.purchase_order_line_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
enableSelection: true, enableSelection: true,

View File

@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { ModelType } from '../../../enums/ModelType'; import { ModelType } from '../../../enums/ModelType';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
import { import {
@ -25,7 +25,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
export function PurchaseOrderTable({ params }: { params?: any }) { export function PurchaseOrderTable({ params }: { params?: any }) {
const navigate = useNavigate(); const navigate = useNavigate();
const { tableKey } = useTableRefresh('purchase-order'); const table = useTable('purchase-order');
// TODO: Custom filters // TODO: Custom filters
@ -76,7 +76,7 @@ export function PurchaseOrderTable({ params }: { params?: any }) {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.purchase_order_list)} url={apiUrl(ApiPaths.purchase_order_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
params: { params: {

View File

@ -6,8 +6,8 @@ import { ApiPaths } from '../../../enums/ApiEndpoints';
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 { useTableRefresh } from '../../../hooks/TableRefresh';
import { useCreateApiFormModal } from '../../../hooks/UseForm'; import { useCreateApiFormModal } from '../../../hooks/UseForm';
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';
import { AddItemButton } from '../../buttons/AddItemButton'; import { AddItemButton } from '../../buttons/AddItemButton';
@ -23,7 +23,7 @@ import { TableHoverCard } from '../TableHoverCard';
*/ */
export function SupplierPartTable({ params }: { params: any }): ReactNode { export function SupplierPartTable({ params }: { params: any }): ReactNode {
const { tableKey, refreshTable } = useTableRefresh('supplierparts'); const table = useTable('supplierparts');
const user = useUserState(); const user = useUserState();
@ -162,7 +162,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
url: ApiPaths.supplier_part_list, url: ApiPaths.supplier_part_list,
title: t`Add Supplier Part`, title: t`Add Supplier Part`,
fields: addSupplierPartFields, fields: addSupplierPartFields,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Supplier part created` successMessage: t`Supplier part created`
}); });
@ -195,7 +195,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
pk: record.pk, pk: record.pk,
title: t`Edit Supplier Part`, title: t`Edit Supplier Part`,
fields: editSupplierPartFields, fields: editSupplierPartFields,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Supplier part updated` successMessage: t`Supplier part updated`
}); });
} }
@ -209,7 +209,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
pk: record.pk, pk: record.pk,
title: t`Delete Supplier Part`, title: t`Delete Supplier Part`,
successMessage: t`Supplier part deleted`, successMessage: t`Supplier part deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to remove this supplier part?`}</Text> <Text>{t`Are you sure you want to remove this supplier part?`}</Text>
) )
@ -226,7 +226,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
{addSupplierPartModal} {addSupplierPartModal}
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.supplier_part_list)} url={apiUrl(ApiPaths.supplier_part_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
params: { params: {

View File

@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { ModelType } from '../../../enums/ModelType'; import { ModelType } from '../../../enums/ModelType';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
import { import {
@ -19,7 +19,7 @@ import {
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
export function ReturnOrderTable({ params }: { params?: any }) { export function ReturnOrderTable({ params }: { params?: any }) {
const { tableKey } = useTableRefresh('return-orders'); const table = useTable('return-orders');
const navigate = useNavigate(); const navigate = useNavigate();
@ -74,7 +74,7 @@ export function ReturnOrderTable({ params }: { params?: any }) {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.return_order_list)} url={apiUrl(ApiPaths.return_order_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
params: { params: {

View File

@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { ModelType } from '../../../enums/ModelType'; import { ModelType } from '../../../enums/ModelType';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
import { import {
@ -20,7 +20,7 @@ import {
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
export function SalesOrderTable({ params }: { params?: any }) { export function SalesOrderTable({ params }: { params?: any }) {
const { tableKey } = useTableRefresh('sales-order'); const table = useTable('sales-order');
const navigate = useNavigate(); const navigate = useNavigate();
@ -73,7 +73,7 @@ export function SalesOrderTable({ params }: { params?: any }) {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.sales_order_list)} url={apiUrl(ApiPaths.sales_order_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
params: { params: {

View File

@ -5,7 +5,7 @@ import { useCallback, useMemo } from 'react';
import { api } from '../../../App'; import { api } from '../../../App';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { ActionButton } from '../../buttons/ActionButton'; import { ActionButton } from '../../buttons/ActionButton';
import { InvenTreeTable } from '../InvenTreeTable'; import { InvenTreeTable } from '../InvenTreeTable';
@ -14,7 +14,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
* Table for displaying available currencies * Table for displaying available currencies
*/ */
export function CurrencyTable() { export function CurrencyTable() {
const { tableKey, refreshTable } = useTableRefresh('currency'); const table = useTable('currency');
const columns = useMemo(() => { const columns = useMemo(() => {
return [ return [
@ -35,7 +35,7 @@ export function CurrencyTable() {
api api
.post(apiUrl(ApiPaths.currency_refresh), {}) .post(apiUrl(ApiPaths.currency_refresh), {})
.then(() => { .then(() => {
refreshTable(); table.refreshTable();
showNotification({ showNotification({
message: t`Exchange rates updated`, message: t`Exchange rates updated`,
color: 'green' color: 'green'
@ -63,7 +63,7 @@ export function CurrencyTable() {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.currency_list)} url={apiUrl(ApiPaths.currency_list)}
tableKey={tableKey} tableState={table}
columns={columns} columns={columns}
props={{ props={{
customActionGroups: tableActions, customActionGroups: tableActions,

View File

@ -9,7 +9,7 @@ import {
openDeleteApiForm, openDeleteApiForm,
openEditApiForm openEditApiForm
} from '../../../functions/forms'; } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; 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';
import { AddItemButton } from '../../buttons/AddItemButton'; import { AddItemButton } from '../../buttons/AddItemButton';
@ -21,7 +21,7 @@ import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
* Table for displaying list of custom physical units * Table for displaying list of custom physical units
*/ */
export function CustomUnitsTable() { export function CustomUnitsTable() {
const { tableKey, refreshTable } = useTableRefresh('custom-units'); const table = useTable('custom-units');
const user = useUserState(); const user = useUserState();
@ -63,7 +63,7 @@ export function CustomUnitsTable() {
definition: {}, definition: {},
symbol: {} symbol: {}
}, },
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Custom unit updated` successMessage: t`Custom unit updated`
}); });
} }
@ -76,7 +76,7 @@ export function CustomUnitsTable() {
pk: record.pk, pk: record.pk,
title: t`Delete custom unit`, title: t`Delete custom unit`,
successMessage: t`Custom unit deleted`, successMessage: t`Custom unit deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to remove this custom unit?`}</Text> <Text>{t`Are you sure you want to remove this custom unit?`}</Text>
) )
@ -98,7 +98,7 @@ export function CustomUnitsTable() {
symbol: {} symbol: {}
}, },
successMessage: t`Custom unit created`, successMessage: t`Custom unit created`,
onFormSuccess: refreshTable onFormSuccess: table.refreshTable
}); });
}, []); }, []);
@ -116,7 +116,7 @@ export function CustomUnitsTable() {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.custom_unit_list)} url={apiUrl(ApiPaths.custom_unit_list)}
tableKey={tableKey} tableState={table}
columns={columns} columns={columns}
props={{ props={{
rowActions: rowActions, rowActions: rowActions,

View File

@ -8,7 +8,7 @@ import {
openDeleteApiForm, openDeleteApiForm,
openEditApiForm openEditApiForm
} from '../../../functions/forms'; } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { AddItemButton } from '../../buttons/AddItemButton'; import { AddItemButton } from '../../buttons/AddItemButton';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -19,7 +19,7 @@ import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
* Table for displaying list of groups * Table for displaying list of groups
*/ */
export function GroupTable() { export function GroupTable() {
const { tableKey, refreshTable } = useTableRefresh('groups'); const table = useTable('groups');
const columns: TableColumn[] = useMemo(() => { const columns: TableColumn[] = useMemo(() => {
return [ return [
@ -42,7 +42,7 @@ export function GroupTable() {
fields: { fields: {
name: {} name: {}
}, },
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Group updated` successMessage: t`Group updated`
}); });
} }
@ -54,7 +54,7 @@ export function GroupTable() {
pk: record.pk, pk: record.pk,
title: t`Delete group`, title: t`Delete group`,
successMessage: t`Group deleted`, successMessage: t`Group deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to delete this group?`}</Text> <Text>{t`Are you sure you want to delete this group?`}</Text>
) )
@ -69,7 +69,7 @@ export function GroupTable() {
url: ApiPaths.group_list, url: ApiPaths.group_list,
title: t`Add group`, title: t`Add group`,
fields: { name: {} }, fields: { name: {} },
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Added group` successMessage: t`Added group`
}); });
}, []); }, []);
@ -91,7 +91,7 @@ export function GroupTable() {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.group_list)} url={apiUrl(ApiPaths.group_list)}
tableKey={tableKey} tableState={table}
columns={columns} columns={columns}
props={{ props={{
rowActions: rowActions, rowActions: rowActions,

View File

@ -9,7 +9,7 @@ import {
openDeleteApiForm, openDeleteApiForm,
openEditApiForm openEditApiForm
} from '../../../functions/forms'; } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; 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';
import { AddItemButton } from '../../buttons/AddItemButton'; import { AddItemButton } from '../../buttons/AddItemButton';
@ -22,7 +22,7 @@ import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
* Table for displaying list of project codes * Table for displaying list of project codes
*/ */
export function ProjectCodeTable() { export function ProjectCodeTable() {
const { tableKey, refreshTable } = useTableRefresh('project-code'); const table = useTable('project-codes');
const user = useUserState(); const user = useUserState();
@ -53,7 +53,7 @@ export function ProjectCodeTable() {
description: {}, description: {},
responsible: {} responsible: {}
}, },
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Project code updated` successMessage: t`Project code updated`
}); });
} }
@ -66,7 +66,7 @@ export function ProjectCodeTable() {
pk: record.pk, pk: record.pk,
title: t`Delete project code`, title: t`Delete project code`,
successMessage: t`Project code deleted`, successMessage: t`Project code deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to remove this project code?`}</Text> <Text>{t`Are you sure you want to remove this project code?`}</Text>
) )
@ -87,7 +87,7 @@ export function ProjectCodeTable() {
description: {}, description: {},
responsible: {} responsible: {}
}, },
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Added project code` successMessage: t`Added project code`
}); });
}, []); }, []);
@ -105,7 +105,7 @@ export function ProjectCodeTable() {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.project_code_list)} url={apiUrl(ApiPaths.project_code_list)}
tableKey={tableKey} tableState={table}
columns={columns} columns={columns}
props={{ props={{
rowActions: rowActions, rowActions: rowActions,

View File

@ -9,7 +9,7 @@ import {
openDeleteApiForm, openDeleteApiForm,
openEditApiForm openEditApiForm
} from '../../../functions/forms'; } from '../../../functions/forms';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { AddItemButton } from '../../buttons/AddItemButton'; import { AddItemButton } from '../../buttons/AddItemButton';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -39,7 +39,7 @@ export interface UserDetailI {
* Table for displaying list of users * Table for displaying list of users
*/ */
export function UserTable() { export function UserTable() {
const { tableKey, refreshTable } = useTableRefresh('users'); const table = useTable('users');
const [opened, { open, close }] = useDisclosure(false); const [opened, { open, close }] = useDisclosure(false);
const [userDetail, setUserDetail] = useState<UserDetailI>(); const [userDetail, setUserDetail] = useState<UserDetailI>();
@ -103,7 +103,7 @@ export function UserTable() {
first_name: {}, first_name: {},
last_name: {} last_name: {}
}, },
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`User updated` successMessage: t`User updated`
}); });
} }
@ -115,7 +115,7 @@ export function UserTable() {
pk: record.pk, pk: record.pk,
title: t`Delete user`, title: t`Delete user`,
successMessage: t`User deleted`, successMessage: t`User deleted`,
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
preFormContent: ( preFormContent: (
<Text>{t`Are you sure you want to delete this user?`}</Text> <Text>{t`Are you sure you want to delete this user?`}</Text>
) )
@ -135,7 +135,7 @@ export function UserTable() {
first_name: {}, first_name: {},
last_name: {} last_name: {}
}, },
onFormSuccess: refreshTable, onFormSuccess: table.refreshTable,
successMessage: t`Added user` successMessage: t`Added user`
}); });
}, []); }, []);
@ -155,12 +155,12 @@ export function UserTable() {
<UserDrawer <UserDrawer
opened={opened} opened={opened}
close={close} close={close}
refreshTable={refreshTable} refreshTable={table.refreshTable}
userDetail={userDetail} userDetail={userDetail}
/> />
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.user_list)} url={apiUrl(ApiPaths.user_list)}
tableKey={tableKey} tableState={table}
columns={columns} columns={columns}
props={{ props={{
rowActions: rowActions, rowActions: rowActions,

View File

@ -6,13 +6,12 @@ import { useNavigate } from 'react-router-dom';
import { formatCurrency, renderDate } from '../../../defaults/formatters'; import { formatCurrency, renderDate } from '../../../defaults/formatters';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { ModelType } from '../../../enums/ModelType'; import { ModelType } from '../../../enums/ModelType';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { Thumbnail } from '../../images/Thumbnail'; import { Thumbnail } from '../../images/Thumbnail';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
import { StatusColumn } from '../ColumnRenderers'; import { StatusColumn } from '../ColumnRenderers';
import { TableFilter } from '../Filter'; import { TableFilter } from '../Filter';
import { RowAction } from '../RowActions';
import { TableHoverCard } from '../TableHoverCard'; import { TableHoverCard } from '../TableHoverCard';
import { InvenTreeTable } from './../InvenTreeTable'; import { InvenTreeTable } from './../InvenTreeTable';
@ -172,7 +171,7 @@ function stockItemTableColumns(): TableColumn[] {
return ( return (
<TableHoverCard <TableHoverCard
value={ value={
<Group spacing="xs" position="left"> <Group spacing="xs" position="left" noWrap={true}>
<Text color={color}>{text}</Text> <Text color={color}>{text}</Text>
{part.units && ( {part.units && (
<Text size="xs" color={color}> <Text size="xs" color={color}>
@ -264,27 +263,19 @@ export function StockItemTable({ params = {} }: { params?: any }) {
let tableColumns = useMemo(() => stockItemTableColumns(), []); let tableColumns = useMemo(() => stockItemTableColumns(), []);
let tableFilters = useMemo(() => stockItemTableFilters(), []); let tableFilters = useMemo(() => stockItemTableFilters(), []);
const { tableKey, refreshTable } = useTableRefresh('stockitem'); const table = useTable('stockitems');
function stockItemRowActions(record: any): RowAction[] {
let actions: RowAction[] = [];
// TODO: Custom row actions for stock table
return actions;
}
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.stock_item_list)} url={apiUrl(ApiPaths.stock_item_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
enableDownload: true, enableDownload: true,
enableSelection: true, enableSelection: true,
customFilters: tableFilters, customFilters: tableFilters,
rowActions: stockItemRowActions,
onRowClick: (record) => navigate(`/stock/item/${record.pk}`), onRowClick: (record) => navigate(`/stock/item/${record.pk}`),
params: { params: {
...params, ...params,

View File

@ -3,7 +3,7 @@ import { useMemo } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { ApiPaths } from '../../../enums/ApiEndpoints'; import { ApiPaths } from '../../../enums/ApiEndpoints';
import { useTableRefresh } from '../../../hooks/TableRefresh'; import { useTable } from '../../../hooks/UseTable';
import { apiUrl } from '../../../states/ApiState'; import { apiUrl } from '../../../states/ApiState';
import { YesNoButton } from '../../items/YesNoButton'; import { YesNoButton } from '../../items/YesNoButton';
import { TableColumn } from '../Column'; import { TableColumn } from '../Column';
@ -14,7 +14,7 @@ import { InvenTreeTable } from '../InvenTreeTable';
* Stock location table * Stock location table
*/ */
export function StockLocationTable({ params = {} }: { params?: any }) { export function StockLocationTable({ params = {} }: { params?: any }) {
const { tableKey, refreshTable } = useTableRefresh('stocklocation'); const table = useTable('stocklocation');
const navigate = useNavigate(); const navigate = useNavigate();
@ -64,7 +64,7 @@ export function StockLocationTable({ params = {} }: { params?: any }) {
return ( return (
<InvenTreeTable <InvenTreeTable
url={apiUrl(ApiPaths.stock_location_list)} url={apiUrl(ApiPaths.stock_location_list)}
tableKey={tableKey} tableState={table}
columns={tableColumns} columns={tableColumns}
props={{ props={{
enableDownload: true, enableDownload: true,

View File

@ -1,29 +0,0 @@
import { randomId } from '@mantine/hooks';
import { useCallback, useState } from 'react';
/**
* Custom hook for refreshing an InvenTreeTable externally
* Returns a unique ID for the table, which can be updated to trigger a refresh of the <table className=""></table>
*
* @returns { tableKey, refreshTable }
*
* To use this hook:
* const { tableKey, refreshTable } = useTableRefresh();
*
* Then, pass the refreshId to the InvenTreeTable component:
* <InvenTreeTable tableKey={tableKey} ... />
*/
export function useTableRefresh(tableName: string) {
const [tableKey, setTableKey] = useState<string>(generateTableName());
function generateTableName() {
return `${tableName}-${randomId()}`;
}
// Generate a new ID to refresh the table
const refreshTable = useCallback(function () {
setTableKey(generateTableName());
}, []);
return { tableKey, refreshTable };
}

View File

@ -0,0 +1,34 @@
import { randomId } from '@mantine/hooks';
import { useCallback, useState } from 'react';
export type TableState = {
tableKey: string;
refreshTable: () => void;
};
/**
* A custom hook for managing the state of an <InvenTreeTable> component.
*
* tableKey: A unique key for the table. When this key changes, the table will be refreshed.
* refreshTable: A callback function to externally refresh the table.
*
*/
export function useTable(tableName: string): TableState {
// Function to generate a new ID (to refresh the table)
function generateTableName() {
return `${tableName}-${randomId()}`;
}
const [tableKey, setTableKey] = useState<string>(generateTableName());
// Callback used to refresh (reload) the table
const refreshTable = useCallback(() => {
setTableKey(generateTableName());
}, []);
return {
tableKey,
refreshTable
};
}

View File

@ -14,12 +14,12 @@ import { PageDetail } from '../components/nav/PageDetail';
import { PanelGroup } from '../components/nav/PanelGroup'; import { PanelGroup } from '../components/nav/PanelGroup';
import { NotificationTable } from '../components/tables/notifications/NotificationsTable'; import { NotificationTable } from '../components/tables/notifications/NotificationsTable';
import { ApiPaths } from '../enums/ApiEndpoints'; import { ApiPaths } from '../enums/ApiEndpoints';
import { useTableRefresh } from '../hooks/TableRefresh'; import { useTable } from '../hooks/UseTable';
import { apiUrl } from '../states/ApiState'; import { apiUrl } from '../states/ApiState';
export default function NotificationsPage() { export default function NotificationsPage() {
const unreadRefresh = useTableRefresh('unreadnotifications'); const unreadTable = useTable('unreadnotifications');
const historyRefresh = useTableRefresh('readnotifications'); const readTable = useTable('readnotifications');
const notificationPanels = useMemo(() => { const notificationPanels = useMemo(() => {
return [ return [
@ -30,7 +30,7 @@ export default function NotificationsPage() {
content: ( content: (
<NotificationTable <NotificationTable
params={{ read: false }} params={{ read: false }}
tableKey={unreadRefresh.tableKey} tableState={unreadTable}
actions={(record) => [ actions={(record) => [
{ {
title: t`Mark as read`, title: t`Mark as read`,
@ -43,7 +43,7 @@ export default function NotificationsPage() {
read: true read: true
}) })
.then((response) => { .then((response) => {
unreadRefresh.refreshTable(); unreadTable.refreshTable();
}); });
} }
} }
@ -58,7 +58,7 @@ export default function NotificationsPage() {
content: ( content: (
<NotificationTable <NotificationTable
params={{ read: true }} params={{ read: true }}
tableKey={historyRefresh.tableKey} tableState={readTable}
actions={(record) => [ actions={(record) => [
{ {
title: t`Mark as unread`, title: t`Mark as unread`,
@ -71,7 +71,7 @@ export default function NotificationsPage() {
read: false read: false
}) })
.then((response) => { .then((response) => {
historyRefresh.refreshTable(); readTable.refreshTable();
}); });
} }
}, },
@ -83,7 +83,7 @@ export default function NotificationsPage() {
api api
.delete(apiUrl(ApiPaths.notifications_list, record.pk)) .delete(apiUrl(ApiPaths.notifications_list, record.pk))
.then((response) => { .then((response) => {
historyRefresh.refreshTable(); readTable.refreshTable();
}); });
} }
} }
@ -92,7 +92,7 @@ export default function NotificationsPage() {
) )
} }
]; ];
}, [historyRefresh, unreadRefresh]); }, [unreadTable, readTable]);
return ( return (
<> <>