diff --git a/src/frontend/lib/types/Forms.tsx b/src/frontend/lib/types/Forms.tsx
index 8e3a574f01..47c6dc70cc 100644
--- a/src/frontend/lib/types/Forms.tsx
+++ b/src/frontend/lib/types/Forms.tsx
@@ -174,6 +174,7 @@ export interface ApiFormProps {
*/
export interface ApiFormModalProps extends ApiFormProps {
title: string;
+ modalId?: string;
cancelText?: string;
cancelColor?: string;
onClose?: () => void;
diff --git a/src/frontend/lib/types/Modals.tsx b/src/frontend/lib/types/Modals.tsx
index a0df9c8b0c..5aabf2e248 100644
--- a/src/frontend/lib/types/Modals.tsx
+++ b/src/frontend/lib/types/Modals.tsx
@@ -1,6 +1,7 @@
import type { UiSizeType } from './Core';
export interface UseModalProps {
+ id: string;
title: string;
children: React.ReactElement;
size?: UiSizeType;
diff --git a/src/frontend/src/components/forms/fields/TableField.tsx b/src/frontend/src/components/forms/fields/TableField.tsx
index cfa7ed741f..09eaa9153e 100644
--- a/src/frontend/src/components/forms/fields/TableField.tsx
+++ b/src/frontend/src/components/forms/fields/TableField.tsx
@@ -155,7 +155,7 @@ export function TableField({
- {value.length > 0 ? (
+ {(value?.length ?? 0) > 0 ? (
value.map((item: any, idx: number) => {
return (
(
null
@@ -47,6 +49,7 @@ export function useBuildOrderFields({
const [batchCode, setBatchCode] = useState('');
const batchGenerator = useBatchCodeGenerator({
+ modalId: modalId,
onGenerate: (value: any) => {
setBatchCode((batch: any) => batch || value);
}
@@ -152,9 +155,11 @@ export function useBuildOrderFields({
}
export function useBuildOrderOutputFields({
- build
+ build,
+ modalId
}: {
build: any;
+ modalId: string;
}): ApiFormFieldSet {
const trackable: boolean = useMemo(() => {
return build.part_detail?.trackable ?? false;
@@ -176,12 +181,14 @@ export function useBuildOrderOutputFields({
}, [build]);
const serialGenerator = useSerialNumberGenerator({
+ modalId: modalId,
initialQuery: {
part: build.part || build.part_detail?.pk
}
});
const batchGenerator = useBatchCodeGenerator({
+ modalId: modalId,
initialQuery: {
part: build.part || build.part_detail?.pk,
quantity: build.quantity
diff --git a/src/frontend/src/forms/PurchaseOrderForms.tsx b/src/frontend/src/forms/PurchaseOrderForms.tsx
index f95e762089..575d626976 100644
--- a/src/frontend/src/forms/PurchaseOrderForms.tsx
+++ b/src/frontend/src/forms/PurchaseOrderForms.tsx
@@ -296,6 +296,7 @@ function LineItemFormRow({
// Batch code generator
const batchCodeGenerator = useBatchCodeGenerator({
+ isEnabled: () => batchOpen,
onGenerate: (value: any) => {
if (value) {
props.changeFn(props.idx, 'batch_code', value);
@@ -305,6 +306,7 @@ function LineItemFormRow({
// Serial number generator
const serialNumberGenerator = useSerialNumberGenerator({
+ isEnabled: () => batchOpen && trackable,
onGenerate: (value: any) => {
if (value) {
props.changeFn(props.idx, 'serial_numbers', value);
diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx
index d4c6cb0317..47ee508363 100644
--- a/src/frontend/src/forms/StockForms.tsx
+++ b/src/frontend/src/forms/StockForms.tsx
@@ -65,10 +65,12 @@ import { StatusFilterOptions } from '../tables/Filter';
export function useStockFields({
partId,
stockItem,
+ modalId,
create = false
}: {
partId?: number;
stockItem?: any;
+ modalId: string;
create: boolean;
}): ApiFormFieldSet {
const globalSettings = useGlobalSettingsState();
@@ -81,12 +83,14 @@ export function useStockFields({
const [expiryDate, setExpiryDate] = useState(null);
const batchGenerator = useBatchCodeGenerator({
+ modalId: modalId,
initialQuery: {
part: partInstance?.pk || partId
}
});
const serialGenerator = useSerialNumberGenerator({
+ modalId: modalId,
initialQuery: {
part: partInstance?.pk || partId
}
@@ -235,11 +239,15 @@ export function useStockFields({
* Launch a form to create a new StockItem instance
*/
export function useCreateStockItem() {
- const fields = useStockFields({ create: true });
+ const fields = useStockFields({
+ create: true,
+ modalId: 'create-stock-item'
+ });
return useCreateApiFormModal({
url: ApiEndpoints.stock_item_list,
fields: fields,
+ modalId: 'create-stock-item',
title: t`Add Stock Item`
});
}
@@ -318,12 +326,15 @@ export function useStockItemInstallFields({
*/
export function useStockItemSerializeFields({
partId,
- trackable
+ trackable,
+ modalId
}: {
partId: number;
trackable: boolean;
+ modalId: string;
}) {
const serialGenerator = useSerialNumberGenerator({
+ modalId: modalId,
initialQuery: {
part: partId
}
@@ -1018,7 +1029,7 @@ type apiModalFunc = (props: ApiFormModalProps) => {
modal: JSX.Element;
};
-function stockOperationModal({
+function useStockOperationModal({
items,
pk,
model,
@@ -1061,25 +1072,29 @@ function stockOperationModal({
return query_params;
}, [baseParams, filters, model, pk]);
+ const [opened, setOpened] = useState(false);
+
const { data } = useQuery({
- queryKey: ['stockitems', model, pk, items, params],
+ queryKey: ['stockitems', opened, model, pk, items, params],
queryFn: async () => {
if (items) {
+ // If a list of items is provided, use that directly
return Array.isArray(items) ? items : [items];
}
+
+ if (!pk || !opened) {
+ return [];
+ }
+
const url = apiUrl(ApiEndpoints.stock_item_list);
return api
.get(url, {
params: params
})
- .then((response) => {
- if (response.status === 200) {
- return response.data;
- }
- })
+ .then((response) => response.data ?? [])
.catch(() => {
- return null;
+ return [];
});
}
});
@@ -1095,7 +1110,9 @@ function stockOperationModal({
title: title,
size: '80%',
successMessage: successMessage,
- onFormSuccess: () => refresh()
+ onFormSuccess: () => refresh(),
+ onClose: () => setOpened(false),
+ onOpen: () => setOpened(true)
});
}
@@ -1108,7 +1125,7 @@ export type StockOperationProps = {
};
export function useAddStockItem(props: StockOperationProps) {
- return stockOperationModal({
+ return useStockOperationModal({
...props,
fieldGenerator: stockAddFields,
endpoint: ApiEndpoints.stock_add,
@@ -1118,7 +1135,7 @@ export function useAddStockItem(props: StockOperationProps) {
}
export function useRemoveStockItem(props: StockOperationProps) {
- return stockOperationModal({
+ return useStockOperationModal({
...props,
fieldGenerator: stockRemoveFields,
endpoint: ApiEndpoints.stock_remove,
@@ -1128,7 +1145,7 @@ export function useRemoveStockItem(props: StockOperationProps) {
}
export function useTransferStockItem(props: StockOperationProps) {
- return stockOperationModal({
+ return useStockOperationModal({
...props,
fieldGenerator: stockTransferFields,
endpoint: ApiEndpoints.stock_transfer,
@@ -1138,7 +1155,7 @@ export function useTransferStockItem(props: StockOperationProps) {
}
export function useCountStockItem(props: StockOperationProps) {
- return stockOperationModal({
+ return useStockOperationModal({
...props,
fieldGenerator: stockCountFields,
endpoint: ApiEndpoints.stock_count,
@@ -1148,7 +1165,7 @@ export function useCountStockItem(props: StockOperationProps) {
}
export function useChangeStockStatus(props: StockOperationProps) {
- return stockOperationModal({
+ return useStockOperationModal({
...props,
fieldGenerator: stockChangeStatusFields,
endpoint: ApiEndpoints.stock_change_status,
@@ -1158,7 +1175,7 @@ export function useChangeStockStatus(props: StockOperationProps) {
}
export function useMergeStockItem(props: StockOperationProps) {
- return stockOperationModal({
+ return useStockOperationModal({
...props,
fieldGenerator: stockMergeFields,
endpoint: ApiEndpoints.stock_merge,
@@ -1182,7 +1199,7 @@ export function useAssignStockItem(props: StockOperationProps) {
return props.items?.filter((item) => item?.part_detail?.salable);
}, [props.items]);
- return stockOperationModal({
+ return useStockOperationModal({
...props,
items: items,
fieldGenerator: stockAssignFields,
@@ -1193,7 +1210,7 @@ export function useAssignStockItem(props: StockOperationProps) {
}
export function useDeleteStockItem(props: StockOperationProps) {
- return stockOperationModal({
+ return useStockOperationModal({
...props,
fieldGenerator: stockDeleteFields,
endpoint: ApiEndpoints.stock_item_list,
diff --git a/src/frontend/src/hooks/UseForm.tsx b/src/frontend/src/hooks/UseForm.tsx
index dd8b10f1dc..878d0daf82 100644
--- a/src/frontend/src/hooks/UseForm.tsx
+++ b/src/frontend/src/hooks/UseForm.tsx
@@ -8,6 +8,7 @@ import type {
BulkEditApiFormModalProps
} from '@lib/types/Forms';
import { OptionsApiForm } from '../components/forms/ApiForm';
+import { useModalState } from '../states/ModalState';
import { useModal } from './UseModal';
/**
@@ -17,6 +18,12 @@ export function useApiFormModal(props: ApiFormModalProps) {
const id = useId();
const modalClose = useRef(() => {});
+ const modalState = useModalState();
+
+ const modalId = useMemo(() => {
+ return props.modalId ?? id;
+ }, [props.modalId, id]);
+
const formProps = useMemo(
() => ({
...props,
@@ -44,15 +51,22 @@ export function useApiFormModal(props: ApiFormModalProps) {
);
const modal = useModal({
+ id: modalId,
title: formProps.title,
- onOpen: formProps.onOpen,
- onClose: formProps.onClose,
+ onOpen: () => {
+ modalState.setModalOpen(modalId, true);
+ formProps.onOpen?.();
+ },
+ onClose: () => {
+ modalState.setModalOpen(modalId, false);
+ formProps.onClose?.();
+ },
closeOnClickOutside: formProps.closeOnClickOutside,
size: props.size ?? 'xl',
children: (
-
+
)
});
diff --git a/src/frontend/src/hooks/UseGenerator.tsx b/src/frontend/src/hooks/UseGenerator.tsx
index c923a2c0e1..b1ad515844 100644
--- a/src/frontend/src/hooks/UseGenerator.tsx
+++ b/src/frontend/src/hooks/UseGenerator.tsx
@@ -5,12 +5,15 @@ import { useCallback, useState } from 'react';
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { apiUrl } from '@lib/functions/Api';
import { api } from '../App';
+import { useModalState } from '../states/ModalState';
export type GeneratorProps = {
endpoint: ApiEndpoints;
key: string;
initialQuery?: Record;
onGenerate?: (value: any) => void;
+ isEnabled?: () => boolean;
+ modalId?: string;
};
export type GeneratorState = {
@@ -25,6 +28,8 @@ export type GeneratorState = {
* Each update calls a new query to the API, and the result is stored in the state.
*/
export function useGenerator(props: GeneratorProps): GeneratorState {
+ const modalState = useModalState();
+
// Track the result
const [result, setResult] = useState(null);
@@ -34,6 +39,24 @@ export function useGenerator(props: GeneratorProps): GeneratorState {
// Prevent rapid updates
const [debouncedQuery] = useDebouncedValue>(query, 100);
+ // Callback to determine if the function is enabled
+ const isEnabled = useCallback(() => {
+ if (props.isEnabled?.() == false) {
+ return false;
+ }
+
+ if (props.modalId && !modalState.isModalOpen(props.modalId)) {
+ return false;
+ }
+
+ return true;
+ }, [
+ modalState.isModalOpen,
+ modalState.openModals,
+ props.isEnabled,
+ props.modalId
+ ]);
+
// Callback to update the generator query
const update = useCallback(
(params: Record, overwrite?: boolean) => {
@@ -57,6 +80,7 @@ export function useGenerator(props: GeneratorProps): GeneratorState {
props.key,
props.endpoint,
props.initialQuery,
+ modalState.openModals,
debouncedQuery
],
refetchOnMount: false,
@@ -67,6 +91,11 @@ export function useGenerator(props: GeneratorProps): GeneratorState {
...(props.initialQuery ?? {})
};
+ if (!isEnabled()) {
+ setResult(null);
+ return;
+ }
+
return api
.post(apiUrl(props.endpoint), generatorQuery)
.then((response) => {
@@ -96,31 +125,43 @@ export function useGenerator(props: GeneratorProps): GeneratorState {
// Generate a batch code with provided data
export function useBatchCodeGenerator({
initialQuery,
- onGenerate
+ onGenerate,
+ isEnabled,
+ modalId
}: {
initialQuery?: Record;
onGenerate?: (value: any) => void;
+ isEnabled?: () => boolean;
+ modalId?: string;
}): GeneratorState {
return useGenerator({
endpoint: ApiEndpoints.generate_batch_code,
key: 'batch_code',
initialQuery: initialQuery,
- onGenerate: onGenerate
+ onGenerate: onGenerate,
+ isEnabled: isEnabled,
+ modalId: modalId
});
}
// Generate a serial number with provided data
export function useSerialNumberGenerator({
initialQuery,
- onGenerate
+ onGenerate,
+ isEnabled,
+ modalId
}: {
initialQuery?: Record;
onGenerate?: (value: any) => void;
+ isEnabled?: () => boolean;
+ modalId?: string;
}): GeneratorState {
return useGenerator({
endpoint: ApiEndpoints.generate_serial_number,
key: 'serial_number',
initialQuery: initialQuery,
- onGenerate: onGenerate
+ onGenerate: onGenerate,
+ isEnabled: isEnabled,
+ modalId: modalId
});
}
diff --git a/src/frontend/src/hooks/UseModal.tsx b/src/frontend/src/hooks/UseModal.tsx
index 47c6d53d08..284cd623ae 100644
--- a/src/frontend/src/hooks/UseModal.tsx
+++ b/src/frontend/src/hooks/UseModal.tsx
@@ -25,6 +25,7 @@ export function useModal(props: UseModalProps): UseModalReturn {
toggle,
modal: (
- {duplicatePart.modal}
{editPart.modal}
{deletePart.modal}
- {findBySerialNumber.modal}
+ {duplicatePart.modal}
+ {countStockItems.modal}
{orderPartsWizard.wizard}
+ {findBySerialNumber.modal}
+ {transferStockItems.modal}
- {transferStockItems.modal}
- {countStockItems.modal}
>
diff --git a/src/frontend/src/pages/stock/StockDetail.tsx b/src/frontend/src/pages/stock/StockDetail.tsx
index 0c4de8082a..088fa283b4 100644
--- a/src/frontend/src/pages/stock/StockDetail.tsx
+++ b/src/frontend/src/pages/stock/StockDetail.tsx
@@ -640,22 +640,28 @@ export default function StockDetail() {
const editStockItemFields = useStockFields({
create: false,
stockItem: stockitem,
- partId: stockitem.part
+ partId: stockitem.part,
+ modalId: 'edit-stock-item'
});
const editStockItem = useEditApiFormModal({
url: ApiEndpoints.stock_item_list,
pk: stockitem.pk,
title: t`Edit Stock Item`,
+ modalId: 'edit-stock-item',
fields: editStockItemFields,
onFormSuccess: refreshInstance
});
- const duplicateStockItemFields = useStockFields({ create: true });
+ const duplicateStockItemFields = useStockFields({
+ create: true,
+ modalId: 'duplicate-stock-item'
+ });
const duplicateStockItem = useCreateApiFormModal({
url: ApiEndpoints.stock_item_list,
title: t`Add Stock Item`,
+ modalId: 'duplicate-stock-item',
fields: duplicateStockItemFields,
initialData: {
...stockitem
@@ -700,13 +706,15 @@ export default function StockDetail() {
const serializeStockFields = useStockItemSerializeFields({
partId: stockitem.part,
- trackable: stockitem.part_detail?.trackable
+ trackable: stockitem.part_detail?.trackable,
+ modalId: 'stock-item-serialize'
});
const serializeStockItem = useCreateApiFormModal({
url: ApiEndpoints.stock_serialize,
pk: stockitem.pk,
title: t`Serialize Stock Item`,
+ modalId: 'stock-item-serialize',
fields: serializeStockFields,
initialData: {
quantity: stockitem.quantity,
diff --git a/src/frontend/src/states/ModalState.tsx b/src/frontend/src/states/ModalState.tsx
new file mode 100644
index 0000000000..42d9b7aced
--- /dev/null
+++ b/src/frontend/src/states/ModalState.tsx
@@ -0,0 +1,28 @@
+import { create } from 'zustand';
+
+interface ModalStateProps {
+ openModals: Record;
+ isModalOpen: (modalKey: string) => boolean;
+ setModalOpen: (modalKey: string, isOpen: boolean) => void;
+}
+
+/**
+ * Global state manager for determining modal visibility.
+ * Useful to share modal state (open / closed) between components.
+ */
+export const useModalState = create()((set, get) => ({
+ openModals: {},
+
+ isModalOpen: (modalKey: string) => {
+ return get().openModals[modalKey] ?? false;
+ },
+
+ setModalOpen: (modalKey: string, isOpen: boolean) => {
+ set((state) => ({
+ openModals: {
+ ...state.openModals,
+ [modalKey]: isOpen
+ }
+ }));
+ }
+}));
diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx
index a61a98e607..8e7a26b7b9 100644
--- a/src/frontend/src/tables/InvenTreeTable.tsx
+++ b/src/frontend/src/tables/InvenTreeTable.tsx
@@ -176,10 +176,24 @@ export function InvenTreeTable>({
);
}, [props.tableFilters, fieldNames]);
+ // Build table properties based on provided props (and default props)
+ const tableProps: InvenTreeTableProps = useMemo(() => {
+ return {
+ ...defaultInvenTreeTableProps,
+ ...props
+ };
+ }, [props]);
+
// Request OPTIONS data from the API, before we load the table
const tableOptionQuery = useQuery({
enabled: !!url && !tableData,
- queryKey: ['options', url, cacheKey, props.enableColumnCaching],
+ queryKey: [
+ 'options',
+ url,
+ cacheKey,
+ tableProps.params,
+ props.enableColumnCaching
+ ],
retry: 3,
refetchOnMount: true,
gcTime: 5000,
@@ -255,14 +269,6 @@ export function InvenTreeTable>({
tableOptionQuery.refetch();
}, [cacheKey, url, props.params, props.enableColumnCaching]);
- // Build table properties based on provided props (and default props)
- const tableProps: InvenTreeTableProps = useMemo(() => {
- return {
- ...defaultInvenTreeTableProps,
- ...props
- };
- }, [props]);
-
const enableSelection: boolean = useMemo(() => {
return tableProps.enableSelection || tableProps.enableBulkDelete || false;
}, [tableProps]);
@@ -450,13 +456,17 @@ export function InvenTreeTable>({
]
);
+ const [sortingLoaded, setSortingLoaded] = useState(false);
+
useEffect(() => {
const tableKey: string = tableState.tableKey.split('-')[0];
const sorting: DataTableSortStatus = getTableSorting(tableKey);
- if (sorting) {
+ if (sorting && !!sorting.columnAccessor && !!sorting.direction) {
setSortStatus(sorting);
}
+
+ setSortingLoaded(true);
}, []);
// Return the ordering parameter
@@ -492,6 +502,12 @@ export function InvenTreeTable>({
const queryParams = getTableFilters(true);
if (!url) {
+ // No URL supplied - do not load!
+ return [];
+ }
+
+ if (!sortingLoaded) {
+ // Sorting not yet loaded - do not load!
return [];
}
@@ -560,6 +576,7 @@ export function InvenTreeTable>({
url,
tableState.page,
props.params,
+ sortingLoaded,
sortStatus.columnAccessor,
sortStatus.direction,
tableState.tableKey,
diff --git a/src/frontend/src/tables/build/BuildLineTable.tsx b/src/frontend/src/tables/build/BuildLineTable.tsx
index 1a5030189f..00e5a86940 100644
--- a/src/frontend/src/tables/build/BuildLineTable.tsx
+++ b/src/frontend/src/tables/build/BuildLineTable.tsx
@@ -419,7 +419,10 @@ export default function BuildLineTable({
];
}, [hasOutput, isActive, table, output]);
- const buildOrderFields = useBuildOrderFields({ create: true });
+ const buildOrderFields = useBuildOrderFields({
+ create: true,
+ modalId: 'new-build-order'
+ });
const [initialData, setInitialData] = useState({});
@@ -431,6 +434,7 @@ export default function BuildLineTable({
url: ApiEndpoints.build_order_list,
title: t`Create Build Order`,
fields: buildOrderFields,
+ modalId: 'new-build-order',
initialData: initialData,
follow: true,
modelType: ModelType.build
diff --git a/src/frontend/src/tables/build/BuildOrderTable.tsx b/src/frontend/src/tables/build/BuildOrderTable.tsx
index 8c407e216f..275f6f0220 100644
--- a/src/frontend/src/tables/build/BuildOrderTable.tsx
+++ b/src/frontend/src/tables/build/BuildOrderTable.tsx
@@ -194,11 +194,15 @@ export function BuildOrderTable({
const user = useUserState();
- const buildOrderFields = useBuildOrderFields({ create: true });
+ const buildOrderFields = useBuildOrderFields({
+ create: true,
+ modalId: 'create-build-order'
+ });
const newBuild = useCreateApiFormModal({
url: ApiEndpoints.build_order_list,
title: t`Add Build Order`,
+ modalId: 'create-build-order',
fields: buildOrderFields,
initialData: {
part: partId,
diff --git a/src/frontend/src/tables/build/BuildOutputTable.tsx b/src/frontend/src/tables/build/BuildOutputTable.tsx
index 22ebbef86b..59aadfe8e4 100644
--- a/src/frontend/src/tables/build/BuildOutputTable.tsx
+++ b/src/frontend/src/tables/build/BuildOutputTable.tsx
@@ -256,11 +256,15 @@ export default function BuildOutputTable({
[partId, buildId, testTemplates, trackedItems]
);
- const buildOutputFields = useBuildOrderOutputFields({ build: build });
+ const buildOutputFields = useBuildOrderOutputFields({
+ build: build,
+ modalId: 'add-build-output'
+ });
const addBuildOutput = useCreateApiFormModal({
url: apiUrl(ApiEndpoints.build_output_create, buildId),
title: t`Add Build Output`,
+ modalId: 'add-build-output',
fields: buildOutputFields,
timeout: 10000,
initialData: {
@@ -302,13 +306,15 @@ export default function BuildOutputTable({
const editStockItemFields = useStockFields({
create: false,
partId: partId,
- stockItem: selectedOutputs[0]
+ stockItem: selectedOutputs[0],
+ modalId: 'edit-build-output'
});
const editBuildOutput = useEditApiFormModal({
url: ApiEndpoints.stock_item_list,
pk: selectedOutputs[0]?.pk,
title: t`Edit Build Output`,
+ modalId: 'edit-build-output',
fields: editStockItemFields,
table: table
});
diff --git a/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx b/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx
index 1872c3b6bd..a727513c10 100644
--- a/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx
+++ b/src/frontend/src/tables/sales/SalesOrderLineItemTable.tsx
@@ -276,11 +276,15 @@ export default function SalesOrderLineItemTable({
table: table
});
- const buildOrderFields = useBuildOrderFields({ create: true });
+ const buildOrderFields = useBuildOrderFields({
+ create: true,
+ modalId: 'build-order-create-from-sales-order'
+ });
const newBuildOrder = useCreateApiFormModal({
url: ApiEndpoints.build_order_list,
title: t`Create Build Order`,
+ modalId: 'build-order-create-from-sales-order',
fields: buildOrderFields,
initialData: initialData,
follow: true,
diff --git a/src/frontend/src/tables/stock/StockItemTable.tsx b/src/frontend/src/tables/stock/StockItemTable.tsx
index 53adb8f38a..9d2479811d 100644
--- a/src/frontend/src/tables/stock/StockItemTable.tsx
+++ b/src/frontend/src/tables/stock/StockItemTable.tsx
@@ -526,12 +526,14 @@ export function StockItemTable({
const newStockItemFields = useStockFields({
create: true,
- partId: params.part
+ partId: params.part,
+ modalId: 'add-stock-item'
});
const newStockItem = useCreateApiFormModal({
url: ApiEndpoints.stock_item_list,
title: t`Add Stock Item`,
+ modalId: 'add-stock-item',
fields: newStockItemFields,
initialData: {
part: params.part,