diff --git a/src/frontend/src/forms/ReturnOrderForms.tsx b/src/frontend/src/forms/ReturnOrderForms.tsx
index 3377ff1f22..0fe1866b7b 100644
--- a/src/frontend/src/forms/ReturnOrderForms.tsx
+++ b/src/frontend/src/forms/ReturnOrderForms.tsx
@@ -199,7 +199,7 @@ function ReturnOrderLineItemFormRow({
label: t`Status`,
choices: statusOptions,
onValueChange: (value) => {
- props.changeFn(props.idx, 'status', value);
+ props.changeFn(props.rowId, 'status', value);
}
}}
defaultValue={record.item_detail?.status}
@@ -207,7 +207,7 @@ function ReturnOrderLineItemFormRow({
/>
- props.removeFn(props.idx)} />
+ props.removeFn(props.rowId)} />
>
@@ -226,6 +226,7 @@ export function useReceiveReturnOrderLineItems(
field_type: 'table',
value: props.items.map((item: any) => {
return {
+ id: item.pk,
item: item.pk
};
}),
@@ -236,7 +237,7 @@ export function useReceiveReturnOrderLineItems(
);
},
diff --git a/src/frontend/src/forms/SalesOrderForms.tsx b/src/frontend/src/forms/SalesOrderForms.tsx
index c6f81f2ffb..af5a73d467 100644
--- a/src/frontend/src/forms/SalesOrderForms.tsx
+++ b/src/frontend/src/forms/SalesOrderForms.tsx
@@ -26,6 +26,7 @@ import type {
} from '@lib/types/Forms';
import dayjs from 'dayjs';
import type { TableFieldRowProps } from '../components/forms/fields/TableField';
+import { useWhyDidYouUpdate } from '../functions/debug';
import useBackgroundTask from '../hooks/UseBackgroundTask';
import { useCreateApiFormModal, useEditApiFormModal } from '../hooks/UseForm';
import { useGlobalSettingsState } from '../states/SettingsStates';
@@ -310,6 +311,12 @@ function SalesOrderAllocateLineRow({
record: any;
sourceLocation?: number | null;
}>) {
+ useWhyDidYouUpdate('SalesOrderAllocateLineRow', {
+ props,
+ record,
+ sourceLocation
+ });
+
// Statically defined field for selecting the stock item
const stockItemField: ApiFormFieldType = useMemo(() => {
return {
@@ -328,28 +335,33 @@ function SalesOrderAllocateLineRow({
value: props.item.stock_item,
name: 'stock_item',
onValueChange: (value: any, instance: any) => {
- props.changeFn(props.idx, 'stock_item', value);
+ props.changeFn(props.rowId, 'stock_item', value);
// Update the allocated quantity based on the selected stock item
if (instance) {
const available = instance.quantity - instance.allocated;
const required = record.quantity - record.allocated;
- let quantity = props.item?.quantity ?? 0;
+ let q = props.item?.quantity ?? 0;
- quantity = Math.max(quantity, required);
- quantity = Math.min(quantity, available);
+ q = Math.max(q, required);
+ q = Math.min(q, available);
- if (quantity != props.item.quantity) {
- props.changeFn(props.idx, 'quantity', quantity);
+ if (q != props.item?.quantity) {
+ setQuantity(q);
+ props.changeFn(props.rowId, 'quantity', q);
}
}
}
};
}, [sourceLocation, record, props]);
+ const [quantity, setQuantity] = useState(
+ props.item?.quantity ?? ''
+ );
+
return (
-
+
@@ -373,7 +385,7 @@ function SalesOrderAllocateLineRow({
min={0}
step={1}
decimalScale={10}
- value={props.item.quantity ?? ''}
+ value={quantity}
onChange={(value: number | string) => {
let nextValue: number | '' = '';
@@ -384,13 +396,14 @@ function SalesOrderAllocateLineRow({
nextValue = Number.isFinite(parsed) ? parsed : '';
}
- props.changeFn(props.idx, 'quantity', nextValue);
+ setQuantity(nextValue);
+ props.changeFn(props.rowId, 'quantity', nextValue);
}}
error={props.rowErrors?.quantity?.message}
/>
- props.removeFn(props.idx)} />
+ props.removeFn(props.rowId)} />
);
@@ -445,7 +458,7 @@ export function useAllocateToSalesOrderForm({
return (
{
return {
+ id: item.pk,
line_item: item.pk,
quantity: 0,
stock_item: null
diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx
index 9660c3ee6c..3bdc6a0a7b 100644
--- a/src/frontend/src/forms/StockForms.tsx
+++ b/src/frontend/src/forms/StockForms.tsx
@@ -39,7 +39,6 @@ import dayjs from 'dayjs';
import {
type JSX,
Suspense,
- memo,
useCallback,
useEffect,
useMemo,
@@ -57,6 +56,7 @@ import {
import { Thumbnail } from '../components/images/Thumbnail';
import { StatusRenderer } from '../components/render/StatusRenderer';
import { RenderStockLocation } from '../components/render/Stock';
+import { useWhyDidYouUpdate } from '../functions/debug';
import { InvenTreeIcon } from '../functions/icons';
import {
useApiFormModal,
@@ -636,6 +636,18 @@ function StockOperationsRow({
}) {
const rowId = props.rowId;
+ useWhyDidYouUpdate('StockOperationsRow', {
+ props,
+ transfer,
+ changeStatus,
+ add,
+ setMax,
+ merge,
+ transferMerge,
+ returnStock,
+ record
+ });
+
const statusOptions: ApiFormFieldChoice[] = useMemo(() => {
return (
StatusFilterOptions(ModelType.stockitem)()?.map((choice) => {
@@ -878,39 +890,6 @@ function StockOperationsRow({
);
}
-// Memoize each stock operations row, so that we don't re-render the entire table when a single row is updated
-const MemoizedStockOperationsRow = memo(
- StockOperationsRow,
- (previousProps, nextProps) => {
- const prevItem = previousProps.props.item;
- const nextItem = nextProps.props.item;
-
- const itemUnchanged =
- prevItem === nextItem ||
- (prevItem?.pk === nextItem?.pk &&
- prevItem?.quantity === nextItem?.quantity &&
- prevItem?.status === nextItem?.status &&
- prevItem?.packaging === nextItem?.packaging &&
- prevItem?.merge === nextItem?.merge);
-
- return (
- previousProps.props.rowId === nextProps.props.rowId &&
- itemUnchanged &&
- previousProps.props.rowErrors === nextProps.props.rowErrors &&
- previousProps.props.changeFn === nextProps.props.changeFn &&
- previousProps.props.removeFn === nextProps.props.removeFn &&
- previousProps.record === nextProps.record &&
- previousProps.transfer === nextProps.transfer &&
- previousProps.changeStatus === nextProps.changeStatus &&
- previousProps.add === nextProps.add &&
- previousProps.setMax === nextProps.setMax &&
- previousProps.merge === nextProps.merge &&
- previousProps.transferMerge === nextProps.transferMerge &&
- previousProps.returnStock === nextProps.returnStock
- );
- }
-);
-
type StockItemQuantity = number | '' | undefined;
type StockAdjustmentItem = {
@@ -959,7 +938,7 @@ function stockTransferFields(
const record = records[row.item.pk];
return (
-
);
@@ -1146,16 +1125,14 @@ function stockAddFields(items: any[]): ApiFormFieldSet {
}
function stockCountFields(items: any[]): ApiFormFieldSet {
- if (!items) {
- return {};
- }
+ const records = Object.fromEntries(
+ items?.map((item) => [item.pk, item]) ?? []
+ );
- const records = Object.fromEntries(items.map((item) => [item.pk, item]));
-
- const initialValue = mapAdjustmentItems(items);
+ const initialValue = items ? mapAdjustmentItems(items) : [];
// Extract all location values from the items
- const locations = [...new Set(items.map((item) => item.location))];
+ const locations = [...new Set(items?.map((item) => item.location))];
const fields: ApiFormFieldSet = {
items: {
@@ -1163,11 +1140,11 @@ function stockCountFields(items: any[]): ApiFormFieldSet {
value: initialValue,
modelRenderer: (row: TableFieldRowProps) => {
return (
-
);
},
@@ -1212,7 +1189,7 @@ function stockChangeStatusFields(items: any[]): ApiFormFieldSet {
}),
modelRenderer: (row: TableFieldRowProps) => {
return (
- {
return (
- {
return (
- {
return lineItems.map((item) => {
- console.log('line:', item);
return {
id: item.pk,
...item