@topconsultnpm/sdkui-react 6.21.0-t1 → 6.21.0-t2

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 (91) hide show
  1. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +4 -4
  2. package/lib/components/base/TMAccordionNew.d.ts +1 -0
  3. package/lib/components/base/TMAccordionNew.js +6 -5
  4. package/lib/components/base/TMAreaManager.js +19 -3
  5. package/lib/components/base/TMDataGrid.js +2 -2
  6. package/lib/components/base/TMModal.d.ts +1 -0
  7. package/lib/components/base/TMModal.js +2 -2
  8. package/lib/components/base/TMPanel.d.ts +7 -4
  9. package/lib/components/base/TMPanel.js +58 -26
  10. package/lib/components/base/TMTreeView.js +12 -2
  11. package/lib/components/base/TMWaitPanel.js +7 -4
  12. package/lib/components/choosers/TMDistinctValues.js +35 -21
  13. package/lib/components/choosers/TMUserChooser.d.ts +4 -0
  14. package/lib/components/choosers/TMUserChooser.js +7 -5
  15. package/lib/components/editors/TMDateBox.js +4 -2
  16. package/lib/components/editors/TMFormulaEditor.d.ts +2 -0
  17. package/lib/components/editors/TMFormulaEditor.js +75 -21
  18. package/lib/components/editors/TMMetadataValues.js +2 -1
  19. package/lib/components/editors/TMRadioButton.js +7 -5
  20. package/lib/components/editors/TMTextArea.d.ts +2 -0
  21. package/lib/components/editors/TMTextArea.js +6 -3
  22. package/lib/components/editors/TMTextBox.d.ts +2 -0
  23. package/lib/components/editors/TMTextBox.js +3 -3
  24. package/lib/components/features/archive/TMArchive.js +1 -1
  25. package/lib/components/features/documents/TMCopyToFolderForm.d.ts +24 -0
  26. package/lib/components/features/documents/TMCopyToFolderForm.js +379 -0
  27. package/lib/components/features/documents/TMDcmtForm.d.ts +1 -0
  28. package/lib/components/features/documents/TMDcmtForm.js +147 -45
  29. package/lib/components/features/documents/TMDcmtFormActionButtons.js +259 -60
  30. package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -0
  31. package/lib/components/features/documents/TMDcmtPreview.js +2 -2
  32. package/lib/components/features/documents/TMDcmtTasks.d.ts +1 -0
  33. package/lib/components/features/documents/TMDcmtTasks.js +2 -2
  34. package/lib/components/features/documents/TMDownloadRelationViewerSection.d.ts +23 -0
  35. package/lib/components/features/documents/TMDownloadRelationViewerSection.js +173 -0
  36. package/lib/components/features/documents/TMFileUploader.js +1 -1
  37. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +4 -0
  38. package/lib/components/features/documents/TMMasterDetailDcmts.js +29 -9
  39. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +26 -0
  40. package/lib/components/features/documents/TMMergeToPdfForm.js +293 -0
  41. package/lib/components/features/documents/TMRelationViewer.d.ts +13 -0
  42. package/lib/components/features/documents/TMRelationViewer.js +75 -6
  43. package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +71 -0
  44. package/lib/components/features/documents/copyAndMergeDcmtsShared.js +304 -0
  45. package/lib/components/features/search/SignatureParamsManager.d.ts +70 -0
  46. package/lib/components/features/search/SignatureParamsManager.js +145 -0
  47. package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
  48. package/lib/components/features/search/TMSavedQuerySelector.js +3 -2
  49. package/lib/components/features/search/TMSearch.d.ts +6 -1
  50. package/lib/components/features/search/TMSearch.js +16 -10
  51. package/lib/components/features/search/TMSearchQueryPanel.js +1 -1
  52. package/lib/components/features/search/TMSearchResult.d.ts +4 -0
  53. package/lib/components/features/search/TMSearchResult.js +118 -22
  54. package/lib/components/features/search/TMViewHistoryDcmt.js +1 -2
  55. package/lib/components/features/workflow/TMWorkflowPopup.js +3 -0
  56. package/lib/components/features/workflow/diagram/queryDescriptorParser.js +3 -6
  57. package/lib/components/forms/Login/TMLoginForm.d.ts +9 -0
  58. package/lib/components/forms/Login/TMLoginForm.js +61 -0
  59. package/lib/components/forms/TMResultDialog.d.ts +1 -1
  60. package/lib/components/forms/TMResultDialog.js +4 -2
  61. package/lib/components/grids/TMBlogAttachments.d.ts +1 -0
  62. package/lib/components/grids/TMBlogAttachments.js +38 -12
  63. package/lib/components/grids/TMBlogsPost.js +7 -1
  64. package/lib/components/grids/TMBlogsPostUtils.js +11 -17
  65. package/lib/components/index.d.ts +1 -0
  66. package/lib/components/index.js +1 -0
  67. package/lib/components/pages/TMPage.js +3 -1
  68. package/lib/components/query/TMQueryEditor.js +2 -2
  69. package/lib/components/viewers/TMTidViewer.js +1 -1
  70. package/lib/helper/GlobalStyles.js +6 -0
  71. package/lib/helper/SDKUI_Globals.d.ts +15 -0
  72. package/lib/helper/SDKUI_Globals.js +15 -1
  73. package/lib/helper/SDKUI_Localizator.d.ts +106 -2
  74. package/lib/helper/SDKUI_Localizator.js +1060 -12
  75. package/lib/helper/TMPdfViewer.js +25 -24
  76. package/lib/helper/TMUtils.d.ts +20 -0
  77. package/lib/helper/TMUtils.js +17 -0
  78. package/lib/helper/ZipManager.d.ts +56 -0
  79. package/lib/helper/ZipManager.js +127 -0
  80. package/lib/helper/index.d.ts +1 -0
  81. package/lib/helper/index.js +1 -0
  82. package/lib/hooks/useDataUserIdItem.js +6 -4
  83. package/lib/hooks/useDcmtOperations.d.ts +9 -2
  84. package/lib/hooks/useDcmtOperations.js +78 -35
  85. package/lib/hooks/useDocumentOperations.d.ts +5 -0
  86. package/lib/hooks/useDocumentOperations.js +238 -27
  87. package/lib/hooks/useForm.js +5 -2
  88. package/lib/hooks/useResizeObserver.d.ts +1 -1
  89. package/lib/hooks/useResizeObserver.js +16 -15
  90. package/lib/ts/types.d.ts +1 -0
  91. package/package.json +3 -2
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import TMDcmtPreview from './TMDcmtPreview';
4
- import { AccessLevelsEx, AppModules, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataDomains, MetadataDataTypes, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TID_DID, UpdateEngineByID, UserListCacheService, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
4
+ import { AccessLevelsEx, AppModules, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, DossierCacheService, LayoutCacheService, LayoutModes, MetadataDataDomains, MetadataDataTypes, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TID_DID, UpdateEngineByID, UserListCacheService, ValidationItem, WorkflowCacheService, WorkingGroupCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
5
5
  import { FormModes, SearchResultContext } from '../../../ts';
6
6
  import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
7
7
  import { getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
@@ -57,7 +57,7 @@ export var InvocationContext;
57
57
  let abortControllerLocal = new AbortController();
58
58
  ;
59
59
  //#endregion
60
- const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMode = FormModes.Update, invocationContext = InvocationContext.Default, showHeader = true, showBackButton = true, showDcmtFormSidebar = true, isClosable = false, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, isModal = false, titleModal, widthModal = "100%", heightModal = "100%", allowNavigation = true, canNext, canPrev, count, itemIndex, onNext, onPrev, inputFile = null, inputMids = [], connectorFileSave = undefined, isSharedDcmt = false, sharedSourceTID, sharedSourceDID, allowRelations = true, allowButtonsRefs = false, openS4TViewer = false, enableDragDropOverlay = false, onClose, onSavedAsyncCallback, onSaveRecents, onWFOperationCompleted, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, onTaskCompleted, onTaskCreateRequest, moreInfoTasks, taskFormDialogComponent, handleNavigateToWGs, handleNavigateToDossiers, onReferenceClick, onOpenS4TViewerRequest, onOpenPdfEditorRequest, openFileUploaderPdfEditor, s4TViewerDialogComponent, onScanRequest, passToSearch, datagridUtility }) => {
60
+ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMode = FormModes.Update, invocationContext = InvocationContext.Default, showHeader = true, showBackButton = true, showDcmtFormSidebar = true, isClosable = false, showTodoDcmtForm = false, isExpertMode = SDKUI_Globals.userSettings.advancedSettings.expertMode === 1, isModal = false, titleModal, widthModal = "100%", heightModal = "100%", allowNavigation = true, canNext, canPrev, count, itemIndex, onNext, onPrev, inputFile = null, inputMids = [], connectorFileSave = undefined, isSharedDcmt = false, sharedSourceTID, sharedSourceDID, allowRelations = true, allowButtonsRefs = false, openS4TViewer = false, enableDragDropOverlay = false, onClose, onSavedAsyncCallback, onSaveRecents, onWFOperationCompleted, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, onTaskCompleted, onTaskCreateRequest, moreInfoTasks, taskFormDialogComponent, handleNavigateToWGs, handleNavigateToDossiers, onReferenceClick, onOpenS4TViewerRequest, onOpenPdfEditorRequest, openFileUploaderPdfEditor, s4TViewerDialogComponent, onScanRequest, passToSearch, datagridUtility }) => {
61
61
  const { onRefreshSearchAsyncDatagrid, onRefreshBlogDatagrid, onRefreshPreviewDatagrid } = datagridUtility || {};
62
62
  const floatingBarContainerRef = useRef(null);
63
63
  const [id, setID] = useState('');
@@ -91,6 +91,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
91
91
  const formDataRef = useRef([]);
92
92
  const fromDTDRef = useRef();
93
93
  const dcmtFileRef = useRef(null);
94
+ const metadataDcmtOriginRef = useRef(null);
94
95
  const [isOpenDistinctValues, setIsOpenDistinctValues] = useState(false);
95
96
  const [isOpenFormulaEditor, setIsOpenFormulaEditor] = useState(false);
96
97
  const [currentTIDHasDetailRelations, setCurrentTIDHasDetailRelations] = useState();
@@ -114,6 +115,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
114
115
  const [refreshPreviewTrigger, setRefreshPreviewTrigger] = useState(0);
115
116
  const [wfError, setWfError] = useState(null);
116
117
  const [metadataDcmtOrigin, setMetadataDcmtOrigin] = useState(null);
118
+ const { workflowApproveData, getWorkItemsByDID } = useWorkflowApprove();
117
119
  // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
118
120
  const deviceType = useDeviceType();
119
121
  // This avoids unnecessary re-renders by only recalculating when deviceType changes.
@@ -134,7 +136,30 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
134
136
  if (!did)
135
137
  return;
136
138
  TMSpinner.show({ description: 'Loading Metadata...' });
137
- let res = getMetadataResult ?? await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(TID, did, true);
139
+ let res = getMetadataResult;
140
+ if (!res) {
141
+ try {
142
+ res = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(TID, did, true);
143
+ }
144
+ catch (metadataError) {
145
+ // Estrai ErrorCode dal campo detail se disponibile
146
+ let errorCode = undefined;
147
+ if (metadataError?.isApiException && metadataError?.response?.detail) {
148
+ try {
149
+ const detailObj = JSON.parse(metadataError.response.detail);
150
+ errorCode = detailObj?.ErrorCode;
151
+ }
152
+ catch (parseError) {
153
+ console.log("Impossibile parsare il detail dell'eccezione:", parseError);
154
+ }
155
+ }
156
+ // Se ErrorCode è -5, ignora silenziosamente, altrimenti mostra l'eccezione originale
157
+ if (errorCode !== -5) {
158
+ TMExceptionBoxManager.show({ exception: metadataError });
159
+ }
160
+ return;
161
+ }
162
+ }
138
163
  const origin = { fromName: res?.fromName, fromTID: res?.fromTID };
139
164
  let dtd = res?.dtdResult;
140
165
  let rows = dtd.rows ? dtd.rows[0] : [];
@@ -235,7 +260,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
235
260
  const handleReset = useCallback(() => {
236
261
  setDcmtFile(null);
237
262
  }, []);
238
- const onRefreshSearchAsync = useCallback(async () => {
263
+ const loadDocumentFormDataAsync = useCallback(async () => {
239
264
  try {
240
265
  setFetchError(false);
241
266
  if (!TID)
@@ -254,12 +279,34 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
254
279
  layoutMode === LayoutModes.Update
255
280
  ? LayoutCacheService.GetAsync(TID, LayoutModes.None)
256
281
  : Promise.resolve(undefined),
257
- // 4. Opcionalmente FindAllReferencesAsync se abilitato nelle impostazioni e se i bottoni sono richiesti
258
- (() => {
259
- const refs = SDKUI_Globals?.userSettings?.searchSettings?.autoFindReferences ?? [];
260
- const hasRefs = allowButtonsRefs && Array.isArray(refs) && refs.length > 0;
282
+ // 4. FindAllReferencesAsync - Cerca riferimenti a WorkingGroup, Dossier e Workflow se presenti nel sistema e se allowButtonsRefs è abilitato
283
+ (async () => {
284
+ // Array per raccogliere le classi di riferimento da cercare
285
+ const refs = [];
286
+ // Recupera working groups, dossier e dati di approvazione workflow in parallelo
287
+ const [workingGroups, dossiers] = await Promise.all([
288
+ WorkingGroupCacheService.GetAllAsync(),
289
+ DossierCacheService.GetAllAsync(),
290
+ ]);
291
+ // Aggiunge WorkingGroup se esistono WG diversi da quello di sistema (id=1)
292
+ if (workingGroups.filter(wg => wg.id !== 1).length > 0) {
293
+ refs.push(ObjectClasses.WorkingGroup);
294
+ }
295
+ // Aggiunge Dossier se ne esistono
296
+ if (dossiers.length > 0) {
297
+ refs.push(ObjectClasses.Dossier);
298
+ }
299
+ // Aggiunge Workflow se ci sono dati di approvazione presenti
300
+ if (workflowApproveData.length > 0) {
301
+ refs.push(ObjectClasses.Workflow);
302
+ }
303
+ // Recupera le preferenze utente per autoFindReferences e le merge con i refs già raccolti
304
+ const userRefs = SDKUI_Globals?.userSettings?.searchSettings?.autoFindReferences ?? [];
305
+ const mergedRefs = [...new Set([...refs, ...userRefs])];
306
+ // Verifica se ci sono riferimenti da cercare e se i bottoni sono abilitati
307
+ const hasRefs = allowButtonsRefs && Array.isArray(mergedRefs) && mergedRefs.length > 0;
261
308
  return hasRefs
262
- ? SDK_Globals.tmSession?.NewSearchEngine().FindAllReferencesAsync(TID, DID, refs) ?? Promise.resolve(undefined)
309
+ ? SDK_Globals.tmSession?.NewSearchEngine().FindAllReferencesAsync(TID, DID, mergedRefs) ?? Promise.resolve(undefined)
263
310
  : Promise.resolve(undefined);
264
311
  })()
265
312
  ];
@@ -284,7 +331,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
284
331
  }
285
332
  else {
286
333
  const renderedMetadata = dtd?.metadata?.filter((metadata) => handleArchiveVisibility(metadata)) ?? [];
287
- const metadataList = searchResultToMetadataValues(dtd?.id, undefined, [], [], renderedMetadata, layoutMode, isReadOnlyOriginCallback(metadataDcmtOrigin?.fromTID));
334
+ const metadataList = searchResultToMetadataValues(dtd?.id, undefined, [], [], renderedMetadata, layoutMode, isReadOnlyOriginCallback(metadataDcmtOriginRef.current?.fromTID));
288
335
  setFormDataOrig(structuredClone(metadataList));
289
336
  setFormData(structuredClone(metadataList));
290
337
  formDataOrigRef.current = structuredClone(metadataList);
@@ -299,7 +346,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
299
346
  setIsInitialLoading(false);
300
347
  setIsNavigating(false);
301
348
  }
302
- }, [TID, DID, layoutMode, inputFile, setMetadataList, handleReset, allowButtonsRefs, isReadOnlyOriginCallback, metadataDcmtOrigin?.fromTID]);
349
+ }, [TID, DID, layoutMode, inputFile, setMetadataList, handleReset, allowButtonsRefs, isReadOnlyOriginCallback]);
303
350
  const currentSearchResults = useMemo(() => {
304
351
  if (!formData || formData.length === 0 || !TID || !DID)
305
352
  return [];
@@ -342,8 +389,8 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
342
389
  context: SearchResultContext.DCMT_FORM,
343
390
  documentData: {
344
391
  dtd: fromDTD,
345
- selectedItems: currentDcmt ? [{ TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt, rowIndex: 0 }] : [],
346
- focusedItem: currentDcmt ? { TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt, rowIndex: 0 } : undefined,
392
+ selectedItems: currentDcmt ? [{ TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt, ISSIGNED: currentDcmt.isSigned ?? 0, rowIndex: 0 }] : [],
393
+ focusedItem: currentDcmt ? { TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt, ISSIGNED: currentDcmt.isSigned ?? 0, rowIndex: 0 } : undefined,
347
394
  searchResult: currentSearchResults ? currentSearchResults[0] : undefined,
348
395
  currentSearchResults,
349
396
  currentMetadataValues: formData,
@@ -385,7 +432,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
385
432
  },
386
433
  callbacks: {
387
434
  // Refresh operations (data consistency)
388
- onRefreshSearchAsync,
435
+ onRefreshSearchAsync: loadDocumentFormDataAsync,
389
436
  onSavedAsyncCallback,
390
437
  // Workflow operations
391
438
  onWFOperationCompleted,
@@ -413,7 +460,6 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
413
460
  if (!allowButtonsRefs)
414
461
  setDcmtReferences(undefined);
415
462
  }, [allowButtonsRefs]);
416
- const { workflowApproveData, getWorkItemsByDID } = useWorkflowApprove();
417
463
  const fetchErrorShownRef = useRef(false);
418
464
  useEffect(() => {
419
465
  if (!TID)
@@ -455,6 +501,9 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
455
501
  useEffect(() => {
456
502
  dcmtFileRef.current = dcmtFile;
457
503
  }, [dcmtFile]);
504
+ useEffect(() => {
505
+ metadataDcmtOriginRef.current = metadataDcmtOrigin;
506
+ }, [metadataDcmtOrigin]);
458
507
  useEffect(() => {
459
508
  if (!inputFile || inputFile === null)
460
509
  return;
@@ -467,12 +516,12 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
467
516
  // Distinguish between initial load and navigation
468
517
  if (isInitialLoading) {
469
518
  // First load - keep isInitialLoading true
470
- await onRefreshSearchAsync();
519
+ await loadDocumentFormDataAsync();
471
520
  }
472
521
  else {
473
522
  // Navigation - use isNavigating instead
474
523
  setIsNavigating(true);
475
- await onRefreshSearchAsync();
524
+ await loadDocumentFormDataAsync();
476
525
  }
477
526
  }
478
527
  catch (e) {
@@ -486,7 +535,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
486
535
  }
487
536
  };
488
537
  run();
489
- }, [TID, DID, onRefreshSearchAsync]);
538
+ }, [TID, DID, loadDocumentFormDataAsync]);
490
539
  useEffect(() => {
491
540
  if (formData.length > 0) {
492
541
  setValidationItems(validateMetadataList(formData));
@@ -495,14 +544,16 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
495
544
  did: formData.find(o => o.mid == SystemMIDsAsNumber.DID)?.value,
496
545
  fileCount: formData.find(o => o.mid == SystemMIDsAsNumber.FileCount)?.value,
497
546
  fileSize: formData.find(o => o.mid == SystemMIDsAsNumber.FileSize)?.value,
498
- fileExt: formData.find(o => o.mid == SystemMIDsAsNumber.FileExt)?.value
547
+ fileExt: formData.find(o => o.mid == SystemMIDsAsNumber.FileExt)?.value,
548
+ isSigned: formData.find(o => o.mid == SystemMIDsAsNumber.IsSigned)?.value?.toString() === '1' ? 1 : 0,
499
549
  };
500
550
  if (!currentDcmt ||
501
551
  currentDcmt.tid !== newDcmt.tid ||
502
552
  currentDcmt.did !== newDcmt.did ||
503
553
  currentDcmt.fileExt !== newDcmt.fileExt ||
504
554
  currentDcmt.fileSize !== newDcmt.fileSize ||
505
- currentDcmt.fileCount !== newDcmt.fileCount) {
555
+ currentDcmt.fileCount !== newDcmt.fileCount ||
556
+ currentDcmt.isSigned !== newDcmt.isSigned) {
506
557
  setCurrentDcmt(newDcmt);
507
558
  }
508
559
  }
@@ -751,7 +802,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
751
802
  // Verifica che ci siano riferimenti renderizzabili (solo Dossier o WorkingGroup)
752
803
  return dcmtReferences.some(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup);
753
804
  }, [allowButtonsRefs, layoutMode, dcmtReferences, isOpenDetails, isOpenMaster]);
754
- const isToppyVisible = useMemo(() => Boolean((showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences) && !openS4TViewer), [showToppyForApprove, showToppyForCompleteMoreInfo, showToppyForReferences, openS4TViewer]);
805
+ const isToppyVisible = useMemo(() => Boolean((showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences) && !openS4TViewer && !showTodoDcmtForm), [showToppyForApprove, showToppyForCompleteMoreInfo, showToppyForReferences, openS4TViewer, showTodoDcmtForm]);
755
806
  const isModified = useMemo(() => calcIsModified(formData, formDataOrig), [formData, formDataOrig]);
756
807
  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 &&
757
808
  _jsx(ContextMenu, { items: operationItems, trigger: "left", children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) }), layoutMode === LayoutModes.Ark &&
@@ -820,7 +871,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
820
871
  const handleArchiveCompleted = useCallback(async () => {
821
872
  let firstBlock = true;
822
873
  let maxFileSize = 0;
823
- let operationTitle = 'Archiviazione';
874
+ let operationTitle = SDKUI_Localizator.Archiving;
824
875
  setUseWaitPanelLocalState(true);
825
876
  setShowWaitPanelLocal(true);
826
877
  setShowPrimaryLocal(false);
@@ -869,7 +920,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
869
920
  firstBlock = false;
870
921
  }
871
922
  setWaitPanelValueSecondaryLocal(pd.ProgressBarValue);
872
- setWaitPanelTextSecondaryLocal(`Archiviazione... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
923
+ setWaitPanelTextSecondaryLocal(`${SDKUI_Localizator.Archiving}... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
873
924
  if (pd.ProgressBarValue === pd.ProgressBarMaximum) {
874
925
  setWaitPanelMaxValueSecondaryLocal(0);
875
926
  setWaitPanelValueSecondaryLocal(0);
@@ -992,6 +1043,21 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
992
1043
  fd.tid = TID;
993
1044
  return fd;
994
1045
  }, [focusedMetadataValue?.value, focusedMetadataValue?.mid, TID]);
1046
+ /**
1047
+ * Restituisce l'handler onBack per i pannelli, evitando duplicazione di codice.
1048
+ * @param isMainPanel - Se true, è il pannello principale (tmDcmtForm)
1049
+ */
1050
+ const getOnBackHandler = (isMainPanel = false) => {
1051
+ // Se showBackButton è false, non mostrare mai il back
1052
+ if (showBackButton === false)
1053
+ return undefined;
1054
+ // Mobile: mostra back su tutti i pannelli (se showBackButton è definito e non è closable)
1055
+ if (isMobile) {
1056
+ return (showBackButton !== undefined && !isClosable) ? handleClose : undefined;
1057
+ }
1058
+ // Desktop: mostra back solo sul pannello principale (se showBackButton è definito e non è closable)
1059
+ return (showBackButton !== undefined && isMainPanel && !isClosable) ? handleClose : undefined;
1060
+ };
995
1061
  // Determina se showAll deve essere automaticamente true
996
1062
  // Best practice: usa useMemo per calcolare valori derivati invece di useEffect con setState
997
1063
  const shouldShowAll = useMemo(() => {
@@ -1076,7 +1142,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1076
1142
  ]);
1077
1143
  const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: TID, did: DID, fetchBlogDataTrigger: refreshBlogTrigger, onRefreshBlogDatagrid: onRefreshBlogDatagrid, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [TID, DID, allTasks, refreshBlogTrigger, handleNavigateToWGs, handleNavigateToDossiers]);
1078
1144
  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]);
1079
- const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { refreshPreviewTrigger: refreshPreviewTrigger, fromDTD: fromDTD, currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, layoutMode: layoutMode, onFileUpload: (file) => { setDcmtFile(file); }, openFileUploaderPdfEditor: openFileUploaderPdfEditor, enableDragDropOverlay: enableDragDropOverlay, onScanRequest: onScanRequest }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile, onScanRequest, openFileUploaderPdfEditor, refreshPreviewTrigger]);
1145
+ const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { refreshPreviewTrigger: refreshPreviewTrigger, fromDTD: fromDTD, currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, onBack: getOnBackHandler(), layoutMode: layoutMode, onFileUpload: (file) => { setDcmtFile(file); }, openFileUploaderPdfEditor: openFileUploaderPdfEditor, enableDragDropOverlay: enableDragDropOverlay, onScanRequest: onScanRequest }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile, onScanRequest, openFileUploaderPdfEditor, refreshPreviewTrigger]);
1080
1146
  const tmWF = useMemo(() => {
1081
1147
  if (isWFDataLoading) {
1082
1148
  return (_jsx("div", { style: {
@@ -1147,7 +1213,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1147
1213
  did: Number(DID),
1148
1214
  name: fromDTD?.nameLoc ?? SDKUI_Localizator.Widget_Activities,
1149
1215
  },
1150
- }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, afterTaskSaved: afterTaskSaved, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }));
1216
+ }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, afterTaskSaved: afterTaskSaved, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onBack: getOnBackHandler() }));
1151
1217
  }, [allTasks, TID, DID, fromDTD]);
1152
1218
  const normalizedTID = TID !== undefined ? Number(TID) : undefined;
1153
1219
  const defaultPanelDimensions = {
@@ -1206,7 +1272,7 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1206
1272
  showHeader: showHeader,
1207
1273
  title: titleDcmtFormPanel,
1208
1274
  allowMaximize: !isMobile,
1209
- onBack: showBackButton ? (isClosable && deviceType !== DeviceType.MOBILE) ? undefined : handleClose : undefined,
1275
+ onBack: getOnBackHandler(true),
1210
1276
  onClose: isClosable ? () => { } : undefined,
1211
1277
  toolbar: allowNavigation ? formToolbar : _jsx(_Fragment, {})
1212
1278
  },
@@ -1221,7 +1287,14 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1221
1287
  {
1222
1288
  id: 'tmBlog',
1223
1289
  name: SDKUI_Localizator.BlogCase,
1224
- contentOptions: { component: tmBlog, panelContainer: { title: SDKUI_Localizator.BlogCase, allowMaximize: !isMobile } },
1290
+ contentOptions: {
1291
+ component: tmBlog,
1292
+ panelContainer: {
1293
+ title: SDKUI_Localizator.BlogCase,
1294
+ allowMaximize: !isMobile,
1295
+ onBack: getOnBackHandler(),
1296
+ }
1297
+ },
1225
1298
  toolbarOptions: {
1226
1299
  icon: _jsx(IconBoard, { fontSize: 24 }),
1227
1300
  visible: getDcmtFormToolbarVisibility(SDK_Globals.tmSession?.SessionDescr?.appModuleID ?? AppModules.SURFER).tmBlog,
@@ -1233,7 +1306,14 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1233
1306
  {
1234
1307
  id: 'tmSysMetadata',
1235
1308
  name: SDKUI_Localizator.MetadataSystem,
1236
- contentOptions: { component: tmSysMetadata, panelContainer: { title: SDKUI_Localizator.MetadataSystem, allowMaximize: !isMobile } },
1309
+ contentOptions: {
1310
+ component: tmSysMetadata,
1311
+ panelContainer: {
1312
+ title: SDKUI_Localizator.MetadataSystem,
1313
+ allowMaximize: !isMobile,
1314
+ onBack: getOnBackHandler(),
1315
+ }
1316
+ },
1237
1317
  toolbarOptions: { icon: _jsx(IconDcmtTypeSys, { fontSize: 24 }), visible: getDcmtFormToolbarVisibility(SDK_Globals.tmSession?.SessionDescr?.appModuleID ?? AppModules.SURFER).tmSysMetadata, disabled: isSysMetadataDisabled, orderNumber: 3, isActive: allInitialPanelVisibility['tmSysMetadata'] }
1238
1318
  },
1239
1319
  {
@@ -1254,7 +1334,8 @@ const TMDcmtForm = ({ TID, DID, groupId, layoutMode = LayoutModes.Update, formMo
1254
1334
  contentOptions: {
1255
1335
  component: tmWF,
1256
1336
  panelContainer: {
1257
- title: "Workflow", allowMaximize: !isMobile
1337
+ title: "Workflow", allowMaximize: !isMobile,
1338
+ onBack: getOnBackHandler(),
1258
1339
  }
1259
1340
  },
1260
1341
  toolbarOptions: {
@@ -1513,38 +1594,59 @@ const validateMaxLength = (mvd, value, validationItems) => {
1513
1594
  //#endregion Validation
1514
1595
  // Synchronizes panel visibility and toolbar button disabled states when panels become disabled
1515
1596
  const PanelDisabledStateHandler = ({ isWFDisabled, isSysMetadataDisabled, isBoardDisabled, isDcmtTasksDisabled, isPreviewDisabled }) => {
1516
- const { setPanelVisibilityById, setToolbarButtonDisabled, panelVisibility } = useTMPanelManagerContext();
1597
+ const { setPanelVisibilityById, setToolbarButtonDisabled } = useTMPanelManagerContext();
1517
1598
  useEffect(() => {
1518
- // Aggiorna lo stato disabled del bottone toolbar
1519
- setToolbarButtonDisabled('tmSysMetadata', isSysMetadataDisabled);
1520
- setToolbarButtonDisabled('tmBlog', isBoardDisabled);
1521
- setToolbarButtonDisabled('tmWF', isWFDisabled);
1522
- setToolbarButtonDisabled('tmDcmtTasks', isDcmtTasksDisabled);
1523
- setToolbarButtonDisabled('tmDcmtPreview', isPreviewDisabled);
1524
- // Chiude il pannello solo se è attualmente visibile e deve essere disabilitato
1525
- if (isSysMetadataDisabled && panelVisibility['tmSysMetadata']) {
1599
+ if (isSysMetadataDisabled) {
1600
+ setToolbarButtonDisabled('tmSysMetadata', true);
1526
1601
  setPanelVisibilityById('tmSysMetadata', false);
1527
1602
  }
1528
- if (isBoardDisabled && panelVisibility['tmBlog']) {
1603
+ else {
1604
+ setToolbarButtonDisabled('tmSysMetadata', false);
1605
+ }
1606
+ }, [isSysMetadataDisabled]);
1607
+ useEffect(() => {
1608
+ if (isBoardDisabled) {
1609
+ setToolbarButtonDisabled('tmBlog', true);
1529
1610
  setPanelVisibilityById('tmBlog', false);
1530
1611
  }
1531
- if (isWFDisabled && panelVisibility['tmWF']) {
1612
+ else {
1613
+ setToolbarButtonDisabled('tmBlog', false);
1614
+ }
1615
+ }, [isBoardDisabled]);
1616
+ useEffect(() => {
1617
+ if (isWFDisabled) {
1618
+ setToolbarButtonDisabled('tmWF', true);
1532
1619
  setPanelVisibilityById('tmWF', false);
1533
1620
  }
1534
- if (isDcmtTasksDisabled && panelVisibility['tmDcmtTasks']) {
1621
+ else {
1622
+ setToolbarButtonDisabled('tmWF', false);
1623
+ }
1624
+ }, [isWFDisabled]);
1625
+ useEffect(() => {
1626
+ if (isDcmtTasksDisabled) {
1627
+ setToolbarButtonDisabled('tmDcmtTasks', true);
1535
1628
  setPanelVisibilityById('tmDcmtTasks', false);
1536
1629
  }
1537
- if (isPreviewDisabled && panelVisibility['tmDcmtPreview']) {
1630
+ else {
1631
+ setToolbarButtonDisabled('tmDcmtTasks', false);
1632
+ }
1633
+ }, [isDcmtTasksDisabled]);
1634
+ useEffect(() => {
1635
+ if (isPreviewDisabled) {
1636
+ setToolbarButtonDisabled('tmDcmtPreview', true);
1538
1637
  setPanelVisibilityById('tmDcmtPreview', false);
1539
1638
  }
1540
- }, [isSysMetadataDisabled, isBoardDisabled, isWFDisabled, isDcmtTasksDisabled, isPreviewDisabled, setPanelVisibilityById, setToolbarButtonDisabled, panelVisibility]);
1639
+ else {
1640
+ setToolbarButtonDisabled('tmDcmtPreview', false);
1641
+ }
1642
+ }, [isPreviewDisabled]);
1541
1643
  return null;
1542
1644
  };
1543
- const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, fromDTD, currentDcmt, layoutMode, dcmtFile, deviceType, isVisible, onFileUpload, openFileUploaderPdfEditor, enableDragDropOverlay = false, onScanRequest }) => {
1645
+ const TMDcmtPreviewWrapper = ({ refreshPreviewTrigger, fromDTD, currentDcmt, layoutMode, dcmtFile, deviceType, isVisible, onFileUpload, openFileUploaderPdfEditor, enableDragDropOverlay = false, onScanRequest, onBack }) => {
1544
1646
  const { setPanelVisibilityById, toggleMaximize, isResizingActive, countVisibleLeafPanels, panelVisibility } = useTMPanelManagerContext();
1545
1647
  const isMobile = deviceType === DeviceType.MOBILE;
1546
1648
  return (layoutMode === LayoutModes.Update ?
1547
- _jsx(TMDcmtPreview, { dcmtData: currentDcmt, isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, isResizingActive: isResizingActive }, refreshPreviewTrigger) :
1649
+ _jsx(TMDcmtPreview, { dcmtData: currentDcmt, isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, onBack: onBack, isResizingActive: isResizingActive }, refreshPreviewTrigger) :
1548
1650
  _jsx(TMFileUploader, { fromDTD: fromDTD, onFileUpload: onFileUpload, openFileUploaderPdfEditor: openFileUploaderPdfEditor, 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, onScanRequest: onScanRequest }));
1549
1651
  };
1550
1652
  const Ribbon = styled.div `