@topconsultnpm/sdkui-react 6.20.0-dev1.11 → 6.20.0-dev1.111

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 (177) hide show
  1. package/lib/assets/Toppy-help-center.png +0 -0
  2. package/lib/assets/headergradient.svg +87 -0
  3. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +285 -28
  4. package/lib/components/NewComponents/ContextMenu/hooks.d.ts +8 -1
  5. package/lib/components/NewComponents/ContextMenu/hooks.js +80 -8
  6. package/lib/components/NewComponents/ContextMenu/index.d.ts +3 -0
  7. package/lib/components/NewComponents/ContextMenu/index.js +2 -0
  8. package/lib/components/NewComponents/ContextMenu/styles.d.ts +9 -1
  9. package/lib/components/NewComponents/ContextMenu/styles.js +157 -37
  10. package/lib/components/NewComponents/ContextMenu/types.d.ts +14 -1
  11. package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
  12. package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
  13. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +563 -112
  14. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +21 -5
  15. package/lib/components/NewComponents/FloatingMenuBar/styles.js +210 -58
  16. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +8 -2
  17. package/lib/components/base/TMAccordionNew.js +35 -14
  18. package/lib/components/base/TMCustomButton.js +61 -17
  19. package/lib/components/base/TMDataGrid.d.ts +7 -4
  20. package/lib/components/base/TMDataGrid.js +153 -11
  21. package/lib/components/base/TMDropDownMenu.js +19 -18
  22. package/lib/components/base/TMFileManager.d.ts +4 -3
  23. package/lib/components/base/TMFileManager.js +32 -24
  24. package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
  25. package/lib/components/base/TMFileManagerDataGridView.js +1 -11
  26. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
  27. package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
  28. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
  29. package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
  30. package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
  31. package/lib/components/base/TMListView.js +33 -15
  32. package/lib/components/base/TMPanel.d.ts +1 -1
  33. package/lib/components/base/TMPanel.js +1 -1
  34. package/lib/components/base/TMTreeView.d.ts +2 -1
  35. package/lib/components/base/TMTreeView.js +33 -26
  36. package/lib/components/choosers/TMDistinctValues.js +2 -2
  37. package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
  38. package/lib/components/choosers/TMMetadataChooser.js +8 -1
  39. package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
  40. package/lib/components/choosers/TMUserChooser.d.ts +0 -5
  41. package/lib/components/choosers/TMUserChooser.js +25 -45
  42. package/lib/components/editors/TMDateBox.js +18 -9
  43. package/lib/components/editors/TMLocalizedTextBox.d.ts +3 -1
  44. package/lib/components/editors/TMLocalizedTextBox.js +16 -14
  45. package/lib/components/editors/TMMetadataTextBox.d.ts +9 -0
  46. package/lib/components/editors/TMMetadataTextBox.js +92 -0
  47. package/lib/components/editors/TMMetadataValues.js +23 -5
  48. package/lib/components/editors/TMTextArea.js +18 -30
  49. package/lib/components/editors/TMTextBox.d.ts +1 -1
  50. package/lib/components/editors/TMTextBox.js +6 -3
  51. package/lib/components/editors/TMTextExpression.js +6 -91
  52. package/lib/components/features/archive/TMArchive.js +2 -2
  53. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
  54. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +460 -0
  55. package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
  56. package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
  57. package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
  58. package/lib/components/features/documents/TMDcmtForm.js +457 -206
  59. package/lib/components/features/documents/TMDcmtPreview.js +44 -110
  60. package/lib/components/features/documents/TMDcmtTasks.js +9 -9
  61. package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
  62. package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
  63. package/lib/components/features/documents/TMRelationViewer.js +2 -2
  64. package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
  65. package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +2 -2
  66. package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
  67. package/lib/components/features/search/TMSearch.d.ts +3 -0
  68. package/lib/components/features/search/TMSearch.js +50 -11
  69. package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
  70. package/lib/components/features/search/TMSearchQueryPanel.js +29 -21
  71. package/lib/components/features/search/TMSearchResult.d.ts +3 -0
  72. package/lib/components/features/search/TMSearchResult.js +208 -250
  73. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
  74. package/lib/components/features/search/TMSearchResultsMenuItems.js +205 -169
  75. package/lib/components/features/search/TMSignSettingsForm.js +1 -1
  76. package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
  77. package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
  78. package/lib/components/features/search/TMViewHistoryDcmt.js +2 -2
  79. package/lib/components/features/tasks/TMTaskForm.js +20 -1
  80. package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
  81. package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
  82. package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
  83. package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
  84. package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
  85. package/lib/components/features/tasks/TMTasksUtils.js +43 -36
  86. package/lib/components/features/tasks/TMTasksView.js +28 -19
  87. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
  88. package/lib/components/features/workflow/TMWorkflowPopup.js +139 -34
  89. package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
  90. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +12 -7
  91. package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
  92. package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
  93. package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
  94. package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
  95. package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
  96. package/lib/components/forms/Login/LoginValidatorService.js +7 -2
  97. package/lib/components/forms/Login/TMLoginForm.js +34 -6
  98. package/lib/components/forms/TMChooserForm.js +1 -1
  99. package/lib/components/grids/TMBlogsPost.js +56 -31
  100. package/lib/components/grids/TMRecentsManager.js +20 -10
  101. package/lib/components/index.d.ts +6 -3
  102. package/lib/components/index.js +6 -3
  103. package/lib/components/query/TMQueryEditor.d.ts +2 -1
  104. package/lib/components/query/TMQueryEditor.js +92 -92
  105. package/lib/components/settings/SettingsAppearance.d.ts +2 -1
  106. package/lib/components/settings/SettingsAppearance.js +99 -30
  107. package/lib/components/sidebar/TMHeader.js +7 -7
  108. package/lib/components/sidebar/TMSidebar.d.ts +0 -1
  109. package/lib/components/sidebar/TMSidebar.js +16 -44
  110. package/lib/components/sidebar/TMSidebarItem.js +34 -17
  111. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  112. package/lib/components/viewers/TMDataListItemViewer.js +35 -71
  113. package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
  114. package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
  115. package/lib/css/tm-sdkui.css +1 -1
  116. package/lib/helper/SDKUI_Globals.d.ts +22 -0
  117. package/lib/helper/SDKUI_Globals.js +10 -1
  118. package/lib/helper/SDKUI_Localizator.d.ts +17 -1
  119. package/lib/helper/SDKUI_Localizator.js +167 -1
  120. package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
  121. package/lib/helper/TMCommandsContextMenu.js +15 -4
  122. package/lib/helper/TMIcons.d.ts +4 -0
  123. package/lib/helper/TMIcons.js +13 -3
  124. package/lib/helper/TMPdfViewer.d.ts +8 -0
  125. package/lib/helper/TMPdfViewer.js +373 -0
  126. package/lib/helper/checkinCheckoutManager.d.ts +31 -1
  127. package/lib/helper/checkinCheckoutManager.js +112 -30
  128. package/lib/helper/devextremeCustomMessages.d.ts +30 -0
  129. package/lib/helper/devextremeCustomMessages.js +30 -0
  130. package/lib/helper/helpers.d.ts +28 -1
  131. package/lib/helper/helpers.js +130 -3
  132. package/lib/helper/index.d.ts +2 -0
  133. package/lib/helper/index.js +2 -0
  134. package/lib/helper/queryHelper.d.ts +1 -1
  135. package/lib/helper/queryHelper.js +33 -3
  136. package/lib/helper/workItemsHelper.d.ts +6 -0
  137. package/lib/helper/workItemsHelper.js +230 -0
  138. package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
  139. package/lib/hooks/useCheckInOutOperations.js +223 -0
  140. package/lib/hooks/useDataListItem.d.ts +12 -0
  141. package/lib/hooks/useDataListItem.js +132 -0
  142. package/lib/hooks/useDataUserIdItem.d.ts +10 -0
  143. package/lib/hooks/useDataUserIdItem.js +96 -0
  144. package/lib/hooks/useMetadataExpression.d.ts +19 -0
  145. package/lib/hooks/useMetadataExpression.js +99 -0
  146. package/lib/hooks/useSettingsFeedback.d.ts +11 -0
  147. package/lib/hooks/useSettingsFeedback.js +38 -0
  148. package/lib/hooks/useWorkflowApprove.d.ts +4 -0
  149. package/lib/hooks/useWorkflowApprove.js +14 -1
  150. package/lib/index.d.ts +1 -0
  151. package/lib/index.js +3 -2
  152. package/lib/services/platform_services.d.ts +3 -3
  153. package/lib/ts/types.d.ts +61 -1
  154. package/lib/utils/theme.d.ts +1 -1
  155. package/lib/utils/theme.js +1 -1
  156. package/package.json +7 -4
  157. package/lib/components/NewComponents/Notification/Notification.d.ts +0 -4
  158. package/lib/components/NewComponents/Notification/Notification.js +0 -60
  159. package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +0 -8
  160. package/lib/components/NewComponents/Notification/NotificationContainer.js +0 -33
  161. package/lib/components/NewComponents/Notification/index.d.ts +0 -2
  162. package/lib/components/NewComponents/Notification/index.js +0 -2
  163. package/lib/components/NewComponents/Notification/styles.d.ts +0 -21
  164. package/lib/components/NewComponents/Notification/styles.js +0 -180
  165. package/lib/components/NewComponents/Notification/types.d.ts +0 -18
  166. package/lib/components/NewComponents/Notification/types.js +0 -1
  167. package/lib/components/base/TMContextMenu.d.ts +0 -25
  168. package/lib/components/base/TMContextMenu.js +0 -109
  169. package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
  170. package/lib/components/base/TMContextMenuOLD.js +0 -56
  171. package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
  172. package/lib/components/base/TMFloatingToolbar.js +0 -101
  173. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
  174. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
  175. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
  176. package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
  177. package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
@@ -5,7 +5,6 @@ import { TabPanel, Item } from 'devextreme-react/tab-panel';
5
5
  import { Priorities, ResultTypes, SDK_Globals, Task_States } from "@topconsultnpm/sdk-ts";
6
6
  import { calculateNumberOfDays, renderTaskIcons } from "./TMTasksUtilsView";
7
7
  import { getPriorityLocalizatorValue } from "../tasks/TMTasksUtils";
8
- import ContextMenu from 'devextreme-react/context-menu';
9
8
  import { calcResponsiveSizes, getExceptionMessage, SDKUI_Localizator, StyledTabItem, TMCountBadge } from "../../../helper";
10
9
  import { useDeviceType } from "../../base/TMDeviceProvider";
11
10
  import { FormModes } from "../../../ts";
@@ -85,8 +84,9 @@ const TMTasksView = (props) => {
85
84
  onDeleteCallback([focusedRowKey]); }, (rowIds, status) => { if (focusedRowKey)
86
85
  markAsStatus([focusedRowKey], status); }, getAllTasks, taskContext?.workingGroup?.id !== undefined, showContextualWG, setShowContextualWG, taskContext?.dossier?.id !== undefined, showContextualDossier, setShowContextualDossier, taskContext?.document?.tid !== undefined && taskContext?.document?.did !== undefined, showContextualDocument, setShowContextualDocument, true, () => { setCurrentCalendarDate(new Date()); setCurrentAgendaDate(new Date()); }, false),
87
86
  ];
88
- }, [visualizedTasks, focusedRowKey, showId, showSearch, showContextualWG, showContextualDossier, taskContext]);
87
+ }, [focusedRowKey, showId, showSearch, showContextualWG, showContextualDossier, taskContext]);
89
88
  const [menuItems, setMenuItems] = useState(agendaCalendarItems());
89
+ const [datagridMenu, setDatagridMenu] = useState([]);
90
90
  const newTaskCount = getNewTaskCount(allTasks);
91
91
  useEffect(() => {
92
92
  setMenuItems(agendaCalendarItems());
@@ -266,6 +266,23 @@ const TMTasksView = (props) => {
266
266
  }
267
267
  });
268
268
  }, [visualizedTasks]);
269
+ const listMenuItems = useCallback(() => {
270
+ const taskDescriptor = visualizedTasks.find(task => task.id === focusedRowKey);
271
+ return createTasksMenuItems(taskDescriptor, showId, setShowId, showSearch, setShowSearch, openTaskFormCallback, (rowId) => { if (rowId) {
272
+ const task = visualizedTasks.find(t => t.id === rowId);
273
+ if (task)
274
+ openTaskFormCallback(FormModes.Update, task);
275
+ } }, (rowId) => { if (rowId) {
276
+ const task = visualizedTasks.find(t => t.id === rowId);
277
+ if (task)
278
+ openTaskFormCallback(FormModes.Duplicate, task);
279
+ } }, onDeleteCallback, markAsStatus, getAllTasks, taskContext?.workingGroup?.id !== undefined, showContextualWG, setShowContextualWG, taskContext?.dossier?.id !== undefined, showContextualDossier, setShowContextualDossier, taskContext?.document?.tid !== undefined && taskContext?.document?.did !== undefined, showContextualDocument, setShowContextualDocument, false, // showGoToToday
280
+ undefined, true // fromDatagrid
281
+ );
282
+ }, [visualizedTasks, focusedRowKey, showId, showSearch, showContextualWG, showContextualDossier, showContextualDocument, taskContext, openTaskFormCallback, onDeleteCallback, markAsStatus, getAllTasks]);
283
+ useEffect(() => {
284
+ setDatagridMenu(listMenuItems());
285
+ }, [listMenuItems]);
269
286
  const onSavedCallback = async (task) => {
270
287
  // If task is undefined or has no ID, exit early
271
288
  if (task === undefined || task.id === undefined)
@@ -295,22 +312,14 @@ const TMTasksView = (props) => {
295
312
  }
296
313
  setShowTaskForm(false);
297
314
  };
298
- const handleNavigateToDossiersWrapper = useCallback(async (dossierId) => {
315
+ const handleNavigateToDossiersWrapper = useCallback(async (value) => {
299
316
  setShowTaskForm(false);
300
- await handleNavigateToDossiers(dossierId);
301
- }, []);
302
- const handleNavigateToWGsWrapper = useCallback(async (workGroupId) => {
317
+ await handleNavigateToDossiers(value);
318
+ }, [handleNavigateToDossiers]);
319
+ const handleNavigateToWGsWrapper = useCallback(async (value) => {
303
320
  setShowTaskForm(false);
304
- await handleNavigateToWGs(workGroupId);
305
- }, []);
306
- const onContextMenuPreparing = (e) => {
307
- if (e === undefined)
308
- return;
309
- if (e.target === 'content') {
310
- e.items = e.items || [];
311
- e.items = createTasksMenuItems(e.row?.data, showId, setShowId, showSearch, setShowSearch, openTaskFormCallback, () => { openTaskFormCallback(FormModes.Update, e.row?.data); }, () => { openTaskFormCallback(FormModes.Duplicate, e.row?.data); }, onDeleteCallback, markAsStatus, getAllTasks, taskContext?.workingGroup?.id !== undefined, showContextualWG, setShowContextualWG, taskContext?.dossier?.id !== undefined, showContextualDossier, setShowContextualDossier, taskContext?.document?.tid !== undefined && taskContext?.document?.did !== undefined, showContextualDocument, setShowContextualDocument, false);
312
- }
313
- };
321
+ await handleNavigateToWGs(value);
322
+ }, [handleNavigateToWGs]);
314
323
  const RenderCustomHeader = ({ data }) => { return _jsx("p", { style: { color: TEXT_NOT_SELECTED_COLOR }, children: data.column.caption }); };
315
324
  const cellDefaultRender = useCallback((cellData) => {
316
325
  const data = cellData.data;
@@ -519,13 +528,13 @@ const TMTasksView = (props) => {
519
528
  ];
520
529
  }, [showId]);
521
530
  const getFromOrToDatagridElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
522
- return _jsx(TMDataGrid, { dataSource: fromOrToDataSource, dataColumns: getDataColumns(fromCell, toCell), selection: { mode: 'multiple', showCheckBoxesMode: "always" }, focusedRowKey: focusedRowKey, selectedRowKeys: [...selectedRowKeys], onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onRowDblClick: onRowDblClick, onContextMenuPreparing: onContextMenuPreparing, showSearchPanel: showSearch, noDataText: SDKUI_Localizator.TasksEmpty, counterConfig: { show: true }, onHasFiltersChange: (active) => setHasFilters(active) });
531
+ return _jsx(TMDataGrid, { dataSource: fromOrToDataSource, dataColumns: getDataColumns(fromCell, toCell), selection: { mode: 'multiple', showCheckBoxesMode: "always" }, focusedRowKey: focusedRowKey, selectedRowKeys: [...selectedRowKeys], onFocusedRowChanged: onFocusedRowChanged, onSelectionChanged: onSelectionChanged, onRowDblClick: onRowDblClick, customContextMenuItems: datagridMenu, showSearchPanel: showSearch, noDataText: SDKUI_Localizator.TasksEmpty, counterConfig: { show: true }, onHasFiltersChange: (active) => setHasFilters(active) });
523
532
  };
524
533
  const getFromOrToAgendaElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
525
- return _jsxs("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: [_jsx(ContextMenu, { dataSource: menuItems, target: `#tasks-agenda-wrapper-${id}` }), _jsx("div", { style: { width: "100%", height: "100%" }, children: _jsx(TMTasksAgenda, { id: id, showId: showId, showSearch: showSearch, visualizedTasks: fromOrToDataSource, fromCell: fromCell, toCell: toCell, currentAgendaDate: currentAgendaDate, setCurrentAgendaDate: setCurrentAgendaDate, openTaskForm: openTaskFormCallback, handleFocusedRowChange: handleFocusedRowChange }) })] });
534
+ return _jsx("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: _jsx("div", { style: { width: "100%", height: "100%" }, children: _jsx(TMTasksAgenda, { id: id, showId: showId, showSearch: showSearch, visualizedTasks: fromOrToDataSource, fromCell: fromCell, toCell: toCell, currentAgendaDate: currentAgendaDate, setCurrentAgendaDate: setCurrentAgendaDate, openTaskForm: openTaskFormCallback, handleFocusedRowChange: handleFocusedRowChange, menuItems: menuItems }) }) });
526
535
  };
527
536
  const getFromOrToCalendarElement = (fromOrToDataSource, fromCell = false, toCell = false) => {
528
- return _jsxs("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: [_jsx(ContextMenu, { dataSource: menuItems, target: `#tasks-calendar-wrapper-${id}` }), _jsx("div", { style: { width: "100%", height: "100%" }, children: _jsx(TMTasksCalendar, { id: id, visualizedTasks: fromOrToDataSource, showId: showId, fromCell: fromCell, toCell: toCell, showSearch: showSearch, currentCalendarDate: currentCalendarDate, setCurrentCalendarDate: setCurrentCalendarDate, openTaskForm: openTaskFormCallback, onDeleteCallback: onDeleteCallback, setCalendarStartDate: setCalendarStartDate, setCalendarEndDate: setCalendarEndDate, focusedRowKey: focusedRowKey, handleFocusedRowChange: handleFocusedRowChange }) })] });
537
+ return _jsx("div", { style: { width: '100%', height: '100%', display: 'flex', flexDirection: 'column', overflow: "auto" }, children: _jsx("div", { style: { width: "100%", height: "100%" }, children: _jsx(TMTasksCalendar, { id: id, visualizedTasks: fromOrToDataSource, showId: showId, fromCell: fromCell, toCell: toCell, showSearch: showSearch, currentCalendarDate: currentCalendarDate, setCurrentCalendarDate: setCurrentCalendarDate, openTaskForm: openTaskFormCallback, onDeleteCallback: onDeleteCallback, setCalendarStartDate: setCalendarStartDate, setCalendarEndDate: setCalendarEndDate, focusedRowKey: focusedRowKey, handleFocusedRowChange: handleFocusedRowChange, menuItems: menuItems }) }) });
529
538
  };
530
539
  return _jsxs("div", { style: { width: '100%', height: '100%' }, onContextMenu: (e) => e.preventDefault(), children: [_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, isCancelable: true, abortController: abortController, children: _jsxs(TabPanel, { width: "100%", height: "100%", animationEnabled: false, swipeEnabled: false, loop: false, showNavButtons: true, repaintChangesOnly: true, stylingMode: "primary", iconPosition: 'start', tabsPosition: 'top', selectedIndex: activeTabIndex, onSelectedIndexChange: onSelectedIndexChange, id: "task-centered-tab-title", children: [_jsx(Item, { title: SDKUI_Localizator.AssignedToMe, icon: "user", tabRender: (params) => {
531
540
  return _jsxs(StyledTabItem, { "$isSelected": activeTabIndex === AssignedTab.AssignedToMe, children: [_jsxs(TMTooltip, { content: SDKUI_Localizator.AssignedToMe, children: [_jsx("i", { className: `dx-icon-${params.icon}` }), "\u00A0", params.title, " ", (assignedToMeCount > 0) ? `(${assignedToMeCount})` : ''] }), newTaskCount > 0 && (_jsx(TMTooltip, { content: SDKUI_Localizator.NewAssignedActivitiesNumber + ": " + newTaskCount, children: _jsx(TMCountBadge, { children: newTaskCount }) }))] });
@@ -1,5 +1,6 @@
1
- import { DcmtTypeDescriptor } from '@topconsultnpm/sdk-ts';
1
+ import { DcmtTypeDescriptor, WFDescriptor } from '@topconsultnpm/sdk-ts';
2
2
  import { DeviceType } from "../../base/TMDeviceProvider";
3
+ import { WorkItemDetail } from "../../../ts";
3
4
  interface IWorkflowOperationButtonsProps {
4
5
  dtd: DcmtTypeDescriptor | undefined;
5
6
  approveDisable?: boolean;
@@ -24,13 +25,43 @@ export declare const WorkFlowApproveRejectPopUp: ({ TID, DID, deviceType, isReje
24
25
  onClose?: () => void;
25
26
  onCompleted?: () => Promise<void>;
26
27
  }) => import("react/jsx-runtime").JSX.Element;
27
- export declare const WorkFlowReAssignPopUp: ({ DID, TID, deviceType, onClose, selectedItems, onCompleted }: {
28
+ export declare const WorkFlowReAssignPopUp: ({ DID, TID, deviceType, onClose, selectedItems, onCompleted, wf, workItemDetail }: {
28
29
  TID?: number;
29
30
  DID?: number;
30
31
  deviceType?: DeviceType;
31
32
  onClose?: () => void;
32
33
  selectedItems?: any[];
33
34
  onCompleted?: () => Promise<void>;
35
+ wf?: WFDescriptor;
36
+ workItemDetail?: WorkItemDetail;
37
+ }) => import("react/jsx-runtime").JSX.Element;
38
+ /**
39
+ * Modal per forzare l'approvazione di un work item
40
+ */
41
+ export declare const WorkflowForceApproveModal: ({ detail, onClose, onCompleted }: {
42
+ detail: WorkItemDetail;
43
+ onClose?: () => void;
44
+ onCompleted?: () => Promise<void>;
45
+ }) => import("react/jsx-runtime").JSX.Element;
46
+ /**
47
+ * Modal per forzare il rifiuto di un work item
48
+ */
49
+ export declare const WorkflowForceRejectModal: ({ detail, onClose, onCompleted }: {
50
+ detail: WorkItemDetail;
51
+ onClose?: () => void;
52
+ onCompleted?: () => Promise<void>;
53
+ }) => import("react/jsx-runtime").JSX.Element;
54
+ /**
55
+ * Modal per terminare le istanze workflow selezionate
56
+ */
57
+ export declare const WorkflowEndInstanceModal: ({ selectedInstances, onClose, onCompleted }: {
58
+ selectedInstances: Array<{
59
+ wfid?: number;
60
+ tid?: number;
61
+ did?: number;
62
+ }>;
63
+ onClose?: () => void;
64
+ onCompleted?: () => Promise<void>;
34
65
  }) => import("react/jsx-runtime").JSX.Element;
35
66
  export declare const WorkFlowMoreInfoPopUp: ({ DID, TID, deviceType, onClose, onCompleted }: {
36
67
  TID?: number;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
3
- import { Priorities, ResultTypes, SDK_Globals, SDK_Localizator, TaskEngine, UserListCacheService, ValidationItem, WorkflowCacheService } from '@topconsultnpm/sdk-ts';
2
+ import { useEffect, useMemo, useState } from "react";
3
+ import { Priorities, ResultTypes, SDK_Globals, SDK_Localizator, TaskEngine, UserListCacheService, ValidationItem, WFEvents, WorkflowCacheService } from '@topconsultnpm/sdk-ts';
4
4
  import styled from "styled-components";
5
- import { SDKUI_Localizator, IconApply, IconCloseOutline, IconUser, IconInfo, DateDisplayTypes, TASK_MORE_INFO_PREFIX_NAME, IconSignaturePencil, isSign4TopEnabled } from "../../../helper";
5
+ import { SDKUI_Localizator, IconApply, IconCloseOutline, IconUser, IconInfo, DateDisplayTypes, TASK_MORE_INFO_PREFIX_NAME, IconSignaturePencil, isSign4TopEnabled, IconCheck, IconCloseCircle, IconStop } from "../../../helper";
6
6
  import { TMColors } from "../../../utils/theme";
7
7
  import TMButton from "../../base/TMButton";
8
8
  import { DeviceType } from "../../base/TMDeviceProvider";
@@ -21,17 +21,15 @@ const StyledWorkFlowOperationButtonsContainer = styled.div `
21
21
  gap: 10px;
22
22
  flex-direction: column;
23
23
  `;
24
- const StyledTextArea = styled.textarea.attrs({
25
- maxLength: 200
26
- }) `
24
+ const StyledTextArea = styled.textarea `
27
25
  width: 100%;
28
26
  height: 100%;
29
- border: 1px solid ${props => props.$isValid ? '#b4b4b4' : TMColors.error};
27
+ border: 1px solid ${(props) => (props.$isValid ? '#b4b4b4' : TMColors.error)};
30
28
  border-radius: 10px;
31
29
  padding: 10px;
32
- &:focus{
30
+ &:focus {
33
31
  outline: none;
34
- border-bottom: 4px solid ${props => props.$isValid ? TMColors.primaryColor : TMColors.error};
32
+ border-bottom: 4px solid ${(props) => (props.$isValid ? TMColors.primaryColor : TMColors.error)};
35
33
  }
36
34
  `;
37
35
  const CharacterCounter = styled.div `
@@ -68,17 +66,12 @@ const StyledHorizontalContainer = styled.div `
68
66
  export const WorkFlowOperationButtons = (props) => {
69
67
  const { dtd = undefined, deviceType = DeviceType.DESKTOP, approveDisable = false, signApproveDisable = false, rejectDisable = false, reassignDisable = false, infoDisable = false, onApprove, onSignApprove, onReject, onReAssign, onMoreInfo } = props;
70
68
  const isMobile = deviceType === DeviceType.MOBILE;
71
- // Stato per distinguere workflow di firma vs approvazione
72
- const [isSignWorkflow, setIsSignWorkflow] = useState(false);
73
- useEffect(() => {
74
- // Controlla se il documento ha dei widget definiti, se il documento ha il widget SIGN4_TOP abilitato, allora è un workflow di firma
69
+ // Calcola direttamente se è un workflow di firma per evitare flickering durante il render
70
+ const isSignWorkflow = useMemo(() => {
75
71
  if (dtd && dtd.widgets && dtd.widgets.length > 0) {
76
- setIsSignWorkflow(isSign4TopEnabled(dtd.widgets));
77
- }
78
- else {
79
- // Se non ci sono widget o non è SIGN4_TOP, imposta il workflow di default (approvazione senza firma)
80
- setIsSignWorkflow(false);
72
+ return isSign4TopEnabled(dtd.widgets);
81
73
  }
74
+ return false;
82
75
  }, [dtd]);
83
76
  return (_jsx(StyledWorkFlowOperationButtonsContainer, { "$isMobile": isMobile, children: isSignWorkflow ? (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconSignaturePencil, {}), caption: SDKUI_Localizator.SignatureAndApprove, width: "160px", disabled: signApproveDisable, onClick: () => !signApproveDisable && onSignApprove?.(), onMouseDown: e => e.stopPropagation(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.error, color: "error" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), onMouseDown: e => e.stopPropagation(), advancedColor: TMColors.info, color: "info" })] })) : (_jsxs(_Fragment, { children: [_jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: approveDisable, onClick: () => !approveDisable && onApprove?.(), advancedColor: "#1a9a49", color: "success" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: rejectDisable, onClick: () => !rejectDisable && onReject?.(), advancedColor: TMColors.error, color: "error" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: reassignDisable, onClick: () => !reassignDisable && onReAssign?.(), advancedColor: TMColors.tertiary, color: "tertiary" }), _jsx(TMButton, { btnStyle: isMobile ? 'toolbar' : 'advanced', showTooltip: isMobile, icon: _jsx(IconInfo, { fontSize: 16 }), caption: SDKUI_Localizator.MoreInformation, width: "180px", disabled: infoDisable, onClick: () => !infoDisable && onMoreInfo?.(), advancedColor: TMColors.info, color: "info" })] })) }));
84
77
  };
@@ -97,6 +90,7 @@ export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = Devi
97
90
  for (const { TID, DID } of items) {
98
91
  await workflowEngine.WorkItem_CompleteOrRejectAsync(TID, DID, commentValue, isReject);
99
92
  }
93
+ ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: isReject === 0 ? SDKUI_Localizator.WorkitemApprove : SDKUI_Localizator.WorkitemReject, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
100
94
  }
101
95
  catch (e) {
102
96
  TMExceptionBoxManager.show({ exception: e });
@@ -105,33 +99,42 @@ export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = Devi
105
99
  onCompleted?.();
106
100
  onClose?.();
107
101
  TMSpinner.hide();
108
- ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: isReject === 0 ? SDKUI_Localizator.WorkitemApprove : SDKUI_Localizator.WorkitemReject, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
109
102
  }
110
103
  };
111
104
  const workflowAction = isReject === 0 ? SDKUI_Localizator.Approve : SDKUI_Localizator.Reject;
112
105
  const itemCount = selectedItems.length > 0 ? `(${selectedItems.length} workitem)` : '';
113
106
  const title = `${workflowAction} ${itemCount}`;
114
- return (_jsx(TMModal, { title: title, onClose: onClose, width: '600px', height: '270px', isModal: true, children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsxs("p", { style: { color: (isReject === 1 && disable) ? TMColors.error : 'black' }, children: [SDKUI_Localizator.CommentText, " ", isReject === 1 && disable && _jsx("span", { children: ` (${SDKUI_Localizator.RequiredField})` }), " "] }), _jsx(StyledTextArea, { "$isValid": isReject === 0 ? true : !disable, value: commentValue, onChange: (e) => setCommentValue(e.target.value) }), _jsx(CharacterCounter, { children: `${200 - commentValue.length} ${SDKUI_Localizator.CharactersRemaining}` })] }), _jsx(StyledModalFooter, { children: isReject === 0
107
+ return (_jsx(TMModal, { title: title, onClose: onClose, width: '600px', height: '270px', isModal: true, children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsxs("p", { style: { color: (isReject === 1 && disable) ? TMColors.error : 'black' }, children: [SDKUI_Localizator.CommentText, " ", isReject === 1 && disable && _jsx("span", { children: ` (${SDKUI_Localizator.RequiredField})` }), " "] }), _jsx(StyledTextArea, { maxLength: 200, "$isValid": isReject === 0 ? true : !disable, value: commentValue, onChange: (e) => setCommentValue(e.target.value) }), _jsx(CharacterCounter, { children: `${200 - commentValue.length} ${SDKUI_Localizator.CharactersRemaining}` })] }), _jsx(StyledModalFooter, { children: isReject === 0
115
108
  ? _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconApply, {}), caption: SDKUI_Localizator.Approve, disabled: false, onClick: () => completeOrRejectAsync(isReject), advancedColor: TMColors.success })
116
109
  : _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconCloseOutline, {}), caption: SDKUI_Localizator.Reject, disabled: disable, onClick: () => { !disable && completeOrRejectAsync(isReject); }, advancedColor: TMColors.error }) })] }) }));
117
110
  };
118
- export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceType.DESKTOP, onClose, selectedItems = [], onCompleted }) => {
111
+ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceType.DESKTOP, onClose, selectedItems = [], onCompleted, wf, workItemDetail }) => {
119
112
  const [commentValue, setCommentValue] = useState('');
120
113
  const [selectedUserID, setSelectedUserID] = useState([]);
121
114
  const [participants, setParticipants] = useState([]);
122
115
  const disable = commentValue.length === 0 || !selectedUserID;
116
+ // Determina se siamo nel contesto CtrlWorkflow (quando abbiamo workItemDetail)
117
+ const isCtrlWorkflowContext = !!workItemDetail;
123
118
  const reAssignWorkFlowAsync = async () => {
124
119
  try {
125
120
  TMSpinner.show();
126
121
  const workflowEngine = SDK_Globals.tmSession?.NewWorkflowEngine();
127
122
  if (!workflowEngine)
128
123
  throw new Error("Workflow engine is not available");
129
- const items = selectedItems.length > 0
130
- ? selectedItems.map(({ TID, DID }) => ({ TID, DID }))
131
- : [{ TID, DID }];
132
- for (const { TID, DID } of items) {
133
- await SDK_Globals.tmSession?.NewWorkflowEngine().WorkItem_ReassignAsync(TID, DID, selectedUserID?.[0], commentValue);
124
+ if (isCtrlWorkflowContext && workItemDetail) {
125
+ // Contesto CtrlWorkflow: usa WFCtrl_ReassignWIAsync
126
+ await workflowEngine.WFCtrl_ReassignWIAsync(workItemDetail.wfid, workItemDetail.did, selectedUserID?.[0], commentValue);
127
+ }
128
+ else {
129
+ // Contesto WorkItem: usa WorkItem_ReassignAsync
130
+ const items = selectedItems.length > 0
131
+ ? selectedItems.map(({ TID, DID }) => ({ TID, DID }))
132
+ : [{ TID, DID }];
133
+ for (const { TID, DID } of items) {
134
+ await workflowEngine.WorkItem_ReassignAsync(TID, DID, selectedUserID?.[0], commentValue);
135
+ }
134
136
  }
137
+ ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.WorkitemReassign, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
135
138
  }
136
139
  catch (e) {
137
140
  TMExceptionBoxManager.show({ exception: e });
@@ -140,11 +143,10 @@ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
140
143
  onCompleted?.();
141
144
  onClose?.();
142
145
  TMSpinner.hide();
143
- ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.WorkitemReassign, message: SDKUI_Localizator.OperationSuccess, duration: 3000 });
144
146
  }
145
147
  };
146
148
  // Determina il TID da usare
147
- const tidToUse = selectedItems?.[0]?.TID ?? TID;
149
+ const tidToUse = workItemDetail?.tid ?? selectedItems?.[0]?.TID ?? TID;
148
150
  useEffect(() => {
149
151
  let isMounted = true;
150
152
  const fetchData = async () => {
@@ -153,11 +155,11 @@ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
153
155
  if (!tidToUse)
154
156
  return;
155
157
  // Recupera info workflow
156
- const wf = await WorkflowCacheService.GetWFInfoAsync(tidToUse);
158
+ const workflowInfo = wf ?? await WorkflowCacheService.GetWFInfoAsync(tidToUse);
157
159
  // Recupera tutti gli utenti
158
160
  const allUsers = await UserListCacheService.GetAllAsync();
159
161
  // Filtra utenti partecipanti
160
- const participantIds = wf?.participants?.map(p => p.userID);
162
+ const participantIds = workflowInfo?.participants?.map(p => p.userID);
161
163
  const participantUsers = allUsers.filter(u => participantIds?.includes(u.id) && u.id !== SDK_Globals.tmSession?.SessionDescr?.userID);
162
164
  if (isMounted)
163
165
  setParticipants(participantUsers);
@@ -171,10 +173,113 @@ export const WorkFlowReAssignPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
171
173
  };
172
174
  fetchData();
173
175
  return () => { isMounted = false; };
174
- }, [tidToUse]);
175
- return (_jsx(TMModal, { onClose: onClose, width: '600px', height: '270px', isModal: true, title: SDKUI_Localizator.Reassign + (selectedItems.length > 0 ? ' (' + selectedItems.length + ' workitem)' : ''), children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsx(TMUserChooser, { dataSource: participants, values: selectedUserID, onValueChanged: (IDs) => {
176
+ }, [tidToUse, wf, workItemDetail]);
177
+ // Determina il conteggio degli item da mostrare nel titolo
178
+ const itemCount = workItemDetail ? 1 : selectedItems.length;
179
+ const titleSuffix = itemCount > 0 ? ` (${itemCount} workitem)` : '';
180
+ return (_jsx(TMModal, { onClose: onClose, width: '600px', height: '270px', isModal: true, title: SDKUI_Localizator.Reassign + titleSuffix, children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsx(TMUserChooser, { dataSource: participants, values: selectedUserID, onValueChanged: (IDs) => {
176
181
  setSelectedUserID(IDs ?? []);
177
- } }), _jsxs("p", { style: { color: commentValue.length === 0 ? TMColors.error : 'black' }, children: [SDKUI_Localizator.CommentText, " ", commentValue.length === 0 && _jsx("span", { children: ` (${SDKUI_Localizator.RequiredField})` }), " "] }), _jsx(StyledTextArea, { "$isValid": commentValue.length !== 0, value: commentValue, onChange: (e) => setCommentValue(e.target.value) }), _jsx(CharacterCounter, { children: `${200 - commentValue.length} ${SDKUI_Localizator.CharactersRemaining}` })] }), _jsx(StyledModalFooter, { children: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: disable, onClick: () => !disable && reAssignWorkFlowAsync(), advancedColor: TMColors.tertiary }) })] }) }));
182
+ } }), _jsxs("p", { style: { color: commentValue.length === 0 ? TMColors.error : 'black' }, children: [SDKUI_Localizator.CommentText, " ", commentValue.length === 0 && _jsx("span", { children: ` (${SDKUI_Localizator.RequiredField})` }), " "] }), _jsx(StyledTextArea, { maxLength: 200, "$isValid": commentValue.length !== 0, value: commentValue, onChange: (e) => setCommentValue(e.target.value) }), _jsx(CharacterCounter, { children: `${200 - commentValue.length} ${SDKUI_Localizator.CharactersRemaining}` })] }), _jsx(StyledModalFooter, { children: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconUser, { fontSize: 16 }), caption: SDKUI_Localizator.Reassign, disabled: disable, onClick: () => !disable && reAssignWorkFlowAsync(), advancedColor: TMColors.tertiary }) })] }) }));
183
+ };
184
+ /**
185
+ * Modal per forzare l'approvazione di un work item
186
+ */
187
+ export const WorkflowForceApproveModal = ({ detail, onClose, onCompleted }) => {
188
+ const [commentValue, setCommentValue] = useState('');
189
+ const disable = commentValue.length === 0;
190
+ const forceApproveAsync = async () => {
191
+ try {
192
+ TMSpinner.show({ description: 'Forza approvazione in corso...' });
193
+ await SDK_Globals.tmSession?.NewWorkflowEngine().WFCtrl_ForceWIAsync(detail.wfid, detail.did, WFEvents.AfterBtnApprove01, commentValue);
194
+ ShowAlert({
195
+ mode: 'success',
196
+ position: 'TOP_RIGHT',
197
+ title: 'Forza completamento',
198
+ message: 'Work item approvato con successo',
199
+ duration: 3000
200
+ });
201
+ await onCompleted?.();
202
+ }
203
+ catch (e) {
204
+ TMExceptionBoxManager.show({ exception: e });
205
+ }
206
+ finally {
207
+ onClose?.();
208
+ TMSpinner.hide();
209
+ }
210
+ };
211
+ const userName = detail.toUser?.name ?? detail.to;
212
+ const title = `Forza completamento - ${userName}`;
213
+ return (_jsx(TMModal, { title: title, onClose: onClose, width: '600px', height: '270px', isModal: true, children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsx("div", { style: { fontWeight: 600, marginBottom: '8px' }, children: "Motivazione (obbligatorio):" }), _jsx(StyledTextArea, { "$isValid": !disable, value: commentValue, onChange: (e) => setCommentValue(e.target.value), placeholder: "Inserisci il motivo della forzatura...", maxLength: 200 }), _jsxs(CharacterCounter, { children: [commentValue.length, "/200"] })] }), _jsx(StyledModalFooter, { children: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconCheck, {}), caption: "Forza approvazione", width: '180px', disabled: disable, onClick: () => !disable && forceApproveAsync(), advancedColor: TMColors.success }) })] }) }));
214
+ };
215
+ /**
216
+ * Modal per forzare il rifiuto di un work item
217
+ */
218
+ export const WorkflowForceRejectModal = ({ detail, onClose, onCompleted }) => {
219
+ const [commentValue, setCommentValue] = useState('');
220
+ const disable = commentValue.length === 0;
221
+ const forceRejectAsync = async () => {
222
+ try {
223
+ TMSpinner.show({ description: 'Forza rifiuto in corso...' });
224
+ await SDK_Globals.tmSession?.NewWorkflowEngine().WFCtrl_ForceWIAsync(detail.wfid, detail.did, WFEvents.AfterBtnReject01, commentValue);
225
+ ShowAlert({
226
+ mode: 'success',
227
+ position: 'TOP_RIGHT',
228
+ title: 'Forza rifiuto',
229
+ message: 'Work item rifiutato con successo',
230
+ duration: 3000
231
+ });
232
+ await onCompleted?.();
233
+ }
234
+ catch (e) {
235
+ TMExceptionBoxManager.show({ exception: e });
236
+ }
237
+ finally {
238
+ onClose?.();
239
+ TMSpinner.hide();
240
+ }
241
+ };
242
+ const userName = detail.toUser?.name ?? detail.to;
243
+ const title = `Forza rifiuto - ${userName}`;
244
+ return (_jsx(TMModal, { title: title, onClose: onClose, width: '600px', height: '270px', isModal: true, children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsx("div", { style: { fontWeight: 600, marginBottom: '8px' }, children: "Motivazione (obbligatorio):" }), _jsx(StyledTextArea, { "$isValid": !disable, value: commentValue, onChange: (e) => setCommentValue(e.target.value), placeholder: "Inserisci il motivo del rifiuto...", maxLength: 200 }), _jsxs(CharacterCounter, { children: [commentValue.length, "/200"] })] }), _jsx(StyledModalFooter, { children: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconCloseCircle, {}), caption: "Forza rifiuto", width: '150px', disabled: disable, onClick: () => !disable && forceRejectAsync(), advancedColor: TMColors.error }) })] }) }));
245
+ };
246
+ /**
247
+ * Modal per terminare le istanze workflow selezionate
248
+ */
249
+ export const WorkflowEndInstanceModal = ({ selectedInstances, onClose, onCompleted }) => {
250
+ const [commentValue, setCommentValue] = useState('');
251
+ const disable = commentValue.length === 0;
252
+ const endInstancesAsync = async () => {
253
+ try {
254
+ TMSpinner.show({ description: 'Terminazione istanze in corso...' });
255
+ const workflowEngine = SDK_Globals.tmSession?.NewWorkflowEngine();
256
+ if (!workflowEngine)
257
+ throw new Error("Workflow engine non disponibile");
258
+ for (const instance of selectedInstances) {
259
+ if (instance.wfid && instance.did) {
260
+ await workflowEngine.WFCtrl_EndInstanceAsync(instance.wfid, instance.tid ?? 0, instance.did, commentValue);
261
+ }
262
+ }
263
+ ShowAlert({
264
+ mode: 'success',
265
+ position: 'TOP_RIGHT',
266
+ title: 'Terminazione istanze',
267
+ message: `${selectedInstances.length} ${selectedInstances.length === 1 ? 'istanza terminata' : 'istanze terminate'} con successo`,
268
+ duration: 3000
269
+ });
270
+ await onCompleted?.();
271
+ }
272
+ catch (e) {
273
+ TMExceptionBoxManager.show({ exception: e });
274
+ }
275
+ finally {
276
+ onClose?.();
277
+ TMSpinner.hide();
278
+ }
279
+ };
280
+ const itemCount = selectedInstances.length > 0 ? `(${selectedInstances.length} ${selectedInstances.length === 1 ? 'istanza' : 'istanze'})` : '';
281
+ const title = `Termina istanza ${itemCount}`;
282
+ return (_jsx(TMModal, { title: title, onClose: onClose, width: '600px', height: '270px', isModal: true, children: _jsxs(StyledModalBodyWrapper, { children: [_jsxs(StyledModalContentContainer, { children: [_jsx("div", { style: { fontWeight: 600, marginBottom: '8px' }, children: "Motivazione (obbligatorio):" }), _jsx(StyledTextArea, { "$isValid": !disable, value: commentValue, onChange: (e) => setCommentValue(e.target.value), placeholder: "Inserisci il motivo della terminazione...", maxLength: 200 }), _jsxs(CharacterCounter, { children: [commentValue.length, "/200"] })] }), _jsx(StyledModalFooter, { children: _jsx(TMButton, { btnStyle: 'advanced', showTooltip: false, icon: _jsx(IconStop, {}), caption: "Termina istanza", width: '150px', disabled: disable, onClick: () => !disable && endInstancesAsync(), advancedColor: TMColors.error }) })] }) }));
178
283
  };
179
284
  export const WorkFlowMoreInfoPopUp = ({ DID = 0, TID = 0, deviceType = DeviceType.DESKTOP, onClose, onCompleted }) => {
180
285
  const [users, setUsers] = useState([]);
@@ -210,6 +315,7 @@ export const WorkFlowMoreInfoPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
210
315
  name: `${TASK_MORE_INFO_PREFIX_NAME}${nameInput}`
211
316
  };
212
317
  await SDK_Globals.tmSession?.NewWorkflowEngine().WorkItem_MoreInfoAsync(TID, DID, taskWithPrefix);
318
+ ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.MoreInformation, message: SDKUI_Localizator.MoreInfoSent, duration: 3000 });
213
319
  }
214
320
  catch (e) {
215
321
  TMExceptionBoxManager.show({ exception: e });
@@ -218,7 +324,6 @@ export const WorkFlowMoreInfoPopUp = ({ DID = 0, TID = 0, deviceType = DeviceTyp
218
324
  onCompleted?.();
219
325
  onClose?.();
220
326
  TMSpinner.hide();
221
- ShowAlert({ mode: 'success', position: 'TOP_RIGHT', title: SDKUI_Localizator.MoreInformation, message: SDKUI_Localizator.MoreInfoSent, duration: 3000 });
222
327
  }
223
328
  };
224
329
  useEffect(() => {
@@ -6,6 +6,7 @@ interface DiagramItemComponentProps {
6
6
  isSelected: boolean;
7
7
  isCurrent: boolean;
8
8
  readOnly: boolean;
9
+ allowItemClick?: boolean;
9
10
  onClick: (id: string, event: React.MouseEvent) => void;
10
11
  onDrag: (id: string, newX: number, newY: number) => void;
11
12
  onDragEnd: (id: string, finalX: number, finalY: number) => void;
@@ -13,6 +14,7 @@ interface DiagramItemComponentProps {
13
14
  onConnectorMouseUp: (itemId: string, connectorName: string) => void;
14
15
  onDimensionsChange: (itemId: string, width: number, height: number) => void;
15
16
  onDoubleClick?: (id: string) => void;
17
+ backgroundColor?: string;
16
18
  }
17
19
  declare const _default: React.NamedExoticComponent<DiagramItemComponentProps>;
18
20
  export default _default;
@@ -38,11 +38,16 @@ const AnimatingGroup = styled.g `
38
38
  `}
39
39
  `;
40
40
  const StyledDiagramItem = styled.g `
41
- cursor: ${props => (props.$isReadOnly ? 'default' : (props.$isDragging ? 'grabbing' : 'grab'))};
41
+ cursor: ${props => {
42
+ if (props.$isReadOnly && props.$allowItemClick)
43
+ return 'pointer';
44
+ if (props.$isReadOnly)
45
+ return 'default';
46
+ return props.$isDragging ? 'grabbing' : 'grab';
47
+ }};
42
48
  filter: ${props => (props.$isSelected || props.$isDragging || props.$isHovered ? 'drop-shadow(2px 4px 6px rgba(0,0,0,0.4))' : 'none')};
43
49
 
44
50
  & .item-main-shape {
45
- fill: transparent;
46
51
  stroke: ${props => {
47
52
  if (props.$isDragging)
48
53
  return '#ffc107';
@@ -82,7 +87,7 @@ const ConnectorHitArea = styled.circle `
82
87
  opacity: 0;
83
88
  pointer-events: all;
84
89
  `;
85
- const DiagramItemComponent = ({ wf, item, isSelected, isCurrent, readOnly, onClick, onDrag, onDragEnd, onConnectorMouseDown, onConnectorMouseUp, onDimensionsChange, onDoubleClick, }) => {
90
+ const DiagramItemComponent = ({ wf, item, isSelected, isCurrent, readOnly, allowItemClick = false, onClick, onDrag, onDragEnd, onConnectorMouseDown, onConnectorMouseUp, onDimensionsChange, onDoubleClick, backgroundColor, }) => {
86
91
  const diagramItemRef = useRef(null);
87
92
  const textRef = useRef(null);
88
93
  const [isDragging, setIsDragging] = useState(false);
@@ -207,12 +212,12 @@ const DiagramItemComponent = ({ wf, item, isSelected, isCurrent, readOnly, onCli
207
212
  };
208
213
  }, [isDragging, handleMouseMove, handleMouseUp, readOnly]);
209
214
  const handleItemClick = useCallback((event) => {
210
- if (readOnly)
215
+ if (readOnly && !allowItemClick)
211
216
  return;
212
217
  if (!isDragging) {
213
218
  onClick(item.ID, event);
214
219
  }
215
- }, [item.ID, onClick, isDragging, readOnly]);
220
+ }, [item.ID, onClick, isDragging, readOnly, allowItemClick]);
216
221
  const handleMouseEnter = useCallback(() => {
217
222
  setIsHovered(true);
218
223
  }, []);
@@ -257,8 +262,8 @@ const DiagramItemComponent = ({ wf, item, isSelected, isCurrent, readOnly, onCli
257
262
  isTruncated = textLines[textLines.length - 1].endsWith('...');
258
263
  }
259
264
  }
260
- return (_jsxs(_Fragment, { children: [isTruncated && _jsx("title", { children: item.ItemName }), _jsx("rect", { x: "0", y: "0", width: calculatedWidth, height: calculatedHeight, className: "item-main-shape" }), _jsx("g", { transform: `translate(${svgX}, ${svgY})`, children: _jsx(DiagramItemSvgContent, { itemType: item.Type, width: iconRenderWidth, height: iconRenderHeight, statusData: statusData }) }), textLines.length > 0 && (_jsx("text", { ref: textRef, x: calculatedWidth / 2, dominantBaseline: "central", className: "item-text", children: textLines.map((line, index) => (_jsx("tspan", { x: calculatedWidth / 2, dy: index === 0 ? PADDING_TOP + SVG_ICON_SIZE + SPACING_SVG_TEXT : FONT_SIZE + 1, children: line }, index))) })), connectors] }));
265
+ return (_jsxs(_Fragment, { children: [isTruncated && _jsx("title", { children: item.ItemName }), backgroundColor && (_jsx("rect", { x: "-5", y: "-5", width: calculatedWidth + 10, height: calculatedHeight + 10, rx: "12", ry: "12", fill: backgroundColor, opacity: "0.4", style: { filter: 'blur(3px)' } })), _jsx("rect", { x: "0", y: "0", width: calculatedWidth, height: calculatedHeight, className: "item-main-shape", fill: "transparent" }), _jsx("g", { transform: `translate(${svgX}, ${svgY})`, children: _jsx(DiagramItemSvgContent, { itemType: item.Type, width: iconRenderWidth, height: iconRenderHeight, statusData: statusData }) }), textLines.length > 0 && (_jsx("text", { ref: textRef, x: calculatedWidth / 2, dominantBaseline: "central", className: "item-text", children: textLines.map((line, index) => (_jsx("tspan", { x: calculatedWidth / 2, dy: index === 0 ? PADDING_TOP + SVG_ICON_SIZE + SPACING_SVG_TEXT : FONT_SIZE + 1, children: line }, index))) })), connectors] }));
261
266
  };
262
- return (_jsx(StyledDiagramItem, { ref: diagramItemRef, transform: `translate(${currentPosition.x}, ${currentPosition.y})`, "$isSelected": isSelected, "$itemType": item.Type, "$isDragging": isDragging, "$isHovered": isHovered, "$isReadOnly": readOnly, onMouseDown: handleMouseDown, onClick: handleItemClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onDoubleClick: handleDoubleClick, children: _jsx(AnimatingGroup, { "$isCurrent": isCurrent, children: renderContent() }) }));
267
+ return (_jsx(StyledDiagramItem, { ref: diagramItemRef, transform: `translate(${currentPosition.x}, ${currentPosition.y})`, "$isSelected": isSelected, "$itemType": item.Type, "$isDragging": isDragging, "$isHovered": isHovered, "$isReadOnly": readOnly, "$allowItemClick": allowItemClick, onMouseDown: handleMouseDown, onClick: handleItemClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onDoubleClick: handleDoubleClick, children: _jsx(AnimatingGroup, { "$isCurrent": isCurrent, children: renderContent() }) }));
263
268
  };
264
269
  export default React.memo(DiagramItemComponent);
@@ -409,7 +409,7 @@ const DiagramItemForm = ({ itemToEdit, wf, onClose, onApply }) => {
409
409
  return qd;
410
410
  };
411
411
  const qdForRecipientsEditor = localItem.QD ?? newQD();
412
- return (_jsxs(_Fragment, { children: [_jsx(TMLocalizedTextBox, { label: SDKUI_Localizator.Description, value: localItem.Description, value_IT: localItem.Description_IT, value_EN: localItem.Description_EN, value_FR: localItem.Description_FR, value_PT: localItem.Description_PT, value_ES: localItem.Description_ES, value_DE: localItem.Description_DE, isModifiedWhen: localItem.Description !== localItemOrig.Description, validationItems: validationItems.filter(v => v.PropertyName === DiagramItemProps.Description), onValueChanged: handleLocalizedDescriptionChange }), _jsx(TMTextBox, { label: "SetID", value: localItem.ID ?? '', readOnly: true }), _jsx(WorkitemRecipientsEditor, { tos: localItem.Tos ?? '', mTID: wf?.MTID, qd: qdForRecipientsEditor, onTosChange: handleTosChange, onQDChange: handleSetRuleQDChange }), _jsx(TMVilViewer, { vil: validationItems.filter(v => v.PropertyName === DiagramItemProps.Tos) }), _jsxs(FlexContainer, { children: [_jsx(TMDropDown, { label: SDKUI_Localizator.WorkflowRecipientSetRule, elementStyle: { width: '320px' }, dataSource: SET_RULE_DATASOURCE, value: localItem.SetRule, isModifiedWhen: localItem.SetRule !== localItemOrig.SetRule, onValueChanged: (e) => { handleSetRuleChange(e.target.value); } }), _jsx(TMCheckBox, { value: localItem.AllowZeroTos ?? 0, label: SDKUI_Localizator.WorkflowAllowZeroTos, isModifiedWhen: localItem.AllowZeroTos !== localItemOrig.AllowZeroTos, onValueChanged: handleAllowZeroTosChange })] }), localItem.Type === DiagramItemTypes.ExecTask &&
412
+ return (_jsxs(_Fragment, { children: [_jsx(TMLocalizedTextBox, { label: SDKUI_Localizator.Description, value: localItem.Description, value_IT: localItem.Description_IT, value_EN: localItem.Description_EN, value_FR: localItem.Description_FR, value_PT: localItem.Description_PT, value_ES: localItem.Description_ES, value_DE: localItem.Description_DE, tid: wf?.MTID, isModifiedWhen: localItem.Description !== localItemOrig.Description, validationItems: validationItems.filter(v => v.PropertyName === DiagramItemProps.Description), onValueChanged: handleLocalizedDescriptionChange }), _jsx(TMTextBox, { label: "SetID", value: localItem.ID ?? '', readOnly: true }), _jsx(WorkitemRecipientsEditor, { tos: localItem.Tos ?? '', mTID: wf?.MTID, qd: qdForRecipientsEditor, onTosChange: handleTosChange, onQDChange: handleSetRuleQDChange }), _jsx(TMVilViewer, { vil: validationItems.filter(v => v.PropertyName === DiagramItemProps.Tos) }), _jsxs(FlexContainer, { children: [_jsx(TMDropDown, { label: SDKUI_Localizator.WorkflowRecipientSetRule, elementStyle: { width: '320px' }, dataSource: SET_RULE_DATASOURCE, value: localItem.SetRule, isModifiedWhen: localItem.SetRule !== localItemOrig.SetRule, onValueChanged: (e) => { handleSetRuleChange(e.target.value); } }), _jsx(TMCheckBox, { value: localItem.AllowZeroTos ?? 0, label: SDKUI_Localizator.WorkflowAllowZeroTos, isModifiedWhen: localItem.AllowZeroTos !== localItemOrig.AllowZeroTos, onValueChanged: handleAllowZeroTosChange })] }), localItem.Type === DiagramItemTypes.ExecTask &&
413
413
  _jsxs(BoxContainer, { children: [_jsx(HeaderContainer, { children: _jsx("span", { children: SDKUI_Localizator.Application }) }), renderAppFields()] })] }));
414
414
  };
415
415
  // Function to render UpdateDcmt-specific fields
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
3
3
  import styled from 'styled-components';
4
4
  import TMButton from '../../../base/TMButton';
5
5
  import { IconAdd, IconDelete, SDKUI_Localizator } from '../../../../helper';
6
- import { TMUserChooserForm, TMUserIdViewer } from '../../../choosers/TMUserChooser';
6
+ import { TMUserChooserForm } from '../../../choosers/TMUserChooser';
7
7
  import { TMGroupChooserForm, TMGroupIdViewer } from '../../../choosers/TMGroupChooser';
8
8
  import { TMMidViewer } from '../../../viewers/TMMidViewer';
9
9
  import { SDK_Globals, SDK_Localizator } from '@topconsultnpm/sdk-ts';
@@ -13,6 +13,7 @@ import { TMMessageBoxManager, ButtonNames } from '../../../base/TMPopUp';
13
13
  import TMModal from '../../../base/TMModal';
14
14
  import { TMMetadataChooserForm } from '../../../choosers/TMMetadataChooser';
15
15
  import TMQueryEditor from '../../../query/TMQueryEditor';
16
+ import TMDataUserIdItemViewer from '../../../viewers/TMDataUserIdItemViewer';
16
17
  export var WorkItemActorTypes;
17
18
  (function (WorkItemActorTypes) {
18
19
  WorkItemActorTypes[WorkItemActorTypes["None"] = 0] = "None";
@@ -168,7 +169,7 @@ const RecipientList = ({ recipients, title, tid, qd, onAdd, onRemove, onQDChange
168
169
  const actorId = parseInt(recipient.ActorID, 10);
169
170
  switch (recipient.ActorType) {
170
171
  case WorkItemActorTypes.UID:
171
- return _jsx(TMUserIdViewer, { userId: actorId, showIcon: true });
172
+ return _jsx(TMDataUserIdItemViewer, { userId: actorId, showIcon: true });
172
173
  case WorkItemActorTypes.GID:
173
174
  return _jsx(TMGroupIdViewer, { groupID: actorId, showIcon: true });
174
175
  case WorkItemActorTypes.MID:
@@ -1,9 +1,13 @@
1
1
  import React from 'react';
2
+ import { IWorkItemData } from '../../../../ts/types';
2
3
  interface IWFDiagramProps {
3
4
  xmlDiagramString: string;
4
5
  currentSetID?: string;
5
6
  allowEdit?: boolean;
6
7
  onDiagramChange?: (newXmlDiagram: string) => void;
8
+ workitems?: IWorkItemData[];
9
+ defaultAutoZoom?: boolean;
10
+ onDiagramItemClick?: (itemId: string, event: React.MouseEvent) => void;
7
11
  }
8
12
  declare const WFDiagram: React.FC<IWFDiagramProps>;
9
13
  export default WFDiagram;