diff --git a/src/frontend/src/components/forms/ApiForm.tsx b/src/frontend/src/components/forms/ApiForm.tsx
index 9a3ca4a0b0..88eadd0ce2 100644
--- a/src/frontend/src/components/forms/ApiForm.tsx
+++ b/src/frontend/src/components/forms/ApiForm.tsx
@@ -35,6 +35,7 @@ import {
} from '../../functions/forms';
import { invalidResponse } from '../../functions/notifications';
import { getDetailUrl } from '../../functions/urls';
+import { TableState } from '../../hooks/UseTable';
import { PathParams } from '../../states/ApiState';
import { Boundary } from '../Boundary';
import {
@@ -54,6 +55,7 @@ export interface ApiFormAction {
* Properties for the ApiForm component
* @param url : The API endpoint to fetch the form data from
* @param pk : Optional primary-key value when editing an existing object
+ * @param pk_field : Optional primary-key field name (default: pk)
* @param pathParams : Optional path params for the url
* @param method : Optional HTTP method to use when submitting the form (default: GET)
* @param fields : The fields to render in the form
@@ -67,10 +69,12 @@ export interface ApiFormAction {
* @param onFormError : A callback function to call when the form is submitted with errors.
* @param modelType : Define a model type for this form
* @param follow : Boolean, follow the result of the form (if possible)
+ * @param table : Table to update on success (if provided)
*/
export interface ApiFormProps {
url: ApiEndpoints | string;
pk?: number | string | undefined;
+ pk_field?: string;
pathParams?: PathParams;
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
fields?: ApiFormFieldSet;
@@ -87,6 +91,7 @@ export interface ApiFormProps {
successMessage?: string;
onFormSuccess?: (data: any) => void;
onFormError?: () => void;
+ table?: TableState;
modelType?: ModelType;
follow?: boolean;
actions?: ApiFormAction[];
@@ -391,14 +396,22 @@ export function ApiForm({
case 204:
// Form was submitted successfully
- // Optionally call the onFormSuccess callback
if (props.onFormSuccess) {
+ // A custom callback hook is provided
props.onFormSuccess(response.data);
}
- if (props.follow) {
- if (props.modelType && response.data?.pk) {
- navigate(getDetailUrl(props.modelType, response.data?.pk));
+ if (props.follow && props.modelType && response.data?.pk) {
+ // If we want to automatically follow the returned data
+ navigate(getDetailUrl(props.modelType, response.data?.pk));
+ } else if (props.table) {
+ // If we want to automatically update or reload a linked table
+ let pk_field = props.pk_field ?? 'pk';
+
+ if (props.pk && response?.data[pk_field]) {
+ props.table.updateRecord(response.data);
+ } else {
+ props.table.refreshTable();
}
}
diff --git a/src/frontend/src/components/settings/SettingItem.tsx b/src/frontend/src/components/settings/SettingItem.tsx
index dc14022998..292f5a1c19 100644
--- a/src/frontend/src/components/settings/SettingItem.tsx
+++ b/src/frontend/src/components/settings/SettingItem.tsx
@@ -1,4 +1,3 @@
-import { t } from '@lingui/macro';
import {
Button,
Group,
@@ -9,103 +8,25 @@ import {
Text,
useMantineColorScheme
} from '@mantine/core';
-import { showNotification } from '@mantine/notifications';
import { IconEdit } from '@tabler/icons-react';
import { useMemo } from 'react';
-import { api } from '../../App';
-import { ModelType } from '../../enums/ModelType';
-import { openModalApiForm } from '../../functions/forms';
-import { apiUrl } from '../../states/ApiState';
-import { SettingsStateProps } from '../../states/SettingsState';
-import { Setting, SettingType } from '../../states/states';
+import { Setting } from '../../states/states';
import { vars } from '../../theme';
-import { ApiFormFieldType } from '../forms/fields/ApiFormField';
+import { Boundary } from '../Boundary';
/**
* Render a single setting value
*/
function SettingValue({
- settingsState,
setting,
- onChange
+ onEdit,
+ onToggle
}: {
- settingsState: SettingsStateProps;
setting: Setting;
- onChange?: () => void;
+ onEdit: (setting: Setting) => void;
+ onToggle: (setting: Setting, value: boolean) => void;
}) {
- // Callback function when a boolean value is changed
- function onToggle(value: boolean) {
- api
- .patch(
- apiUrl(settingsState.endpoint, setting.key, settingsState.pathParams),
- { value: value }
- )
- .then(() => {
- showNotification({
- title: t`Setting updated`,
- message: t`${setting?.name} updated successfully`,
- color: 'green'
- });
- settingsState.fetchSettings();
- onChange?.();
- })
- .catch((error) => {
- showNotification({
- title: t`Error editing setting`,
- message: error.message,
- color: 'red'
- });
- });
- }
-
- // Callback function to open the edit dialog (for non-boolean settings)
- function onEditButton() {
- const fieldDefinition: ApiFormFieldType = {
- value: setting?.value ?? '',
- field_type: setting?.type ?? 'string',
- label: setting?.name,
- description: setting?.description
- };
-
- // Match related field
- if (
- fieldDefinition.field_type === SettingType.Model &&
- setting.api_url &&
- setting.model_name
- ) {
- fieldDefinition.api_url = setting.api_url;
-
- // TODO: improve this model matching mechanism
- fieldDefinition.model = setting.model_name.split('.')[1] as ModelType;
- } else if (setting.choices?.length > 0) {
- // Match choices
- fieldDefinition.field_type = SettingType.Choice;
- fieldDefinition.choices = setting?.choices || [];
- }
-
- openModalApiForm({
- url: settingsState.endpoint,
- pk: setting.key,
- pathParams: settingsState.pathParams,
- method: 'PATCH',
- title: t`Edit Setting`,
- ignorePermissionCheck: true,
- fields: {
- value: fieldDefinition
- },
- onFormSuccess() {
- showNotification({
- title: t`Setting updated`,
- message: t`${setting?.name} updated successfully`,
- color: 'green'
- });
- settingsState.fetchSettings();
- onChange?.();
- }
- });
- }
-
// Determine the text to display for the setting value
const valueText: string = useMemo(() => {
let value = setting.value;
@@ -130,7 +51,7 @@ function SettingValue({
size="sm"
radius="lg"
checked={setting.value.toLowerCase() == 'true'}
- onChange={(event) => onToggle(event.currentTarget.checked)}
+ onChange={(event) => onToggle(setting, event.currentTarget.checked)}
style={{
paddingRight: '20px'
}}
@@ -140,12 +61,12 @@ function SettingValue({
return valueText ? (
-
) : (
-
+ onEdit(setting)}>
);
@@ -156,15 +77,15 @@ function SettingValue({
* Display a single setting item, and allow editing of the value
*/
export function SettingItem({
- settingsState,
setting,
shaded,
- onChange
+ onEdit,
+ onToggle
}: {
- settingsState: SettingsStateProps;
setting: Setting;
shaded: boolean;
- onChange?: () => void;
+ onEdit: (setting: Setting) => void;
+ onToggle: (setting: Setting, value: boolean) => void;
}) {
const { colorScheme } = useMantineColorScheme();
@@ -184,11 +105,9 @@ export function SettingItem({
{setting.description}
-
+
+
+
);
diff --git a/src/frontend/src/components/settings/SettingList.tsx b/src/frontend/src/components/settings/SettingList.tsx
index bf404578cc..4cd0b4e3ad 100644
--- a/src/frontend/src/components/settings/SettingList.tsx
+++ b/src/frontend/src/components/settings/SettingList.tsx
@@ -1,8 +1,19 @@
-import { Trans } from '@lingui/macro';
+import { Trans, t } from '@lingui/macro';
import { Stack, Text } from '@mantine/core';
-import React, { useEffect, useMemo, useRef } from 'react';
+import { notifications } from '@mantine/notifications';
+import React, {
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState
+} from 'react';
import { useStore } from 'zustand';
+import { api } from '../../App';
+import { ModelType } from '../../enums/ModelType';
+import { useEditApiFormModal } from '../../hooks/UseForm';
+import { apiUrl } from '../../states/ApiState';
import {
SettingsStateProps,
createMachineSettingsState,
@@ -10,6 +21,7 @@ import {
useGlobalSettingsState,
useUserSettingsState
} from '../../states/SettingsState';
+import { Setting } from '../../states/states';
import { SettingItem } from './SettingItem';
/**
@@ -33,8 +45,82 @@ export function SettingList({
[settingsState?.settings]
);
+ const [setting, setSetting] = useState(undefined);
+
+ const editSettingModal = useEditApiFormModal({
+ url: settingsState.endpoint,
+ pk: setting?.key,
+ pathParams: settingsState.pathParams,
+ title: t`Edit Setting`,
+ fields: {
+ value: {
+ value: setting?.value ?? '',
+ field_type:
+ setting?.type ?? (setting?.choices?.length ?? 0) > 0
+ ? 'choice'
+ : 'string',
+ label: setting?.name,
+ description: setting?.description,
+ api_url: setting?.api_url ?? '',
+ model: (setting?.model_name?.split('.')[1] as ModelType) ?? null,
+ choices: setting?.choices ?? undefined
+ }
+ },
+ successMessage: t`Setting ${setting?.key} updated successfully`,
+ onFormSuccess: () => {
+ settingsState.fetchSettings();
+ onChange?.();
+ }
+ });
+
+ // Callback for editing a single setting instance
+ const onValueEdit = useCallback(
+ (setting: Setting) => {
+ setSetting(setting);
+ editSettingModal.open();
+ },
+ [editSettingModal]
+ );
+
+ // Callback for toggling a single boolean setting instance
+ const onValueToggle = useCallback(
+ (setting: Setting, value: boolean) => {
+ api
+ .patch(
+ apiUrl(settingsState.endpoint, setting.key, settingsState.pathParams),
+ {
+ value: value
+ }
+ )
+ .then(() => {
+ notifications.hide('setting');
+ notifications.show({
+ title: t`Setting updated`,
+ message: t`Setting ${setting.key} updated successfully`,
+ color: 'green',
+ id: 'setting'
+ });
+ onChange?.();
+ })
+ .catch((error) => {
+ notifications.hide('setting');
+ notifications.show({
+ title: t`Error editing setting`,
+ message: error.message,
+ color: 'red',
+ id: 'setting'
+ });
+ })
+ .finally(() => {
+ settingsState.fetchSettings();
+ });
+ },
+ [settingsState]
+ );
+
return (
<>
+ {editSettingModal.modal}
{(keys || allKeys).map((key, i) => {
const setting = settingsState?.settings?.find(
@@ -45,10 +131,10 @@ export function SettingList({
{setting ? (
) : (
diff --git a/src/frontend/src/forms/CompanyForms.tsx b/src/frontend/src/forms/CompanyForms.tsx
index 7073110004..2f71c89672 100644
--- a/src/frontend/src/forms/CompanyForms.tsx
+++ b/src/frontend/src/forms/CompanyForms.tsx
@@ -82,6 +82,9 @@ export function useManufacturerPartFields() {
export function useManufacturerPartParameterFields() {
return useMemo(() => {
const fields: ApiFormFieldSet = {
+ manufacturer_part: {
+ disabled: true
+ },
name: {},
value: {},
units: {}
diff --git a/src/frontend/src/pages/part/pricing/PriceBreakPanel.tsx b/src/frontend/src/pages/part/pricing/PriceBreakPanel.tsx
index a82f837e41..8a8f87d5d0 100644
--- a/src/frontend/src/pages/part/pricing/PriceBreakPanel.tsx
+++ b/src/frontend/src/pages/part/pricing/PriceBreakPanel.tsx
@@ -84,9 +84,7 @@ export default function PriceBreakPanel({
url: tableUrl,
pk: selectedPriceBreak,
title: t`Delete Price Break`,
- onFormSuccess: () => {
- table.refreshTable();
- }
+ table: table
});
const columns: TableColumn[] = useMemo(() => {
diff --git a/src/frontend/src/tables/bom/BomTable.tsx b/src/frontend/src/tables/bom/BomTable.tsx
index 5fa5ef2120..b2e5cf018f 100644
--- a/src/frontend/src/tables/bom/BomTable.tsx
+++ b/src/frontend/src/tables/bom/BomTable.tsx
@@ -312,7 +312,7 @@ export function BomTable({
part: partId
},
successMessage: t`BOM item created`,
- onFormSuccess: table.refreshTable
+ table: table
});
const editBomItem = useEditApiFormModal({
@@ -321,7 +321,7 @@ export function BomTable({
title: t`Edit BOM Item`,
fields: bomItemFields(),
successMessage: t`BOM item updated`,
- onFormSuccess: table.refreshTable
+ table: table
});
const deleteBomItem = useDeleteApiFormModal({
@@ -329,7 +329,7 @@ export function BomTable({
pk: selectedBomItem,
title: t`Delete BOM Item`,
successMessage: t`BOM item deleted`,
- onFormSuccess: table.refreshTable
+ table: table
});
const rowActions = useCallback(
diff --git a/src/frontend/src/tables/build/BuildOutputTable.tsx b/src/frontend/src/tables/build/BuildOutputTable.tsx
index 8b1ec7b99c..1ea8403896 100644
--- a/src/frontend/src/tables/build/BuildOutputTable.tsx
+++ b/src/frontend/src/tables/build/BuildOutputTable.tsx
@@ -113,9 +113,7 @@ export default function BuildOutputTable({ build }: { build: any }) {
url: apiUrl(ApiEndpoints.build_output_create, buildId),
title: t`Add Build Output`,
fields: buildOutputFields,
- onFormSuccess: () => {
- table.refreshTable();
- }
+ table: table
});
const [selectedOutputs, setSelectedOutputs] = useState([]);
diff --git a/src/frontend/src/tables/company/AddressTable.tsx b/src/frontend/src/tables/company/AddressTable.tsx
index bef8d0cef9..f888e01dd3 100644
--- a/src/frontend/src/tables/company/AddressTable.tsx
+++ b/src/frontend/src/tables/company/AddressTable.tsx
@@ -124,7 +124,7 @@ export function AddressTable({
company: companyId
},
successMessage: t`Address created`,
- onFormSuccess: table.refreshTable
+ table: table
});
const [selectedAddress, setSelectedAddress] = useState(-1);
@@ -134,15 +134,15 @@ export function AddressTable({
pk: selectedAddress,
title: t`Edit Address`,
fields: addressFields,
- onFormSuccess: (record: any) => table.updateRecord(record)
+ table: table
});
const deleteAddress = useDeleteApiFormModal({
url: ApiEndpoints.address_list,
pk: selectedAddress,
title: t`Delete Address`,
- onFormSuccess: table.refreshTable,
- preFormWarning: t`Are you sure you want to delete this address?`
+ preFormWarning: t`Are you sure you want to delete this address?`,
+ table: table
});
const rowActions = useCallback(
diff --git a/src/frontend/src/tables/company/ContactTable.tsx b/src/frontend/src/tables/company/ContactTable.tsx
index 83e4e6ebf8..763bbaf923 100644
--- a/src/frontend/src/tables/company/ContactTable.tsx
+++ b/src/frontend/src/tables/company/ContactTable.tsx
@@ -80,14 +80,14 @@ export function ContactTable({
company: companyId
},
fields: contactFields,
- onFormSuccess: table.refreshTable
+ table: table
});
const deleteContact = useDeleteApiFormModal({
url: ApiEndpoints.contact_list,
pk: selectedContact,
title: t`Delete Contact`,
- onFormSuccess: table.refreshTable
+ table: table
});
const rowActions = useCallback(
diff --git a/src/frontend/src/tables/part/PartCategoryTable.tsx b/src/frontend/src/tables/part/PartCategoryTable.tsx
index 8f78438b18..90576ee729 100644
--- a/src/frontend/src/tables/part/PartCategoryTable.tsx
+++ b/src/frontend/src/tables/part/PartCategoryTable.tsx
@@ -1,6 +1,5 @@
import { t } from '@lingui/macro';
import { useCallback, useMemo, useState } from 'react';
-import { useNavigate } from 'react-router-dom';
import { AddItemButton } from '../../components/buttons/AddItemButton';
import { YesNoButton } from '../../components/buttons/YesNoButton';
@@ -8,7 +7,6 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
import { partCategoryFields } from '../../forms/PartForms';
-import { getDetailUrl } from '../../functions/urls';
import {
useCreateApiFormModal,
useEditApiFormModal
@@ -26,8 +24,6 @@ import { RowEditAction } from '../RowActions';
* PartCategoryTable - Displays a table of part categories
*/
export function PartCategoryTable({ parentId }: { parentId?: any }) {
- const navigate = useNavigate();
-
const table = useTable('partcategory');
const user = useUserState();
@@ -79,13 +75,9 @@ export function PartCategoryTable({ parentId }: { parentId?: any }) {
initialData: {
parent: parentId
},
- onFormSuccess(data: any) {
- if (data.pk) {
- navigate(getDetailUrl(ModelType.partcategory, data.pk));
- } else {
- table.refreshTable();
- }
- }
+ follow: true,
+ modelType: ModelType.partcategory,
+ table: table
});
const [selectedCategory, setSelectedCategory] = useState(-1);
diff --git a/src/frontend/src/tables/part/PartCategoryTemplateTable.tsx b/src/frontend/src/tables/part/PartCategoryTemplateTable.tsx
index 861747cb9b..e44b756df1 100644
--- a/src/frontend/src/tables/part/PartCategoryTemplateTable.tsx
+++ b/src/frontend/src/tables/part/PartCategoryTemplateTable.tsx
@@ -37,7 +37,7 @@ export default function PartCategoryTemplateTable({}: {}) {
url: ApiEndpoints.category_parameter_list,
title: t`Add Category Parameter`,
fields: useMemo(() => ({ ...formFields }), [formFields]),
- onFormSuccess: table.refreshTable
+ table: table
});
const editTemplate = useEditApiFormModal({
@@ -45,14 +45,14 @@ export default function PartCategoryTemplateTable({}: {}) {
pk: selectedTemplate,
title: t`Edit Category Parameter`,
fields: useMemo(() => ({ ...formFields }), [formFields]),
- onFormSuccess: (record: any) => table.updateRecord(record)
+ table: table
});
const deleteTemplate = useDeleteApiFormModal({
url: ApiEndpoints.category_parameter_list,
pk: selectedTemplate,
title: t`Delete Category Parameter`,
- onFormSuccess: table.refreshTable
+ table: table
});
const tableFilters: TableFilter[] = useMemo(() => {
diff --git a/src/frontend/src/tables/part/PartParameterTable.tsx b/src/frontend/src/tables/part/PartParameterTable.tsx
index f6550d642d..c01f37118a 100644
--- a/src/frontend/src/tables/part/PartParameterTable.tsx
+++ b/src/frontend/src/tables/part/PartParameterTable.tsx
@@ -115,7 +115,7 @@ export function PartParameterTable({ partId }: { partId: any }) {
initialData: {
part: partId
},
- onFormSuccess: table.refreshTable
+ table: table
});
const [selectedParameter, setSelectedParameter] = useState<
@@ -127,14 +127,14 @@ export function PartParameterTable({ partId }: { partId: any }) {
pk: selectedParameter,
title: t`Edit Part Parameter`,
fields: useMemo(() => ({ ...partParameterFields }), [partParameterFields]),
- onFormSuccess: table.refreshTable
+ table: table
});
const deleteParameter = useDeleteApiFormModal({
url: ApiEndpoints.part_parameter_list,
pk: selectedParameter,
title: t`Delete Part Parameter`,
- onFormSuccess: table.refreshTable
+ table: table
});
// Callback for row actions
@@ -171,6 +171,7 @@ export function PartParameterTable({ partId }: { partId: any }) {
const tableActions = useMemo(() => {
return [
newParameter.open()}
diff --git a/src/frontend/src/tables/part/PartParameterTemplateTable.tsx b/src/frontend/src/tables/part/PartParameterTemplateTable.tsx
index 5b2256c3ca..5d86ae1e43 100644
--- a/src/frontend/src/tables/part/PartParameterTemplateTable.tsx
+++ b/src/frontend/src/tables/part/PartParameterTemplateTable.tsx
@@ -83,11 +83,11 @@ export default function PartParameterTemplateTable() {
const newTemplate = useCreateApiFormModal({
url: ApiEndpoints.part_parameter_template_list,
title: t`Add Parameter Template`,
+ table: table,
fields: useMemo(
() => ({ ...partParameterTemplateFields }),
[partParameterTemplateFields]
- ),
- onFormSuccess: table.refreshTable
+ )
});
const [selectedTemplate, setSelectedTemplate] = useState(
@@ -98,18 +98,18 @@ export default function PartParameterTemplateTable() {
url: ApiEndpoints.part_parameter_template_list,
pk: selectedTemplate,
title: t`Edit Parameter Template`,
+ table: table,
fields: useMemo(
() => ({ ...partParameterTemplateFields }),
[partParameterTemplateFields]
- ),
- onFormSuccess: (record: any) => table.updateRecord(record)
+ )
});
const deleteTemplate = useDeleteApiFormModal({
url: ApiEndpoints.part_parameter_template_list,
pk: selectedTemplate,
title: t`Delete Parameter Template`,
- onFormSuccess: table.refreshTable
+ table: table
});
// Callback for row actions
diff --git a/src/frontend/src/tables/part/PartTestTemplateTable.tsx b/src/frontend/src/tables/part/PartTestTemplateTable.tsx
index b92140e0f3..4b453f5b9e 100644
--- a/src/frontend/src/tables/part/PartTestTemplateTable.tsx
+++ b/src/frontend/src/tables/part/PartTestTemplateTable.tsx
@@ -131,7 +131,7 @@ export default function PartTestTemplateTable({ partId }: { partId: number }) {
initialData: {
part: partId
},
- onFormSuccess: table.refreshTable
+ table: table
});
const [selectedTest, setSelectedTest] = useState(-1);
@@ -140,11 +140,11 @@ export default function PartTestTemplateTable({ partId }: { partId: number }) {
url: ApiEndpoints.part_test_template_list,
pk: selectedTest,
title: t`Edit Test Template`,
+ table: table,
fields: useMemo(
() => ({ ...partTestTemplateFields }),
[partTestTemplateFields]
- ),
- onFormSuccess: (record: any) => table.updateRecord(record)
+ )
});
const deleteTestTemplate = useDeleteApiFormModal({
@@ -160,7 +160,7 @@ export default function PartTestTemplateTable({ partId }: { partId: number }) {
),
- onFormSuccess: table.refreshTable
+ table: table
});
const rowActions = useCallback(
diff --git a/src/frontend/src/tables/part/RelatedPartTable.tsx b/src/frontend/src/tables/part/RelatedPartTable.tsx
index fc082a4a0b..8b4c23004b 100644
--- a/src/frontend/src/tables/part/RelatedPartTable.tsx
+++ b/src/frontend/src/tables/part/RelatedPartTable.tsx
@@ -86,7 +86,7 @@ export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
initialData: {
part_1: partId
},
- onFormSuccess: table.refreshTable
+ table: table
});
const [selectedRelatedPart, setSelectedRelatedPart] = useState<
@@ -97,7 +97,7 @@ export function RelatedPartTable({ partId }: { partId: number }): ReactNode {
url: ApiEndpoints.related_part_list,
pk: selectedRelatedPart,
title: t`Delete Related Part`,
- onFormSuccess: table.refreshTable
+ table: table
});
const tableActions: ReactNode[] = useMemo(() => {
diff --git a/src/frontend/src/tables/plugin/PluginListTable.tsx b/src/frontend/src/tables/plugin/PluginListTable.tsx
index 690797decc..b4123b5473 100644
--- a/src/frontend/src/tables/plugin/PluginListTable.tsx
+++ b/src/frontend/src/tables/plugin/PluginListTable.tsx
@@ -10,12 +10,10 @@ import {
Title,
Tooltip
} from '@mantine/core';
-import { modals } from '@mantine/modals';
-import { notifications, showNotification } from '@mantine/notifications';
+import { showNotification } from '@mantine/notifications';
import {
IconCircleCheck,
IconCircleX,
- IconDots,
IconHelpCircle,
IconInfoCircle,
IconPlaylistAdd,
@@ -26,16 +24,11 @@ import { useNavigate } from 'react-router-dom';
import { api } from '../../App';
import { ActionButton } from '../../components/buttons/ActionButton';
-import {
- ActionDropdown,
- EditItemAction
-} from '../../components/items/ActionDropdown';
+import { YesNoButton } from '../../components/buttons/YesNoButton';
import { InfoItem } from '../../components/items/InfoItem';
-import { StylishText } from '../../components/items/StylishText';
import { DetailDrawer } from '../../components/nav/DetailDrawer';
import { PluginSettingList } from '../../components/settings/SettingList';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
-import { openEditApiForm } from '../../functions/forms';
import {
useCreateApiFormModal,
useDeleteApiFormModal,
@@ -80,16 +73,9 @@ export interface PluginI {
>;
}
-export function PluginDrawer({
- pluginKey,
- refreshTable
-}: {
- pluginKey: string;
- refreshTable: () => void;
-}) {
+export function PluginDrawer({ pluginKey }: { pluginKey: Readonly }) {
const {
instance: plugin,
- refreshInstance,
instanceQuery: { isFetching, error }
} = useInstance({
endpoint: ApiEndpoints.plugin_list,
@@ -98,11 +84,6 @@ export function PluginDrawer({
throwError: true
});
- const refetch = useCallback(() => {
- refreshTable();
- refreshInstance();
- }, [refreshTable, refreshInstance]);
-
if (!pluginKey || isFetching) {
return ;
}
@@ -121,44 +102,18 @@ export function PluginDrawer({
return (
-
-
+
+
+
-
- {plugin && }
-
- {plugin?.meta?.human_name ?? plugin?.name ?? '-'}
-
+
+ {plugin && }
+
+ {plugin?.meta?.human_name ?? plugin?.name ?? '-'}
+
+
-
- }
- actions={[
- EditItemAction({
- tooltip: t`Edit plugin`,
- onClick: () => {
- openEditApiForm({
- title: t`Edit plugin`,
- url: ApiEndpoints.plugin_list,
- pathParams: { key: pluginKey },
- fields: {
- active: {}
- },
- onClose: refetch
- });
- }
- }),
- {
- name: t`Reload`,
- tooltip: t`Reload`,
- icon: ,
- onClick: refreshInstance
- }
- ]}
- />
-
-
+
@@ -166,64 +121,74 @@ export function PluginDrawer({
Plugin information
-
-
-
-
-
-
-
-
+ {plugin.active ? (
+
+
+
+
+
+
+
+
+ ) : (
+ {t`Plugin is not active`}
+ )}
-
-
-
- Package information
-
-
- {plugin?.is_package && (
+ {plugin.active && (
+
+
+
+ Package information
+
+
+ {plugin?.is_package && (
+
+ )}
- )}
-
-
-
+
+
+
-
-
+
+ )}
{plugin && plugin?.active && (
@@ -300,6 +265,12 @@ export default function PluginListTable() {
);
}
},
+ {
+ accessor: 'active',
+ sortable: true,
+ title: t`Active`,
+ render: (record: any) =>
+ },
{
accessor: 'meta.description',
title: t`Description`,
@@ -312,6 +283,7 @@ export default function PluginListTable() {
return (
{t`Description not available`}
);
}
@@ -333,87 +305,49 @@ export default function PluginListTable() {
[]
);
- const activatePlugin = useCallback(
- (plugin_key: string, plugin_name: string, active: boolean) => {
- modals.openConfirmModal({
- title: (
-
- {active ? t`Activate Plugin` : t`Deactivate Plugin`}
-
- ),
- children: (
- }
- title={
- active
- ? t`Confirm plugin activation`
- : t`Confirm plugin deactivation`
- }
- >
-
-
- {active
- ? t`The following plugin will be activated`
- : t`The following plugin will be deactivated`}
- :
-
-
- {plugin_name}
-
-
-
- ),
- labels: {
- cancel: t`Cancel`,
- confirm: t`Confirm`
- },
- onConfirm: () => {
- let url = apiUrl(ApiEndpoints.plugin_activate, null, {
- key: plugin_key
- });
+ const [selectedPlugin, setSelectedPlugin] = useState('');
+ const [activate, setActivate] = useState(false);
- const id = 'plugin-activate';
+ const activateModalContent = useMemo(() => {
+ return (
+
+ }
+ title={
+ activate
+ ? t`Confirm plugin activation`
+ : t`Confirm plugin deactivation`
+ }
+ >
+
+ {activate
+ ? t`The selected plugin will be activated`
+ : t`The selected plugin will be deactivated`}
+
+
+
+ );
+ }, [activate]);
- // Show a progress notification
- notifications.show({
- id: id,
- message: active ? t`Activating plugin` : t`Deactivating plugin`,
- loading: true
- });
-
- api
- .patch(
- url,
- { active: active },
- {
- timeout: 30 * 1000
- }
- )
- .then(() => {
- table.refreshTable();
- notifications.hide(id);
- notifications.show({
- title: t`Plugin updated`,
- message: active
- ? t`The plugin was activated`
- : t`The plugin was deactivated`,
- color: 'green'
- });
- })
- .catch((_err) => {
- notifications.hide(id);
- notifications.show({
- title: t`Error`,
- message: t`Error updating plugin`,
- color: 'red'
- });
- });
- }
- });
+ const activatePluginModal = useEditApiFormModal({
+ title: t`Activate Plugin`,
+ url: ApiEndpoints.plugin_activate,
+ pathParams: { key: selectedPlugin },
+ preFormContent: activateModalContent,
+ fetchInitialData: false,
+ method: 'POST',
+ successMessage: activate
+ ? `The plugin was activated`
+ : `The plugin was deactivated`,
+ fields: {
+ active: {
+ value: activate,
+ hidden: true
+ }
},
- []
- );
+ table: table
+ });
// Determine available actions for a given plugin
const rowActions = useCallback(
@@ -429,7 +363,9 @@ export default function PluginListTable() {
color: 'red',
icon: ,
onClick: () => {
- activatePlugin(record.key, record.name, false);
+ setSelectedPlugin(record.key);
+ setActivate(false);
+ activatePluginModal.open();
}
});
} else {
@@ -438,7 +374,9 @@ export default function PluginListTable() {
color: 'green',
icon: ,
onClick: () => {
- activatePlugin(record.key, record.name, true);
+ setSelectedPlugin(record.key);
+ setActivate(true);
+ activatePluginModal.open();
}
});
}
@@ -511,21 +449,10 @@ export default function PluginListTable() {
},
closeOnClickOutside: false,
submitText: t`Install`,
- successMessage: undefined,
- onFormSuccess: (data) => {
- notifications.show({
- title: t`Plugin installed successfully`,
- message: data.result,
- autoClose: 30000,
- color: 'green'
- });
-
- table.refreshTable();
- }
+ successMessage: t`Plugin installed successfully`,
+ table: table
});
- const [selectedPlugin, setSelectedPlugin] = useState('');
-
const uninstallPluginModal = useEditApiFormModal({
title: t`Uninstall Plugin`,
url: ApiEndpoints.plugin_uninstall,
@@ -547,24 +474,16 @@ export default function PluginListTable() {
),
- onFormSuccess: (data) => {
- notifications.show({
- title: t`Plugin uninstalled successfully`,
- message: data.result,
- autoClose: 30000,
- color: 'green'
- });
-
- table.refreshTable();
- }
+ successMessage: t`Plugin uninstalled successfully`,
+ table: table
});
const deletePluginModal = useDeleteApiFormModal({
url: ApiEndpoints.plugin_list,
pathParams: { key: selectedPlugin },
title: t`Delete Plugin`,
- onFormSuccess: table.refreshTable,
- preFormWarning: t`Deleting this plugin configuration will remove all associated settings and data. Are you sure you want to delete this plugin?`
+ preFormWarning: t`Deleting this plugin configuration will remove all associated settings and data. Are you sure you want to delete this plugin?`,
+ table: table
});
const reloadPlugins = useCallback(() => {
@@ -617,6 +536,7 @@ export default function PluginListTable() {
return (
<>
+ {activatePluginModal.modal}
{installPluginModal.modal}
{uninstallPluginModal.modal}
{deletePluginModal.modal}
@@ -625,12 +545,7 @@ export default function PluginListTable() {
size={'50%'}
renderContent={(pluginKey) => {
if (!pluginKey) return;
- return (
-
- );
+ return ;
}}
/>
(undefined);
+
+ const createParameter = useCreateApiFormModal({
+ url: ApiEndpoints.manufacturer_part_parameter_list,
+ title: t`Add Parameter`,
+ fields: fields,
+ table: table,
+ initialData: {
+ manufacturer_part: params.manufacturer_part
+ }
+ });
+
+ const editParameter = useEditApiFormModal({
+ url: ApiEndpoints.manufacturer_part_parameter_list,
+ pk: selectedParameter,
+ title: t`Edit Parameter`,
+ fields: fields,
+ table: table
+ });
+
+ const deleteParameter = useDeleteApiFormModal({
+ url: ApiEndpoints.manufacturer_part_parameter_list,
+ pk: selectedParameter,
+ title: t`Delete Parameter`,
+ table: table
+ });
+
const rowActions = useCallback(
(record: any) => {
return [
RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order),
onClick: () => {
- openEditApiForm({
- url: ApiEndpoints.manufacturer_part_parameter_list,
- pk: record.pk,
- title: t`Edit Parameter`,
- fields: fields,
- onFormSuccess: table.refreshTable,
- successMessage: t`Parameter updated`
- });
+ setSelectedParameter(record.pk);
+ editParameter.open();
}
}),
RowDeleteAction({
hidden: !user.hasDeleteRole(UserRoles.purchase_order),
onClick: () => {
- record.pk &&
- openDeleteApiForm({
- url: ApiEndpoints.manufacturer_part_parameter_list,
- pk: record.pk,
- title: t`Delete Parameter`,
- onFormSuccess: table.refreshTable,
- successMessage: t`Parameter deleted`,
- preFormWarning: t`Are you sure you want to delete this parameter?`
- });
+ setSelectedParameter(record.pk);
+ deleteParameter.open();
}
})
];
@@ -80,17 +101,36 @@ export default function ManufacturerPartParameterTable({
[user]
);
+ const tableActions = useMemo(() => {
+ return [
+ {
+ createParameter.open();
+ }}
+ hidden={!user.hasAddRole(UserRoles.purchase_order)}
+ />
+ ];
+ }, [user]);
+
return (
-
+ <>
+ {createParameter.modal}
+ {editParameter.modal}
+ {deleteParameter.modal}
+
+ >
);
}
diff --git a/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx b/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx
index fb91b1c74d..e862f10359 100644
--- a/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx
+++ b/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx
@@ -1,5 +1,5 @@
import { t } from '@lingui/macro';
-import { ReactNode, useCallback, useMemo } from 'react';
+import { ReactNode, useCallback, useMemo, useState } from 'react';
import { AddItemButton } from '../../components/buttons/AddItemButton';
import { Thumbnail } from '../../components/images/Thumbnail';
@@ -7,8 +7,11 @@ import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
import { useManufacturerPartFields } from '../../forms/CompanyForms';
-import { openDeleteApiForm, openEditApiForm } from '../../functions/forms';
-import { useCreateApiFormModal } from '../../hooks/UseForm';
+import {
+ useCreateApiFormModal,
+ useDeleteApiFormModal,
+ useEditApiFormModal
+} from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState';
import { useUserState } from '../../states/UserState';
@@ -58,16 +61,37 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
];
}, [params]);
+ const manufacturerPartFields = useManufacturerPartFields();
+
+ const [selectedPart, setSelectedPart] = useState(
+ undefined
+ );
+
const createManufacturerPart = useCreateApiFormModal({
url: ApiEndpoints.manufacturer_part_list,
title: t`Add Manufacturer Part`,
- fields: useManufacturerPartFields(),
- onFormSuccess: table.refreshTable,
+ fields: manufacturerPartFields,
+ table: table,
initialData: {
manufacturer: params?.manufacturer
}
});
+ const editManufacturerPart = useEditApiFormModal({
+ url: ApiEndpoints.manufacturer_part_list,
+ pk: selectedPart,
+ title: t`Edit Manufacturer Part`,
+ fields: manufacturerPartFields,
+ table: table
+ });
+
+ const deleteManufacturerPart = useDeleteApiFormModal({
+ url: ApiEndpoints.manufacturer_part_list,
+ pk: selectedPart,
+ title: t`Delete Manufacturer Part`,
+ table: table
+ });
+
const tableActions = useMemo(() => {
let can_add =
user.hasAddRole(UserRoles.purchase_order) &&
@@ -82,37 +106,21 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
];
}, [user]);
- const editManufacturerPartFields = useManufacturerPartFields();
-
const rowActions = useCallback(
(record: any) => {
return [
RowEditAction({
hidden: !user.hasChangeRole(UserRoles.purchase_order),
onClick: () => {
- record.pk &&
- openEditApiForm({
- url: ApiEndpoints.manufacturer_part_list,
- pk: record.pk,
- title: t`Edit Manufacturer Part`,
- fields: editManufacturerPartFields,
- onFormSuccess: table.refreshTable,
- successMessage: t`Manufacturer part updated`
- });
+ setSelectedPart(record.pk);
+ editManufacturerPart.open();
}
}),
RowDeleteAction({
hidden: !user.hasDeleteRole(UserRoles.purchase_order),
onClick: () => {
- record.pk &&
- openDeleteApiForm({
- url: ApiEndpoints.manufacturer_part_list,
- pk: record.pk,
- title: t`Delete Manufacturer Part`,
- successMessage: t`Manufacturer part deleted`,
- onFormSuccess: table.refreshTable,
- preFormWarning: t`Are you sure you want to remove this manufacturer part?`
- });
+ setSelectedPart(record.pk);
+ deleteManufacturerPart.open();
}
})
];
@@ -123,6 +131,8 @@ export function ManufacturerPartTable({ params }: { params: any }): ReactNode {
return (
<>
{createManufacturerPart.modal}
+ {editManufacturerPart.modal}
+ {deleteManufacturerPart.modal}
(0);
@@ -214,14 +214,14 @@ export function PurchaseOrderLineItemTable({
pk: selectedLine,
title: t`Edit Line Item`,
fields: editPurchaseOrderFields,
- onFormSuccess: table.refreshTable
+ table: table
});
const deleteLine = useDeleteApiFormModal({
url: ApiEndpoints.purchase_order_line_list,
pk: selectedLine,
title: t`Delete Line Item`,
- onFormSuccess: table.refreshTable
+ table: table
});
const rowActions = useCallback(
diff --git a/src/frontend/src/tables/purchasing/SupplierPartTable.tsx b/src/frontend/src/tables/purchasing/SupplierPartTable.tsx
index 3a6af2b841..0b3f21ba3e 100644
--- a/src/frontend/src/tables/purchasing/SupplierPartTable.tsx
+++ b/src/frontend/src/tables/purchasing/SupplierPartTable.tsx
@@ -166,7 +166,7 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
part: params?.part,
supplier: params?.supplier
},
- onFormSuccess: table.refreshTable,
+ table: table,
successMessage: t`Supplier part created`
});
@@ -209,14 +209,14 @@ export function SupplierPartTable({ params }: { params: any }): ReactNode {
pk: selectedSupplierPart,
title: t`Edit Supplier Part`,
fields: editSupplierPartFields,
- onFormSuccess: () => table.refreshTable()
+ table: table
});
const deleteSupplierPart = useDeleteApiFormModal({
url: ApiEndpoints.supplier_part_list,
pk: selectedSupplierPart,
title: t`Delete Supplier Part`,
- onFormSuccess: () => table.refreshTable()
+ table: table
});
// Row action callback
diff --git a/src/frontend/src/tables/purchasing/SupplierPriceBreakTable.tsx b/src/frontend/src/tables/purchasing/SupplierPriceBreakTable.tsx
index d2d0950ce7..56ee44e8f0 100644
--- a/src/frontend/src/tables/purchasing/SupplierPriceBreakTable.tsx
+++ b/src/frontend/src/tables/purchasing/SupplierPriceBreakTable.tsx
@@ -140,9 +140,7 @@ export default function SupplierPriceBreakTable({
initialData: {
part: supplierPartId
},
- onFormSuccess: (data: any) => {
- table.refreshTable();
- }
+ table: table
});
const editPriceBreak = useEditApiFormModal({
@@ -150,18 +148,14 @@ export default function SupplierPriceBreakTable({
pk: selectedPriceBreak,
title: t`Edit Price Break`,
fields: supplierPriceBreakFields,
- onFormSuccess: (data: any) => {
- table.refreshTable();
- }
+ table: table
});
const deletePriceBreak = useDeleteApiFormModal({
url: apiUrl(ApiEndpoints.supplier_part_pricing_list),
pk: selectedPriceBreak,
title: t`Delete Price Break`,
- onFormSuccess: () => {
- table.refreshTable();
- }
+ table: table
});
const tableActions = useMemo(() => {
diff --git a/src/frontend/src/tables/settings/CustomUnitsTable.tsx b/src/frontend/src/tables/settings/CustomUnitsTable.tsx
index 75f0195af6..3d0f2341c3 100644
--- a/src/frontend/src/tables/settings/CustomUnitsTable.tsx
+++ b/src/frontend/src/tables/settings/CustomUnitsTable.tsx
@@ -49,7 +49,7 @@ export default function CustomUnitsTable() {
url: ApiEndpoints.custom_unit_list,
title: t`Add Custom Unit`,
fields: customUnitsFields(),
- onFormSuccess: table.refreshTable
+ table: table
});
const [selectedUnit, setSelectedUnit] = useState(-1);
@@ -66,7 +66,7 @@ export default function CustomUnitsTable() {
url: ApiEndpoints.custom_unit_list,
pk: selectedUnit,
title: t`Delete Custom Unit`,
- onFormSuccess: table.refreshTable
+ table: table
});
const rowActions = useCallback(
diff --git a/src/frontend/src/tables/settings/ErrorTable.tsx b/src/frontend/src/tables/settings/ErrorTable.tsx
index 4fec4e3c34..e313d0b542 100644
--- a/src/frontend/src/tables/settings/ErrorTable.tsx
+++ b/src/frontend/src/tables/settings/ErrorTable.tsx
@@ -5,7 +5,7 @@ import { useCallback, useMemo, useState } from 'react';
import { StylishText } from '../../components/items/StylishText';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
-import { openDeleteApiForm } from '../../functions/forms';
+import { useDeleteApiFormModal } from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable';
import { apiUrl } from '../../states/ApiState';
import { TableColumn } from '../Column';
@@ -41,18 +41,27 @@ export default function ErrorReportTable() {
];
}, []);
+ const [selectedError, setSelectedError] = useState(
+ undefined
+ );
+
+ const deleteErrorModal = useDeleteApiFormModal({
+ url: ApiEndpoints.error_report_list,
+ pk: selectedError,
+ title: t`Delete Error Report`,
+ preFormContent: (
+ {t`Are you sure you want to delete this error report?`}
+ ),
+ successMessage: t`Error report deleted`,
+ table: table
+ });
+
const rowActions = useCallback((record: any): RowAction[] => {
return [
RowDeleteAction({
onClick: () => {
- openDeleteApiForm({
- url: ApiEndpoints.error_report_list,
- pk: record.pk,
- title: t`Delete error report`,
- onFormSuccess: table.refreshTable,
- successMessage: t`Error report deleted`,
- preFormWarning: t`Are you sure you want to delete this error report?`
- });
+ setSelectedError(record.pk);
+ deleteErrorModal.open();
}
})
];
@@ -60,6 +69,7 @@ export default function ErrorReportTable() {
return (
<>
+ {deleteErrorModal.modal}
{
diff --git a/src/frontend/src/tables/settings/ProjectCodeTable.tsx b/src/frontend/src/tables/settings/ProjectCodeTable.tsx
index b365cc372d..ee21364d34 100644
--- a/src/frontend/src/tables/settings/ProjectCodeTable.tsx
+++ b/src/frontend/src/tables/settings/ProjectCodeTable.tsx
@@ -41,7 +41,7 @@ export default function ProjectCodeTable() {
url: ApiEndpoints.project_code_list,
title: t`Add Project Code`,
fields: projectCodeFields(),
- onFormSuccess: table.refreshTable
+ table: table
});
const [selectedProjectCode, setSelectedProjectCode] = useState<
@@ -53,14 +53,14 @@ export default function ProjectCodeTable() {
pk: selectedProjectCode,
title: t`Edit Project Code`,
fields: projectCodeFields(),
- onFormSuccess: (record: any) => table.updateRecord(record)
+ table: table
});
const deleteProjectCode = useDeleteApiFormModal({
url: ApiEndpoints.project_code_list,
pk: selectedProjectCode,
title: t`Delete Project Code`,
- onFormSuccess: table.refreshTable
+ table: table
});
const rowActions = useCallback(
diff --git a/src/frontend/src/tables/settings/TemplateTable.tsx b/src/frontend/src/tables/settings/TemplateTable.tsx
index e1928430ad..724fa79a66 100644
--- a/src/frontend/src/tables/settings/TemplateTable.tsx
+++ b/src/frontend/src/tables/settings/TemplateTable.tsx
@@ -234,7 +234,7 @@ export function TemplateTable({
pathParams: { variant },
pk: selectedTemplate,
title: t`Delete` + ' ' + templateTypeTranslation,
- onFormSuccess: table.refreshTable
+ table: table
});
const newTemplate = useCreateApiFormModal({
diff --git a/src/frontend/src/tables/settings/UserTable.tsx b/src/frontend/src/tables/settings/UserTable.tsx
index e2793d1c8d..a7108e64f5 100644
--- a/src/frontend/src/tables/settings/UserTable.tsx
+++ b/src/frontend/src/tables/settings/UserTable.tsx
@@ -230,7 +230,7 @@ export function UserTable() {
pk: selectedUser,
title: t`Delete user`,
successMessage: t`User deleted`,
- onFormSuccess: table.refreshTable,
+ table: table,
preFormWarning: t`Are you sure you want to delete this user?`
});
@@ -244,7 +244,7 @@ export function UserTable() {
first_name: {},
last_name: {}
},
- onFormSuccess: table.refreshTable,
+ table: table,
successMessage: t`Added user`
});
diff --git a/src/frontend/src/tables/stock/StockItemTestResultTable.tsx b/src/frontend/src/tables/stock/StockItemTestResultTable.tsx
index ba38d376ce..2439ba870b 100644
--- a/src/frontend/src/tables/stock/StockItemTestResultTable.tsx
+++ b/src/frontend/src/tables/stock/StockItemTestResultTable.tsx
@@ -268,7 +268,7 @@ export default function StockItemTestResultTable({
result: true
},
title: t`Add Test Result`,
- onFormSuccess: () => table.refreshTable(),
+ table: table,
successMessage: t`Test result added`
});
@@ -279,7 +279,7 @@ export default function StockItemTestResultTable({
pk: selectedTest,
fields: resultFields,
title: t`Edit Test Result`,
- onFormSuccess: () => table.refreshTable(),
+ table: table,
successMessage: t`Test result updated`
});
@@ -287,7 +287,7 @@ export default function StockItemTestResultTable({
url: ApiEndpoints.stock_test_result_list,
pk: selectedTest,
title: t`Delete Test Result`,
- onFormSuccess: () => table.refreshTable(),
+ table: table,
successMessage: t`Test result deleted`
});
diff --git a/src/frontend/src/tables/stock/StockLocationTable.tsx b/src/frontend/src/tables/stock/StockLocationTable.tsx
index 1b2ef2b328..f8c66a03b7 100644
--- a/src/frontend/src/tables/stock/StockLocationTable.tsx
+++ b/src/frontend/src/tables/stock/StockLocationTable.tsx
@@ -1,13 +1,11 @@
import { t } from '@lingui/macro';
import { useCallback, useMemo, useState } from 'react';
-import { useNavigate } from 'react-router-dom';
import { AddItemButton } from '../../components/buttons/AddItemButton';
import { ApiEndpoints } from '../../enums/ApiEndpoints';
import { ModelType } from '../../enums/ModelType';
import { UserRoles } from '../../enums/Roles';
import { stockLocationFields } from '../../forms/StockForms';
-import { getDetailUrl } from '../../functions/urls';
import {
useCreateApiFormModal,
useEditApiFormModal
@@ -28,8 +26,6 @@ export function StockLocationTable({ parentId }: { parentId?: any }) {
const table = useTable('stocklocation');
const user = useUserState();
- const navigate = useNavigate();
-
const tableFilters: TableFilter[] = useMemo(() => {
return [
{
@@ -91,13 +87,9 @@ export function StockLocationTable({ parentId }: { parentId?: any }) {
initialData: {
parent: parentId
},
- onFormSuccess(data: any) {
- if (data.pk) {
- navigate(getDetailUrl(ModelType.stocklocation, data.pk));
- } else {
- table.refreshTable();
- }
- }
+ follow: true,
+ modelType: ModelType.stocklocation,
+ table: table
});
const [selectedLocation, setSelectedLocation] = useState(-1);