@@ -35,7 +35,7 @@ import CloudUploadIcon from '@mui/icons-material/CloudUpload';
35
35
import IosShare from '@mui/icons-material/IosShare' ;
36
36
import LinkOffIcon from '@mui/icons-material/LinkOff' ;
37
37
import DeleteIcon from '@mui/icons-material/Delete' ;
38
- import { useEffect , useState } from 'react' ;
38
+ import { useEffect , useState , useCallback } from 'react' ;
39
39
import { SerializedPart } from '../types' ;
40
40
import { SerializedPartTwinRead } from '../types/twin-types' ;
41
41
import { createSerializedPartTwin , shareSerializedPartTwin , unshareSerializedPartTwin , deleteSerializedPart , fetchAllSerializedPartTwins } from '../api' ;
@@ -61,6 +61,23 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
61
61
const [ twinUnsharingId , setTwinUnsharingId ] = useState < number | null > ( null ) ;
62
62
const [ partDeletingId , setPartDeletingId ] = useState < number | null > ( null ) ;
63
63
64
+ // Helper function to fetch twins for all unique parts in the table
65
+ const fetchTwinsForParts = useCallback ( async ( ) : Promise < SerializedPartTwinRead [ ] > => {
66
+ const uniqueParts = Array . from (
67
+ new Set ( parts . map ( p => `${ p . manufacturerId } -${ p . manufacturerPartId } ` ) )
68
+ ) . map ( key => {
69
+ const [ manufacturerId , manufacturerPartId ] = key . split ( '-' ) ;
70
+ return { manufacturerId, manufacturerPartId } ;
71
+ } ) ;
72
+
73
+ const allTwins : SerializedPartTwinRead [ ] = [ ] ;
74
+ for ( const { manufacturerId, manufacturerPartId } of uniqueParts ) {
75
+ const twins = await fetchAllSerializedPartTwins ( manufacturerId , manufacturerPartId ) ;
76
+ allTwins . push ( ...twins ) ;
77
+ }
78
+ return allTwins ;
79
+ } , [ parts ] ) ;
80
+
64
81
// Determine twin status based on twin data
65
82
const determineTwinStatus = ( serializedPart : SerializedPart , twins : SerializedPartTwinRead [ ] ) : { status : StatusVariants ; globalId ?: string } => {
66
83
const twin = twins . find (
@@ -83,12 +100,12 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
83
100
useEffect ( ( ) => {
84
101
const loadTwinData = async ( ) => {
85
102
try {
86
- // Fetch all twins to determine status
87
- const twins = await fetchAllSerializedPartTwins ( ) ;
103
+ // Fetch twins for the specific parts being displayed
104
+ const allTwins = await fetchTwinsForParts ( ) ;
88
105
89
106
// Merge serialized parts with twin status
90
107
const rowsWithStatus = parts . map ( ( serializedPart , index ) => {
91
- const { status, globalId } = determineTwinStatus ( serializedPart , twins ) ;
108
+ const { status, globalId } = determineTwinStatus ( serializedPart , allTwins ) ;
92
109
return {
93
110
...serializedPart ,
94
111
id : serializedPart . id || index ,
@@ -115,7 +132,7 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
115
132
} ;
116
133
117
134
loadTwinData ( ) ;
118
- } , [ parts ] ) ;
135
+ } , [ parts , fetchTwinsForParts ] ) ;
119
136
120
137
const handleCreateTwin = async ( row : SerializedPartWithStatus ) => {
121
138
setTwinCreatingId ( row . id ) ;
@@ -126,10 +143,11 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
126
143
partInstanceId : row . partInstanceId ,
127
144
} ) ;
128
145
129
- // Refresh twin data after successful creation
130
- const twins = await fetchAllSerializedPartTwins ( ) ;
146
+ // Refresh twin data after successful creation - reload all twins for this table
147
+ const allTwins = await fetchTwinsForParts ( ) ;
148
+
131
149
const rowsWithStatus = parts . map ( ( serializedPart , index ) => {
132
- const { status, globalId } = determineTwinStatus ( serializedPart , twins ) ;
150
+ const { status, globalId } = determineTwinStatus ( serializedPart , allTwins ) ;
133
151
return {
134
152
...serializedPart ,
135
153
id : serializedPart . id || index ,
@@ -159,7 +177,7 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
159
177
} ) ;
160
178
161
179
// Refresh twin data after successful share
162
- const twins = await fetchAllSerializedPartTwins ( ) ;
180
+ const twins = await fetchTwinsForParts ( ) ;
163
181
const rowsWithStatus = parts . map ( ( serializedPart , index ) => {
164
182
const { status, globalId } = determineTwinStatus ( serializedPart , twins ) ;
165
183
return {
@@ -185,7 +203,7 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
185
203
setTwinUnsharingId ( row . id ) ;
186
204
try {
187
205
// Find the twin to get the AAS ID
188
- const twins = await fetchAllSerializedPartTwins ( ) ;
206
+ const twins = await fetchTwinsForParts ( ) ;
189
207
const twin = twins . find (
190
208
( t ) => t . manufacturerId === row . manufacturerId &&
191
209
t . manufacturerPartId === row . manufacturerPartId &&
@@ -207,7 +225,7 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
207
225
} ) ;
208
226
209
227
// Refresh twin data after successful unshare
210
- const updatedTwins = await fetchAllSerializedPartTwins ( ) ;
228
+ const updatedTwins = await fetchTwinsForParts ( ) ;
211
229
const rowsWithStatus = parts . map ( ( serializedPart , index ) => {
212
230
const { status, globalId } = determineTwinStatus ( serializedPart , updatedTwins ) ;
213
231
return {
@@ -243,7 +261,7 @@ const SerializedPartsTable = ({ parts, onRefresh }: SerializedPartsTableProps) =
243
261
console . log ( "Delete API call successful" ) ;
244
262
245
263
// Refresh data after successful deletion
246
- const twins = await fetchAllSerializedPartTwins ( ) ;
264
+ const twins = await fetchTwinsForParts ( ) ;
247
265
const rowsWithStatus = parts . map ( ( serializedPart , index ) => {
248
266
const { status, globalId } = determineTwinStatus ( serializedPart , twins ) ;
249
267
return {
0 commit comments