@topconsultnpm/sdkui-react 6.22.0-t1 → 6.22.0-t2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +1 -1
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +45 -43
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +67 -60
- package/lib/components/base/Styled.d.ts +92 -76
- package/lib/components/base/TMButton.d.ts +13 -0
- package/lib/components/base/TMButton.js +137 -5
- package/lib/components/base/TMDataGrid.d.ts +2 -0
- package/lib/components/base/TMDataGrid.js +260 -8
- package/lib/components/base/TMDataGridExportForm.js +39 -30
- package/lib/components/base/TMEditorBase.d.ts +2 -0
- package/lib/components/base/TMFileManager.js +5 -3
- package/lib/components/base/TMFileManagerDataGridView.js +11 -2
- package/lib/components/base/TMFileManagerThumbnailItems.js +19 -9
- package/lib/components/base/TMFileManagerUtils.d.ts +6 -6
- package/lib/components/base/TMFileManagerUtils.js +37 -1
- package/lib/components/base/TMModal.d.ts +11 -0
- package/lib/components/base/TMModal.js +47 -13
- package/lib/components/base/TMPanel.d.ts +6 -0
- package/lib/components/base/TMPanel.js +138 -25
- package/lib/components/base/TMPopUp.js +3 -0
- package/lib/components/base/TMTooltip.d.ts +2 -1
- package/lib/components/base/TMTooltip.js +24 -8
- package/lib/components/base/TMTreeView.d.ts +13 -7
- package/lib/components/base/TMTreeView.js +108 -67
- package/lib/components/choosers/TMDcmtTypeChooser.js +4 -3
- package/lib/components/choosers/TMDistinctValues.d.ts +9 -7
- package/lib/components/choosers/TMDistinctValues.js +149 -142
- package/lib/components/choosers/TMMetadataChooser.js +1 -1
- package/lib/components/choosers/TMQuickSearchInfo.d.ts +13 -0
- package/lib/components/choosers/TMQuickSearchInfo.js +279 -0
- package/lib/components/choosers/TMQuickSearchSettingsForm.d.ts +16 -0
- package/lib/components/choosers/TMQuickSearchSettingsForm.js +94 -0
- package/lib/components/choosers/TMSelectedValuesSummary.d.ts +13 -0
- package/lib/components/choosers/TMSelectedValuesSummary.js +91 -0
- package/lib/components/editors/TMDateBox.d.ts +16 -1
- package/lib/components/editors/TMDateBox.js +90 -22
- package/lib/components/editors/TMDropDown.d.ts +3 -0
- package/lib/components/editors/TMDropDown.js +197 -5
- package/lib/components/editors/TMEditorStyled.d.ts +20 -42
- package/lib/components/editors/TMMetadataEditor.d.ts +5 -1
- package/lib/components/editors/TMMetadataEditor.js +27 -23
- package/lib/components/editors/TMTextArea.d.ts +1 -0
- package/lib/components/editors/TMTextArea.js +23 -15
- package/lib/components/editors/TMTextBox.d.ts +2 -0
- package/lib/components/editors/TMTextBox.js +30 -19
- package/lib/components/features/archive/TMArchive.js +17 -3
- package/lib/components/features/documents/TMBatchUpdateForm.js +19 -5
- package/lib/components/features/documents/TMDcmtBlog.d.ts +3 -0
- package/lib/components/features/documents/TMDcmtBlog.js +4 -4
- package/lib/components/features/documents/TMDcmtForm.d.ts +7 -0
- package/lib/components/features/documents/TMDcmtForm.js +232 -53
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +11 -0
- package/lib/components/features/documents/TMDcmtFormActionButtons.js +77 -7
- package/lib/components/features/documents/TMDcmtIcon.js +5 -3
- package/lib/components/features/documents/TMDcmtPreview.d.ts +7 -5
- package/lib/components/features/documents/TMDcmtPreview.js +10 -6
- package/lib/components/features/documents/TMMasterDetailDcmts.js +95 -33
- package/lib/components/features/documents/TMMasterInfoFields.d.ts +20 -0
- package/lib/components/features/documents/TMMasterInfoFields.js +186 -0
- package/lib/components/features/documents/TMMergeToPdfForm.d.ts +1 -2
- package/lib/components/features/documents/TMMergeToPdfForm.js +30 -5
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +46 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +323 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +370 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +283 -0
- package/lib/components/features/documents/TMRelationViewer.d.ts +14 -1
- package/lib/components/features/documents/TMRelationViewer.js +82 -52
- package/lib/components/features/search/TMSearch.js +103 -24
- package/lib/components/features/search/TMSearchQueryEditor.js +5 -3
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +14 -4
- package/lib/components/features/search/TMSearchQueryPanel.js +152 -57
- package/lib/components/features/search/TMSearchResult.d.ts +16 -0
- package/lib/components/features/search/TMSearchResult.js +438 -145
- package/lib/components/features/search/TMTreeSelector.js +109 -64
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +10 -0
- package/lib/components/features/workflow/TMWorkflowPopup.js +8 -4
- package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +3 -1
- package/lib/components/forms/Login/ChangePasswordInputs.d.ts +3 -1
- package/lib/components/grids/TMBlogAttachments.js +13 -2
- package/lib/components/grids/TMBlogHeader.js +5 -1
- package/lib/components/grids/TMBlogsPost.d.ts +2 -0
- package/lib/components/grids/TMBlogsPost.js +31 -4
- package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
- package/lib/components/grids/TMBlogsPostUtils.js +14 -3
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +24 -14
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +68 -93
- package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +4 -5
- package/lib/components/layout/panelManager/TMPanelWrapper.js +2 -2
- package/lib/components/layout/panelManager/types.d.ts +3 -0
- package/lib/components/layout/panelManager/utils.js +13 -11
- package/lib/components/query/TMQueryEditor.d.ts +14 -10
- package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -4
- package/lib/components/sidebar/TMHeader.js +30 -20
- package/lib/components/viewers/TMMidViewer.js +5 -2
- package/lib/components/viewers/TMTidViewer.js +86 -25
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/devextreme-license.d.ts +1 -0
- package/lib/devextreme-license.js +3 -0
- package/lib/helper/Globalization.d.ts +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +110 -0
- package/lib/helper/SDKUI_Globals.js +151 -0
- package/lib/helper/SDKUI_Localizator.d.ts +55 -0
- package/lib/helper/SDKUI_Localizator.js +550 -0
- package/lib/helper/TMAppUpdatedModal.d.ts +2 -0
- package/lib/helper/TMAppUpdatedModal.js +134 -0
- package/lib/helper/TMIcons.d.ts +1 -0
- package/lib/helper/TMIcons.js +3 -0
- package/lib/helper/TMUtils.d.ts +51 -4
- package/lib/helper/TMUtils.js +272 -11
- package/lib/helper/dataGridSearchHelper.d.ts +28 -0
- package/lib/helper/dataGridSearchHelper.js +51 -0
- package/lib/helper/dcmtsHelper.d.ts +20 -0
- package/lib/helper/dcmtsHelper.js +58 -1
- package/lib/helper/helpers.d.ts +23 -1
- package/lib/helper/helpers.js +57 -1
- package/lib/helper/index.d.ts +2 -0
- package/lib/helper/index.js +2 -0
- package/lib/helper/queryHelper.d.ts +6 -1
- package/lib/helper/queryHelper.js +8 -3
- package/lib/hooks/tmDistinctValuesGridHelper.d.ts +16 -0
- package/lib/hooks/tmDistinctValuesGridHelper.js +31 -0
- package/lib/hooks/useArchiveListForm.d.ts +39 -0
- package/lib/hooks/useArchiveListForm.js +46 -0
- package/lib/hooks/useCaseFlowApprove.d.ts +56 -0
- package/lib/hooks/useCaseFlowApprove.js +157 -0
- package/lib/hooks/useDataUserIdItem.d.ts +1 -0
- package/lib/hooks/useDataUserIdItem.js +1 -0
- package/lib/hooks/useDocumentOperations.d.ts +4 -0
- package/lib/hooks/useDocumentOperations.js +52 -10
- package/lib/hooks/useMultiMasterDetailDcmts.d.ts +113 -0
- package/lib/hooks/useMultiMasterDetailDcmts.js +760 -0
- package/lib/hooks/useRelatedDocuments.d.ts +1 -0
- package/lib/hooks/useRelatedDocuments.js +22 -27
- package/lib/hooks/useShowDossiersV5.d.ts +12 -0
- package/lib/hooks/useShowDossiersV5.js +37 -0
- package/lib/hooks/useTMDistinctValuesMetadataDisplay.d.ts +18 -0
- package/lib/hooks/useTMDistinctValuesMetadataDisplay.js +103 -0
- package/lib/hooks/useTMDistinctValuesQuickSearch.d.ts +49 -0
- package/lib/hooks/useTMDistinctValuesQuickSearch.js +307 -0
- package/lib/hooks/useTMDistinctValuesSelection.d.ts +42 -0
- package/lib/hooks/useTMDistinctValuesSelection.js +103 -0
- package/lib/hooks/useTMDistinctValuesSource.d.ts +29 -0
- package/lib/hooks/useTMDistinctValuesSource.js +105 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +5 -2
- package/lib/services/caseflow/CaseFlowService.d.ts +236 -0
- package/lib/services/caseflow/CaseFlowService.js +693 -0
- package/lib/services/caseflow/CaseFlowTemplateCacheService.d.ts +28 -0
- package/lib/services/caseflow/CaseFlowTemplateCacheService.js +121 -0
- package/lib/services/caseflow/caseFlowNameCache.d.ts +32 -0
- package/lib/services/caseflow/caseFlowNameCache.js +116 -0
- package/lib/services/caseflow/caseFlowWorkItemUtils.d.ts +61 -0
- package/lib/services/caseflow/caseFlowWorkItemUtils.js +113 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/services/index.js +4 -0
- package/lib/services/platform_services.d.ts +1 -1
- 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, useMemo, 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([]);
|
|
@@ -22,80 +31,76 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
22
31
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
|
23
32
|
// State hook to store the currently focused row key, initially set to undefined
|
|
24
33
|
const [focusedRowKey, setFocusedRowKey] = useState(undefined);
|
|
34
|
+
// Elemento selezionato nell'albero: dopo un refresh va riproposto se esiste ancora
|
|
35
|
+
const [selectedTreeItemKey, setSelectedTreeItemKey] = useState(undefined);
|
|
36
|
+
const selectedTreeItemKeys = useMemo(() => selectedTreeItemKey !== undefined ? [selectedTreeItemKey] : [], [selectedTreeItemKey]);
|
|
25
37
|
const [isGridBoxOpened, setIsGridBoxOpened] = useState(false);
|
|
26
38
|
const [defaultTreeId, setDefaultTreeId] = useState(-1);
|
|
27
39
|
const deviceType = useDeviceType();
|
|
28
40
|
const isMobile = deviceType === DeviceType.MOBILE;
|
|
29
41
|
const panelRef = useOutsideClick(() => setInfoDTD(undefined));
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
42
|
+
// Tiene traccia dell'albero selezionato senza far dipendere loadTreesAsync da selectedTreeId:
|
|
43
|
+
// così il refresh può riproporre la selezione corrente senza ricaricare a ogni cambio di albero
|
|
44
|
+
const selectedTreeIdRef = useRef(selectedTreeId);
|
|
45
|
+
useEffect(() => { selectedTreeIdRef.current = selectedTreeId; }, [selectedTreeId]);
|
|
46
|
+
// Carica tutti gli alberi del contesto corrente (ricerca o archiviazione).
|
|
47
|
+
// Con forceRefresh la cache viene invalidata, altrimenti GetAll* restituirebbe gli alberi già in memoria.
|
|
48
|
+
const loadTreesAsync = useCallback(async (forceRefresh = false) => {
|
|
49
|
+
const isSearchContext = layoutMode == LayoutModes.Update;
|
|
50
|
+
if (forceRefresh) {
|
|
51
|
+
if (isSearchContext)
|
|
52
|
+
TreeCacheService.RemoveAllSearch();
|
|
53
|
+
else
|
|
54
|
+
TreeCacheService.RemoveAllArchive();
|
|
55
|
+
}
|
|
56
|
+
const result = isSearchContext
|
|
57
|
+
? await TreeCacheService.GetAllSearchAsync()
|
|
58
|
+
: await TreeCacheService.GetAllArchiveAsync();
|
|
59
|
+
if (!result || result.length === 0) {
|
|
60
|
+
// Sul refresh gli alberi possono essere spariti lato server: allinea anche lo stato vuoto
|
|
61
|
+
if (forceRefresh) {
|
|
62
|
+
setTrees([]);
|
|
63
|
+
setSelectedTreeId(0);
|
|
64
|
+
setSelectedRowKeys([]);
|
|
54
65
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
setTrees(result);
|
|
69
|
+
// Dopo un refresh mantiene l'albero corrente, se ancora presente
|
|
70
|
+
const currentTreeId = selectedTreeIdRef.current;
|
|
71
|
+
if (forceRefresh && result.some(o => o.id == currentTreeId)) {
|
|
72
|
+
setSelectedTreeId(currentTreeId);
|
|
73
|
+
setSelectedRowKeys([currentTreeId]);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
let defaultTree = SDKUI_Globals.userSettings.searchSettings.defaultTree;
|
|
77
|
+
let initialTreeId;
|
|
78
|
+
let treeToSelect;
|
|
79
|
+
if (defaultTree > 0) {
|
|
80
|
+
initialTreeId = defaultTree;
|
|
81
|
+
treeToSelect = result.find(o => o.id == defaultTree);
|
|
58
82
|
}
|
|
59
83
|
else {
|
|
60
|
-
|
|
84
|
+
initialTreeId = result[0]?.id ?? 0;
|
|
85
|
+
treeToSelect = result[0];
|
|
86
|
+
}
|
|
87
|
+
setSelectedTreeId(initialTreeId);
|
|
88
|
+
if (treeToSelect?.id) {
|
|
89
|
+
setSelectedRowKeys([treeToSelect.id]);
|
|
61
90
|
}
|
|
62
91
|
}, [layoutMode]);
|
|
92
|
+
useEffect(() => { loadTreesAsync(); }, [loadTreesAsync]);
|
|
63
93
|
useEffect(() => {
|
|
64
94
|
let newTreeItems = trees.find(o => o.id == selectedTreeId)?.items ?? [];
|
|
65
95
|
setTreeItems(newTreeItems);
|
|
96
|
+
// Mantiene la selezione dopo il refresh solo se l'elemento e' ancora presente (al cambio albero si azzera)
|
|
97
|
+
setSelectedTreeItemKey(prev => prev !== undefined && newTreeItems.some(o => o.id == prev) ? prev : undefined);
|
|
66
98
|
}, [selectedTreeId, trees]);
|
|
67
99
|
const renderCell = useCallback((data) => {
|
|
68
100
|
const treeItem = data.data;
|
|
69
|
-
const [showInfo, setShowInfo] = useState(false);
|
|
70
101
|
// Documento (DcmtType)
|
|
71
102
|
if (treeItem.type === TreeItemTypes.DcmtType) {
|
|
72
|
-
return (
|
|
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 }) }) }))] }));
|
|
103
|
+
return _jsx(TMTreeDcmtTypeCell, { tid: treeItem.tid, isMobile: isMobile });
|
|
99
104
|
}
|
|
100
105
|
// Folder (altri tipi)
|
|
101
106
|
return (_jsxs(StyledDivHorizontal, { style: { gap: 5, alignItems: 'center', minWidth: 0 }, children: [_jsx("span", { style: {
|
|
@@ -113,7 +118,7 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
113
118
|
whiteSpace: 'nowrap',
|
|
114
119
|
flex: 1,
|
|
115
120
|
}, children: treeItem.nameLoc })] }));
|
|
116
|
-
}, [isMobile
|
|
121
|
+
}, [isMobile]);
|
|
117
122
|
// Handles selection change in the data grid
|
|
118
123
|
const onSelectionChanged = useCallback((e) => {
|
|
119
124
|
const selectedKeys = e.component.getSelectedRowKeys() ?? [];
|
|
@@ -126,6 +131,16 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
126
131
|
setSelectedRowKeys(selectedKeys);
|
|
127
132
|
setIsGridBoxOpened(false);
|
|
128
133
|
}, []);
|
|
134
|
+
// Handles click on a tree row in the trees data grid: clicking the already selected tree
|
|
135
|
+
// does not raise onSelectionChanged, so the drop down must be closed here as well
|
|
136
|
+
const onRowClickTrees = useCallback((e) => {
|
|
137
|
+
const tree = e.data;
|
|
138
|
+
if (tree?.id === undefined)
|
|
139
|
+
return;
|
|
140
|
+
setSelectedTreeId(tree.id);
|
|
141
|
+
setSelectedRowKeys([tree.id]);
|
|
142
|
+
setIsGridBoxOpened(false);
|
|
143
|
+
}, []);
|
|
129
144
|
// Handles focus change in the data grid
|
|
130
145
|
const onFocusedRowChanged = useCallback((e) => {
|
|
131
146
|
setFocusedRowKey(e.row?.key);
|
|
@@ -161,7 +176,18 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
161
176
|
}
|
|
162
177
|
}
|
|
163
178
|
}, []);
|
|
164
|
-
|
|
179
|
+
// Callback function to handle click events on a tree view row.
|
|
180
|
+
const onRowClickTreeView = useCallback((e) => {
|
|
181
|
+
const treeItem = e.data;
|
|
182
|
+
if (treeItem?.type === TreeItemTypes.DcmtType) {
|
|
183
|
+
onSelectedTIDChanged?.(treeItem.tid, selectedTreeId);
|
|
184
|
+
}
|
|
185
|
+
}, [onSelectedTIDChanged, selectedTreeId]);
|
|
186
|
+
// La selezione la decide il widget (click, ctrl+click che deseleziona, barra spaziatrice): qui si allinea solo lo stato
|
|
187
|
+
const onSelectionChangedTreeView = useCallback((e) => {
|
|
188
|
+
setSelectedTreeItemKey(e.selectedRowKeys?.[0]);
|
|
189
|
+
}, []);
|
|
190
|
+
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
191
|
if (defaultTreeId == selectedTreeId) {
|
|
166
192
|
if (layoutMode == LayoutModes.Update)
|
|
167
193
|
SDKUI_Globals.userSettings.searchSettings.defaultTree = -1;
|
|
@@ -193,14 +219,33 @@ const TMTreeSelector = ({ layoutMode = LayoutModes.Update, isVisible, onSelected
|
|
|
193
219
|
}, 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
220
|
{ dataField: 'nameLoc', caption: SDKUI_Localizator.Name, width: 'auto' },
|
|
195
221
|
{ 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,
|
|
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)] })] })] })
|
|
222
|
+
], 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, selectedRowKeys: selectedTreeItemKeys, onSelectionChanged: onSelectionChangedTreeView, 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
223
|
: _jsx("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', fontSize: '1.5rem' }, children: SDKUI_Localizator.TreesNoAvailable }) }));
|
|
202
224
|
};
|
|
203
225
|
export default TMTreeSelector;
|
|
226
|
+
const StyledTreeDcmtTypeRow = styled(StyledDivHorizontal) `
|
|
227
|
+
align-items: center;
|
|
228
|
+
min-width: 0;
|
|
229
|
+
width: 100%;
|
|
230
|
+
gap: 2px;
|
|
231
|
+
position: relative;
|
|
232
|
+
|
|
233
|
+
.info-icon {
|
|
234
|
+
display: flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
margin-left: auto;
|
|
237
|
+
z-index: 2;
|
|
238
|
+
cursor: pointer;
|
|
239
|
+
opacity: 0;
|
|
240
|
+
pointer-events: none;
|
|
241
|
+
transition: opacity 0.2s;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
&:hover .info-icon {
|
|
245
|
+
opacity: 1;
|
|
246
|
+
pointer-events: auto;
|
|
247
|
+
}
|
|
248
|
+
`;
|
|
204
249
|
const StyledTreeListWrapper = styled.div `
|
|
205
250
|
width: 100%;
|
|
206
251
|
height: 100%;
|
|
@@ -4,6 +4,16 @@ import { DeviceType } from "../../base/TMDeviceProvider";
|
|
|
4
4
|
import { WorkItemDetail } from "../../../ts";
|
|
5
5
|
interface IWorkflowOperationButtonsProps {
|
|
6
6
|
dtd: DcmtTypeDescriptor | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Forza la forma dei pulsanti: `true` = flusso di FIRMA (Firma e approva),
|
|
9
|
+
* `false` = flusso di APPROVAZIONE. Se omesso si deduce dal tipo documento
|
|
10
|
+
* (widget Sign4Top), che è il comportamento del workflow.
|
|
11
|
+
*
|
|
12
|
+
* Serve a chi conosce la natura dell'attività meglio del tipo documento: un
|
|
13
|
+
* work item di sola approvazione su un tipo ABILITATO alla firma non deve
|
|
14
|
+
* mostrare "Firma e approva".
|
|
15
|
+
*/
|
|
16
|
+
signFlow?: boolean;
|
|
7
17
|
approveDisable?: boolean;
|
|
8
18
|
signApproveDisable?: boolean;
|
|
9
19
|
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,7 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { QueryDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
3
|
import { WorkItemActor } from './RecipientList';
|
|
4
|
-
export declare const RecipientsContainer: import("styled-components/dist/types").IStyledComponentBase<"web",
|
|
4
|
+
export declare const RecipientsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
5
|
+
style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
|
|
6
|
+
}> & string;
|
|
5
7
|
export declare const tosToActors: (tosString: string) => {
|
|
6
8
|
andRecipients: WorkItemActor[];
|
|
7
9
|
orRecipients: WorkItemActor[];
|
|
@@ -11,4 +11,6 @@ interface ChangePasswordInputsProps {
|
|
|
11
11
|
}
|
|
12
12
|
declare const ChangePasswordInputs: React.FC<ChangePasswordInputsProps>;
|
|
13
13
|
export default ChangePasswordInputs;
|
|
14
|
-
export declare const Divider: import("styled-components/dist/types").IStyledComponentBase<"web",
|
|
14
|
+
export declare const Divider: import("styled-components/dist/types").IStyledComponentBase<"web", Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
|
|
15
|
+
style?: React.CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
|
|
16
|
+
}> & string;
|
|
@@ -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',
|
|
@@ -4,7 +4,11 @@ import TMDropDown from "../editors/TMDropDown";
|
|
|
4
4
|
import TMTreeDropDown from "../editors/TMTreeDropDown";
|
|
5
5
|
import { TMSearchBar } from "../sidebar/TMHeader";
|
|
6
6
|
const TMBlogHeader = (props) => {
|
|
7
|
-
const { isVisible, layoutMode, height, width,
|
|
7
|
+
const { isVisible, layoutMode, height, width,
|
|
8
|
+
// Difensivo: un chiamante che passa una bacheca non ancora caricata (o
|
|
9
|
+
// assente perche' il ramo blog e' fallito lato server) non deve far
|
|
10
|
+
// esplodere l'header sulla lettura di length.
|
|
11
|
+
allPosts = [], postsToShow, onPostsToShowChange, categoryIdDataSource, appliedCategoryIdFilters, setAppliedCategoryIdFilters, searchText, onSearchChange } = props;
|
|
8
12
|
// Data source for the number of posts to display in the UI
|
|
9
13
|
const postsToShowDataSource = [
|
|
10
14
|
{ value: 30, display: SDKUI_Localizator.Latest + ' 30' },
|
|
@@ -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) => React.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";
|
|
@@ -21,7 +22,11 @@ import TMTaskForm from "../features/tasks/TMTaskForm";
|
|
|
21
22
|
import { useDeviceType } from "../base/TMDeviceProvider";
|
|
22
23
|
let localAbortController = new AbortController();
|
|
23
24
|
const TMBlogsPost = (props) => {
|
|
24
|
-
const { scrollToSelected, id,
|
|
25
|
+
const { scrollToSelected, id,
|
|
26
|
+
// Difensivo: `posts` e' obbligatoria nei tipi, ma a runtime puo' arrivare
|
|
27
|
+
// undefined (dato non ancora caricato o risposta parziale del server):
|
|
28
|
+
// il default evita i crash su filter/length.
|
|
29
|
+
posts = [], displayMode = "stacked", height = "100%", width = "100%", scrollToBottom = true, header, showExtendedAttachments = true, treeFs, draftLatestInfoMap, archivedDocumentMap, context, participants, contextMenuParams = {
|
|
25
30
|
isShowHideFilterEnabled: true,
|
|
26
31
|
isShowHideIDEnaled: true,
|
|
27
32
|
isCommentEnabled: false,
|
|
@@ -32,7 +37,7 @@ const TMBlogsPost = (props) => {
|
|
|
32
37
|
isRestoreEnabled: false,
|
|
33
38
|
isRefreshEnabled: false,
|
|
34
39
|
isCreateContextualTask: false,
|
|
35
|
-
}, showFloatingCommentButton = false, showCommentFormCallback, refreshCallback, showId, setShowId, refreshHomePageNews, markBlogAsRead, externalBlogPost, resetExternalBlogPost, visible = true, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved, handleNavigateToWGs, handleNavigateToDossiers, } = props;
|
|
40
|
+
}, showFloatingCommentButton = false, showCommentFormCallback, refreshCallback, showId, setShowId, refreshHomePageNews, markBlogAsRead, externalBlogPost, resetExternalBlogPost, visible = true, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, afterTaskSaved, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToCaseflows, } = props;
|
|
36
41
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
|
|
37
42
|
// Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
|
|
38
43
|
const deviceType = useDeviceType();
|
|
@@ -292,6 +297,8 @@ const TMBlogsPost = (props) => {
|
|
|
292
297
|
handleNavigateToWGs(blogPost);
|
|
293
298
|
if (handleNavigateToDossiers && id && blogPost.classID === 'DS')
|
|
294
299
|
handleNavigateToDossiers(blogPost);
|
|
300
|
+
if (handleNavigateToCaseflows && id && blogPost.classID === 'CF')
|
|
301
|
+
handleNavigateToCaseflows(blogPost);
|
|
295
302
|
};
|
|
296
303
|
const handleKeyDown = (event) => {
|
|
297
304
|
if (!selectedItem.length)
|
|
@@ -324,6 +331,9 @@ const TMBlogsPost = (props) => {
|
|
|
324
331
|
if (handleNavigateToDossiers && item.id && classItemID === 'DS') {
|
|
325
332
|
handleNavigateToDossiers(item);
|
|
326
333
|
}
|
|
334
|
+
if (handleNavigateToCaseflows && item.id && classItemID === 'CF') {
|
|
335
|
+
handleNavigateToCaseflows(item);
|
|
336
|
+
}
|
|
327
337
|
break;
|
|
328
338
|
default:
|
|
329
339
|
break;
|
|
@@ -367,6 +377,17 @@ const TMBlogsPost = (props) => {
|
|
|
367
377
|
result.push({ rowIndex: currentBlog.id, id1: currentBlog.id, id2: currentBlog.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
|
|
368
378
|
});
|
|
369
379
|
break;
|
|
380
|
+
case 'CF':
|
|
381
|
+
// La notizia porta il solo CFIID: il template (cftid) che l'API
|
|
382
|
+
// richiede lo risolve CaseFlowService.setFollow.
|
|
383
|
+
await CaseFlowService.setFollow(currentBlog.id, false).then(async () => {
|
|
384
|
+
result.push({ rowIndex: currentBlog.id, id1: currentBlog.id, id2: currentBlog.id, description: SDKUI_Localizator.OperationSuccess, resultType: ResultTypes.SUCCESS });
|
|
385
|
+
refreshHomePageNews?.();
|
|
386
|
+
})
|
|
387
|
+
.catch((err) => {
|
|
388
|
+
result.push({ rowIndex: currentBlog.id, id1: currentBlog.id, id2: currentBlog.id, resultType: ResultTypes.ERROR, description: getExceptionMessage(err) });
|
|
389
|
+
});
|
|
390
|
+
break;
|
|
370
391
|
default:
|
|
371
392
|
ShowAlert({ message: 'TODO', mode: 'warning', title: SDKUI_Localizator.Unfollow, duration: 3000 });
|
|
372
393
|
break;
|
|
@@ -570,7 +591,7 @@ const TMBlogsPost = (props) => {
|
|
|
570
591
|
beginGroup: true
|
|
571
592
|
});
|
|
572
593
|
}
|
|
573
|
-
if (targetItem && Boolean(classId && (classId === 'WG' || classId === 'DS'))) {
|
|
594
|
+
if (targetItem && Boolean(classId && (classId === 'WG' || classId === 'DS' || classId === 'CF'))) {
|
|
574
595
|
menuItems.push({
|
|
575
596
|
icon: _jsx("span", { className: "dx-icon-eyeclose" }),
|
|
576
597
|
name: SDKUI_Localizator.Unfollow,
|
|
@@ -632,6 +653,12 @@ const TMBlogsPost = (props) => {
|
|
|
632
653
|
else
|
|
633
654
|
console.log("Working Group reference missing objID");
|
|
634
655
|
break;
|
|
656
|
+
case ObjectClasses.CaseFlowInstance:
|
|
657
|
+
if (ref.objID)
|
|
658
|
+
handleNavigateToCaseflows?.(ref.objID);
|
|
659
|
+
else
|
|
660
|
+
console.log("CaseFlow instance reference missing objID");
|
|
661
|
+
break;
|
|
635
662
|
// Handle other object types as needed
|
|
636
663
|
default:
|
|
637
664
|
console.warn(`Unhandled object type: ${ref.objClass}`);
|
|
@@ -687,7 +714,7 @@ const TMBlogsPost = (props) => {
|
|
|
687
714
|
textDecoration: blogPost.isDel ? 'line-through' : 'none',
|
|
688
715
|
boxShadow: isFocused ? "0 4px 12px rgba(19, 85, 150, 0.6)" : "none",
|
|
689
716
|
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);
|
|
717
|
+
}, 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
718
|
}), _jsx("div", { ref: bottomRef })] }), _jsx(TMContextMenu, { items: menuItems, target: `#${id}-blogs-wrapper`, externalControl: {
|
|
692
719
|
visible: menuVisible,
|
|
693
720
|
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) => React.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
|
|
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",
|
|
@@ -6,6 +6,7 @@ interface TMPanelManagerContainerProps {
|
|
|
6
6
|
direction: TMPanelDirection;
|
|
7
7
|
parentId?: string;
|
|
8
8
|
minPanelSizePx?: number;
|
|
9
|
+
gutterSizePx?: number;
|
|
9
10
|
}
|
|
10
11
|
declare const TMPanelManagerContainer: (props: TMPanelManagerContainerProps) => React.JSX.Element | null;
|
|
11
12
|
export default TMPanelManagerContainer;
|