@chenchaolong/plugin-trade-compliance-workbench 1.0.148 → 1.0.150

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -153,6 +153,8 @@ function App() {
153
153
  }
154
154
  });
155
155
  const changeRouteRef = React.useRef(() => undefined);
156
+ const taskStateRefreshInFlightRef = React.useRef(null);
157
+ const taskStateRefreshQueuedRef = React.useRef(false);
156
158
  const [procurementContext, setProcurementContext] = React.useState({ supplier: null, order: null, metrics: null });
157
159
  const [purchaseImportTask, setPurchaseImportTask] = React.useState(null);
158
160
  const [purchaseReviewDraft, setPurchaseReviewDraft] = React.useState(null);
@@ -280,6 +282,23 @@ function App() {
280
282
  return normalized.importTasks;
281
283
  }
282
284
  }, []);
285
+ const pruneTaskTrackingState = React.useCallback((tasks) => {
286
+ const currentTaskIds = new Set(tasks.map(task => task.id));
287
+ for (const taskId of handledContractTasksRef.current) {
288
+ if (!currentTaskIds.has(taskId))
289
+ handledContractTasksRef.current.delete(taskId);
290
+ }
291
+ const currentRevisions = new Set();
292
+ for (const task of tasks) {
293
+ const revision = taskBusinessRefreshRevision(task);
294
+ if (revision)
295
+ currentRevisions.add(revision);
296
+ }
297
+ for (const revision of refreshedTaskBusinessRevisionsRef.current) {
298
+ if (!currentRevisions.has(revision))
299
+ refreshedTaskBusinessRevisionsRef.current.delete(revision);
300
+ }
301
+ }, []);
283
302
  const configureSalesFilesPrototypeCapability = React.useCallback((parameters) => {
284
303
  salesFilesPrototypeListenerCleanupRef.current?.();
285
304
  salesFilesPrototypeListenerCleanupRef.current = null;
@@ -378,7 +397,7 @@ function App() {
378
397
  setBusy(gate.activeCount() + routeRequestGateRef.current.activeCount() + analyticsRequestsRef.current.activeCount() > 0);
379
398
  }
380
399
  }, [loadImportTasksFallback, loadRoute]);
381
- const loadTaskState = React.useCallback(async () => {
400
+ const loadTaskStateCore = React.useCallback(async () => {
382
401
  const active = contextRef.current;
383
402
  if (!active)
384
403
  return false;
@@ -414,6 +433,21 @@ function App() {
414
433
  gate.finish(requestId);
415
434
  }
416
435
  }, [loadImportTasksFallback]);
436
+ const loadTaskState = React.useCallback(async () => {
437
+ if (taskStateRefreshInFlightRef.current) {
438
+ taskStateRefreshQueuedRef.current = true;
439
+ return taskStateRefreshInFlightRef.current;
440
+ }
441
+ const run = loadTaskStateCore();
442
+ taskStateRefreshInFlightRef.current = run;
443
+ return run.finally(() => {
444
+ taskStateRefreshInFlightRef.current = null;
445
+ if (!taskStateRefreshQueuedRef.current)
446
+ return;
447
+ taskStateRefreshQueuedRef.current = false;
448
+ void loadTaskState();
449
+ });
450
+ }, [loadTaskStateCore]);
417
451
  const scheduleTaskStateRecovery = React.useCallback(() => {
418
452
  if (taskRecoveryTimerRef.current != null)
419
453
  return;
@@ -430,7 +464,8 @@ function App() {
430
464
  }, [loadTaskState]);
431
465
  React.useEffect(() => {
432
466
  importTaskItemsRef.current = data.importTasks.items;
433
- }, [data.importTasks.items]);
467
+ pruneTaskTrackingState(data.importTasks.items);
468
+ }, [data.importTasks.items, pruneTaskTrackingState]);
434
469
  React.useEffect(() => {
435
470
  void syncSelectedTaskForChat(taskChatSynchronizerRef.current, data.importTasks.items).catch(notifyTaskStatusActionError);
436
471
  }, [data.importTasks.items, notifyTaskStatusActionError]);
@@ -472,6 +507,8 @@ function App() {
472
507
  const normalized = normalizeWorkbenchData(nextContext.payload);
473
508
  bridge.configure({ uploadPolicy: normalized.uploadPolicy });
474
509
  setData(current => mergeWorkbenchDataWithLocalTasks(current, normalized, deletedImportTaskIdsRef.current));
510
+ if (normalized.importTasks.items.length === 0)
511
+ void loadTaskState();
475
512
  }
476
513
  });
477
514
  return () => {
@@ -936,6 +973,11 @@ function App() {
936
973
  }
937
974
  }, [applyCustomerContractReanalysisResult, consumeCustomerContractReanalysisResult, loadTaskState, runMutation, scheduleTaskStateRecovery]);
938
975
  React.useEffect(() => {
976
+ const currentRunIds = new Set(data.customerContractAnalyses.items.map(recovery => recovery.run.id));
977
+ for (const runId of handledReanalysisResultsRef.current) {
978
+ if (!currentRunIds.has(runId))
979
+ handledReanalysisResultsRef.current.delete(runId);
980
+ }
939
981
  for (const recovery of data.customerContractAnalyses.items) {
940
982
  const recoverable = recovery.recoveryType === 'ACTIVE_POLL' || recovery.recoveryType === 'SUCCEEDED_RESULT';
941
983
  if (!recoverable)