From 476a01eafbf2bc02af9b9fed043f417e199a1868 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sat, 20 Jun 2026 22:36:48 +0100 Subject: [PATCH] Fixed warnings and bugs. --- .../Dashboard/common/ObjectChildTable.jsx | 56 ++++++++++++++++--- .../Dashboard/context/AuthContext.jsx | 5 +- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/components/Dashboard/common/ObjectChildTable.jsx b/src/components/Dashboard/common/ObjectChildTable.jsx index 6b80f1a..ab519a6 100644 --- a/src/components/Dashboard/common/ObjectChildTable.jsx +++ b/src/components/Dashboard/common/ObjectChildTable.jsx @@ -68,6 +68,38 @@ const ObjectChildTable = ({ }) => { const mainTableWrapperRef = useRef(null) const rollupTableWrapperRef = useRef(null) + const generatedRowKeysRef = useRef(new WeakMap()) + const generatedRowKeyCountRef = useRef(0) + + const getFallbackRowKey = (record) => { + if (!record || typeof record !== 'object') { + return `object-child-table-row-${String(record)}` + } + + if (record._objectChildTableKey != null) { + return record._objectChildTableKey + } + + const existing = generatedRowKeysRef.current.get(record) + if (existing) return existing + + const generated = `object-child-table-row-${generatedRowKeyCountRef.current}` + generatedRowKeyCountRef.current += 1 + generatedRowKeysRef.current.set(record, generated) + return generated + } + + const getResolvedRecordKey = (record) => { + if (typeof rowKey === 'function') { + return rowKey(record) ?? getFallbackRowKey(record) + } + + if (typeof rowKey === 'string' && rowKey.length > 0) { + return record?.[rowKey] ?? getFallbackRowKey(record) + } + + return getFallbackRowKey(record) + } const propertyMap = useMemo(() => { const map = new Map() @@ -130,10 +162,14 @@ const ObjectChildTable = ({ const currentItems = Array.isArray(itemsSource) ? [...itemsSource] : [] + const existingRowKey = getResolvedRecordKey(record) const updatedItem = { ...currentItems[index], [property.name]: resolved } + // Preserve fallback row identity across immutable updates so the row + // is not remounted while typing (which causes input focus loss). + generatedRowKeysRef.current.set(updatedItem, existingRowKey) currentItems[index] = updatedItem if (typeof onChange === 'function') { onChange(currentItems) @@ -186,10 +222,11 @@ const ObjectChildTable = ({ (item) => item[rowKey] !== record[rowKey] ) } else if (typeof rowKey === 'function') { - // If rowKey is a function, find the item by comparing the resolved keys - const recordKey = rowKey(record, index) - newItems = currentItems.filter((item, i) => { - const itemKey = rowKey(item, i) + // If rowKey is a function, find the item by comparing resolved keys. + // Ant Design deprecates index-based rowKey callbacks. + const recordKey = getResolvedRecordKey(record) + newItems = currentItems.filter((item) => { + const itemKey = getResolvedRecordKey(item) return itemKey !== recordKey }) } else { @@ -216,6 +253,7 @@ const ObjectChildTable = ({ resolvedProperties, additionalColumns, isEditing, + canAddRemove, itemsSource, onChange, rowKey @@ -237,7 +275,7 @@ const ObjectChildTable = ({ }, [itemsSource, loading, skeletonData]) const resolvedRowKey = - typeof rowKey === 'function' ? rowKey : (_record, index) => index + (record) => getResolvedRecordKey(record) const scrollConfig = scrollHeight != null @@ -281,7 +319,9 @@ const ObjectChildTable = ({ // Single summary row where each rollup value is placed under // the column that matches its `property` field. - const summaryRow = {} + const summaryRow = { + _objectChildTableKey: 'object-child-table-rollup-summary' + } properties.forEach((property) => { const rollup = rollups.find( @@ -354,7 +394,7 @@ const ObjectChildTable = ({ ...propertyColumns, ...(blankDeleteColumn ? [blankDeleteColumn] : []) ] - }, [properties, rollups, isEditing]) + }, [properties, rollups, isEditing, canAddRemove]) const hasRollups = useMemo( () => Array.isArray(rollups) && rollups.length > 0, @@ -414,7 +454,7 @@ const ObjectChildTable = ({ dataSource={rollupDataSource} showHeader={false} columns={rollupColumns} - loading={{ spinning: loading, indicator: <> }} + loading={{ spinning: loading, indicator: null }} pagination={false} size={size} rowKey={resolvedRowKey} diff --git a/src/components/Dashboard/context/AuthContext.jsx b/src/components/Dashboard/context/AuthContext.jsx index 2f264b0..dacb516 100644 --- a/src/components/Dashboard/context/AuthContext.jsx +++ b/src/components/Dashboard/context/AuthContext.jsx @@ -291,6 +291,9 @@ const AuthProvider = ({ children }) => { }) }, [authenticated, token, expiresAt, userProfile, persistSession]) + const profileImageDependency = + userProfile?.profileImage?._id ?? userProfile?.profileImage + // Fetch and cache profile image when userProfile.profileImage changes useEffect(() => { const profileImage = userProfile?.profileImage @@ -365,7 +368,7 @@ const AuthProvider = ({ children }) => { } setProfileImageUrl(null) } - }, [userProfile?.profileImage?._id ?? userProfile?.profileImage, token]) + }, [profileImageDependency, token]) useEffect(() => { console.log('userProfile', userProfile)