@topconsultnpm/sdkui-react 6.19.0-dev1.9 → 6.19.0-dev2.2

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 (116) hide show
  1. package/lib/components/base/Styled.d.ts +1 -0
  2. package/lib/components/base/Styled.js +40 -0
  3. package/lib/components/base/TMCustomButton.d.ts +11 -0
  4. package/lib/components/base/TMCustomButton.js +63 -0
  5. package/lib/components/base/TMFileManagerDataGridView.js +4 -1
  6. package/lib/components/base/TMLayout.d.ts +2 -1
  7. package/lib/components/base/TMLayout.js +2 -2
  8. package/lib/components/base/TMPopUp.js +5 -18
  9. package/lib/components/base/TMTreeView.js +3 -2
  10. package/lib/components/editors/TMHtmlEditor.d.ts +5 -0
  11. package/lib/components/editors/TMHtmlEditor.js +72 -12
  12. package/lib/components/editors/TMMetadataValues.js +90 -40
  13. package/lib/components/features/archive/TMArchive.d.ts +10 -0
  14. package/lib/components/features/archive/TMArchive.js +56 -25
  15. package/lib/components/features/blog/TMBlogCommentForm.d.ts +4 -4
  16. package/lib/components/features/blog/TMBlogCommentForm.js +76 -51
  17. package/lib/components/features/documents/TMDcmtBlog.d.ts +15 -0
  18. package/lib/components/features/documents/TMDcmtBlog.js +21 -33
  19. package/lib/components/features/documents/TMDcmtForm.d.ts +17 -3
  20. package/lib/components/features/documents/TMDcmtForm.js +205 -46
  21. package/lib/components/features/documents/TMDcmtTasks.d.ts +13 -0
  22. package/lib/components/features/documents/TMDcmtTasks.js +24 -0
  23. package/lib/components/features/documents/TMDragDropOverlay.js +2 -1
  24. package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +8 -1
  25. package/lib/components/features/documents/TMMasterDetailDcmts.js +6 -6
  26. package/lib/components/features/documents/TMRelationViewer.d.ts +53 -3
  27. package/lib/components/features/documents/TMRelationViewer.js +232 -85
  28. package/lib/components/features/search/TMSearch.d.ts +10 -1
  29. package/lib/components/features/search/TMSearch.js +14 -5
  30. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
  31. package/lib/components/features/search/TMSearchQueryPanel.js +36 -7
  32. package/lib/components/features/search/TMSearchResult.d.ts +10 -1
  33. package/lib/components/features/search/TMSearchResult.js +140 -422
  34. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -2
  35. package/lib/components/features/search/TMSearchResultsMenuItems.js +33 -8
  36. package/lib/components/features/tasks/TMTaskForm.d.ts +38 -0
  37. package/lib/components/features/tasks/TMTaskForm.js +386 -0
  38. package/lib/components/features/tasks/TMTasksAgenda.d.ts +17 -0
  39. package/lib/components/features/tasks/TMTasksAgenda.js +107 -0
  40. package/lib/components/features/tasks/TMTasksCalendar.d.ts +21 -0
  41. package/lib/components/features/tasks/TMTasksCalendar.js +240 -0
  42. package/lib/components/features/tasks/TMTasksHeader.d.ts +14 -0
  43. package/lib/components/features/tasks/TMTasksHeader.js +37 -0
  44. package/lib/components/features/tasks/TMTasksPanelContent.d.ts +20 -0
  45. package/lib/components/features/tasks/TMTasksPanelContent.js +65 -0
  46. package/lib/components/features/tasks/TMTasksUtils.d.ts +132 -0
  47. package/lib/components/features/tasks/TMTasksUtils.js +634 -0
  48. package/lib/components/features/tasks/TMTasksUtilsView.d.ts +39 -0
  49. package/lib/components/features/tasks/TMTasksUtilsView.js +118 -0
  50. package/lib/components/features/tasks/TMTasksView.d.ts +40 -0
  51. package/lib/components/features/tasks/TMTasksView.js +560 -0
  52. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +3 -1
  53. package/lib/components/features/workflow/TMWorkflowPopup.js +19 -6
  54. package/lib/components/features/workflow/diagram/RecipientList.js +4 -3
  55. package/lib/components/forms/Login/Chooser.js +1 -1
  56. package/lib/components/forms/TMChooserForm.d.ts +1 -1
  57. package/lib/components/forms/TMChooserForm.js +2 -2
  58. package/lib/components/grids/TMBlogAttachments.d.ts +42 -0
  59. package/lib/components/grids/TMBlogAttachments.js +43 -0
  60. package/lib/components/grids/TMBlogHeader.d.ts +31 -0
  61. package/lib/components/grids/TMBlogHeader.js +41 -0
  62. package/lib/components/grids/{TMBlogs.d.ts → TMBlogsPost.d.ts} +42 -58
  63. package/lib/components/grids/TMBlogsPost.js +628 -0
  64. package/lib/components/grids/{TMBlogsUtils.d.ts → TMBlogsPostUtils.d.ts} +61 -47
  65. package/lib/components/grids/{TMBlogsUtils.js → TMBlogsPostUtils.js} +146 -124
  66. package/lib/components/index.d.ts +14 -1
  67. package/lib/components/index.js +15 -1
  68. package/lib/components/layout/panelManager/TMPanelManagerContext.js +7 -0
  69. package/lib/components/settings/SettingsAppearance.js +8 -0
  70. package/lib/components/viewers/TMTidViewer.js +20 -2
  71. package/lib/css/tm-sdkui.css +1 -1
  72. package/lib/helper/SDKUI_Globals.d.ts +4 -1
  73. package/lib/helper/SDKUI_Globals.js +10 -1
  74. package/lib/helper/SDKUI_Localizator.d.ts +62 -4
  75. package/lib/helper/SDKUI_Localizator.js +618 -25
  76. package/lib/helper/TMCustomSearchBar.d.ts +8 -0
  77. package/lib/helper/TMCustomSearchBar.js +54 -0
  78. package/lib/helper/TMIcons.d.ts +2 -0
  79. package/lib/helper/TMIcons.js +6 -0
  80. package/lib/helper/TMImageLibrary.d.ts +3 -2
  81. package/lib/helper/TMImageLibrary.js +230 -230
  82. package/lib/helper/TMToppyMessage.d.ts +7 -0
  83. package/lib/helper/TMToppyMessage.js +42 -0
  84. package/lib/helper/TMUtils.d.ts +10 -1
  85. package/lib/helper/TMUtils.js +42 -1
  86. package/lib/helper/dcmtsHelper.d.ts +2 -0
  87. package/lib/helper/dcmtsHelper.js +18 -0
  88. package/lib/helper/helpers.js +1 -0
  89. package/lib/helper/index.d.ts +1 -0
  90. package/lib/helper/index.js +1 -0
  91. package/lib/hooks/useRelatedDocuments.d.ts +72 -0
  92. package/lib/hooks/useRelatedDocuments.js +655 -0
  93. package/lib/index.d.ts +1 -0
  94. package/lib/index.js +1 -0
  95. package/lib/ts/types.d.ts +14 -0
  96. package/lib/ts/types.js +15 -0
  97. package/lib/utils/theme.d.ts +1 -0
  98. package/lib/utils/theme.js +1 -0
  99. package/package.json +7 -7
  100. package/lib/components/grids/TMBlogs.js +0 -721
  101. package/lib/stories/TMButton.stories.d.ts +0 -4
  102. package/lib/stories/TMButton.stories.js +0 -29
  103. package/lib/stories/TMDataGrid.stories.d.ts +0 -9
  104. package/lib/stories/TMDataGrid.stories.js +0 -310
  105. package/lib/stories/TMHtmlContentDisplay.stories.d.ts +0 -6
  106. package/lib/stories/TMHtmlContentDisplay.stories.js +0 -45
  107. package/lib/stories/TMHtmlEditor.stories.d.ts +0 -6
  108. package/lib/stories/TMHtmlEditor.stories.js +0 -49
  109. package/lib/stories/TMIcons.stories.d.ts +0 -4
  110. package/lib/stories/TMIcons.stories.js +0 -13
  111. package/lib/stories/TMSDKUI_Localizator.stories.d.ts +0 -4
  112. package/lib/stories/TMSDKUI_Localizator.stories.js +0 -123
  113. package/lib/stories/TMStoriesUtils.d.ts +0 -1
  114. package/lib/stories/TMStoriesUtils.js +0 -10
  115. package/lib/stories/TMUserAvatar.stories.d.ts +0 -6
  116. package/lib/stories/TMUserAvatar.stories.js +0 -20
@@ -1,17 +1,17 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import TMDcmtPreview from './TMDcmtPreview';
4
- import { AccessLevels, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutModes, MetadataDataTypes, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TemplateTIDs, UpdateEngineByID, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
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
5
  import { ContextMenu } from 'devextreme-react';
6
6
  import { WorkFlowApproveRejectPopUp, WorkFlowMoreInfoPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../workflow/TMWorkflowPopup';
7
7
  import { DownloadTypes, FormModes } from '../../../ts';
8
8
  import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
9
9
  import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
10
10
  import { getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
11
- 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 } from '../../../helper';
11
+ 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 } from '../../../helper';
12
12
  import { hasDetailRelations, hasMasterRelations, isXMLFileExt } from '../../../helper/dcmtsHelper';
13
13
  import { Gutters, TMColors } from '../../../utils/theme';
14
- import { StyledFormButtonsContainer, StyledLoadingContainer, StyledModalContainer, StyledSpinner, StyledToolbarCardContainer } from '../../base/Styled';
14
+ import { StyledFormButtonsContainer, StyledLoadingContainer, StyledModalContainer, StyledReferenceButton, StyledSpinner, StyledToolbarCardContainer } from '../../base/Styled';
15
15
  import ShowAlert from '../../base/TMAlert';
16
16
  import TMButton from '../../base/TMButton';
17
17
  import { TMExceptionBoxManager, TMMessageBoxManager, ButtonNames } from '../../base/TMPopUp';
@@ -35,9 +35,13 @@ import ToppyHelpCenter from '../assistant/ToppyHelpCenter';
35
35
  import TMBlogCommentForm from '../blog/TMBlogCommentForm';
36
36
  import WFDiagram from '../workflow/diagram/WFDiagram';
37
37
  import TMTooltip from '../../base/TMTooltip';
38
+ import TMDcmtTasks from './TMDcmtTasks';
39
+ import TMToppyMessage from '../../../helper/TMToppyMessage';
40
+ import { getTaskAssignedToMe } from '../tasks/TMTasksUtils';
41
+ import TMCustomButton from '../../base/TMCustomButton';
38
42
  let abortControllerLocal = new AbortController();
39
43
  //#endregion
40
- const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes.Update, 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, inputFile = null, taskFormDialogComponent, taskMoreInfo, connectorFileSave = undefined, inputMids = [], onOpenS4TViewerRequest, s4TViewerDialogComponent, enableDragDropOverlay = false, passToSearch }) => {
44
+ 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, inputFile = null, taskFormDialogComponent, taskMoreInfo, connectorFileSave = undefined, inputMids = [], onOpenS4TViewerRequest, s4TViewerDialogComponent, enableDragDropOverlay = false, passToSearch, isSharedDcmt = false, sharedSourceTID, sharedSourceDID, allowButtonsRefs = false, onReferenceClick, }) => {
41
45
  const [id, setID] = useState('');
42
46
  const [showWaitPanelLocal, setShowWaitPanelLocal] = useState(false);
43
47
  const [waitPanelTitleLocal, setWaitPanelTitleLocal] = useState('');
@@ -59,6 +63,8 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
59
63
  const [showReAssignPopup, setShowReAssignPopup] = useState(false);
60
64
  const [showMoreInfoPopup, setShowMoreInfoPopup] = useState(false);
61
65
  const [layout, setLayout] = useState();
66
+ const [customButtonsLayout, setCustomButtonsLayout] = useState();
67
+ const [customButton, setCustomButton] = useState();
62
68
  const appliedInputMidsRef = useRef(null);
63
69
  // Refs per evitare stale closure nei callback
64
70
  // I useCallback catturano i valori delle dipendenze al momento della creazione.
@@ -67,6 +73,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
67
73
  const formDataOrigRef = useRef([]);
68
74
  const formDataRef = useRef([]);
69
75
  const fromDTDRef = useRef();
76
+ const dcmtFileRef = useRef(null);
70
77
  const [isOpenDetails, setIsOpenDetails] = useState(false);
71
78
  const [isOpenMaster, setIsOpenMaster] = useState(false);
72
79
  const [secondaryMasterDcmts, setSecondaryMasterDcmts] = useState([]);
@@ -85,6 +92,15 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
85
92
  const [showCommentForm, setShowCommentForm] = useState(false);
86
93
  const [isInitialLoading, setIsInitialLoading] = useState(true);
87
94
  const [isNavigating, setIsNavigating] = useState(false);
95
+ const [dcmtReferences, setDcmtReferences] = useState(undefined);
96
+ // Dcmt Blog states
97
+ const [blogsDatasource, setBlogsDatasource] = useState([]);
98
+ const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false); //traccia se *qualsiasi* dato è stato caricato per la prima volta
99
+ const [lastLoadedDid, setLastLoadedDid] = useState(undefined); // `lastLoadedDid` tiene traccia dell'ultimo `did` per cui abbiamo caricato i dati
100
+ useEffect(() => {
101
+ if (!allowButtonsRefs)
102
+ setDcmtReferences(undefined);
103
+ }, [allowButtonsRefs]);
88
104
  const { openConfirmAttachmentsDialog, ConfirmAttachmentsDialog } = useInputAttachmentsDialog();
89
105
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
90
106
  // Custom hook to manage workflow approval data
@@ -152,9 +168,41 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
152
168
  return;
153
169
  if (!DID && layoutMode === LayoutModes.Update)
154
170
  return;
155
- let getMetadataResult;
156
- if (layoutMode === LayoutModes.Update)
157
- getMetadataResult = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(TID, DID, true);
171
+ // Esegui chiamate in parallelo per ottimizzare le performance
172
+ const parallelCalls = [
173
+ // 1. GetMetadataAsync - solo se layoutMode === Update
174
+ layoutMode === LayoutModes.Update
175
+ ? SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(TID, DID, true) ?? Promise.resolve(undefined)
176
+ : Promise.resolve(undefined),
177
+ // 2. Layout per il layoutMode corrente
178
+ LayoutCacheService.GetAsync(TID, layoutMode),
179
+ // 3. CustomButtonsLayout - solo se layoutMode === Update
180
+ layoutMode === LayoutModes.Update
181
+ ? LayoutCacheService.GetAsync(TID, LayoutModes.None)
182
+ : Promise.resolve(undefined),
183
+ // 4. Opcionalmente FindAllReferencesAsync se abilitato nelle impostazioni e se i bottoni sono richiesti
184
+ (() => {
185
+ const refs = SDKUI_Globals?.userSettings?.searchSettings?.autoFindReferences ?? [];
186
+ const hasRefs = allowButtonsRefs && Array.isArray(refs) && refs.length > 0;
187
+ return hasRefs
188
+ ? SDK_Globals.tmSession?.NewSearchEngine().FindAllReferencesAsync(TID, DID, refs) ?? Promise.resolve(undefined)
189
+ : Promise.resolve(undefined);
190
+ })()
191
+ ];
192
+ const results = await Promise.all(parallelCalls);
193
+ // Destructuring: first three are always the original ones, fourth is references (or undefined)
194
+ const getMetadataResult = results[0];
195
+ const resLayout = results[1];
196
+ const customButtonsLayoutResult = results[2];
197
+ const findRefsResult = results[3];
198
+ // Save references result into state (may be undefined)
199
+ setDcmtReferences(findRefsResult);
200
+ // Imposta il layout e customButtonsLayout immediatamente
201
+ setLayout(resLayout);
202
+ if (layoutMode === LayoutModes.Update && customButtonsLayoutResult) {
203
+ setCustomButtonsLayout(customButtonsLayoutResult);
204
+ }
205
+ // Carica DTD e metadata
158
206
  let dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(TID, DID, getMetadataResult);
159
207
  setFromDTD(dtd);
160
208
  if (layoutMode === LayoutModes.Update || (layoutMode === LayoutModes.Ark && DID)) {
@@ -167,8 +215,6 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
167
215
  setFormData(structuredClone(metadataList));
168
216
  formDataOrigRef.current = structuredClone(metadataList);
169
217
  }
170
- let resLayout = await SDK_Globals.tmSession?.NewDcmtTypeEngine().LayoutRetrieveAsync(TID, layoutMode);
171
- setLayout(resLayout);
172
218
  (layoutMode === LayoutModes.Ark && !inputFile) && handleReset();
173
219
  }
174
220
  catch (e) {
@@ -179,7 +225,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
179
225
  setIsInitialLoading(false);
180
226
  setIsNavigating(false);
181
227
  }
182
- }, [TID, DID, layoutMode, inputFile, setMetadataList, handleReset]);
228
+ }, [TID, DID, layoutMode, inputFile, setMetadataList, handleReset, allowButtonsRefs]);
183
229
  const createChange = useCallback((mid, metadataType, modifiedValue) => {
184
230
  return { mid, metadataType, modifiedValue };
185
231
  }, []);
@@ -211,6 +257,9 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
211
257
  useEffect(() => {
212
258
  fromDTDRef.current = fromDTD;
213
259
  }, [fromDTD]);
260
+ useEffect(() => {
261
+ dcmtFileRef.current = dcmtFile;
262
+ }, [dcmtFile]);
214
263
  useEffect(() => {
215
264
  if (!inputFile || inputFile === null)
216
265
  return;
@@ -271,6 +320,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
271
320
  if (layoutMode !== LayoutModes.Ark)
272
321
  return;
273
322
  setFocusedMetadataValue(undefined);
323
+ appliedInputMidsRef.current = null;
274
324
  }, [fromDTD, layoutMode]);
275
325
  useEffect(() => {
276
326
  if (!inputMids || inputMids.length === 0)
@@ -279,9 +329,13 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
279
329
  return;
280
330
  if (!formData || formData.length === 0)
281
331
  return;
332
+ if (!formDataOrig || formDataOrig.length === 0)
333
+ return;
334
+ // Check if formData has actual user metadata (mid > 99), not just system metadata
335
+ if (!formData.some(md => md.mid && md.mid > 99))
336
+ return;
282
337
  if (appliedInputMidsRef.current && deepCompare(appliedInputMidsRef.current, inputMids))
283
338
  return;
284
- appliedInputMidsRef.current = inputMids;
285
339
  let data = structuredClone(formData);
286
340
  for (let md of data) {
287
341
  if (!md.mid)
@@ -312,6 +366,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
312
366
  }
313
367
  });
314
368
  setFormData(data);
369
+ appliedInputMidsRef.current = inputMids;
315
370
  }, [inputMids, layoutMode, formData, formDataOrig]);
316
371
  // Memoizza solo il valore WI_SetID per evitare re-render quando altri metadata cambiano
317
372
  const workItemSetIDValue = useMemo(() => formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [formData]);
@@ -396,8 +451,8 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
396
451
  const outputMids = formData
397
452
  .filter(md => md.mid && md.mid > 100 && md.value && md.value.length > 0)
398
453
  .map(md => ({ mid: md.mid, value: md.value }));
399
- passToSearch(outputMids);
400
- }, [passToSearch, formData]);
454
+ passToSearch(outputMids, TID);
455
+ }, [passToSearch, formData, TID]);
401
456
  const isPreviewDisabled = useMemo(() => layoutMode === LayoutModes.Ark && fromDTD?.archiveConstraint === ArchiveConstraints.OnlyMetadata, [layoutMode, fromDTD?.archiveConstraint]);
402
457
  const isBoardDisabled = useMemo(() => layoutMode !== LayoutModes.Update || fromDTD?.hasBlog !== 1, [layoutMode, fromDTD?.hasBlog]);
403
458
  const isSysMetadataDisabled = useMemo(() => layoutMode !== LayoutModes.Update, [layoutMode]);
@@ -406,18 +461,34 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
406
461
  const isWFDisabled = useMemo(() => layoutMode !== LayoutModes.Update || fetchError || workItems.length <= 0, [layoutMode, fetchError, workItems.length]);
407
462
  const showToppyForApprove = useMemo(() => layoutMode === LayoutModes.Update && !fetchError && workItems.length > 0 && !isOpenDetails && !isOpenMaster, [layoutMode, fetchError, workItems.length, isOpenDetails, isOpenMaster]);
408
463
  const showToppyForCompleteMoreInfo = useMemo(() => layoutMode === LayoutModes.Update && isTaskMoreInfo(taskMoreInfo?.name) && taskMoreInfo?.state !== Task_States.Completed, [layoutMode, taskMoreInfo?.name, taskMoreInfo?.state]);
464
+ const showToppyForReferences = useMemo(() => allowButtonsRefs && layoutMode === LayoutModes.Update && dcmtReferences && dcmtReferences.length > 0 && !isOpenDetails && !isOpenMaster, [allowButtonsRefs, layoutMode, dcmtReferences, isOpenDetails, isOpenMaster]);
409
465
  const isMobile = useMemo(() => deviceType === DeviceType.MOBILE, [deviceType]);
410
466
  const isApprView = useMemo(() => fromDTD?.templateTID === TemplateTIDs.WF_WIApprView, [fromDTD?.templateTID]);
411
467
  const workitemSetID = useMemo(() => workItems.find(o => o.did === Number(DID))?.setID || formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [workItems, DID, formData]);
412
468
  const approvalVID = useMemo(() => workItems.length > 0 ? Number(workItems[0].tid) : -1, [workItems]);
413
- const commandsMenuItems = useMemo(() => [
414
- { icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes, text: "Download file", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Dcmt, "download") },
415
- { icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: !isXMLFileExt(currentDcmt?.fileExt), text: "Download allegati XML", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Attachment, "download", undefined, openConfirmAttachmentsDialog) },
416
- ...(allowRelations && currentTIDHasMasterRelations ? [{ icon: svgToString(_jsx(IconDetailDcmts, { transform: 'scale(-1, 1)' })), operationType: 'singleRow', disabled: isMasterDisabled, text: SDKUI_Localizator.DcmtsMaster, onClick: () => { if (!isMasterDisabled)
417
- setIsOpenMaster(!isOpenMaster); } }] : []),
418
- ...(allowRelations && currentTIDHasDetailRelations ? [{ icon: svgToString(_jsx(IconDetailDcmts, {})), operationType: 'singleRow', disabled: isDetailsDisabled, text: SDKUI_Localizator.DcmtsDetail, onClick: () => { if (!isDetailsDisabled)
419
- setIsOpenDetails(!isOpenDetails); } }] : []),
420
- ], [fromDTD?.perm?.canRetrieveFile, currentDcmt?.fileExt, allowRelations, currentTIDHasMasterRelations, isMasterDisabled, currentTIDHasDetailRelations, isDetailsDisabled, getDcmts, downloadDcmtsAsync, openConfirmAttachmentsDialog]);
469
+ const commandsMenuItems = useMemo(() => {
470
+ const items = [
471
+ { icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: fromDTD?.perm?.canRetrieveFile !== AccessLevels.Yes, text: "Download file", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Dcmt, "download") },
472
+ { icon: svgToString(_jsx(IconDownload, {})), operationType: 'singleRow', disabled: !isXMLFileExt(currentDcmt?.fileExt), text: "Download allegati XML", onClick: async () => await downloadDcmtsAsync(getDcmts(), DownloadTypes.Attachment, "download", undefined, openConfirmAttachmentsDialog) },
473
+ ...(allowRelations && currentTIDHasMasterRelations ? [{ icon: svgToString(_jsx(IconDetailDcmts, { transform: 'scale(-1, 1)' })), operationType: 'singleRow', disabled: isMasterDisabled, text: SDKUI_Localizator.DcmtsMaster, onClick: () => { if (!isMasterDisabled)
474
+ setIsOpenMaster(!isOpenMaster); } }] : []),
475
+ ...(allowRelations && currentTIDHasDetailRelations ? [{ icon: svgToString(_jsx(IconDetailDcmts, {})), operationType: 'singleRow', disabled: isDetailsDisabled, text: SDKUI_Localizator.DcmtsDetail, onClick: () => { if (!isDetailsDisabled)
476
+ setIsOpenDetails(!isOpenDetails); } }] : []),
477
+ ];
478
+ // Aggiungi submenu "Bottoni personalizzati" se esistono customButtons
479
+ if (customButtonsLayout?.customButtons && Array.isArray(customButtonsLayout.customButtons) && customButtonsLayout.customButtons.length > 0) {
480
+ const customButtonsItems = customButtonsLayout.customButtons.map((customButton) => ({
481
+ text: customButton.title || 'Bottone personalizzato',
482
+ onClick: () => setCustomButton(customButton)
483
+ }));
484
+ items.push({
485
+ icon: svgToString(_jsx(IconCheck, {})),
486
+ text: 'Bottoni personalizzati',
487
+ items: customButtonsItems
488
+ });
489
+ }
490
+ return items;
491
+ }, [fromDTD?.perm?.canRetrieveFile, currentDcmt?.fileExt, allowRelations, currentTIDHasMasterRelations, isMasterDisabled, currentTIDHasDetailRelations, isDetailsDisabled, customButtonsLayout, getDcmts, downloadDcmtsAsync, openConfirmAttachmentsDialog]);
421
492
  const isModified = useMemo(() => calcIsModified(formData, formDataOrig), [formData, formDataOrig]);
422
493
  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 &&
423
494
  _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]);
@@ -566,7 +637,13 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
566
637
  ae.ArchivingFile = file;
567
638
  }
568
639
  else {
569
- ae.ArchivingFile = dcmtFile;
640
+ ae.ArchivingFile = dcmtFileRef.current;
641
+ }
642
+ if (isSharedDcmt && sharedSourceTID && sharedSourceDID) {
643
+ const sharedDcmt = new TID_DID();
644
+ sharedDcmt.tid = sharedSourceTID;
645
+ sharedDcmt.did = sharedSourceDID;
646
+ ae.SharedDcmt = sharedDcmt;
570
647
  }
571
648
  let newDID = await ae.ArchiveAsync(abortControllerLocal.signal, (pd) => {
572
649
  if (firstBlock) {
@@ -614,7 +691,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
614
691
  setShowWaitPanelLocal(false);
615
692
  setUseWaitPanelLocalState(false);
616
693
  }
617
- }, [TID, dcmtFile, connectorFileSave, onSavedAsyncCallback, onSaveRecents, onClose, DID, setMetadataList, handleReset, layoutMode]);
694
+ }, [TID, connectorFileSave, onSavedAsyncCallback, onSaveRecents, onClose, DID, setMetadataList, handleReset, layoutMode, isSharedDcmt]);
618
695
  const handleClearForm = useCallback(() => {
619
696
  let data = structuredClone(formData);
620
697
  if (!data || data.length === 0)
@@ -705,6 +782,28 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
705
782
  setShowAll(true);
706
783
  }
707
784
  }, [shouldShowAll, showAll]);
785
+ const fetchBlogDataAsync = useCallback(async (tid, did) => {
786
+ try {
787
+ TMSpinner.show({ description: 'Caricamento - Bacheca...' });
788
+ const res = await SDK_Globals.tmSession?.NewSearchEngine().BlogRetrieveAsync(tid, did);
789
+ setBlogsDatasource(res ?? []);
790
+ setHasLoadedDataOnce(true);
791
+ setLastLoadedDid(did);
792
+ }
793
+ catch (e) {
794
+ let err = e;
795
+ TMExceptionBoxManager.show({ exception: err });
796
+ }
797
+ finally {
798
+ TMSpinner.hide();
799
+ }
800
+ }, []);
801
+ const afterTaskSaved = useCallback(async (task, formMode, forceRefresh = false) => {
802
+ const shouldRefresh = forceRefresh || (task && task.state === Task_States.Completed) || formMode === FormModes.Create || formMode === FormModes.Duplicate;
803
+ if (TID && DID && shouldRefresh) {
804
+ await fetchBlogDataAsync(TID, DID);
805
+ }
806
+ }, [TID, DID]);
708
807
  const tmDcmtForm = useMemo(() => {
709
808
  return _jsx(_Fragment, { children: metadataValuesSource.length > 0 &&
710
809
  _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) => {
@@ -722,7 +821,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
722
821
  break;
723
822
  }
724
823
  } }), _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 })] }) :
725
- _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 })] }) }) }), totalItems > listMaxItems &&
824
+ _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 &&
726
825
  !isApprView &&
727
826
  TID !== SystemTIDs.Drafts &&
728
827
  !shouldShowAll &&
@@ -754,11 +853,11 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
754
853
  handleUndo,
755
854
  handleClearForm
756
855
  ]);
757
- const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: TID, did: DID }), [TID, DID]);
856
+ const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { blogsDatasource: blogsDatasource, hasLoadedDataOnce: hasLoadedDataOnce, lastLoadedDid: lastLoadedDid, setBlogsDatasource: setBlogsDatasource, setHasLoadedDataOnce: setHasLoadedDataOnce, setLastLoadedDid: setLastLoadedDid, fetchBlogDataAsync: fetchBlogDataAsync, tid: TID, did: DID, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [blogsDatasource, hasLoadedDataOnce, lastLoadedDid, TID, DID, allTasks]);
758
857
  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]);
759
- const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, fromDTD: fromDTD, layoutMode: layoutMode, onFileUpload: (setFile) => {
760
- setDcmtFile(setFile);
761
- }, enableDragDropOverlay: enableDragDropOverlay }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay]);
858
+ const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { currentDcmt: currentDcmt, dcmtFile: dcmtFile ?? inputFile, deviceType: deviceType, fromDTD: fromDTD, layoutMode: layoutMode, onFileUpload: (file) => {
859
+ setDcmtFile(file);
860
+ }, enableDragDropOverlay: enableDragDropOverlay }), [currentDcmt, dcmtFile, deviceType, fromDTD, layoutMode, inputFile, enableDragDropOverlay, setDcmtFile]);
762
861
  const tmWF = useMemo(() => {
763
862
  if (isWFDataLoading) {
764
863
  return (_jsx("div", { style: {
@@ -798,13 +897,27 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
798
897
  borderRadius: 8
799
898
  }, children: SDKUI_Localizator.WorkItemTechnicalNote_SetID })] }));
800
899
  }, [workflows, formData, workitemSetID, workItems, isWFDataLoading]);
900
+ const tmDcmtTasks = useMemo(() => {
901
+ const isReady = TID && DID && getAllTasks && deleteTaskByIdsCallback && addTaskCallback && editTaskCallback;
902
+ if (!isReady) {
903
+ return _jsx(TMToppyMessage, { message: SDKUI_Localizator.TasksEmpty });
904
+ }
905
+ return (_jsx(TMDcmtTasks, { taskContext: {
906
+ document: {
907
+ tid: Number(TID),
908
+ did: Number(DID),
909
+ name: fromDTD?.nameLoc ?? SDKUI_Localizator.Widget_Activities,
910
+ },
911
+ }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, afterTaskSaved: afterTaskSaved }));
912
+ }, [allTasks, TID, DID, fromDTD]);
801
913
  const normalizedTID = TID !== undefined ? Number(TID) : undefined;
802
914
  const defaultPanelDimensions = {
803
- 'tmDcmtForm': { width: '20%', height: '100%' },
804
- 'tmBlog': { width: '20%', height: '100%' },
805
- 'tmSysMetadata': { width: '20%', height: '100%' },
806
- 'tmDcmtPreview': { width: '20%', height: '100%' },
807
- 'tmWF': { width: '20%', height: '100%' },
915
+ 'tmDcmtForm': { width: '16.66%', height: '100%' },
916
+ 'tmBlog': { width: '16.66%', height: '100%' },
917
+ 'tmSysMetadata': { width: '16.66%', height: '100%' },
918
+ 'tmDcmtPreview': { width: '16.66%', height: '100%' },
919
+ 'tmWF': { width: '16.66%', height: '100%' },
920
+ 'tmDcmtTasks': { width: '16.66%', height: '100%' },
808
921
  };
809
922
  const allInitialPanelVisibility = {
810
923
  'tmDcmtForm': true,
@@ -812,6 +925,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
812
925
  'tmSysMetadata': false,
813
926
  'tmDcmtPreview': true,
814
927
  'tmWF': false,
928
+ 'tmDcmtTasks': false,
815
929
  };
816
930
  const initialPanels = useMemo(() => [
817
931
  {
@@ -824,7 +938,7 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
824
938
  showHeader: showHeader,
825
939
  title: fromDTD?.nameLoc,
826
940
  allowMaximize: !isMobile,
827
- onBack: (isClosable && deviceType !== DeviceType.MOBILE) ? undefined : handleClose,
941
+ onBack: showBackButton ? (isClosable && deviceType !== DeviceType.MOBILE) ? undefined : handleClose : undefined,
828
942
  onClose: isClosable ? () => { } : undefined,
829
943
  toolbar: allowNavigation ? formToolbar : _jsx(_Fragment, {})
830
944
  },
@@ -877,7 +991,25 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
877
991
  isActive: allInitialPanelVisibility['tmWF']
878
992
  }
879
993
  },
880
- ], [fromDTD, tmDcmtForm, tmBlog, tmSysMetadata, tmDcmtPreview, tmWF, isPreviewDisabled, isSysMetadataDisabled, isBoardDisabled, isWFDisabled, inputFile, isClosable]);
994
+ {
995
+ id: 'tmDcmtTasks',
996
+ name: SDKUI_Localizator.Widget_Activities,
997
+ contentOptions: {
998
+ component: tmDcmtTasks,
999
+ },
1000
+ toolbarOptions: {
1001
+ icon: _jsx(IconActivity, { fontSize: 24 }),
1002
+ visible: layoutMode !== LayoutModes.Ark,
1003
+ orderNumber: 6,
1004
+ isActive: allInitialPanelVisibility['tmDcmtTasks'],
1005
+ count: (TID && DID && allTasks && allTasks.length > 0) ?
1006
+ getTaskAssignedToMe(allTasks).filter(task => task.iD1?.toString() === TID.toString()
1007
+ && task.iD2?.toString() === DID.toString()
1008
+ && task.state !== Task_States.Completed).length ?? 0
1009
+ : 0
1010
+ }
1011
+ },
1012
+ ], [fromDTD, showBackButton, tmDcmtForm, tmBlog, tmSysMetadata, tmDcmtPreview, tmWF, tmDcmtTasks, isPreviewDisabled, isSysMetadataDisabled, isBoardDisabled, isWFDisabled, inputFile, isClosable, allTasks, DID, TID]);
881
1013
  // Retrieves the current document form setting based on the normalized TID
882
1014
  const getCurrentDcmtFormSetting = () => {
883
1015
  const settings = SDKUI_Globals.userSettings.dcmtFormSettings;
@@ -959,6 +1091,23 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
959
1091
  title: SDKUI_Localizator.SignatureAndApprove,
960
1092
  });
961
1093
  }, [onOpenS4TViewerRequest, TID, DID]);
1094
+ const handleNavigateToReference = useCallback((ref) => {
1095
+ if (onReferenceClick) {
1096
+ try {
1097
+ onReferenceClick(ref);
1098
+ }
1099
+ catch (e) {
1100
+ console.error('onReferenceClick handler failed', e);
1101
+ }
1102
+ return;
1103
+ }
1104
+ }, [onReferenceClick]);
1105
+ // Mapping for objClass specific label/action. Easy to extend for future objClass types.
1106
+ const referenceActionMap = useMemo(() => ({
1107
+ [ObjectClasses.Dossier]: { label: 'Vai a pratica' },
1108
+ [ObjectClasses.WorkingGroup]: { label: 'Vai a gruppo di lavoro' },
1109
+ // add other ObjectClasses here as needed
1110
+ }), []);
962
1111
  const renderDcmtForm = () => {
963
1112
  // Show flat spinner during initial load (before component is mounted)
964
1113
  if (isInitialLoading) {
@@ -989,16 +1138,26 @@ const TMDcmtForm = ({ showHeader = true, onSaveRecents, layoutMode = LayoutModes
989
1138
  isEditable: true,
990
1139
  value: FormulaHelper.addFormulaTag(newFormula.expression)
991
1140
  }));
992
- } }), 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 })] }), showToppyForApprove && (_jsx(ToppyHelpCenter, { deviceType: deviceType, usePortal: false, content: workItems.length === 1 ?
993
- _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true) }) })
994
- :
995
- _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 && (_jsx(ToppyHelpCenter, { deviceType: deviceType, usePortal: false, content: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10 }, 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: () => {
996
- setShowCommentForm(true);
997
- } })] }) })), (showCommentForm && TID && DID) &&
1141
+ } }), 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 })] }), (showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences) && (_jsx(ToppyHelpCenter, { deviceType: deviceType, usePortal: false, content: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: [showToppyForApprove && (workItems.length === 1 ?
1142
+ _jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true), dtd: fromDTD })
1143
+ :
1144
+ _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: () => {
1145
+ setShowCommentForm(true);
1146
+ } })] })), showToppyForReferences && dcmtReferences && dcmtReferences
1147
+ .filter(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup) // keep only known objClass types
1148
+ .map((ref, index, arr) => {
1149
+ const mapEntry = referenceActionMap[String(ref.objClass)];
1150
+ const label = mapEntry?.label ?? 'Vai a riferimento';
1151
+ return (_jsxs(React.Fragment, { children: [index === 0 && (showToppyForApprove || showToppyForCompleteMoreInfo) && (_jsx("div", { style: {
1152
+ height: 1,
1153
+ backgroundColor: 'rgba(255,255,255,0.2)',
1154
+ margin: '6px 0'
1155
+ } })), _jsxs(StyledReferenceButton, { onClick: () => handleNavigateToReference(ref), children: [_jsx("span", { children: label }), _jsx("span", { children: `"${ref.objName}"` })] }, `ref-${index}-${ref.objID}`)] }, `ref-frag-${index}-${ref.objID}`));
1156
+ })] }) })), (showCommentForm && TID && DID) &&
998
1157
  _jsx(TMBlogCommentForm, { context: { engine: 'SearchEngine', object: { tid: TID, did: DID } }, onClose: () => setShowCommentForm(false), refreshCallback: handleCompleteMoreInfo, participants: [], showAttachmentsSection: false, allArchivedDocumentsFileItems: [] }), isOpenDetails &&
999
- _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, isForMaster: false, inputDcmts: getSelectionDcmtInfo(), allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenDetails(false) }) }), isOpenMaster &&
1000
- _jsxs(StyledModalContainer, { style: { backgroundColor: 'white' }, children: [_jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: getSelectionDcmtInfo(), isForMaster: true, allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenMaster(false), appendMasterDcmts: handleAddItem }), secondaryMasterDcmts.length > 0 && secondaryMasterDcmts.map((dcmt, index) => {
1001
- return (_jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: [dcmt], isForMaster: true, allowNavigation: false, onBack: () => handleRemoveItem(dcmt.TID, dcmt.DID), appendMasterDcmts: handleAddItem }) }, `${index}-${dcmt.DID}`));
1158
+ _jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, isForMaster: false, inputDcmts: getSelectionDcmtInfo(), allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenDetails(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }), isOpenMaster &&
1159
+ _jsxs(StyledModalContainer, { style: { backgroundColor: 'white' }, children: [_jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: getSelectionDcmtInfo(), isForMaster: true, allowNavigation: allowNavigation, canNext: canNext, canPrev: canPrev, onNext: onNext, onPrev: onPrev, onBack: () => setIsOpenMaster(false), appendMasterDcmts: handleAddItem, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), secondaryMasterDcmts.length > 0 && secondaryMasterDcmts.map((dcmt, index) => {
1160
+ return (_jsx(StyledModalContainer, { style: { backgroundColor: 'white' }, children: _jsx(TMMasterDetailDcmts, { deviceType: deviceType, inputDcmts: [dcmt], isForMaster: true, allowNavigation: false, onBack: () => handleRemoveItem(dcmt.TID, dcmt.DID), appendMasterDcmts: handleAddItem, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }, `${index}-${dcmt.DID}`));
1002
1161
  })] }), taskFormDialogComponent, s4TViewerDialogComponent] }));
1003
1162
  };
1004
1163
  return (_jsx(_Fragment, { children: (isModal && onClose)
@@ -1034,7 +1193,7 @@ const applyMetadataFilter = (data, showAll, listMaxItems, TID) => {
1034
1193
  return showAll ? filteredData : filteredData.slice(0, listMaxItems);
1035
1194
  };
1036
1195
  //#region Validaion
1037
- const validateMetadataList = (mvdList = []) => {
1196
+ export const validateMetadataList = (mvdList = []) => {
1038
1197
  if (!Array.isArray(mvdList)) {
1039
1198
  throw new TypeError("metadataList must be an array of ITMMetadataProps.");
1040
1199
  }
@@ -0,0 +1,13 @@
1
+ import { FormModes, TaskContext } from "../../../ts";
2
+ import { TaskDescriptor } from "@topconsultnpm/sdk-ts";
3
+ interface TMDcmtTasksProps {
4
+ taskContext: TaskContext;
5
+ allTasks: Array<TaskDescriptor>;
6
+ getAllTasks: () => Promise<void>;
7
+ deleteTaskByIdsCallback: (deletedTaskIds: Array<number>) => Promise<void>;
8
+ addTaskCallback: (task: TaskDescriptor) => Promise<void>;
9
+ editTaskCallback: (task: TaskDescriptor) => Promise<void>;
10
+ afterTaskSaved: (task: TaskDescriptor | undefined, formMode: FormModes | undefined, forceRefresh?: boolean) => Promise<void>;
11
+ }
12
+ declare const TMDcmtTasks: (props: TMDcmtTasksProps) => import("react/jsx-runtime").JSX.Element;
13
+ export default TMDcmtTasks;
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { IconMenuVertical, IconRefresh, SDKUI_Localizator, svgToString, TMCommandsContextMenu } from "../../../helper";
4
+ import { DeviceType, useDeviceType } from "../../base/TMDeviceProvider";
5
+ import { useTMPanelManagerContext } from "../../layout/panelManager/TMPanelManagerContext";
6
+ import TMPanel from "../../base/TMPanel";
7
+ import TMTasksPanelContent from "../tasks/TMTasksPanelContent";
8
+ const TMDcmtTasks = (props) => {
9
+ const { taskContext, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved } = props;
10
+ // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
11
+ const deviceType = useDeviceType();
12
+ // This avoids unnecessary re-renders by only recalculating when deviceType changes.
13
+ let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
14
+ const { togglePanelVisibility, toggleMaximize, countVisibleLeafPanels } = useTMPanelManagerContext();
15
+ const toolbar = useMemo(() => _jsxs(_Fragment, { children: [_jsx(IconMenuVertical, { id: "TMTaksPanel-Commands-Header", color: 'white', cursor: 'pointer' }), _jsx(TMCommandsContextMenu, { target: '#TMTaksPanel-Commands-Header', showEvent: "click", menuItems: [
16
+ {
17
+ icon: svgToString(_jsx(IconRefresh, {})),
18
+ onClick: async () => await getAllTasks(),
19
+ text: SDKUI_Localizator.Refresh,
20
+ },
21
+ ] })] }), []);
22
+ return _jsx("div", { style: { width: "100%", height: "100%", position: 'relative' }, children: _jsx(TMPanel, { title: SDKUI_Localizator.Widget_Activities, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onClose: countVisibleLeafPanels() > 1 ? () => togglePanelVisibility("tmDcmtTasks") : undefined, onMaximize: countVisibleLeafPanels() > 1 ? () => toggleMaximize("tmDcmtTasks") : undefined, toolbar: toolbar, children: _jsx(TMTasksPanelContent, { id: "dcmtTasks", taskContext: taskContext, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: () => { return Promise.resolve(); }, handleNavigateToDossiers: () => { return Promise.resolve(); }, afterTaskSaved: afterTaskSaved }) }) });
23
+ };
24
+ export default TMDcmtTasks;
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from "react";
3
3
  import Toppy from '../../../assets/Toppy-generico.png';
4
+ import { SDKUI_Localizator } from "../../../helper";
4
5
  const TMDragDropOverlay = (props) => {
5
6
  const { handleFile, refocusAfterFileInput } = props;
6
7
  const [dragOver, setDragOver] = useState(false);
@@ -91,6 +92,6 @@ const TMDragDropOverlay = (props) => {
91
92
  alignItems: 'center',
92
93
  gap: 20,
93
94
  textAlign: 'center',
94
- }, children: [_jsx("img", { src: Toppy, alt: "Toppy", style: { width: 80, height: 'auto' } }), _jsx("div", { style: { fontSize: '1.6rem' }, children: "Rilascia il tuo file qui" })] })] }));
95
+ }, children: [_jsx("img", { src: Toppy, alt: "Toppy", style: { width: 80, height: 'auto' } }), _jsx("div", { style: { fontSize: '1.6rem' }, children: SDKUI_Localizator.DropFileHere })] })] }));
95
96
  };
96
97
  export default TMDragDropOverlay;
@@ -1,8 +1,15 @@
1
1
  import React from 'react';
2
- import { TaskDescriptor } from '@topconsultnpm/sdk-ts';
2
+ import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
3
3
  import { DcmtInfo, TaskContext } from '../../../ts';
4
4
  import { DeviceContextProps } from '../../base/TMDeviceProvider';
5
5
  interface ITMMasterDetailDcmtsProps extends DeviceContextProps {
6
+ allTasks?: Array<TaskDescriptor>;
7
+ getAllTasks?: () => Promise<void>;
8
+ deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
9
+ addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
10
+ editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
11
+ handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
12
+ handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
6
13
  inputDcmts?: DcmtInfo[];
7
14
  isForMaster?: boolean;
8
15
  showCurrentDcmtIndicator?: boolean;
@@ -14,7 +14,7 @@ import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/p
14
14
  import TMSearchResult from '../search/TMSearchResult';
15
15
  import TMDcmtForm from './TMDcmtForm';
16
16
  import { TMNothingToShow } from './TMDcmtPreview';
17
- const TMMasterDetailDcmts = ({ deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest }) => {
17
+ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest }) => {
18
18
  const [id, setID] = useState('');
19
19
  const [focusedItem, setFocusedItem] = useState();
20
20
  const [selectedItems, setSelectedItems] = useState([]);
@@ -169,7 +169,7 @@ const TMMasterDetailDcmts = ({ deviceType, inputDcmts, isForMaster, showCurrentD
169
169
  _jsx(TMRelationViewerWrapper, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
170
170
  // customItemRender={customItemRender}
171
171
  allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged]);
172
- const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest }), [focusedItem, deviceType]);
172
+ const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [focusedItem, deviceType, allTasks]);
173
173
  const initialPanelDimensions = {
174
174
  'tmTreeView': { width: '50%', height: '100%' },
175
175
  'tmFormOrResult': { width: '50%', height: '100%' },
@@ -276,13 +276,13 @@ const TMRelationViewerWrapper = ({ inputDcmts, isForMaster, showCurrentDcmtIndic
276
276
  }, [onFocusedItemChanged, setPanelVisibilityById, setToolbarButtonVisibility]);
277
277
  return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false }));
278
278
  };
279
- const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest }) => {
279
+ const TMFormOrResultWrapper = ({ deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers }) => {
280
280
  const { setPanelVisibilityById } = useTMPanelManagerContext();
281
281
  return (_jsx(_Fragment, { children: focusedItem?.isDcmt ?
282
- _jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => {
282
+ _jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, allowButtonsRefs: true, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => {
283
283
  setPanelVisibilityById('tmTreeView', true);
284
- } }) :
284
+ }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) :
285
285
  _jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => {
286
286
  setPanelVisibilityById('tmTreeView', true);
287
- } }) }));
287
+ }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }) }));
288
288
  };