@topconsultnpm/sdkui-react 6.20.0-dev1.6 → 6.20.0-dev1.60

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.
Files changed (84) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.d.ts +4 -0
  2. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +416 -0
  3. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +13 -0
  4. package/lib/components/NewComponents/ContextMenu/hooks.js +61 -0
  5. package/lib/components/NewComponents/ContextMenu/index.d.ts +5 -0
  6. package/lib/components/NewComponents/ContextMenu/index.js +3 -0
  7. package/lib/components/NewComponents/ContextMenu/styles.d.ts +31 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.js +336 -0
  9. package/lib/components/NewComponents/ContextMenu/types.d.ts +39 -0
  10. package/lib/components/NewComponents/ContextMenu/types.js +1 -0
  11. package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
  12. package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
  13. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.d.ts +4 -0
  14. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +745 -0
  15. package/lib/components/NewComponents/FloatingMenuBar/index.d.ts +2 -0
  16. package/lib/components/NewComponents/FloatingMenuBar/index.js +2 -0
  17. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +51 -0
  18. package/lib/components/NewComponents/FloatingMenuBar/styles.js +385 -0
  19. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +29 -0
  20. package/lib/components/NewComponents/FloatingMenuBar/types.js +1 -0
  21. package/lib/components/base/TMAccordionNew.js +35 -14
  22. package/lib/components/base/TMCustomButton.js +61 -17
  23. package/lib/components/base/TMDataGrid.d.ts +7 -4
  24. package/lib/components/base/TMDataGrid.js +142 -11
  25. package/lib/components/choosers/TMMetadataChooser.js +8 -1
  26. package/lib/components/editors/TMMetadataValues.js +23 -5
  27. package/lib/components/editors/TMTextBox.js +6 -3
  28. package/lib/components/features/documents/TMDcmtForm.d.ts +13 -1
  29. package/lib/components/features/documents/TMDcmtForm.js +386 -194
  30. package/lib/components/features/documents/TMDcmtPreview.js +40 -69
  31. package/lib/components/features/documents/TMMasterDetailDcmts.js +37 -52
  32. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
  33. package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +5 -10
  34. package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
  35. package/lib/components/features/search/TMSearch.js +30 -5
  36. package/lib/components/features/search/TMSearchQueryPanel.js +13 -12
  37. package/lib/components/features/search/TMSearchResult.js +57 -216
  38. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
  39. package/lib/components/features/search/TMSearchResultsMenuItems.js +205 -169
  40. package/lib/components/features/search/TMSignSettingsForm.js +1 -1
  41. package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
  42. package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
  43. package/lib/components/features/search/TMViewHistoryDcmt.js +1 -1
  44. package/lib/components/features/tasks/TMTaskForm.js +20 -1
  45. package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
  46. package/lib/components/features/tasks/TMTasksUtils.js +62 -52
  47. package/lib/components/features/tasks/TMTasksView.js +6 -6
  48. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +32 -2
  49. package/lib/components/features/workflow/TMWorkflowPopup.js +112 -14
  50. package/lib/components/features/workflow/diagram/WFDiagram.js +2 -2
  51. package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
  52. package/lib/components/forms/Login/LoginValidatorService.js +7 -2
  53. package/lib/components/forms/Login/TMLoginForm.js +34 -6
  54. package/lib/components/forms/TMChooserForm.js +1 -1
  55. package/lib/components/grids/TMBlogsPost.js +55 -30
  56. package/lib/components/index.d.ts +2 -0
  57. package/lib/components/index.js +2 -0
  58. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  59. package/lib/components/viewers/TMDataListItemViewer.js +12 -11
  60. package/lib/css/tm-sdkui.css +1 -1
  61. package/lib/helper/SDKUI_Globals.d.ts +17 -0
  62. package/lib/helper/SDKUI_Globals.js +9 -0
  63. package/lib/helper/SDKUI_Localizator.d.ts +9 -1
  64. package/lib/helper/SDKUI_Localizator.js +87 -1
  65. package/lib/helper/TMIcons.d.ts +2 -0
  66. package/lib/helper/TMIcons.js +6 -0
  67. package/lib/helper/TMPdfViewer.d.ts +8 -0
  68. package/lib/helper/TMPdfViewer.js +368 -0
  69. package/lib/helper/checkinCheckoutManager.d.ts +32 -2
  70. package/lib/helper/checkinCheckoutManager.js +115 -38
  71. package/lib/helper/devextremeCustomMessages.d.ts +30 -0
  72. package/lib/helper/devextremeCustomMessages.js +30 -0
  73. package/lib/helper/helpers.d.ts +2 -1
  74. package/lib/helper/helpers.js +14 -3
  75. package/lib/helper/index.d.ts +1 -0
  76. package/lib/helper/index.js +1 -0
  77. package/lib/helper/queryHelper.js +29 -0
  78. package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
  79. package/lib/hooks/useCheckInOutOperations.js +223 -0
  80. package/lib/hooks/useWorkflowApprove.d.ts +4 -0
  81. package/lib/hooks/useWorkflowApprove.js +14 -1
  82. package/lib/ts/types.d.ts +56 -1
  83. package/package.json +5 -2
  84. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
@@ -1,15 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import TMDcmtPreview from './TMDcmtPreview';
4
- import { AccessLevels, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataTypes, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TemplateTIDs, TID_DID, UpdateEngineByID, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
5
- import { ContextMenu } from 'devextreme-react';
4
+ import { AccessLevels, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataTypes, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TID_DID, UpdateEngineByID, UserListCacheService, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
6
5
  import { WorkFlowApproveRejectPopUp, WorkFlowMoreInfoPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../workflow/TMWorkflowPopup';
7
6
  import { DownloadTypes, FormModes, DcmtOperationTypes } from '../../../ts';
8
7
  import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
9
8
  import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
10
9
  import { useRelatedDocuments } from '../../../hooks/useRelatedDocuments';
11
10
  import { getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
12
- import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, svgToString, IconDownload, calcIsModified, IconMenuVertical, Globalization, getListMaxItems, getSystemMetadata, IconBoxArchiveIn, IconClear, IconUndo, SDKUI_Globals, IconPreview, isTaskMoreInfo, IconWorkflow, IconSearch, deepCompare, IconCheck, IconActivity, TMImageLibrary, IconStar, IconRelation, IconInfo, IconArchiveDoc, IconDelete, IconPair, IconUnpair, IconArchiveMaster, IconArchiveDetail } from '../../../helper';
11
+ import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, IconDownload, calcIsModified, IconMenuVertical, Globalization, getListMaxItems, getSystemMetadata, IconBoxArchiveIn, IconClear, IconUndo, SDKUI_Globals, IconPreview, isTaskMoreInfo, IconWorkflow, IconSearch, deepCompare, IconCheck, IconActivity, TMImageLibrary, IconStar, IconRelation, IconInfo, IconArchiveDoc, IconDelete, IconPair, IconUnpair, IconArchiveMaster, IconArchiveDetail, getExceptionMessage, isApprovalWorkflowView, getDcmtCicoStatus, IconFileDots, IconCustom } from '../../../helper';
13
12
  import { hasDetailRelations, hasMasterRelations, isXMLFileExt } from '../../../helper/dcmtsHelper';
14
13
  import { Gutters, TMColors } from '../../../utils/theme';
15
14
  import { StyledFormButtonsContainer, StyledLoadingContainer, StyledModalContainer, StyledReferenceButton, StyledSpinner, StyledToolbarCardContainer } from '../../base/Styled';
@@ -42,9 +41,30 @@ import TMToppyMessage from '../../../helper/TMToppyMessage';
42
41
  import { getTaskAssignedToMe } from '../tasks/TMTasksUtils';
43
42
  import TMCustomButton from '../../base/TMCustomButton';
44
43
  import ToppyDraggableHelpCenter from '../assistant/ToppyDraggableHelpCenter';
44
+ import { useCheckInOutOperations } from '../../../hooks/useCheckInOutOperations';
45
+ import TMViewHistoryDcmt from '../search/TMViewHistoryDcmt';
46
+ import TMDcmtCheckoutInfoForm from '../search/TMDcmtCheckoutInfoForm';
47
+ import styled from 'styled-components';
48
+ import { ContextMenu } from '../../NewComponents/ContextMenu';
49
+ //#region Interfaces, Types and Enums
50
+ /**
51
+ * Definisce il contesto da cui è stato invocato il TMDcmtForm.
52
+ * Permette di gestire logiche diverse in base alla provenienza.
53
+ */
54
+ export var InvocationContext;
55
+ (function (InvocationContext) {
56
+ /** Invocazione standard */
57
+ InvocationContext["Default"] = "default";
58
+ /** Invocato dalla pagina Todo/Task */
59
+ InvocationContext["Todo"] = "todo";
60
+ /** Invocato dalla pagina WorkflowCtrl */
61
+ InvocationContext["WorkflowCtrl"] = "workflowCtrl";
62
+ // Aggiungi qui altri contesti futuri secondo necessità
63
+ })(InvocationContext || (InvocationContext = {}));
45
64
  let abortControllerLocal = new AbortController();
46
65
  //#endregion
47
- const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, showHeader = true, onSaveRecents, layoutMode = LayoutModes.Update, showBackButton = true, onClose, onSavedAsyncCallback, TID, DID, formMode = FormModes.Update, canNext, canPrev, count, itemIndex, onNext, onPrev, allowNavigation = true, allowRelations = true, isClosable = false, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, showDcmtFormSidebar = true, invokedByTodo = false, titleModal, isModal = false, widthModal = "100%", heightModal = "100%", groupId, onWFOperationCompleted, onTaskCompleted, onTaskCreateRequest, inputFile = null, taskFormDialogComponent, taskMoreInfo, connectorFileSave = undefined, inputMids = [], openS4TViewer = false, onOpenS4TViewerRequest, s4TViewerDialogComponent, enableDragDropOverlay = false, passToSearch, isSharedDcmt = false, sharedSourceTID, sharedSourceDID, allowButtonsRefs = false, onReferenceClick, }) => {
66
+ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, showHeader = true, onSaveRecents, layoutMode = LayoutModes.Update, showBackButton = true, onClose, onSavedAsyncCallback, TID, DID, formMode = FormModes.Update, canNext, canPrev, count, itemIndex, onNext, onPrev, allowNavigation = true, allowRelations = true, isClosable = false, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, showDcmtFormSidebar = true, invocationContext = InvocationContext.Default, titleModal, isModal = false, widthModal = "100%", heightModal = "100%", groupId, onWFOperationCompleted, onTaskCompleted, onTaskCreateRequest, inputFile = null, taskFormDialogComponent, taskMoreInfo, connectorFileSave = undefined, inputMids = [], openS4TViewer = false, onOpenS4TViewerRequest, s4TViewerDialogComponent, enableDragDropOverlay = false, passToSearch, isSharedDcmt = false, sharedSourceTID, sharedSourceDID, allowButtonsRefs = false, onReferenceClick, }) => {
67
+ const { showHistory, showHistoryCallback, hideHistoryCallback, showCheckoutInformationForm, commentFormState, hideCommentFormCallback, showCheckoutInformationFormCallback, hideCheckoutInformationFormCallback, copyCheckoutPathToClipboardCallback, handleCheckOutCallback, handleCheckInCallback, refreshPreviewTrigger, showCicoWaitPanel, cicoWaitPanelTitle, showCicoPrimaryProgress, cicoPrimaryProgressText, cicoPrimaryProgressValue, cicoPrimaryProgressMax, } = useCheckInOutOperations();
48
68
  const [id, setID] = useState('');
49
69
  const [showWaitPanelLocal, setShowWaitPanelLocal] = useState(false);
50
70
  const [waitPanelTitleLocal, setWaitPanelTitleLocal] = useState('');
@@ -68,6 +88,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
68
88
  const [layout, setLayout] = useState();
69
89
  const [customButtonsLayout, setCustomButtonsLayout] = useState();
70
90
  const [customButton, setCustomButton] = useState();
91
+ const [allUsers, setAllUsers] = useState([]);
71
92
  const appliedInputMidsRef = useRef(null);
72
93
  // Refs per evitare stale closure nei callback
73
94
  // I useCallback catturano i valori delle dipendenze al momento della creazione.
@@ -98,16 +119,24 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
98
119
  const [dcmtReferences, setDcmtReferences] = useState(undefined);
99
120
  // Stato per triggerare il refresh del blog dall'esterno
100
121
  const [refreshBlogTrigger, setRefreshBlogTrigger] = useState(0);
122
+ const [wfError, setWfError] = useState(null);
101
123
  const triggerBlogRefresh = useCallback(async () => {
102
124
  setRefreshBlogTrigger(prev => prev + 1);
103
125
  }, []);
126
+ useEffect(() => {
127
+ const fetchAllUsers = async () => {
128
+ const users = await UserListCacheService.GetAllAsync();
129
+ setAllUsers(users ?? []);
130
+ };
131
+ fetchAllUsers();
132
+ }, []);
104
133
  useEffect(() => {
105
134
  if (!allowButtonsRefs)
106
135
  setDcmtReferences(undefined);
107
136
  }, [allowButtonsRefs]);
108
137
  const { openConfirmAttachmentsDialog, ConfirmAttachmentsDialog } = useInputAttachmentsDialog();
109
138
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync } = useDcmtOperations();
110
- const { workflowApproveData } = useWorkflowApprove();
139
+ const { workflowApproveData, getWorkItemsByDID } = useWorkflowApprove();
111
140
  const currentSearchResults = useMemo(() => {
112
141
  if (!formData || formData.length === 0 || !TID || !DID)
113
142
  return [];
@@ -124,7 +153,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
124
153
  selectMIDs: selectMIDs,
125
154
  dtdResult: {
126
155
  rows: [rowValues],
127
- columns: selectMIDs.map(mid => ({ name: `MID_${mid}` }))
156
+ columns: selectMIDs.map(mid => ({ name: `MID_${mid}`, }))
128
157
  },
129
158
  dcmtsFound: 1,
130
159
  dcmtsReturned: 1
@@ -410,74 +439,125 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
410
439
  const workItemSetIDValue = useMemo(() => formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [formData]);
411
440
  // Valore derivato: true se formData ha elementi validi
412
441
  const hasFormData = useMemo(() => formData.length > 0 && formData.some(md => md.mid && md.mid > 99), [formData]);
442
+ const handleCheckOutOperationCallback = async (checkout) => {
443
+ if (!currentDcmt)
444
+ return;
445
+ await handleCheckOutCallback({ TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt }, checkout, fromDTD?.name ?? SDKUI_Localizator.SearchResult, downloadDcmtsAsync, updateCurrentDcmt);
446
+ };
447
+ const handleCheckInOperationCallback = async () => {
448
+ if (!currentDcmt)
449
+ return;
450
+ await handleCheckInCallback({ TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt, fileName: fromDTD?.name ?? SDKUI_Localizator.SearchResult }, updateCurrentDcmt, undefined);
451
+ };
452
+ const copyCheckoutPathToClipboardOperationCallback = () => {
453
+ if (!currentDcmt)
454
+ return;
455
+ copyCheckoutPathToClipboardCallback({ TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt }, fromDTD?.name ?? SDKUI_Localizator.SearchResult);
456
+ };
457
+ // useEffect per il caricamento dei dati del workflow
413
458
  useEffect(() => {
459
+ // Funzione helper per caricare le informazioni del workflow
460
+ const loadWorkflowInfo = async (tid) => {
461
+ await WorkflowCacheService.GetWFInfoAsync(tid)
462
+ .then((result) => {
463
+ if (result) {
464
+ setWorkflows([result]);
465
+ setWfError(null);
466
+ }
467
+ else {
468
+ setWorkflows([]);
469
+ setWfError("Workflow info not found");
470
+ }
471
+ })
472
+ .catch(error => {
473
+ setWorkflows([]);
474
+ console.log("Error fetching workflow info:", error);
475
+ setWfError(getExceptionMessage(error));
476
+ });
477
+ };
414
478
  const loadAllWfData = async () => {
415
- if (layoutMode !== LayoutModes.Update || !DID || fromDTD?.templateTID !== TemplateTIDs.WF_WIApprView) {
479
+ // FASE 1: Validazione prerequisiti
480
+ if (layoutMode !== LayoutModes.Update || !DID) {
416
481
  setWorkItems([]);
417
482
  setWorkflows([]);
418
483
  return;
419
484
  }
420
485
  setIsWFDataLoading(true);
421
486
  try {
422
- // 1. item da processare in modo sincrono
423
- const itemsToProcess = [];
424
- for (const workflow of workflowApproveData) {
425
- for (const dataRow of workflow.dtdResult?.rows ?? []) {
426
- const did = Number(dataRow?.[1]);
427
- if (did === Number(DID)) {
428
- const tid = Number(dataRow?.[0]);
429
- itemsToProcess.push({ tid, did });
430
- }
431
- }
432
- }
487
+ // FASE 2: Raccolta work items: array di tutti i possibili work items che matchano il DID corrente
488
+ const itemsToProcess = getWorkItemsByDID(Number(DID));
489
+ // Se non ci sono work items per questo DID, resetta e esci
433
490
  if (itemsToProcess.length === 0) {
434
491
  setWorkItems([]);
435
492
  setWorkflows([]);
436
493
  setIsWFDataLoading(false);
437
494
  return;
438
495
  }
439
- // promises per i setID in modo condizionale
440
- let setIDPromises;
441
- if (workItemSetIDValue !== undefined) {
442
- // Se abbiamo il setID dal form, non facciamo chiamate di rete.
443
- setIDPromises = itemsToProcess.map(() => Promise.resolve(workItemSetIDValue));
496
+ // FASE 3: Ricerca work item specifico
497
+ // Cerca prima un match esatto con TID e DID correnti
498
+ const foundItem = itemsToProcess.find(item => item.tid === Number(TID) && item.did === Number(DID));
499
+ if (foundItem) {
500
+ // SCENARIO A: Match esatto trovato (TID e DID corrispondono)
501
+ // Il documento corrente è esattamente il work item nel workflow
502
+ let setID = undefined;
503
+ // Prova a usare il setID già presente nei metadati (più veloce)
504
+ if (workItemSetIDValue !== undefined) {
505
+ setID = workItemSetIDValue;
506
+ }
507
+ else {
508
+ // Altrimenti caricalo dal server
509
+ setID = await getWorkItemSetIDAsync(foundItem.tid, foundItem.did);
510
+ }
511
+ // Imposta un singolo work item con il setID caricato
512
+ setWorkItems([{ ...foundItem, setID }]);
513
+ // Carica le informazioni complete del workflow
514
+ await loadWorkflowInfo(foundItem.tid);
444
515
  }
445
516
  else {
446
- // Altrimenti, procediamo con le chiamate di rete come prima.
447
- setIDPromises = itemsToProcess.map(item => getWorkItemSetIDAsync(item.tid, item.did));
517
+ // SCENARIO B: Nessun match esatto, cerca solo per DID
518
+ const itemsByDID = itemsToProcess.filter(item => item.did === Number(DID));
519
+ if (itemsByDID.length === 1) {
520
+ // SCENARIO B.1: Un solo item trovato per DID
521
+ // Situazione sicura: sappiamo esattamente quale work item usare
522
+ const singleItem = itemsByDID[0];
523
+ let setID;
524
+ // Carica il setID (da cache o da server)
525
+ if (workItemSetIDValue !== undefined) {
526
+ setID = workItemSetIDValue;
527
+ }
528
+ else {
529
+ setID = await getWorkItemSetIDAsync(singleItem.tid, singleItem.did);
530
+ }
531
+ setWorkItems([{ ...singleItem, setID }]);
532
+ // Carica le informazioni del workflow
533
+ await loadWorkflowInfo(singleItem.tid);
534
+ }
535
+ else if (itemsByDID.length > 1) {
536
+ // SCENARIO B.2: Più item trovati per lo stesso DID
537
+ // Ambiguità: lo stesso documento appare in più workflow diversi
538
+ const finalWorkItems = itemsByDID.map((item, index) => ({ ...item, setID: undefined }));
539
+ setWorkItems(finalWorkItems);
540
+ setWorkflows([]); // Non carichiamo il workflow in caso di ambiguità
541
+ }
448
542
  }
449
- // Crea un array di Promise per tutte le chiamate a GetWFInfoAsync
450
- const workflowInfoPromises = itemsToProcess.map(item => WorkflowCacheService.GetWFInfoAsync(item.tid));
451
- // Esegui tutte le chiamate in parallelo e attendi i risultati
452
- const setIDResults = await Promise.all(setIDPromises);
453
- const workflowInfoResults = await Promise.all(workflowInfoPromises);
454
- // Combina i risultati
455
- const finalWorkItems = itemsToProcess.map((item, index) => ({
456
- ...item,
457
- setID: setIDResults[index],
458
- }));
459
- const validWorkflows = workflowInfoResults.filter(Boolean);
460
- // Aggiorna lo stato una sola volta con i dati finali
461
- setWorkItems(finalWorkItems);
462
- setWorkflows(validWorkflows);
463
543
  }
464
544
  catch (error) {
545
+ // FASE 4: Gestione errori
465
546
  TMExceptionBoxManager.show({ exception: error });
466
547
  setWorkItems([]);
467
548
  setWorkflows([]);
468
549
  }
469
550
  finally {
551
+ // Garantisce sempre il reset del flag di loading
470
552
  setIsWFDataLoading(false);
471
553
  }
472
554
  };
473
- // Usa hasFormData invece di formDataRef.current
474
555
  if (!hasFormData || !fromDTD?.id) {
475
- // console.log("formData is empty or fromDTD not loaded, skipping loadAllWfData");
476
556
  return;
477
557
  }
478
558
  if (workItemSetIDValue !== undefined || workflowApproveData.length > 0)
479
559
  loadAllWfData();
480
- }, [hasFormData, workItemSetIDValue, workflowApproveData, DID, layoutMode, fromDTD?.templateTID, fromDTD?.id]);
560
+ }, [hasFormData, workItemSetIDValue, workflowApproveData, getWorkItemsByDID, TID, DID, layoutMode, fromDTD?.templateTID, fromDTD?.id]);
481
561
  const getSelectionDcmtInfo = useCallback(() => {
482
562
  let dcmts = [];
483
563
  dcmts.push({ TID: TID ?? 0, DID: DID ?? 0 });
@@ -508,7 +588,11 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
508
588
  const showToppyForCompleteMoreInfo = useMemo(() => layoutMode === LayoutModes.Update && !!isTaskMoreInfo(taskMoreInfo?.name) && taskMoreInfo?.state !== Task_States.Completed, [layoutMode, taskMoreInfo?.name, taskMoreInfo?.state]);
509
589
  const showToppyForReferences = useMemo(() => allowButtonsRefs && layoutMode === LayoutModes.Update && !!(dcmtReferences && dcmtReferences.length > 0) && !isOpenDetails && !isOpenMaster, [allowButtonsRefs, layoutMode, dcmtReferences, isOpenDetails, isOpenMaster]);
510
590
  const isMobile = useMemo(() => deviceType === DeviceType.MOBILE, [deviceType]);
511
- const isApprView = useMemo(() => fromDTD?.templateTID === TemplateTIDs.WF_WIApprView, [fromDTD?.templateTID]);
591
+ const isApprView = useMemo(() => {
592
+ if (!fromDTD)
593
+ return false;
594
+ return isApprovalWorkflowView(fromDTD);
595
+ }, [fromDTD?.id]);
512
596
  const workitemSetID = useMemo(() => workItems.find(o => o.did === Number(DID))?.setID || formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [workItems, DID, formData]);
513
597
  const approvalVID = useMemo(() => workItems.length > 0 ? Number(workItems[0].tid) : -1, [workItems]);
514
598
  //here
@@ -516,23 +600,20 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
516
600
  const items = [];
517
601
  const operationsItems = [];
518
602
  operationsItems.push({
519
- icon: svgToString(_jsx(IconDownload, {})),
520
- operationType: 'singleRow',
603
+ icon: _jsx(IconDownload, {}),
521
604
  disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes,
522
- text: SDKUI_Localizator.DownloadFile,
605
+ name: SDKUI_Localizator.DownloadFile,
523
606
  onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Dcmt, "download", undefined, undefined, true)
524
607
  }, {
525
- icon: svgToString(_jsx(IconDownload, {})),
526
- operationType: 'singleRow',
608
+ icon: _jsx(IconDownload, {}),
527
609
  disabled: !isXMLFileExt(currentDcmt?.fileExt),
528
- text: SDKUI_Localizator.DownloadXMLAttachments,
610
+ name: SDKUI_Localizator.DownloadXMLAttachments,
529
611
  onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Attachment, "download", undefined, openConfirmAttachmentsDialog, true)
530
612
  });
531
613
  if (layoutMode === LayoutModes.Update && DID) {
532
614
  operationsItems.push({
533
- icon: svgToString(_jsx(IconStar, {})),
534
- text: SDKUI_Localizator.AddTo + ' ' + SDKUI_Localizator.Favorites,
535
- operationType: 'singleRow',
615
+ icon: _jsx(IconStar, {}),
616
+ name: SDKUI_Localizator.AddTo + ' ' + SDKUI_Localizator.Favorites,
536
617
  disabled: false,
537
618
  onClick: async () => {
538
619
  await runOperationAsync(getDcmts(), DcmtOperationTypes.AddToFavs);
@@ -541,17 +622,17 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
541
622
  }
542
623
  if (onTaskCreateRequest && layoutMode === LayoutModes.Update && DID) {
543
624
  operationsItems.push({
544
- icon: svgToString(_jsx(IconActivity, {})),
545
- text: SDKUI_Localizator.CreateContextualTask,
546
- operationType: 'singleRow',
625
+ icon: _jsx(IconActivity, {}),
626
+ name: SDKUI_Localizator.CreateContextualTask,
547
627
  disabled: false,
548
628
  onClick: () => {
549
629
  const dcmt = getDcmts()[0];
630
+ const name = `${fromDTD?.name ?? '-'} (DID: ${dcmt.DID})`;
550
631
  const taskContext = {
551
632
  document: {
552
633
  tid: dcmt.TID,
553
634
  did: dcmt.DID,
554
- name: fromDTD?.description || ''
635
+ name: name
555
636
  }
556
637
  };
557
638
  onTaskCreateRequest(taskContext);
@@ -560,76 +641,106 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
560
641
  }
561
642
  if (operationsItems.length > 0) {
562
643
  items.push({
563
- icon: svgToString(_jsx(IconCheck, {})),
564
- text: SDKUI_Localizator.DocumentOperations,
565
- items: operationsItems
644
+ icon: _jsx(IconCheck, {}),
645
+ name: SDKUI_Localizator.DocumentOperations,
646
+ submenu: operationsItems
647
+ });
648
+ }
649
+ if (fromDTD?.id !== SystemTIDs.Drafts) {
650
+ // Check in/Check out menu
651
+ const { cicoEnabled, checkoutStatus } = getDcmtCicoStatus(formData, allUsers, fromDTD);
652
+ items.push({
653
+ icon: _jsx(IconFileDots, {}),
654
+ name: "Check in/Check out",
655
+ disabled: false,
656
+ submenu: [
657
+ {
658
+ name: 'Check out',
659
+ disabled: !cicoEnabled || checkoutStatus.isCheckedOut,
660
+ onClick: () => handleCheckOutOperationCallback(true),
661
+ },
662
+ {
663
+ name: 'Check in',
664
+ onClick: () => handleCheckInOperationCallback(),
665
+ disabled: !cicoEnabled || !checkoutStatus.isCheckedOut || checkoutStatus.mode === 'lockMode'
666
+ },
667
+ {
668
+ name: SDKUI_Localizator.CancelCheckOut,
669
+ disabled: !cicoEnabled || !checkoutStatus.isCheckedOut || checkoutStatus.mode === 'lockMode',
670
+ onClick: () => handleCheckOutOperationCallback(false),
671
+ },
672
+ {
673
+ name: SDKUI_Localizator.CheckoutInfo,
674
+ onClick: showCheckoutInformationFormCallback,
675
+ disabled: !checkoutStatus.isCheckedOut
676
+ },
677
+ {
678
+ name: SDKUI_Localizator.CopyCheckoutPath,
679
+ onClick: copyCheckoutPathToClipboardOperationCallback,
680
+ disabled: !checkoutStatus.isCheckedOut
681
+ },
682
+ {
683
+ name: SDKUI_Localizator.History,
684
+ disabled: !cicoEnabled,
685
+ onClick: showHistoryCallback,
686
+ },
687
+ ]
566
688
  });
567
689
  }
568
690
  if (allowRelations && layoutMode === LayoutModes.Update && DID) {
569
691
  const relationsItems = [
570
692
  {
571
- icon: svgToString(_jsx(IconPair, {})),
572
- text: SDKUI_Localizator.MatchManyDocumentsManyToMany,
573
- operationType: 'singleRow',
693
+ icon: _jsx(IconPair, {}),
694
+ name: SDKUI_Localizator.MatchManyDocumentsManyToMany,
574
695
  disabled: !hasManyToManyRelation,
575
696
  onClick: async () => await pairManyToMany?.(true)
576
697
  },
577
698
  {
578
- icon: svgToString(_jsx(IconUnpair, {})),
579
- text: SDKUI_Localizator.UnmatchManyDocumentsManyToMany,
580
- operationType: 'singleRow',
699
+ icon: _jsx(IconUnpair, {}),
700
+ name: SDKUI_Localizator.UnmatchManyDocumentsManyToMany,
581
701
  disabled: !hasManyToManyRelation,
582
702
  onClick: async () => await pairManyToMany?.(false)
583
703
  },
584
704
  {
585
- icon: svgToString(_jsx(IconArchiveMaster, {})),
586
- text: SDKUI_Localizator.ArchiveMasterDocument,
587
- operationType: 'singleRow',
588
- beginGroup: true,
705
+ icon: _jsx(IconArchiveMaster, {}),
706
+ name: SDKUI_Localizator.ArchiveMasterDocument,
589
707
  disabled: canArchiveMasterRelation !== true,
590
708
  onClick: async () => { if (TID)
591
709
  await archiveMasterDocuments?.(TID); }
592
710
  },
593
711
  {
594
- icon: svgToString(_jsx(IconArchiveDetail, {})),
595
- text: SDKUI_Localizator.ArchiveDetailDocument,
596
- operationType: 'singleRow',
712
+ icon: _jsx(IconArchiveDetail, {}),
713
+ name: SDKUI_Localizator.ArchiveDetailDocument,
597
714
  disabled: canArchiveDetailRelation !== true,
598
715
  onClick: async () => { if (TID)
599
716
  await archiveDetailDocuments?.(TID); }
600
717
  },
601
718
  {
602
- icon: svgToString(_jsx(IconDetailDcmts, { transform: 'scale(-1, 1)' })),
603
- text: SDKUI_Localizator.DcmtsMaster,
604
- operationType: 'singleRow',
605
- visible: true,
606
- beginGroup: true,
719
+ icon: _jsx(IconDetailDcmts, { transform: 'scale(-1, 1)' }),
720
+ name: SDKUI_Localizator.DcmtsMaster,
607
721
  disabled: !currentTIDHasMasterRelations || isMasterDisabled,
608
722
  onClick: () => { if (!isMasterDisabled)
609
723
  setIsOpenMaster(!isOpenMaster); }
610
724
  },
611
725
  {
612
- icon: svgToString(_jsx(IconDetailDcmts, {})),
613
- text: SDKUI_Localizator.DcmtsDetail,
614
- operationType: 'singleRow',
726
+ icon: _jsx(IconDetailDcmts, {}),
727
+ name: SDKUI_Localizator.DcmtsDetail,
615
728
  disabled: !currentTIDHasDetailRelations || isDetailsDisabled,
616
- visible: true,
617
729
  onClick: () => { if (!isDetailsDisabled)
618
730
  setIsOpenDetails(!isOpenDetails); }
619
731
  }
620
732
  ];
621
733
  items.push({
622
- icon: svgToString(_jsx(IconRelation, {})),
623
- text: SDKUI_Localizator.Relations,
624
- items: relationsItems
734
+ icon: _jsx(IconRelation, {}),
735
+ name: SDKUI_Localizator.Relations,
736
+ submenu: relationsItems
625
737
  });
626
738
  }
627
739
  if (layoutMode === LayoutModes.Update && DID) {
628
740
  const fullTextItems = [
629
741
  {
630
- icon: svgToString(_jsx(IconInfo, {})),
631
- text: SDKUI_Localizator.IndexingInformation,
632
- operationType: 'singleRow',
742
+ icon: _jsx(IconInfo, {}),
743
+ name: SDKUI_Localizator.IndexingInformation,
633
744
  disabled: false,
634
745
  onClick: async () => {
635
746
  try {
@@ -647,18 +758,16 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
647
758
  }
648
759
  },
649
760
  {
650
- icon: svgToString(_jsx(IconArchiveDoc, {})),
651
- text: SDKUI_Localizator.IndexOrReindex,
652
- operationType: 'singleRow',
761
+ icon: _jsx(IconArchiveDoc, {}),
762
+ name: SDKUI_Localizator.IndexOrReindex,
653
763
  disabled: false,
654
764
  onClick: async () => {
655
765
  await runOperationAsync(getDcmts(), DcmtOperationTypes.FreeSearchReindex);
656
766
  }
657
767
  },
658
768
  {
659
- icon: svgToString(_jsx(IconDelete, {})),
660
- text: SDKUI_Localizator.IndexingDelete,
661
- operationType: 'singleRow',
769
+ icon: _jsx(IconDelete, {}),
770
+ name: SDKUI_Localizator.IndexingDelete,
662
771
  disabled: false,
663
772
  onClick: async () => {
664
773
  await runOperationAsync(getDcmts(), DcmtOperationTypes.FreeSearchPurge);
@@ -666,9 +775,9 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
666
775
  }
667
776
  ];
668
777
  items.push({
669
- icon: svgToString(_jsx(IconSearch, {})),
670
- text: SDKUI_Localizator.FullTextSearch,
671
- items: fullTextItems
778
+ icon: _jsx(IconSearch, {}),
779
+ name: SDKUI_Localizator.FullTextSearch,
780
+ submenu: fullTextItems
672
781
  });
673
782
  }
674
783
  // Aggiungi submenu "Bottoni personalizzati" se esistono customButtons
@@ -676,18 +785,19 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
676
785
  const customButtonsItems = customButtonsLayout.customButtons
677
786
  .filter((customButton) => customButton.isForUpdate && customButton.isForUpdate > 0)
678
787
  .map((customButton) => ({
679
- icon: svgToString(TMImageLibrary({ imageID: customButton.glyphID, showPath: true })),
680
- text: customButton.title || 'Bottone personalizzato',
788
+ icon: TMImageLibrary({ imageID: customButton.glyphID }),
789
+ name: customButton.title || 'Bottone personalizzato',
681
790
  onClick: () => setCustomButton(customButton)
682
791
  }));
683
- items.push({
684
- icon: svgToString(_jsx(IconCheck, {})),
685
- text: SDKUI_Localizator.CustomButtons,
686
- items: customButtonsItems
792
+ customButtonsItems && customButtonsItems.length > 0 && items.push({
793
+ icon: _jsx(IconCustom, {}),
794
+ name: SDKUI_Localizator.CustomButtons,
795
+ submenu: customButtonsItems
687
796
  });
688
797
  }
689
798
  return items;
690
799
  }, [
800
+ fromDTD?.id,
691
801
  fromDTD?.perm?.canRetrieveFile,
692
802
  fromDTD?.description,
693
803
  currentDcmt?.fileExt,
@@ -713,8 +823,9 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
713
823
  openConfirmAttachmentsDialog
714
824
  ]);
715
825
  const isModified = useMemo(() => calcIsModified(formData, formDataOrig), [formData, formDataOrig]);
716
- const formToolbar = useMemo(() => _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowNavigation && canPrev != undefined && _jsx("p", { style: { textAlign: 'center', padding: '1px 4px', display: 'flex' }, children: `${itemIndex}/${count}` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: isModified, formMode: formMode, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: isModified, formMode: formMode, canNext: canNext, onNext: onNext }), layoutMode === LayoutModes.Update && _jsx(IconMenuVertical, { id: `commands-detail-${id}`, color: 'white', cursor: 'pointer' }), layoutMode === LayoutModes.Update && _jsx(ContextMenu, { showEvent: 'click', dataSource: commandsMenuItems, target: `#commands-detail-${id}` }), layoutMode === LayoutModes.Ark &&
717
- _jsx(TMTooltip, { content: SDKUI_Localizator.PassToSearch, position: 'bottom', children: _jsx(IconSearch, { style: { cursor: 'pointer' }, onClick: handlePassToSearch }) })] }), [allowNavigation, canPrev, canNext, itemIndex, count, isModified, formMode, onPrev, onNext, layoutMode, id, commandsMenuItems, handlePassToSearch]);
826
+ const formToolbar = useMemo(() => _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '10px' }, children: [allowNavigation && canPrev != undefined && _jsx("p", { style: { textAlign: 'center', padding: '1px 4px', display: 'flex' }, children: `${itemIndex}/${count}` }), allowNavigation && canPrev != undefined && _jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', iconColor: 'white', isModified: isModified, formMode: formMode, canPrev: canPrev, onPrev: onPrev }), allowNavigation && canNext != undefined && _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', iconColor: 'white', isModified: isModified, formMode: formMode, canNext: canNext, onNext: onNext }), layoutMode === LayoutModes.Update &&
827
+ _jsx(ContextMenu, { items: commandsMenuItems, trigger: "left", children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) }), layoutMode === LayoutModes.Ark &&
828
+ _jsx(TMTooltip, { content: SDKUI_Localizator.PassToSearch, position: 'bottom', children: _jsx(IconSearch, { style: { cursor: 'pointer' }, onClick: handlePassToSearch }) })] }), [allowNavigation, canPrev, canNext, itemIndex, count, isModified, formMode, onPrev, onNext, layoutMode, commandsMenuItems, handlePassToSearch]);
718
829
  const handleUndo = useCallback(() => {
719
830
  setFormData(structuredClone(formDataOrig));
720
831
  }, [formDataOrig]);
@@ -730,6 +841,60 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
730
841
  },
731
842
  });
732
843
  }, [isModal, id, layoutMode]);
844
+ // Funzione helper per ottenere e aggiornare i metadati con gestione errori centralizzata
845
+ const refreshMetadataAsync = useCallback(async () => {
846
+ let metadataResult = undefined;
847
+ let hasGetMetadataError = false;
848
+ try {
849
+ metadataResult = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(TID, DID, true);
850
+ }
851
+ catch (metadataError) {
852
+ hasGetMetadataError = true;
853
+ // Estrai ErrorCode dal campo detail se disponibile
854
+ let errorCode = undefined;
855
+ if (metadataError?.isApiException && metadataError?.response?.detail) {
856
+ try {
857
+ const detailObj = JSON.parse(metadataError.response.detail);
858
+ errorCode = detailObj?.ErrorCode;
859
+ }
860
+ catch (parseError) {
861
+ console.log("Impossibile parsare il detail dell'eccezione:", parseError);
862
+ }
863
+ }
864
+ // Se ErrorCode è -5, mostra messaggio personalizzato, altrimenti mostra l'eccezione originale
865
+ if (errorCode === -5) {
866
+ TMMessageBoxManager.show({
867
+ message: SDKUI_Localizator.DcmtOutOfView,
868
+ buttons: [ButtonNames.OK],
869
+ });
870
+ }
871
+ else {
872
+ TMExceptionBoxManager.show({ exception: metadataError });
873
+ }
874
+ // Usa null per indicare al callback che c'è stato un errore e non deve ritentare
875
+ metadataResult = null;
876
+ }
877
+ // Aggiorna i metadati locali solo se non ci sono stati errori
878
+ if (!hasGetMetadataError && metadataResult && metadataResult !== null) {
879
+ await setMetadataList(fromDTDRef.current?.metadata ?? [], metadataResult);
880
+ }
881
+ return { success: !hasGetMetadataError, result: metadataResult };
882
+ }, [TID, DID, setMetadataList]);
883
+ const updateCurrentDcmt = useCallback(async () => {
884
+ try {
885
+ TMSpinner.show({ description: 'Aggiornamento in corso...' });
886
+ const { success, result: metadataResult } = await refreshMetadataAsync();
887
+ if (!success)
888
+ onClose?.();
889
+ await onSavedAsyncCallback?.(TID, DID, metadataResult === null ? null : metadataResult);
890
+ }
891
+ catch (e) {
892
+ TMExceptionBoxManager.show({ exception: e });
893
+ }
894
+ finally {
895
+ TMSpinner.hide();
896
+ }
897
+ }, [refreshMetadataAsync, onClose]);
733
898
  const handleSave = useCallback(async () => {
734
899
  const ue = new UpdateEngineByID(SDK_Globals.tmSession);
735
900
  ue.DID = DID;
@@ -766,55 +931,20 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
766
931
  const savedFormData = structuredClone(formDataRef.current);
767
932
  setFormDataOrig(savedFormData);
768
933
  formDataOrigRef.current = savedFormData;
769
- // Tenta di ottenere i metadati aggiornati
770
- let metadataResult = undefined;
771
- let hasGetMetadataError = false;
772
- try {
773
- metadataResult = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(TID, DID, true);
774
- }
775
- catch (metadataError) {
776
- hasGetMetadataError = true;
777
- // Estrai ErrorCode dal campo detail se disponibile
778
- let errorCode = undefined;
779
- if (metadataError?.isApiException && metadataError?.response?.detail) {
780
- try {
781
- const detailObj = JSON.parse(metadataError.response.detail);
782
- errorCode = detailObj?.ErrorCode;
783
- }
784
- catch (parseError) {
785
- console.log("Impossibile parsare il detail dell'eccezione:", parseError);
786
- }
787
- }
788
- // Se ErrorCode è -5, mostra messaggio personalizzato, altrimenti mostra l'eccezione originale
789
- if (errorCode === -5) {
790
- TMMessageBoxManager.show({
791
- message: SDKUI_Localizator.DcmtOutOfView,
792
- buttons: [ButtonNames.OK],
793
- });
794
- }
795
- else {
796
- TMExceptionBoxManager.show({ exception: metadataError });
797
- }
798
- // Usa null per indicare al callback che c'è stato un errore e non deve ritentare
799
- metadataResult = null;
800
- }
934
+ // Usa la funzione helper per ottenere i metadati aggiornati
935
+ const { success, result: metadataResult } = await refreshMetadataAsync();
801
936
  // Esegui sempre il callback:
802
937
  // - Se metadataResult è un oggetto: refresh normale
803
938
  // - Se metadataResult è null: GetMetadataAsync fallito, rimuove il documento dalla griglia senza ritentare
804
939
  // - Se metadataResult è undefined: nessun parametro passato, il callback può decidere cosa fare
805
940
  await onSavedAsyncCallback?.(TID, DID, metadataResult === null ? null : metadataResult);
806
941
  // Mostra messaggio di successo solo se non ci sono stati errori critici
807
- if (!hasGetMetadataError) {
808
- if (metadataResult && metadataResult !== null) {
809
- // Usa fromDTDRef.current invece di fromDTD per evitare stale closure.
810
- // fromDTD potrebbe essere undefined/vuoto nel callback se lo stato è cambiato,
811
- // mentre fromDTDRef.current contiene sempre il valore corrente sincronizzato tramite useEffect.
812
- await setMetadataList(fromDTDRef.current?.metadata ?? [], metadataResult);
813
- }
942
+ if (success) {
814
943
  ShowAlert({ mode: 'success', title: 'Form di documento', message: 'Le modifiche sono state salvate con successo', duration: 3000 });
815
944
  }
816
- else
945
+ else {
817
946
  onClose?.();
947
+ }
818
948
  }
819
949
  catch (e) {
820
950
  TMExceptionBoxManager.show({ exception: e });
@@ -822,7 +952,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
822
952
  finally {
823
953
  TMSpinner.hide();
824
954
  }
825
- }, [DID, TID, getSpecificChangedKeysWithValues, onSavedAsyncCallback, onClose, setMetadataList]);
955
+ }, [DID, TID, getSpecificChangedKeysWithValues, refreshMetadataAsync, onSavedAsyncCallback, onClose]);
826
956
  const handleArchiveCompleted = useCallback(async () => {
827
957
  let firstBlock = true;
828
958
  let maxFileSize = 0;
@@ -1011,28 +1141,34 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1011
1141
  await triggerBlogRefresh();
1012
1142
  }
1013
1143
  }, [TID, DID, triggerBlogRefresh]);
1144
+ const checkoutBadge = useMemo(() => {
1145
+ const { cicoEnabled, checkoutStatus } = getDcmtCicoStatus(formData, allUsers, fromDTD);
1146
+ if (!cicoEnabled || !checkoutStatus.isCheckedOut)
1147
+ return null;
1148
+ return (_jsx(Ribbon, { "$isMobile": isMobile, children: _jsx(TMTooltip, { content: checkoutStatus.editLockTooltipText, position: "right", children: _jsx("span", { children: checkoutStatus.mode === 'editMode' ? SDKUI_Localizator.CheckOut : 'Locked' }) }) }));
1149
+ }, [formData, fromDTD, isMobile]);
1014
1150
  const tmDcmtForm = useMemo(() => {
1015
- return _jsx(_Fragment, { children: metadataValuesSource.length > 0 &&
1016
- _jsxs(StyledToolbarCardContainer, { children: [_jsx(TMMetadataValues, { TID: TID, metadataValues: metadataValuesSource, metadataValuesOrig: metadataValuesSourceOrig, isExpertMode: isExpertMode, isOpenDistinctValues: isOpenDistinctValues, openChooserBySingleClick: !isOpenDistinctValues, selectedMID: focusedMetadataValue?.mid, isReadOnly: formMode === FormModes.ReadOnly, layoutMode: layoutMode, deviceType: deviceType, validationItems: validationItems, inputMids: inputMids, layout: layout, onFocusedItemChanged: (item) => { (item?.mid !== focusedMetadataValue?.mid) && setFocusedMetadataValue(item); }, onValueChanged: (newItems) => {
1017
- setFormData((prevItems) => prevItems.map((item) => {
1018
- const newItem = newItems.find((newItem) => newItem.tid === item.tid && newItem.mid === item.mid);
1019
- return newItem ? { ...item, ...newItem } : item;
1020
- }));
1021
- }, onAdvancedMenuClick: (e) => {
1022
- switch (e.button) {
1023
- case AdvancedMenuButtons.DistinctValues:
1024
- setIsOpenDistinctValues(!isOpenDistinctValues);
1025
- break;
1026
- case AdvancedMenuButtons.FormulaEditor:
1027
- setIsOpenFormulaEditor(!isOpenFormulaEditor);
1028
- break;
1029
- }
1030
- } }), _jsxs(StyledFormButtonsContainer, { children: [_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, children: _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '8px' }, children: layoutMode === LayoutModes.Update ? _jsxs(_Fragment, { children: [_jsx(TMSaveFormButtonSave, { showTooltip: false, btnStyle: 'advanced', advancedColor: '#f09c0a', isModified: isModified, formMode: formMode, errorsCount: validationItems.filter(o => o.ResultType == ResultTypes.ERROR).length, onSaveAsync: handleConfirmAction }), _jsx(TMSaveFormButtonUndo, { btnStyle: 'toolbar', showTooltip: true, color: 'primary', isModified: isModified, formMode: formMode, onUndo: handleUndo })] }) :
1031
- _jsxs(_Fragment, { children: [_jsx(TMButton, { disabled: archiveBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconBoxArchiveIn, {}), width: 'auto', showTooltip: false, caption: SDKUI_Localizator.Archive, advancedColor: TMColors.success, onClick: handleConfirmAction }), _jsx(TMButton, { disabled: !clearFormBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconClear, {}), width: 'auto', showTooltip: false, caption: SDKUI_Localizator.Clear, advancedColor: TMColors.tertiary, onClick: handleClearForm }), DID && _jsx(TMButton, { disabled: undoBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconUndo, {}), width: '150px', showTooltip: false, caption: SDKUI_Localizator.Undo, advancedColor: TMColors.tertiary, onClick: handleUndo })] }) }) }), customButton && _jsx(TMCustomButton, { button: customButton, formData: formData, selectedItems: [], onClose: () => setCustomButton(undefined) }), totalItems > listMaxItems &&
1032
- !isApprView &&
1033
- TID !== SystemTIDs.Drafts &&
1034
- !shouldShowAll &&
1035
- _jsx(TMShowAllOrMaxItemsButton, { showAll: showAll, dataSourceLength: totalItems, onClick: () => { setShowAll(!showAll); } })] }), _jsx(ConfirmAttachmentsDialog, {})] }) });
1151
+ return _jsxs(_Fragment, { children: [checkoutBadge && _jsx("div", { style: { padding: '10px', display: 'flex', justifyContent: 'center' }, children: checkoutBadge }), metadataValuesSource.length > 0 &&
1152
+ _jsxs(StyledToolbarCardContainer, { children: [_jsx(TMMetadataValues, { TID: TID, metadataValues: metadataValuesSource, metadataValuesOrig: metadataValuesSourceOrig, isExpertMode: isExpertMode, isOpenDistinctValues: isOpenDistinctValues, openChooserBySingleClick: !isOpenDistinctValues, selectedMID: focusedMetadataValue?.mid, isReadOnly: formMode === FormModes.ReadOnly, layoutMode: layoutMode, deviceType: deviceType, validationItems: validationItems, inputMids: inputMids, layout: layout, onFocusedItemChanged: (item) => { (item?.mid !== focusedMetadataValue?.mid) && setFocusedMetadataValue(item); }, onValueChanged: (newItems) => {
1153
+ setFormData((prevItems) => prevItems.map((item) => {
1154
+ const newItem = newItems.find((newItem) => newItem.tid === item.tid && newItem.mid === item.mid);
1155
+ return newItem ? { ...item, ...newItem } : item;
1156
+ }));
1157
+ }, onAdvancedMenuClick: (e) => {
1158
+ switch (e.button) {
1159
+ case AdvancedMenuButtons.DistinctValues:
1160
+ setIsOpenDistinctValues(!isOpenDistinctValues);
1161
+ break;
1162
+ case AdvancedMenuButtons.FormulaEditor:
1163
+ setIsOpenFormulaEditor(!isOpenFormulaEditor);
1164
+ break;
1165
+ }
1166
+ } }), _jsxs(StyledFormButtonsContainer, { children: [_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, children: _jsx("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '8px' }, children: layoutMode === LayoutModes.Update ? _jsxs(_Fragment, { children: [_jsx(TMSaveFormButtonSave, { showTooltip: false, btnStyle: 'advanced', advancedColor: '#f09c0a', isModified: isModified, formMode: formMode, errorsCount: validationItems.filter(o => o.ResultType == ResultTypes.ERROR).length, onSaveAsync: handleConfirmAction }), _jsx(TMSaveFormButtonUndo, { btnStyle: 'toolbar', showTooltip: true, color: 'primary', isModified: isModified, formMode: formMode, onUndo: handleUndo })] }) :
1167
+ _jsxs(_Fragment, { children: [_jsx(TMButton, { disabled: archiveBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconBoxArchiveIn, {}), width: 'auto', showTooltip: false, caption: SDKUI_Localizator.Archive, advancedColor: TMColors.success, onClick: handleConfirmAction }), _jsx(TMButton, { disabled: !clearFormBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconClear, {}), width: 'auto', showTooltip: false, caption: SDKUI_Localizator.Clear, advancedColor: TMColors.tertiary, onClick: handleClearForm }), DID && _jsx(TMButton, { disabled: undoBtnDisabled, btnStyle: 'advanced', icon: _jsx(IconUndo, {}), width: '150px', showTooltip: false, caption: SDKUI_Localizator.Undo, advancedColor: TMColors.tertiary, onClick: handleUndo })] }) }) }), customButton && _jsx(TMCustomButton, { button: customButton, formData: formData, selectedItems: [], onClose: () => setCustomButton(undefined) }), totalItems > listMaxItems &&
1168
+ !isApprView &&
1169
+ TID !== SystemTIDs.Drafts &&
1170
+ !shouldShowAll &&
1171
+ _jsx(TMShowAllOrMaxItemsButton, { showAll: showAll, dataSourceLength: totalItems, onClick: () => { setShowAll(!showAll); } })] }), _jsx(ConfirmAttachmentsDialog, {})] })] });
1036
1172
  }, [
1037
1173
  TID,
1038
1174
  DID,
@@ -1060,11 +1196,11 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1060
1196
  handleUndo,
1061
1197
  handleClearForm
1062
1198
  ]);
1063
- const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: TID, did: DID, allTasks: allTasks, fetchBlogDataTrigger: refreshBlogTrigger, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [TID, DID, allTasks, refreshBlogTrigger]);
1199
+ const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: TID, did: DID, allTasks: allTasks, fetchBlogDataTrigger: refreshBlogTrigger, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [TID, DID, allTasks, refreshBlogTrigger, handleNavigateToWGs, handleNavigateToDossiers]);
1064
1200
  const tmSysMetadata = useMemo(() => _jsx(TMMetadataValues, { layoutMode: layoutMode, openChooserBySingleClick: !isOpenDistinctValues, TID: TID, isReadOnly: true, deviceType: deviceType, metadataValues: formData.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: formData.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [], inputMids: inputMids }), [TID, layoutMode, formData, deviceType, inputMids]);
1065
1201
  const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, fromDTD: fromDTD, layoutMode: layoutMode, onFileUpload: (file) => {
1066
1202
  setDcmtFile(file);
1067
- }, enableDragDropOverlay: enableDragDropOverlay }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile]);
1203
+ }, enableDragDropOverlay: enableDragDropOverlay }, refreshPreviewTrigger), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile]);
1068
1204
  const tmWF = useMemo(() => {
1069
1205
  if (isWFDataLoading) {
1070
1206
  return (_jsx("div", { style: {
@@ -1088,7 +1224,27 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1088
1224
  fontSize: '1.1rem',
1089
1225
  color: TMColors.primaryColor,
1090
1226
  textAlign: 'center',
1091
- }, children: SDKUI_Localizator.WorkflowDiagramNotAuthorized }))
1227
+ display: 'flex',
1228
+ flexDirection: 'column',
1229
+ alignItems: 'center',
1230
+ gap: '12px',
1231
+ }, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [_jsx("span", { children: SDKUI_Localizator.WorkflowDiagramNotAuthorized }), wfError && (_jsx(TMTooltip, { content: 'Visualizza errore', children: _jsx("i", { className: "dx-icon-info", style: { fontSize: 20, cursor: 'pointer', color: '#dc3545' }, onClick: () => {
1232
+ TMMessageBoxManager.show({
1233
+ title: 'Dettagli Errore Workflow',
1234
+ initialWidth: !isMobile ? '700px' : undefined,
1235
+ message: (_jsx("pre", { style: {
1236
+ whiteSpace: 'pre-wrap',
1237
+ background: '#f5f5f5',
1238
+ padding: '12px',
1239
+ borderRadius: '6px',
1240
+ userSelect: 'text',
1241
+ cursor: 'text',
1242
+ }, children: wfError })),
1243
+ resizable: true,
1244
+ showToppy: false,
1245
+ buttons: [ButtonNames.OK],
1246
+ });
1247
+ } }) }))] }) }))
1092
1248
  : _jsx("div", { style: {
1093
1249
  position: 'absolute',
1094
1250
  top: '50%',
@@ -1228,7 +1384,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1228
1384
  // Checks if there's a saved panel layout for the current context (ToDo or general)
1229
1385
  const hasSavedLayout = () => {
1230
1386
  const { setting } = getCurrentDcmtFormSetting();
1231
- if (invokedByTodo) {
1387
+ if (invocationContext === InvocationContext.Todo) {
1232
1388
  // If invoked by ToDo, check for existence of layoutToDo and that it has keys
1233
1389
  return setting.layoutToDo !== undefined && Object.keys(setting.layoutToDo).length > 0;
1234
1390
  }
@@ -1247,8 +1403,8 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1247
1403
  // Prepare the new setting object with updated layout depending on context
1248
1404
  const newSetting = {
1249
1405
  TID: normalizedTID,
1250
- layout: invokedByTodo ? (existingSetting.layout ?? {}) : state,
1251
- layoutToDo: invokedByTodo ? state : (existingSetting.layoutToDo ?? {}),
1406
+ layout: invocationContext === InvocationContext.Todo ? (existingSetting.layout ?? {}) : state,
1407
+ layoutToDo: invocationContext === InvocationContext.Todo ? state : (existingSetting.layoutToDo ?? {}),
1252
1408
  };
1253
1409
  // Replace existing setting if found, otherwise push a new one
1254
1410
  if (idx >= 0) {
@@ -1267,7 +1423,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1267
1423
  return undefined;
1268
1424
  const settings = getCurrentDcmtFormSetting()?.setting;
1269
1425
  // Return the appropriate layout based on context
1270
- return invokedByTodo ? settings?.layoutToDo : settings?.layout;
1426
+ return invocationContext === InvocationContext.Todo ? settings?.layoutToDo : settings?.layout;
1271
1427
  };
1272
1428
  const handleCompleteMoreInfo = useCallback(async () => {
1273
1429
  try {
@@ -1329,26 +1485,26 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1329
1485
  height: '100%',
1330
1486
  position: 'relative',
1331
1487
  overflow: 'hidden'
1332
- }, children: [_jsxs("div", { style: { width: '100%', height: '100%', display: isOpenDetails || isOpenMaster ? 'none' : 'flex' }, children: [isNavigating && _jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: false }), (fromDTD) && _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: useWaitPanelLocalState ? showWaitPanelLocal : showWaitPanel, showWaitPanelPrimary: useWaitPanelLocalState ? showPrimaryLocal : showPrimary, showWaitPanelSecondary: useWaitPanelLocalState ? showSecondaryLocal : showSecondary, waitPanelTitle: useWaitPanelLocalState ? waitPanelTitleLocal : waitPanelTitle, waitPanelTextPrimary: useWaitPanelLocalState ? waitPanelTextPrimaryLocal : waitPanelTextPrimary, waitPanelValuePrimary: useWaitPanelLocalState ? waitPanelValuePrimaryLocal : waitPanelValuePrimary, waitPanelMaxValuePrimary: useWaitPanelLocalState ? waitPanelMaxValuePrimaryLocal : waitPanelMaxValuePrimary, waitPanelTextSecondary: useWaitPanelLocalState ? waitPanelTextSecondaryLocal : waitPanelTextSecondary, waitPanelValueSecondary: useWaitPanelLocalState ? waitPanelValueSecondaryLocal : waitPanelValueSecondary, waitPanelMaxValueSecondary: useWaitPanelLocalState ? waitPanelMaxValueSecondaryLocal : waitPanelMaxValueSecondary, isCancelable: useWaitPanelLocalState ? dcmtFile ? dcmtFile.size >= 1000000 : false : true, abortController: useWaitPanelLocalState ? abortControllerLocal : abortController, children: [(groupId && groupId.length > 0)
1333
- ? _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })
1334
- : _jsxs(TMPanelManagerWithPersistenceProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: defaultPanelDimensions, initialDimensions: defaultPanelDimensions, initialMobilePanelId: 'tmDcmtForm', isPersistenceEnabled: !isMobile ? hasSavedLayout() : false, persistPanelStates: !isMobile ? (state) => persistPanelStates(state) : undefined, persistedPanelStates: getPersistedPanelStates(), children: [_jsx(WfButtonStateHandler, { isWFDisabled: isWFDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] }), isOpenDistinctValues &&
1335
- _jsx(TMDistinctValues, { tid: TID, mid: focusedMetadataValue?.mid, isModal: true, showHeader: false, layoutMode: layoutMode, onSelectionChanged: (e) => {
1336
- if (!e)
1337
- return;
1338
- setFormData((prevItems) => prevItems.map((item) => item.tid == e.tid && item.mid === e.mid ? { ...item, value: e.newValue } : item));
1339
- } }), isOpenFormulaEditor &&
1340
- _jsx(TMFormulaEditor, { isModal: true, formMode: FormModes.Update, inputData: getFormula(), showBack: false, onClose: () => setIsOpenFormulaEditor(false), onApplied: (newFormula) => {
1341
- setFormData((prevItems) => prevItems.map((item) => item.tid == newFormula.tid && item.mid === newFormula.mid ? { ...item, value: FormulaHelper.addFormulaTag(newFormula.expression), isSelected: true, isEditable: true } : item));
1342
- setFocusedMetadataValue(prevState => ({
1343
- ...prevState,
1344
- isSelected: true,
1345
- isEditable: true,
1346
- value: FormulaHelper.addFormulaTag(newFormula.expression)
1347
- }));
1348
- } }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowMoreInfoPopup(false) }), (isModal && onClose) && _jsx("div", { id: "TMDcmtFormShowConfirmForClose-" + id })] }), _jsx(ToppyDraggableHelpCenter, { initialIsCollapsed: false, deviceType: deviceType, isVisible: (showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences) && !openS4TViewer, content: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: [showToppyForApprove && (workItems.length === 1 ?
1488
+ }, children: [_jsxs("div", { style: { width: '100%', height: '100%', display: isOpenDetails || isOpenMaster ? 'none' : 'flex' }, children: [isNavigating && _jsx(Spinner, { description: SDKUI_Localizator.Loading, flat: false }), (fromDTD) && _jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: useWaitPanelLocalState ? showWaitPanelLocal : showWaitPanel, showWaitPanelPrimary: useWaitPanelLocalState ? showPrimaryLocal : showPrimary, showWaitPanelSecondary: useWaitPanelLocalState ? showSecondaryLocal : showSecondary, waitPanelTitle: useWaitPanelLocalState ? waitPanelTitleLocal : waitPanelTitle, waitPanelTextPrimary: useWaitPanelLocalState ? waitPanelTextPrimaryLocal : waitPanelTextPrimary, waitPanelValuePrimary: useWaitPanelLocalState ? waitPanelValuePrimaryLocal : waitPanelValuePrimary, waitPanelMaxValuePrimary: useWaitPanelLocalState ? waitPanelMaxValuePrimaryLocal : waitPanelMaxValuePrimary, waitPanelTextSecondary: useWaitPanelLocalState ? waitPanelTextSecondaryLocal : waitPanelTextSecondary, waitPanelValueSecondary: useWaitPanelLocalState ? waitPanelValueSecondaryLocal : waitPanelValueSecondary, waitPanelMaxValueSecondary: useWaitPanelLocalState ? waitPanelMaxValueSecondaryLocal : waitPanelMaxValueSecondary, isCancelable: useWaitPanelLocalState ? dcmtFile ? dcmtFile.size >= 1000000 : false : true, abortController: useWaitPanelLocalState ? abortControllerLocal : abortController, children: _jsxs(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showCicoWaitPanel, showWaitPanelPrimary: showCicoPrimaryProgress, waitPanelTitle: cicoWaitPanelTitle, waitPanelTextPrimary: cicoPrimaryProgressText, waitPanelValuePrimary: cicoPrimaryProgressValue, waitPanelMaxValuePrimary: cicoPrimaryProgressMax, isCancelable: true, abortController: abortControllerLocal, children: [(groupId && groupId.length > 0)
1489
+ ? _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })
1490
+ : _jsxs(TMPanelManagerWithPersistenceProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: defaultPanelDimensions, initialDimensions: defaultPanelDimensions, initialMobilePanelId: 'tmDcmtForm', isPersistenceEnabled: !isMobile ? hasSavedLayout() : false, persistPanelStates: !isMobile ? (state) => persistPanelStates(state) : undefined, persistedPanelStates: getPersistedPanelStates(), children: [_jsx(WfButtonStateHandler, { isWFDisabled: isWFDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showDcmtFormSidebar })] }), isOpenDistinctValues &&
1491
+ _jsx(TMDistinctValues, { tid: TID, mid: focusedMetadataValue?.mid, isModal: true, showHeader: false, layoutMode: layoutMode, onSelectionChanged: (e) => {
1492
+ if (!e)
1493
+ return;
1494
+ setFormData((prevItems) => prevItems.map((item) => item.tid == e.tid && item.mid === e.mid ? { ...item, value: e.newValue } : item));
1495
+ } }), isOpenFormulaEditor &&
1496
+ _jsx(TMFormulaEditor, { isModal: true, formMode: FormModes.Update, inputData: getFormula(), showBack: false, onClose: () => setIsOpenFormulaEditor(false), onApplied: (newFormula) => {
1497
+ setFormData((prevItems) => prevItems.map((item) => item.tid == newFormula.tid && item.mid === newFormula.mid ? { ...item, value: FormulaHelper.addFormulaTag(newFormula.expression), isSelected: true, isEditable: true } : item));
1498
+ setFocusedMetadataValue(prevState => ({
1499
+ ...prevState,
1500
+ isSelected: true,
1501
+ isEditable: true,
1502
+ value: FormulaHelper.addFormulaTag(newFormula.expression)
1503
+ }));
1504
+ } }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowMoreInfoPopup(false) }), (isModal && onClose) && _jsx("div", { id: "TMDcmtFormShowConfirmForClose-" + id })] }) }), _jsx(ToppyDraggableHelpCenter, { initialIsCollapsed: false, deviceType: deviceType, isVisible: (showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences) && !openS4TViewer, content: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: [showToppyForApprove && (workItems.length === 1 ?
1349
1505
  _jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true), dtd: fromDTD })
1350
1506
  :
1351
- _jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`Devi approvare ${workItems.length} workitem(s) per questo documento.`, `Vai alla sezione di approvazione.`] })), showToppyForCompleteMoreInfo && (_jsxs(_Fragment, { children: [_jsx("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: `${SDKUI_Localizator.MoreInfoCompleteRequestSentBy} ${taskMoreInfo?.fromName}!` }), _jsx(TMButton, { caption: SDKUI_Localizator.CommentAndComplete, color: 'success', showTooltip: false, onClick: () => {
1507
+ _jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`Questo documento è associato a ${workItems.length} workitem.`, _jsx("br", {}), `Per approvare, vai alla pagina "Approvazione workflow".`] })), showToppyForCompleteMoreInfo && (_jsxs(_Fragment, { children: [_jsx("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: `${SDKUI_Localizator.MoreInfoCompleteRequestSentBy} ${taskMoreInfo?.fromName}!` }), _jsx(TMButton, { caption: SDKUI_Localizator.CommentAndComplete, color: 'success', showTooltip: false, onClick: () => {
1352
1508
  setShowCommentForm(true);
1353
1509
  } })] })), (showToppyForReferences && (dcmtReferences && dcmtReferences.length > 0)) && dcmtReferences
1354
1510
  .filter(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup) // keep only known objClass types
@@ -1399,7 +1555,8 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1399
1555
  finally {
1400
1556
  TMSpinner.hide();
1401
1557
  }
1402
- }, onClose: () => setShowManyToManyChooser(false), manageUseLocalizedName: false })), isOpenArchiveRelationForm && (_jsx(TMDcmtForm, { isModal: true, titleModal: SDKUI_Localizator.Archive + ' - ' + (archiveType === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster), TID: archiveRelatedDcmtFormTID, layoutMode: LayoutModes.Ark, inputMids: archiveRelatedDcmtFormMids, showBackButton: false, allowButtonsRefs: false, onClose: () => {
1558
+ }, onClose: () => setShowManyToManyChooser(false), manageUseLocalizedName: false })), (showHistory && fromDTD && currentDcmt) && _jsx(TMViewHistoryDcmt, { fromDTD: fromDTD, deviceType: deviceType, inputDcmt: { TID: currentDcmt.tid, DID: currentDcmt.did }, onClose: hideHistoryCallback, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), (showCheckoutInformationForm && fromDTD && currentDcmt) &&
1559
+ _jsx(TMDcmtCheckoutInfoForm, { dtdName: fromDTD.name ?? SDKUI_Localizator.SearchResult, selectedDcmtOrFocused: { TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt }, onClose: hideCheckoutInformationFormCallback }), (commentFormState.show && currentDcmt) && _jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid: currentDcmt.tid, did: currentDcmt.did } }, onClose: hideCommentFormCallback, refreshCallback: triggerBlogRefresh, participants: [], showAttachmentsSection: false, allArchivedDocumentsFileItems: [], isCommentRequired: commentFormState.isRequired, removeAndEditAttachment: commentFormState.removeAndEditAttachment }), isOpenArchiveRelationForm && (_jsx(TMDcmtForm, { isModal: true, titleModal: SDKUI_Localizator.Archive + ' - ' + (archiveType === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster), TID: archiveRelatedDcmtFormTID, layoutMode: LayoutModes.Ark, inputMids: archiveRelatedDcmtFormMids, showBackButton: false, allowButtonsRefs: false, onClose: () => {
1403
1560
  setIsOpenArchiveRelationForm(false);
1404
1561
  setArchiveType(undefined);
1405
1562
  setArchiveRelatedDcmtFormTID(undefined);
@@ -1410,7 +1567,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
1410
1567
  setArchiveRelatedDcmtFormTID(undefined);
1411
1568
  setArchiveRelatedDcmtFormMids([]);
1412
1569
  await fetchData();
1413
- }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers })), showPairDcmtsModal && (_jsx(TMModal, { title: (isPairingManyToMany ? "Abbina" : "Disabbina") + " documenti", onClose: () => setShowPairDcmtsModal(false), width: isMobile ? '90%' : '50%', height: isMobile ? '90%' : '70%', children: _jsx(TMSearchResult, { searchResults: pairedSearchResults, onRefreshSearchAsync: async () => await fetchData(), onTaskCreateRequest: onTaskCreateRequest, allowFloatingBar: false, floatingActionConfig: pairFloatingActionConfig, showBackButton: false, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }))] }));
1570
+ }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onReferenceClick: handleNavigateToReference })), showPairDcmtsModal && (_jsx(TMModal, { title: (isPairingManyToMany ? "Abbina" : "Disabbina") + " documenti", onClose: () => setShowPairDcmtsModal(false), width: isMobile ? '90%' : '50%', height: isMobile ? '90%' : '70%', children: _jsx(TMSearchResult, { searchResults: pairedSearchResults, onRefreshSearchAsync: async () => await fetchData(), onTaskCreateRequest: onTaskCreateRequest, allowFloatingBar: false, floatingActionConfig: pairFloatingActionConfig, showBackButton: false, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }))] }));
1414
1571
  };
1415
1572
  export default TMDcmtForm;
1416
1573
  /**
@@ -1433,8 +1590,11 @@ const applyMetadataFilter = (data, showAll, listMaxItems, TID) => {
1433
1590
  o.mid === SystemMIDsAsNumber.FileSize ||
1434
1591
  o.mid === SystemMIDsAsNumber.LastUpdateTime ||
1435
1592
  o.mid === SystemMIDsAsNumber.CreationTime;
1593
+ const chronologySystemFilter = (o) => baseFilter(o) ||
1594
+ o.mid === SystemMIDsAsNumber.FileExt ||
1595
+ o.mid === SystemMIDsAsNumber.FileSize;
1436
1596
  // Select the appropriate filter based on document type
1437
- const currentFilter = TID === SystemTIDs.Drafts ? draftFilter : baseFilter;
1597
+ const currentFilter = TID === SystemTIDs.Drafts ? draftFilter : TID === SystemTIDs.Chronology ? chronologySystemFilter : baseFilter;
1438
1598
  // Apply filter once
1439
1599
  const filteredData = data.filter(currentFilter);
1440
1600
  // Return all filtered data or slice to max items
@@ -1488,3 +1648,35 @@ const TMDcmtPreviewWrapper = ({ currentDcmt, layoutMode, fromDTD, dcmtFile, devi
1488
1648
  _jsx(TMDcmtPreview, { isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, dcmtData: currentDcmt, isResizingActive: isResizingActive }) :
1489
1649
  _jsx(TMFileUploader, { onFileUpload: onFileUpload, onClose: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive, enableDragDropOverlay: panelVisibility['tmDcmtPreview'] && enableDragDropOverlay }));
1490
1650
  };
1651
+ const Ribbon = styled.div `
1652
+ font-size: 0.85rem;
1653
+ font-weight: 600;
1654
+ color: #fff;
1655
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
1656
+ --f: .4em; /* control the folded part */
1657
+ position: absolute;
1658
+ top: 2px;
1659
+ left: 2px;
1660
+ z-index: 1200;
1661
+ line-height: 1.6;
1662
+ padding-inline: 0.8lh;
1663
+ padding-bottom: var(--f);
1664
+ border-image: conic-gradient(#0008 0 0) 51%/var(--f);
1665
+ clip-path: polygon(100% calc(100% - var(--f)),100% 100%,calc(100% - var(--f)) calc(100% - var(--f)),var(--f) calc(100% - var(--f)), 0 100%,0 calc(100% - var(--f)),999px calc(100% - var(--f) - 999px),calc(100% - 999px) calc(100% - var(--f) - 999px));
1666
+ transform: translate(calc((cos(45deg) - 1)*100%), -100%) rotate(-45deg);
1667
+ transform-origin: 100% 100%;
1668
+ background-color: rgba(217, 148, 13, 0.92);
1669
+ display: inline-block;
1670
+ padding-top: 0.1em;
1671
+ white-space: nowrap;
1672
+ transition: ${props => props.$isMobile ? 'none' : 'all 0.3s ease'};
1673
+ cursor: 'default';
1674
+
1675
+ ${props => !props.$isMobile && `
1676
+ &:hover {
1677
+ background-color: #d9940d;
1678
+ font-size: 1.1rem;
1679
+ transform: translate(calc((cos(45deg) - 1)*100%), -100%) rotate(-45deg) scale(1.05);
1680
+ }
1681
+ `}
1682
+ `;