@topconsultnpm/sdkui-react 6.22.0-dev2.5 → 6.22.0-dev2.50

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 (137) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +1 -1
  2. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
  3. package/lib/components/base/TMDataGrid.d.ts +2 -0
  4. package/lib/components/base/TMDataGrid.js +260 -8
  5. package/lib/components/base/TMEditorBase.d.ts +2 -0
  6. package/lib/components/base/TMFileManager.js +5 -3
  7. package/lib/components/base/TMFileManagerDataGridView.js +11 -2
  8. package/lib/components/base/TMFileManagerThumbnailItems.js +19 -9
  9. package/lib/components/base/TMFileManagerUtils.d.ts +2 -0
  10. package/lib/components/base/TMFileManagerUtils.js +37 -1
  11. package/lib/components/base/TMModal.d.ts +11 -0
  12. package/lib/components/base/TMModal.js +47 -13
  13. package/lib/components/base/TMPanel.d.ts +6 -0
  14. package/lib/components/base/TMPanel.js +221 -108
  15. package/lib/components/base/TMPopUp.js +3 -0
  16. package/lib/components/base/TMTooltip.d.ts +2 -1
  17. package/lib/components/base/TMTooltip.js +24 -8
  18. package/lib/components/base/TMTreeView.js +108 -67
  19. package/lib/components/choosers/TMDcmtTypeChooser.js +4 -3
  20. package/lib/components/choosers/TMDistinctValues.d.ts +9 -7
  21. package/lib/components/choosers/TMDistinctValues.js +149 -142
  22. package/lib/components/choosers/TMMetadataChooser.js +1 -1
  23. package/lib/components/choosers/TMQuickSearchInfo.d.ts +12 -0
  24. package/lib/components/choosers/TMQuickSearchInfo.js +279 -0
  25. package/lib/components/choosers/TMQuickSearchSettingsForm.d.ts +16 -0
  26. package/lib/components/choosers/TMQuickSearchSettingsForm.js +94 -0
  27. package/lib/components/choosers/TMSelectedValuesSummary.d.ts +13 -0
  28. package/lib/components/choosers/TMSelectedValuesSummary.js +91 -0
  29. package/lib/components/editors/TMDropDown.d.ts +3 -0
  30. package/lib/components/editors/TMDropDown.js +197 -5
  31. package/lib/components/editors/TMMetadataEditor.d.ts +5 -1
  32. package/lib/components/editors/TMMetadataEditor.js +8 -3
  33. package/lib/components/editors/TMTextBox.js +2 -2
  34. package/lib/components/features/archive/TMArchive.js +17 -3
  35. package/lib/components/features/documents/TMBatchUpdateForm.js +19 -5
  36. package/lib/components/features/documents/TMDcmtBlog.d.ts +3 -0
  37. package/lib/components/features/documents/TMDcmtBlog.js +4 -4
  38. package/lib/components/features/documents/TMDcmtForm.d.ts +7 -0
  39. package/lib/components/features/documents/TMDcmtForm.js +151 -46
  40. package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +11 -0
  41. package/lib/components/features/documents/TMDcmtFormActionButtons.js +74 -7
  42. package/lib/components/features/documents/TMDcmtIcon.js +5 -3
  43. package/lib/components/features/documents/TMDcmtPreview.js +10 -6
  44. package/lib/components/features/documents/TMMasterDetailDcmts.js +95 -33
  45. package/lib/components/features/documents/TMMasterInfoFields.d.ts +19 -0
  46. package/lib/components/features/documents/TMMasterInfoFields.js +186 -0
  47. package/lib/components/features/documents/TMMergeToPdfForm.d.ts +1 -2
  48. package/lib/components/features/documents/TMMergeToPdfForm.js +30 -5
  49. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +45 -0
  50. package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +323 -0
  51. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +370 -0
  52. package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +283 -0
  53. package/lib/components/features/documents/TMRelationViewer.d.ts +14 -1
  54. package/lib/components/features/documents/TMRelationViewer.js +69 -20
  55. package/lib/components/features/search/TMSearch.js +77 -11
  56. package/lib/components/features/search/TMSearchQueryEditor.js +5 -3
  57. package/lib/components/features/search/TMSearchQueryPanel.d.ts +4 -0
  58. package/lib/components/features/search/TMSearchQueryPanel.js +141 -67
  59. package/lib/components/features/search/TMSearchResult.d.ts +16 -0
  60. package/lib/components/features/search/TMSearchResult.js +432 -109
  61. package/lib/components/features/search/TMTreeSelector.js +166 -130
  62. package/lib/components/features/workflow/TMWorkflowPopup.d.ts +10 -0
  63. package/lib/components/features/workflow/TMWorkflowPopup.js +8 -4
  64. package/lib/components/grids/TMBlogAttachments.js +13 -2
  65. package/lib/components/grids/TMBlogsPost.d.ts +2 -0
  66. package/lib/components/grids/TMBlogsPost.js +26 -3
  67. package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
  68. package/lib/components/grids/TMBlogsPostUtils.js +14 -3
  69. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
  70. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +24 -14
  71. package/lib/components/layout/panelManager/TMPanelManagerContext.js +68 -93
  72. package/lib/components/layout/panelManager/TMPanelWrapper.js +2 -2
  73. package/lib/components/layout/panelManager/types.d.ts +3 -0
  74. package/lib/components/layout/panelManager/utils.js +13 -11
  75. package/lib/components/sidebar/TMHeader.js +30 -20
  76. package/lib/components/viewers/TMMidViewer.js +4 -1
  77. package/lib/components/viewers/TMTidViewer.js +83 -22
  78. package/lib/devextreme-license.d.ts +1 -0
  79. package/lib/devextreme-license.js +3 -0
  80. package/lib/helper/SDKUI_Globals.d.ts +110 -0
  81. package/lib/helper/SDKUI_Globals.js +151 -0
  82. package/lib/helper/SDKUI_Localizator.d.ts +42 -0
  83. package/lib/helper/SDKUI_Localizator.js +420 -0
  84. package/lib/helper/TMAppUpdatedModal.d.ts +1 -0
  85. package/lib/helper/TMAppUpdatedModal.js +134 -0
  86. package/lib/helper/TMIcons.d.ts +1 -0
  87. package/lib/helper/TMIcons.js +3 -0
  88. package/lib/helper/TMUtils.d.ts +7 -0
  89. package/lib/helper/TMUtils.js +15 -1
  90. package/lib/helper/dataGridSearchHelper.d.ts +28 -0
  91. package/lib/helper/dataGridSearchHelper.js +51 -0
  92. package/lib/helper/dcmtsHelper.d.ts +20 -0
  93. package/lib/helper/dcmtsHelper.js +58 -1
  94. package/lib/helper/helpers.d.ts +11 -0
  95. package/lib/helper/helpers.js +25 -1
  96. package/lib/helper/index.d.ts +2 -0
  97. package/lib/helper/index.js +2 -0
  98. package/lib/helper/queryHelper.d.ts +6 -1
  99. package/lib/helper/queryHelper.js +8 -3
  100. package/lib/hooks/tmDistinctValuesGridHelper.d.ts +16 -0
  101. package/lib/hooks/tmDistinctValuesGridHelper.js +31 -0
  102. package/lib/hooks/useArchiveListForm.d.ts +39 -0
  103. package/lib/hooks/useArchiveListForm.js +46 -0
  104. package/lib/hooks/useCaseFlowApprove.d.ts +56 -0
  105. package/lib/hooks/useCaseFlowApprove.js +157 -0
  106. package/lib/hooks/useDataUserIdItem.d.ts +1 -0
  107. package/lib/hooks/useDataUserIdItem.js +1 -0
  108. package/lib/hooks/useDocumentOperations.d.ts +4 -0
  109. package/lib/hooks/useDocumentOperations.js +50 -10
  110. package/lib/hooks/useMultiMasterDetailDcmts.d.ts +113 -0
  111. package/lib/hooks/useMultiMasterDetailDcmts.js +760 -0
  112. package/lib/hooks/useRelatedDocuments.d.ts +1 -0
  113. package/lib/hooks/useRelatedDocuments.js +22 -27
  114. package/lib/hooks/useShowDossiersV5.d.ts +12 -0
  115. package/lib/hooks/useShowDossiersV5.js +37 -0
  116. package/lib/hooks/useTMDistinctValuesMetadataDisplay.d.ts +18 -0
  117. package/lib/hooks/useTMDistinctValuesMetadataDisplay.js +103 -0
  118. package/lib/hooks/useTMDistinctValuesQuickSearch.d.ts +49 -0
  119. package/lib/hooks/useTMDistinctValuesQuickSearch.js +307 -0
  120. package/lib/hooks/useTMDistinctValuesSelection.d.ts +42 -0
  121. package/lib/hooks/useTMDistinctValuesSelection.js +103 -0
  122. package/lib/hooks/useTMDistinctValuesSource.d.ts +29 -0
  123. package/lib/hooks/useTMDistinctValuesSource.js +105 -0
  124. package/lib/index.d.ts +2 -0
  125. package/lib/index.js +5 -2
  126. package/lib/services/caseflow/CaseFlowService.d.ts +236 -0
  127. package/lib/services/caseflow/CaseFlowService.js +693 -0
  128. package/lib/services/caseflow/CaseFlowTemplateCacheService.d.ts +28 -0
  129. package/lib/services/caseflow/CaseFlowTemplateCacheService.js +121 -0
  130. package/lib/services/caseflow/caseFlowNameCache.d.ts +32 -0
  131. package/lib/services/caseflow/caseFlowNameCache.js +116 -0
  132. package/lib/services/caseflow/caseFlowWorkItemUtils.d.ts +61 -0
  133. package/lib/services/caseflow/caseFlowWorkItemUtils.js +113 -0
  134. package/lib/services/index.d.ts +4 -0
  135. package/lib/services/index.js +4 -0
  136. package/lib/services/platform_services.d.ts +1 -1
  137. package/package.json +9 -5
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useState } from 'react';
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import { DcmtTypeListCacheService, LayoutModes, SDK_Localizator, TreeCacheService, TreeItemTypes } from '@topconsultnpm/sdk-ts';
4
4
  import { TreeList, Column, Scrolling, Selection } from 'devextreme-react/tree-list';
5
5
  import { DropDownBox } from 'devextreme-react';
@@ -13,6 +13,15 @@ import { TMColors } from '../../../utils/theme';
13
13
  import styled from 'styled-components';
14
14
  import { useOutsideClick } from '../../../hooks/useOutsideClick';
15
15
  import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
16
+ const TMTreeDcmtTypeCell = ({ tid, isMobile }) => {
17
+ const [dtd, setDtd] = useState();
18
+ const loadDTD = useCallback(async () => {
19
+ if (isMobile || dtd || !tid)
20
+ return;
21
+ setDtd(await DcmtTypeListCacheService.GetAsync(tid));
22
+ }, [isMobile, dtd, tid]);
23
+ return (_jsxs(StyledTreeDcmtTypeRow, { onMouseEnter: loadDTD, children: [_jsx("span", { style: { cursor: 'pointer', flex: 1, minWidth: 0 }, children: _jsx(TMTidViewer, { tid: tid, showIcon: false }) }), !isMobile && (_jsx("span", { className: 'info-icon', children: _jsx(TMDcmtTypeTooltip, { dtd: dtd, children: _jsx(IconInfo, { color: TMColors.info }) }) }))] }));
24
+ };
16
25
  const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelectedTIDChanged, onClosePanel, allowMaximize = true, onMaximizePanel }) => {
17
26
  const [trees, setTrees] = useState([]);
18
27
  const [treeItems, setTreeItems] = useState([]);
@@ -27,75 +36,66 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
27
36
  const deviceType = useDeviceType();
28
37
  const isMobile = deviceType === DeviceType.MOBILE;
29
38
  const panelRef = useOutsideClick(() => setInfoDTD(undefined));
30
- // useEffect(() => {
31
- // if (treeItems.length > 0 && treeItems[0].id) {
32
- // setSelectedRowKeys([treeItems[0].id])
33
- // }
34
- // }, [treeItems])
35
- useEffect(() => {
36
- const setResultCache = (result) => {
37
- if (result && result.length > 0) {
38
- setTrees(result);
39
- let defaultTree = SDKUI_Globals.userSettings.searchSettings.defaultTree;
40
- let initialTreeId;
41
- let treeToSelect;
42
- if (defaultTree > 0) {
43
- initialTreeId = defaultTree;
44
- treeToSelect = result.find(o => o.id == defaultTree);
45
- }
46
- else {
47
- initialTreeId = result[0]?.id ?? 0;
48
- treeToSelect = result[0];
49
- }
50
- setSelectedTreeId(initialTreeId);
51
- if (treeToSelect?.id) {
52
- setSelectedRowKeys([treeToSelect.id]);
53
- }
39
+ // Tiene traccia dell'albero selezionato senza far dipendere loadTreesAsync da selectedTreeId:
40
+ // così il refresh può riproporre la selezione corrente senza ricaricare a ogni cambio di albero
41
+ const selectedTreeIdRef = useRef(selectedTreeId);
42
+ useEffect(() => { selectedTreeIdRef.current = selectedTreeId; }, [selectedTreeId]);
43
+ // Carica tutti gli alberi del contesto corrente (ricerca o archiviazione).
44
+ // Con forceRefresh la cache viene invalidata, altrimenti GetAll* restituirebbe gli alberi già in memoria.
45
+ const loadTreesAsync = useCallback(async (forceRefresh = false) => {
46
+ const isSearchContext = layoutMode == LayoutModes.Update;
47
+ if (forceRefresh) {
48
+ if (isSearchContext)
49
+ TreeCacheService.RemoveAllSearch();
50
+ else
51
+ TreeCacheService.RemoveAllArchive();
52
+ }
53
+ const result = isSearchContext
54
+ ? await TreeCacheService.GetAllSearchAsync()
55
+ : await TreeCacheService.GetAllArchiveAsync();
56
+ if (!result || result.length === 0) {
57
+ // Sul refresh gli alberi possono essere spariti lato server: allinea anche lo stato vuoto
58
+ if (forceRefresh) {
59
+ setTrees([]);
60
+ setSelectedTreeId(0);
61
+ setSelectedRowKeys([]);
54
62
  }
55
- };
56
- if (layoutMode == LayoutModes.Update) {
57
- TreeCacheService.GetAllSearchAsync().then((result) => { setResultCache(result); });
63
+ return;
64
+ }
65
+ setTrees(result);
66
+ // Dopo un refresh mantiene l'albero corrente, se ancora presente
67
+ const currentTreeId = selectedTreeIdRef.current;
68
+ if (forceRefresh && result.some(o => o.id == currentTreeId)) {
69
+ setSelectedTreeId(currentTreeId);
70
+ setSelectedRowKeys([currentTreeId]);
71
+ return;
72
+ }
73
+ let defaultTree = SDKUI_Globals.userSettings.searchSettings.defaultTree;
74
+ let initialTreeId;
75
+ let treeToSelect;
76
+ if (defaultTree > 0) {
77
+ initialTreeId = defaultTree;
78
+ treeToSelect = result.find(o => o.id == defaultTree);
58
79
  }
59
80
  else {
60
- TreeCacheService.GetAllArchiveAsync().then((result) => { setResultCache(result); });
81
+ initialTreeId = result[0]?.id ?? 0;
82
+ treeToSelect = result[0];
83
+ }
84
+ setSelectedTreeId(initialTreeId);
85
+ if (treeToSelect?.id) {
86
+ setSelectedRowKeys([treeToSelect.id]);
61
87
  }
62
88
  }, [layoutMode]);
89
+ useEffect(() => { loadTreesAsync(); }, [loadTreesAsync]);
63
90
  useEffect(() => {
64
91
  let newTreeItems = trees.find(o => o.id == selectedTreeId)?.items ?? [];
65
92
  setTreeItems(newTreeItems);
66
93
  }, [selectedTreeId, trees]);
67
94
  const renderCell = useCallback((data) => {
68
95
  const treeItem = data.data;
69
- const [showInfo, setShowInfo] = useState(false);
70
96
  // Documento (DcmtType)
71
97
  if (treeItem.type === TreeItemTypes.DcmtType) {
72
- return (_jsxs(StyledDivHorizontal, { style: {
73
- alignItems: 'center',
74
- minWidth: 0,
75
- width: '100%',
76
- gap: 2,
77
- position: 'relative'
78
- }, onMouseEnter: async () => {
79
- if (!isMobile) {
80
- setShowInfo(true);
81
- let dtd = await DcmtTypeListCacheService.GetAsync(treeItem.tid);
82
- setInfoDTD(dtd);
83
- }
84
- }, onMouseLeave: () => {
85
- if (!isMobile) {
86
- setShowInfo(false);
87
- setInfoDTD(undefined);
88
- }
89
- }, children: [_jsx("span", { style: { cursor: 'pointer', flex: 1, minWidth: 0 }, children: _jsx(TMTidViewer, { tid: treeItem.tid, showIcon: false }) }), !isMobile && (_jsx("span", { style: {
90
- opacity: showInfo ? 1 : 0,
91
- transition: 'opacity 0.2s',
92
- pointerEvents: showInfo ? 'auto' : 'none',
93
- cursor: 'pointer',
94
- display: 'flex',
95
- alignItems: 'center',
96
- marginLeft: 'auto',
97
- zIndex: 2
98
- }, children: _jsx(TMDcmtTypeTooltip, { dtd: infoDTD, children: _jsx(IconInfo, { color: TMColors.info }) }) }))] }));
98
+ return _jsx(TMTreeDcmtTypeCell, { tid: treeItem.tid, isMobile: isMobile });
99
99
  }
100
100
  // Folder (altri tipi)
101
101
  return (_jsxs(StyledDivHorizontal, { style: { gap: 5, alignItems: 'center', minWidth: 0 }, children: [_jsx("span", { style: {
@@ -113,7 +113,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
113
113
  whiteSpace: 'nowrap',
114
114
  flex: 1,
115
115
  }, children: treeItem.nameLoc })] }));
116
- }, [isMobile, infoDTD, setInfoDTD]);
116
+ }, [isMobile]);
117
117
  // Handles selection change in the data grid
118
118
  const onSelectionChanged = useCallback((e) => {
119
119
  const selectedKeys = e.component.getSelectedRowKeys() ?? [];
@@ -126,6 +126,16 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
126
126
  setSelectedRowKeys(selectedKeys);
127
127
  setIsGridBoxOpened(false);
128
128
  }, []);
129
+ // Handles click on a tree row in the trees data grid: clicking the already selected tree
130
+ // does not raise onSelectionChanged, so the drop down must be closed here as well
131
+ const onRowClickTrees = useCallback((e) => {
132
+ const tree = e.data;
133
+ if (tree?.id === undefined)
134
+ return;
135
+ setSelectedTreeId(tree.id);
136
+ setSelectedRowKeys([tree.id]);
137
+ setIsGridBoxOpened(false);
138
+ }, []);
129
139
  // Handles focus change in the data grid
130
140
  const onFocusedRowChanged = useCallback((e) => {
131
141
  setFocusedRowKey(e.row?.key);
@@ -161,7 +171,14 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
161
171
  }
162
172
  }
163
173
  }, []);
164
- return (_jsx(TMPanel, { title: SDK_Localizator.Trees, isVisible: isVisible, totalItems: trees.length, onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, toolbar: _jsx(TMButton, { btnStyle: 'icon', caption: defaultTreeId == selectedTreeId ? SDKUI_Localizator.TreeRemoveDefault : SDKUI_Localizator.SetAsDefault, icon: defaultTreeId == selectedTreeId ? _jsx(IconStarRemove, { color: 'rgb(243, 114, 92)' }) : _jsx(IconStar, { color: 'rgb(248, 215, 117)' }), onClick: () => {
174
+ // Callback function to handle click events on a tree view row.
175
+ const onRowClickTreeView = useCallback((e) => {
176
+ const treeItem = e.data;
177
+ if (treeItem?.type === TreeItemTypes.DcmtType) {
178
+ onSelectedTIDChanged?.(treeItem.tid, selectedTreeId);
179
+ }
180
+ }, [onSelectedTIDChanged, selectedTreeId]);
181
+ return (_jsx(TMPanel, { title: SDK_Localizator.Trees, isVisible: isVisible, totalItems: trees.length, onClose: onClosePanel, allowMaximize: allowMaximize, onMaximize: onMaximizePanel, onHeaderDoubleClick: onMaximizePanel, onRefresh: () => loadTreesAsync(true), toolbar: _jsx(TMButton, { btnStyle: 'icon', caption: defaultTreeId == selectedTreeId ? SDKUI_Localizator.TreeRemoveDefault : SDKUI_Localizator.SetAsDefault, icon: defaultTreeId == selectedTreeId ? _jsx(IconStarRemove, { color: 'rgb(243, 114, 92)' }) : _jsx(IconStar, { color: 'rgb(248, 215, 117)' }), onClick: () => {
165
182
  if (defaultTreeId == selectedTreeId) {
166
183
  if (layoutMode == LayoutModes.Update)
167
184
  SDKUI_Globals.userSettings.searchSettings.defaultTree = -1;
@@ -193,78 +210,97 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
193
210
  }, value: selectedTreeId, opened: isGridBoxOpened, valueExpr: "id", displayExpr: "nameLoc", deferRendering: false, dataSource: trees, onValueChanged: syncDataGridSelection, onOptionChanged: onGridBoxOpened, style: { height: 30, padding: '5px' }, children: _jsx(TMDataGrid, { height: "100%", width: "100%", dataSource: trees, dataColumns: [
194
211
  { dataField: 'nameLoc', caption: SDKUI_Localizator.Name, width: 'auto' },
195
212
  { dataField: 'description', caption: SDKUI_Localizator.Description, width: 'auto' },
196
- ], selection: { mode: 'single', showCheckBoxesMode: "none" }, showHeaderFilter: false, selectedRowKeys: selectedRowKeys, onSelectionChanged: onSelectionChanged, focusedRowKey: focusedRowKey, onFocusedRowChanged: onFocusedRowChanged }) }) }), _jsxs(StyledTreeListWrapper, { children: [_jsxs(TreeList, { height: "100%", dataSource: treeItems, showRowLines: false, showColumnLines: false, showBorders: false, columnAutoWidth: false, keyExpr: "id", parentIdExpr: "parentID", dataStructure: "plain", showColumnHeaders: false, onContentReady: (e) => e.component.clearSelection(), onCellDblClick: onCellDblClickTreeView, onSelectionChanged: (e) => {
197
- if (e.selectedRowsData[0] && e.selectedRowsData[0].type == TreeItemTypes.DcmtType) {
198
- onSelectedTIDChanged?.(e.selectedRowsData[0].tid, selectedTreeId);
199
- }
200
- }, children: [_jsx(Column, { dataField: "nameLoc", caption: SDKUI_Localizator.Name, cellRender: renderCell, width: "100%" }), _jsx(Scrolling, { mode: "virtual", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }), _jsx(Selection, { mode: "single" })] }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, "$isOpen": isMobile && infoDTD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDKUI_Localizator.DcmtType} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoDTD(undefined) })] }), renderDTDTooltipContent(infoDTD)] })] })] })
213
+ ], selection: { mode: 'single', showCheckBoxesMode: "none" }, showHeaderFilter: false, selectedRowKeys: selectedRowKeys, onSelectionChanged: onSelectionChanged, onRowClick: onRowClickTrees, focusedRowKey: focusedRowKey, onFocusedRowChanged: onFocusedRowChanged }) }) }), _jsxs(StyledTreeListWrapper, { children: [_jsxs(TreeList, { height: "100%", dataSource: treeItems, showRowLines: false, showColumnLines: false, showBorders: false, columnAutoWidth: false, keyExpr: "id", parentIdExpr: "parentID", dataStructure: "plain", showColumnHeaders: false, onContentReady: (e) => e.component.clearSelection(), onCellDblClick: onCellDblClickTreeView, onRowClick: onRowClickTreeView, children: [_jsx(Column, { dataField: "nameLoc", caption: SDKUI_Localizator.Name, cellRender: renderCell, width: "100%" }), _jsx(Scrolling, { mode: "virtual", useNative: Number(SDKUI_Globals.userSettings?.themeSettings.gridSettings.useNativeScrollbar) === 1 }), _jsx(Selection, { mode: "single" })] }), _jsxs(StyledOffCanvasPanel, { ref: panelRef, "$isOpen": isMobile && infoDTD !== undefined, children: [_jsxs(StyledDivHorizontal, { style: { gap: 10, padding: '10px 8px', width: '100%', alignItems: 'center' }, children: [_jsx("p", { style: { fontSize: '1.1rem', fontWeight: 'bold' }, children: `${SDKUI_Localizator.DcmtType} - ${SDKUI_Localizator.About}` }), _jsx(IconCloseOutline, { style: { marginLeft: 'auto', cursor: 'pointer' }, onClick: () => setInfoDTD(undefined) })] }), renderDTDTooltipContent(infoDTD)] })] })] })
201
214
  : _jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', fontSize: '1.5rem' }, children: SDKUI_Localizator.TreesNoAvailable }) }));
202
215
  };
203
216
  export default TMTreeSelector;
204
- const StyledTreeListWrapper = styled.div `
205
- width: 100%;
206
- height: 100%;
207
- min-height: 0;
208
- flex: 1;
209
- display: flex;
210
- flex-direction: column;
211
-
212
- .dx-treelist,
213
- .dx-treelist-rowsview,
214
- .dx-scrollable,
215
- .dx-scrollable-wrapper,
216
- .dx-scrollable-container,
217
- .dx-scrollable-content {
218
- height: 100% !important;
219
- min-height: 0 !important;
220
- max-height: 100% !important;
221
- box-sizing: border-box;
222
- }
223
-
224
- .dx-scrollable-scrollbar.dx-scrollbar-vertical {
225
- /* Mostra solo quando serve */
226
- opacity: 1 !important;
227
- }
228
-
229
- .dx-scrollable-scrollbar.dx-scrollbar-horizontal {
230
- display: none !important;
231
- }
232
-
233
- .dx-treelist-container>.dx-treelist-headers,
234
- .dx-treelist-container>.dx-treelist-rowsview {
235
- background-color: transparent;
236
- }
237
-
238
- .dx-treelist-rowsview .dx-treelist-empty-space {
239
- position: relative;
240
- top: 4px;
241
- display: inline-block;
242
- width: 16px;
243
- }
244
-
245
- .dx-row > td {
246
- padding: 10px 4px;
247
- font-size: 1rem;
248
- white-space: nowrap;
249
- overflow: hidden;
250
- text-overflow: ellipsis;
251
- }
252
-
253
- .dx-selection td {
254
- background: oklch(from var(--dx-color-primary) l c h / .2) !important;
255
- }
256
-
257
- .dx-data-row:hover {
258
- cursor: pointer;
259
- background: linear-gradient(
260
- 270deg,
261
- rgba(70, 181, 162, 0.15) 16%,
262
- rgba(59, 170, 188, 0.15) 34%,
263
- rgba(59, 170, 188, 0.15) 34%,
264
- rgba(54, 129, 173, 0.15) 54%,
265
- rgba(51, 104, 165, 0.15) 72%,
266
- rgba(47, 84, 157, 0.15) 88%,
267
- rgba(48, 79, 153, 0.15) 100%
268
- );
269
- }
217
+ const StyledTreeDcmtTypeRow = styled(StyledDivHorizontal) `
218
+ align-items: center;
219
+ min-width: 0;
220
+ width: 100%;
221
+ gap: 2px;
222
+ position: relative;
223
+
224
+ .info-icon {
225
+ display: flex;
226
+ align-items: center;
227
+ margin-left: auto;
228
+ z-index: 2;
229
+ cursor: pointer;
230
+ opacity: 0;
231
+ pointer-events: none;
232
+ transition: opacity 0.2s;
233
+ }
234
+
235
+ &:hover .info-icon {
236
+ opacity: 1;
237
+ pointer-events: auto;
238
+ }
239
+ `;
240
+ const StyledTreeListWrapper = styled.div `
241
+ width: 100%;
242
+ height: 100%;
243
+ min-height: 0;
244
+ flex: 1;
245
+ display: flex;
246
+ flex-direction: column;
247
+
248
+ .dx-treelist,
249
+ .dx-treelist-rowsview,
250
+ .dx-scrollable,
251
+ .dx-scrollable-wrapper,
252
+ .dx-scrollable-container,
253
+ .dx-scrollable-content {
254
+ height: 100% !important;
255
+ min-height: 0 !important;
256
+ max-height: 100% !important;
257
+ box-sizing: border-box;
258
+ }
259
+
260
+ .dx-scrollable-scrollbar.dx-scrollbar-vertical {
261
+ /* Mostra solo quando serve */
262
+ opacity: 1 !important;
263
+ }
264
+
265
+ .dx-scrollable-scrollbar.dx-scrollbar-horizontal {
266
+ display: none !important;
267
+ }
268
+
269
+ .dx-treelist-container>.dx-treelist-headers,
270
+ .dx-treelist-container>.dx-treelist-rowsview {
271
+ background-color: transparent;
272
+ }
273
+
274
+ .dx-treelist-rowsview .dx-treelist-empty-space {
275
+ position: relative;
276
+ top: 4px;
277
+ display: inline-block;
278
+ width: 16px;
279
+ }
280
+
281
+ .dx-row > td {
282
+ padding: 10px 4px;
283
+ font-size: 1rem;
284
+ white-space: nowrap;
285
+ overflow: hidden;
286
+ text-overflow: ellipsis;
287
+ }
288
+
289
+ .dx-selection td {
290
+ background: oklch(from var(--dx-color-primary) l c h / .2) !important;
291
+ }
292
+
293
+ .dx-data-row:hover {
294
+ cursor: pointer;
295
+ background: linear-gradient(
296
+ 270deg,
297
+ rgba(70, 181, 162, 0.15) 16%,
298
+ rgba(59, 170, 188, 0.15) 34%,
299
+ rgba(59, 170, 188, 0.15) 34%,
300
+ rgba(54, 129, 173, 0.15) 54%,
301
+ rgba(51, 104, 165, 0.15) 72%,
302
+ rgba(47, 84, 157, 0.15) 88%,
303
+ rgba(48, 79, 153, 0.15) 100%
304
+ );
305
+ }
270
306
  `;
@@ -3,6 +3,16 @@ import { DeviceType } from "../../base/TMDeviceProvider";
3
3
  import { WorkItemDetail } from "../../../ts";
4
4
  interface IWorkflowOperationButtonsProps {
5
5
  dtd: DcmtTypeDescriptor | undefined;
6
+ /**
7
+ * Forza la forma dei pulsanti: `true` = flusso di FIRMA (Firma e approva),
8
+ * `false` = flusso di APPROVAZIONE. Se omesso si deduce dal tipo documento
9
+ * (widget Sign4Top), che è il comportamento del workflow.
10
+ *
11
+ * Serve a chi conosce la natura dell'attività meglio del tipo documento: un
12
+ * work item di sola approvazione su un tipo ABILITATO alla firma non deve
13
+ * mostrare "Firma e approva".
14
+ */
15
+ signFlow?: boolean;
6
16
  approveDisable?: boolean;
7
17
  signApproveDisable?: boolean;
8
18
  rejectDisable?: boolean;
@@ -53,16 +53,20 @@ const StyledHorizontalContainer = styled.div `
53
53
  /* align-items: flex-end; */
54
54
  `;
55
55
  export const WorkFlowOperationButtons = (props) => {
56
- const { dtd = undefined, deviceType = DeviceType.DESKTOP, approveDisable = false, signApproveDisable = false, rejectDisable = false, reassignDisable = false, infoDisable = false, onApprove, onSignApprove, onReject, onReAssign, onMoreInfo, } = props;
56
+ const { dtd = undefined, signFlow = undefined, deviceType = DeviceType.DESKTOP, approveDisable = false, signApproveDisable = false, rejectDisable = false, reassignDisable = false, infoDisable = false, onApprove, onSignApprove, onReject, onReAssign, onMoreInfo, } = props;
57
57
  const isMobile = deviceType === DeviceType.MOBILE;
58
- // Calcola direttamente se è un workflow di firma per evitare flickering durante il render
58
+ // Calcola direttamente se è un workflow di firma per evitare flickering durante il render.
59
+ // `signFlow`, se fornito, ha la precedenza: chi lo passa conosce la natura
60
+ // dell'attività (es. categoria del work item) meglio del tipo documento.
59
61
  const isSignWorkflow = useMemo(() => {
62
+ if (signFlow !== undefined)
63
+ return signFlow;
60
64
  if (dtd && dtd.widgets && dtd.widgets.length > 0) {
61
65
  return isSign4TopEnabled(dtd.widgets);
62
66
  }
63
67
  return false;
64
- }, [dtd]);
65
- 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" })] })) }));
68
+ }, [dtd, signFlow]);
69
+ 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" }), onMoreInfo && (_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" }), onReAssign && (_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" })), onMoreInfo && (_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" }))] })) }));
66
70
  };
67
71
  export const WorkFlowApproveRejectPopUp = ({ TID = 0, DID = 0, deviceType = DeviceType.DESKTOP, isReject, selectedItems = [], onClose, onCompleted }) => {
68
72
  const { refreshWorkflowApprove } = useWorkflowApprove();
@@ -1,10 +1,13 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SDK_Globals } from "@topconsultnpm/sdk-ts";
3
- import { getAttachmentInfo, lightenColor, removeFileExtension } from "./TMBlogsPostUtils";
3
+ import { findFileItemByDraftID, getAttachmentInfo, lightenColor, removeFileExtension } from "./TMBlogsPostUtils";
4
4
  import TMDcmtIcon from "../features/documents/TMDcmtIcon";
5
5
  import { IconAttachment } from "../../helper";
6
+ import { getFileItemLinkUrl } from "../base/TMFileManagerUtils";
6
7
  const TMBlogAttachments = (props) => {
7
8
  const { layoutMode, attachments, isSelected, isLoading = false, searchText, dcmtTypeDescriptors, treeFs, draftLatestInfoMap, archivedDocumentMap, handleAttachmentFocus, openDcmtForm } = props;
9
+ // Ritorna l'url del link associato all'allegato: gli allegati che sono link non hanno un documento da scaricare o da aprire nella form
10
+ const getAttachmentLinkUrl = (blogPostAttachment) => getFileItemLinkUrl(findFileItemByDraftID(treeFs, blogPostAttachment.draftID) ?? undefined);
8
11
  const handleMouseEnter = (e, blogPostAttachment, name, fileExt) => {
9
12
  e.currentTarget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.15)';
10
13
  e.currentTarget.style.backgroundColor = isSelected ? lightenColor("#135596", 40) : '#cfcfcf';
@@ -18,12 +21,20 @@ const TMBlogAttachments = (props) => {
18
21
  handleAttachmentFocus(undefined);
19
22
  };
20
23
  const onDoubleClick = (e, blogPostAttachment, name, fileExt) => {
24
+ // i link non hanno un documento da aprire: il doppio click (su icona o testo) apre l'url in un nuovo tab
25
+ const linkUrl = getAttachmentLinkUrl(blogPostAttachment);
26
+ if (linkUrl) {
27
+ window.open(linkUrl, '_blank', 'noopener,noreferrer');
28
+ return;
29
+ }
21
30
  const archiveID = SDK_Globals.tmSession?.SessionDescr?.archiveID;
22
31
  const fileName = `${removeFileExtension(name)}_${archiveID}_${blogPostAttachment.tid}_${blogPostAttachment.did}.${fileExt}`;
23
32
  openDcmtForm({ TID: blogPostAttachment.tid, DID: blogPostAttachment.did, fileName });
24
33
  };
25
34
  return _jsx("div", { style: { width: "100%", marginTop: "5px", overflow: "hidden" }, children: attachments.map((blogPostAttachment, index) => {
26
35
  const { name, nameElement, tooltipContent, fileExt, archivedDocumentsExist, draftExist, isSigned } = getAttachmentInfo(blogPostAttachment, treeFs, draftLatestInfoMap, archivedDocumentMap, dcmtTypeDescriptors, isSelected, searchText);
36
+ // i link non hanno un file associato: l'icona non deve avviare il download
37
+ const isLink = getAttachmentLinkUrl(blogPostAttachment) !== undefined;
27
38
  return _jsx("div", { onDoubleClick: (e) => !isLoading && onDoubleClick(e, blogPostAttachment, name, fileExt), onMouseEnter: (e) => !isLoading && handleMouseEnter(e, blogPostAttachment, name, fileExt), onMouseLeave: (e) => !isLoading && handleMouseLeave(e), style: {
28
39
  display: layoutMode === "extended" ? "inline-flex" : "flex",
29
40
  padding: '4px 8px',
@@ -63,7 +74,7 @@ const TMBlogAttachments = (props) => {
63
74
  }
64
75
  ` })] })) : (_jsxs(_Fragment, { children: [(!archivedDocumentsExist && !draftExist) ?
65
76
  _jsx(IconAttachment, { style: { marginRight: "5px", flexShrink: 0 } }) :
66
- _jsx("div", { style: { marginRight: "10px", flexShrink: 0, width: isSigned ? "40px" : undefined }, children: _jsx(TMDcmtIcon, { tid: blogPostAttachment.tid, did: blogPostAttachment.did, fileExtension: fileExt, downloadMode: 'openInNewWindow', tooltipContent: tooltipContent, isSigned: isSigned }) }), _jsx("span", { title: layoutMode === 'compact' ? name + " (DID: " + blogPostAttachment.did + ")" : undefined, style: {
77
+ _jsx("div", { style: { marginRight: "10px", flexShrink: 0, width: isSigned ? "40px" : undefined }, children: _jsx(TMDcmtIcon, { tid: blogPostAttachment.tid, did: blogPostAttachment.did, fileExtension: fileExt, downloadMode: isLink ? 'none' : 'openInNewWindow', tooltipContent: tooltipContent, isSigned: isSigned }) }), _jsx("span", { title: layoutMode === 'compact' ? name + " (DID: " + blogPostAttachment.did + ")" : undefined, style: {
67
78
  whiteSpace: 'nowrap',
68
79
  overflow: 'hidden',
69
80
  textOverflow: 'ellipsis',
@@ -86,6 +86,8 @@ interface TMBlogsPostProps {
86
86
  addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
87
87
  handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
88
88
  handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
89
+ /** Apre la pratica CaseFlow di una notizia con `classID === 'CF'` (bacheca Home V6). */
90
+ handleNavigateToCaseflows?: (value: HomeBlogPost | number) => Promise<void>;
89
91
  }
90
92
  declare const TMBlogsPost: (props: TMBlogsPostProps) => import("react/jsx-runtime").JSX.Element;
91
93
  export default TMBlogsPost;
@@ -5,6 +5,7 @@ import { ContextMenu as TMContextMenu } from "../NewComponents/ContextMenu";
5
5
  import { SDKUI_Localizator, Globalization, getExceptionMessage, TMConditionalWrapper, getMoreInfoTasksForDocument, taskModalSizes } from "../../helper";
6
6
  import TMToppyMessage from "../../helper/TMToppyMessage";
7
7
  import { useDcmtOperations } from "../../hooks/useDcmtOperations";
8
+ import { CaseFlowService } from "../../services/caseflow/CaseFlowService";
8
9
  import { DownloadTypes, FormModes } from "../../ts";
9
10
  import { TMColors } from "../../utils/theme";
10
11
  import ShowAlert from "../base/TMAlert";
@@ -32,7 +33,7 @@ const TMBlogsPost = (props) => {
32
33
  isRestoreEnabled: false,
33
34
  isRefreshEnabled: false,
34
35
  isCreateContextualTask: false,
35
- }, showFloatingCommentButton = false, showCommentFormCallback, refreshCallback, showId, setShowId, refreshHomePageNews, markBlogAsRead, externalBlogPost, resetExternalBlogPost, visible = true, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved, handleNavigateToWGs, handleNavigateToDossiers, } = props;
36
+ }, showFloatingCommentButton = false, showCommentFormCallback, refreshCallback, showId, setShowId, refreshHomePageNews, markBlogAsRead, externalBlogPost, resetExternalBlogPost, visible = true, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToCaseflows, } = props;
36
37
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
37
38
  // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
38
39
  const deviceType = useDeviceType();
@@ -292,6 +293,8 @@ const TMBlogsPost = (props) => {
292
293
  handleNavigateToWGs(blogPost);
293
294
  if (handleNavigateToDossiers && id && blogPost.classID === 'DS')
294
295
  handleNavigateToDossiers(blogPost);
296
+ if (handleNavigateToCaseflows && id && blogPost.classID === 'CF')
297
+ handleNavigateToCaseflows(blogPost);
295
298
  };
296
299
  const handleKeyDown = (event) => {
297
300
  if (!selectedItem.length)
@@ -324,6 +327,9 @@ const TMBlogsPost = (props) => {
324
327
  if (handleNavigateToDossiers && item.id && classItemID === 'DS') {
325
328
  handleNavigateToDossiers(item);
326
329
  }
330
+ if (handleNavigateToCaseflows && item.id && classItemID === 'CF') {
331
+ handleNavigateToCaseflows(item);
332
+ }
327
333
  break;
328
334
  default:
329
335
  break;
@@ -367,6 +373,17 @@ const TMBlogsPost = (props) => {
367
373
  result.push({ rowIndex: currentBlog.id, id1: currentBlog.id, id2: currentBlog.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
368
374
  });
369
375
  break;
376
+ case 'CF':
377
+ // La notizia porta il solo CFIID: il template (cftid) che l'API
378
+ // richiede lo risolve CaseFlowService.setFollow.
379
+ await CaseFlowService.setFollow(currentBlog.id, false).then(async () => {
380
+ result.push({ rowIndex: currentBlog.id, id1: currentBlog.id, id2: currentBlog.id, description: SDKUI_Localizator.OperationSuccess, resultType: ResultTypes.SUCCESS });
381
+ refreshHomePageNews?.();
382
+ })
383
+ .catch((err) => {
384
+ result.push({ rowIndex: currentBlog.id, id1: currentBlog.id, id2: currentBlog.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
385
+ });
386
+ break;
370
387
  default:
371
388
  ShowAlert({ message: 'TODO', mode: 'warning', title: SDKUI_Localizator.Unfollow, duration: 3000 });
372
389
  break;
@@ -570,7 +587,7 @@ const TMBlogsPost = (props) => {
570
587
  beginGroup: true
571
588
  });
572
589
  }
573
- if (targetItem && Boolean(classId && (classId === 'WG' || classId === 'DS'))) {
590
+ if (targetItem && Boolean(classId && (classId === 'WG' || classId === 'DS' || classId === 'CF'))) {
574
591
  menuItems.push({
575
592
  icon: _jsx("span", { className: "dx-icon-eyeclose" }),
576
593
  name: SDKUI_Localizator.Unfollow,
@@ -632,6 +649,12 @@ const TMBlogsPost = (props) => {
632
649
  else
633
650
  console.log("Working Group reference missing objID");
634
651
  break;
652
+ case ObjectClasses.CaseFlowInstance:
653
+ if (ref.objID)
654
+ handleNavigateToCaseflows?.(ref.objID);
655
+ else
656
+ console.log("CaseFlow instance reference missing objID");
657
+ break;
635
658
  // Handle other object types as needed
636
659
  default:
637
660
  console.warn(`Unhandled object type: ${ref.objClass}`);
@@ -687,7 +710,7 @@ const TMBlogsPost = (props) => {
687
710
  textDecoration: blogPost.isDel ? 'line-through' : 'none',
688
711
  boxShadow: isFocused ? "0 4px 12px rgba(19, 85, 150, 0.6)" : "none",
689
712
  cursor: 'pointer',
690
- }, children: [_jsx(BlogPostTitle, { displayMode: displayMode, layoutMode: layoutMode, blogPost: blogPost, isSelected: isSelected, isOwnComment: isOwnComment, searchText: searchText, isSys: isSys, isHomeBlogPost: isHomeBlogPost, showId: localShowId, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), isNew && _jsx(NewBadge, { layoutMode: layoutMode }), _jsx("div", { style: { fontSize: '1rem', color: "#000", marginTop: "10px", overflow: "hidden" }, children: _jsx(TMHtmlContentDisplay, { markup: blogPost.description ?? '-', searchText: searchText, isSelected: isSelected }) }), showExtendedAttachments && blogPost.attachments && blogPost.attachments.length > 0 && (_jsx(TMBlogAttachments, { attachments: blogPost.attachments, layoutMode: layoutMode, isSelected: isSelected, isLoading: !descriptorsLoaded, searchText: searchText, dcmtTypeDescriptors: dcmtTypeDescriptors, treeFs: treeFs, draftLatestInfoMap: draftLatestInfoMap, archivedDocumentMap: archivedDocumentMap, handleAttachmentFocus: handleFocusedAttachment, openDcmtForm: openDcmtForm }))] }, `${id}-blogpost-${blogPost.id}`) })] }, "blog-post-wrapper-" + id + "-" + blogPost.id);
713
+ }, children: [_jsx(BlogPostTitle, { displayMode: displayMode, layoutMode: layoutMode, blogPost: blogPost, isSelected: isSelected, isOwnComment: isOwnComment, searchText: searchText, isSys: isSys, isHomeBlogPost: isHomeBlogPost, showId: localShowId, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, handleNavigateToCaseflows: handleNavigateToCaseflows }), isNew && _jsx(NewBadge, { layoutMode: layoutMode }), _jsx("div", { style: { fontSize: '1rem', color: "#000", marginTop: "10px", overflow: "hidden" }, children: _jsx(TMHtmlContentDisplay, { markup: blogPost.description ?? '-', searchText: searchText, isSelected: isSelected }) }), showExtendedAttachments && blogPost.attachments && blogPost.attachments.length > 0 && (_jsx(TMBlogAttachments, { attachments: blogPost.attachments, layoutMode: layoutMode, isSelected: isSelected, isLoading: !descriptorsLoaded, searchText: searchText, dcmtTypeDescriptors: dcmtTypeDescriptors, treeFs: treeFs, draftLatestInfoMap: draftLatestInfoMap, archivedDocumentMap: archivedDocumentMap, handleAttachmentFocus: handleFocusedAttachment, openDcmtForm: openDcmtForm }))] }, `${id}-blogpost-${blogPost.id}`) })] }, "blog-post-wrapper-" + id + "-" + blogPost.id);
691
714
  }), _jsx("div", { ref: bottomRef })] }), _jsx(TMContextMenu, { items: menuItems, target: `#${id}-blogs-wrapper`, externalControl: {
692
715
  visible: menuVisible,
693
716
  position: menuPosition,
@@ -109,6 +109,7 @@ interface BlogPostTitleProps {
109
109
  showId: boolean;
110
110
  handleNavigateToWGs?: (blogPost: BlogPost | HomeBlogPost) => void;
111
111
  handleNavigateToDossiers?: (blogPost: BlogPost | HomeBlogPost) => void;
112
+ handleNavigateToCaseflows?: (blogPost: BlogPost | HomeBlogPost) => void;
112
113
  }
113
114
  export declare const BlogPostTitle: (props: BlogPostTitleProps) => import("react/jsx-runtime").JSX.Element;
114
115
  export declare const stripHtml: (html: string) => string;
@@ -162,8 +162,16 @@ export const getDcmtTypeDescriptor = async (blogPosts) => {
162
162
  return dcmtTypeMap;
163
163
  };
164
164
  export const BlogPostHomeHeader = (header, classId, isSelected, searchText, headerClickCallback) => {
165
+ // 'CF' = istanza di CaseFlow (bacheca Home V6). Attenzione: nel mondo dei
166
+ // task PdGs.CF indica invece la pratica-dossier; qui il dominio e' il
167
+ // ClassID di HomeBlogPost, dove 'DS' e' la pratica e 'CF' la pratica CaseFlow.
165
168
  const isWorkGroup = classId === 'WG';
166
- const iconColor = isSelected ? '#ffffff' : isWorkGroup ? PDGS_COLORS.WORKING_GROUP : PDGS_COLORS.DOSSIER;
169
+ const isCaseFlow = classId === 'CF';
170
+ const iconColor = isSelected
171
+ ? '#ffffff'
172
+ : isWorkGroup ? PDGS_COLORS.WORKING_GROUP
173
+ : isCaseFlow ? PDGS_COLORS.CASEFLOW
174
+ : PDGS_COLORS.DOSSIER;
167
175
  return (_jsxs("div", { style: {
168
176
  display: "flex",
169
177
  alignItems: "center",
@@ -171,7 +179,7 @@ export const BlogPostHomeHeader = (header, classId, isSelected, searchText, head
171
179
  fontWeight: "bold",
172
180
  color: isSelected ? "#fff" : TMColors.primary,
173
181
  gap: "4px",
174
- }, children: [_jsx(TMTooltip, { content: isWorkGroup ? SDKUI_Localizator.WorkGroup : SDKUI_Localizator.Dossier, children: isWorkGroup ? (_jsx(IconMenuCAWorkingGroups, { color: iconColor, fontSize: 28, onClick: headerClickCallback })) : (_jsx(IconCADossier, { color: iconColor, fontSize: 28, onClick: headerClickCallback })) }), _jsx("div", { onClick: headerClickCallback, style: {
182
+ }, children: [_jsx(TMTooltip, { content: isWorkGroup ? SDKUI_Localizator.WorkGroup : isCaseFlow ? "CaseFlow" : SDKUI_Localizator.Dossier, children: isWorkGroup ? (_jsx(IconMenuCAWorkingGroups, { color: iconColor, fontSize: 28, onClick: headerClickCallback })) : isCaseFlow ? (_jsx(IconCADossier, { color: iconColor, fontSize: 28, onClick: headerClickCallback })) : (_jsx(IconCADossier, { color: iconColor, fontSize: 28, onClick: headerClickCallback })) }), _jsx("div", { onClick: headerClickCallback, style: {
175
183
  whiteSpace: "nowrap",
176
184
  overflow: "hidden",
177
185
  textOverflow: "ellipsis",
@@ -218,7 +226,7 @@ export const removeFileExtension = (filename) => {
218
226
  return filename.includes('.') ? filename.substring(0, filename.lastIndexOf('.')) : filename;
219
227
  };
220
228
  export const BlogPostTitle = (props) => {
221
- const { displayMode, layoutMode, blogPost, isSelected, isOwnComment, searchText, isSys, isHomeBlogPost, showId, handleNavigateToWGs, handleNavigateToDossiers } = props;
229
+ const { displayMode, layoutMode, blogPost, isSelected, isOwnComment, searchText, isSys, isHomeBlogPost, showId, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToCaseflows } = props;
222
230
  const showOwnerBadge = (displayMode === "stacked" || !isOwnComment) && layoutMode === "extended";
223
231
  let subtitle = "";
224
232
  if (isHomeBlogPost) {
@@ -239,6 +247,9 @@ export const BlogPostTitle = (props) => {
239
247
  if (handleNavigateToDossiers && blogPost.id && blogPost.classID === 'DS') {
240
248
  handleNavigateToDossiers(blogPost);
241
249
  }
250
+ if (handleNavigateToCaseflows && blogPost.id && blogPost.classID === 'CF') {
251
+ handleNavigateToCaseflows(blogPost);
252
+ }
242
253
  };
243
254
  return _jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [showOwnerBadge && (_jsx("div", { style: { width: "40px", height: "40px", flexShrink: 0 }, children: OwnerInitialsBadge(blogPost) })), _jsxs("div", { style: {
244
255
  display: "flex",
@@ -5,6 +5,7 @@ interface TMPanelManagerContainerProps {
5
5
  direction: TMPanelDirection;
6
6
  parentId?: string;
7
7
  minPanelSizePx?: number;
8
+ gutterSizePx?: number;
8
9
  }
9
10
  declare const TMPanelManagerContainer: (props: TMPanelManagerContainerProps) => import("react/jsx-runtime").JSX.Element | null;
10
11
  export default TMPanelManagerContainer;