@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
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { DataListViewModes, MetadataDataDomains, SDK_Globals } from '@topconsultnpm/sdk-ts';
|
|
4
|
+
import { hoverStyle, IconChevronDown, IconClearButton, IconCopy, IconSearch, IconSuccess, SDKUI_Localizator } from '../../../helper';
|
|
5
|
+
import { formatScalarValue, getUserMetadataSorted } from '../../../helper/dcmtsHelper';
|
|
6
|
+
import { useDataListItem } from '../../../hooks/useDataListItem';
|
|
7
|
+
import { TMColors } from '../../../utils/theme';
|
|
8
|
+
import ShowAlert from '../../base/TMAlert';
|
|
9
|
+
import TMTooltip from '../../base/TMTooltip';
|
|
10
|
+
// Metadati mostrati in linea prima del pulsante "mostra tutti".
|
|
11
|
+
const PREVIEW_COUNT = 12;
|
|
12
|
+
const styles = {
|
|
13
|
+
wrapper: { display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0, borderTop: `1px solid ${TMColors.card_background}` },
|
|
14
|
+
body: { flex: 1, minHeight: 0, padding: '13px 10px 9px', display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(185px, 1fr))', gridAutoRows: 'max-content', alignContent: 'start', columnGap: '10px', rowGap: '13px', overflow: 'auto' },
|
|
15
|
+
item: { position: 'relative', display: 'flex', alignItems: 'center', minWidth: 0, minHeight: '30px', padding: '5px 10px 4px', borderRadius: '8px', border: `1px solid ${TMColors.card_background}`, background: TMColors.default_background, transition: 'border-color 0.15s ease, box-shadow 0.15s ease' },
|
|
16
|
+
// Come per il pulsante copia, la posizione sta sull'ancora del tooltip; il troncamento con i
|
|
17
|
+
// puntini deve invece stare sull'elemento che contiene il testo
|
|
18
|
+
label: { position: 'absolute', top: '-7px', left: '8px', maxWidth: 'calc(100% - 16px)', minWidth: 0, padding: '0 5px', background: TMColors.default_background },
|
|
19
|
+
labelText: { maxWidth: '100%', fontSize: '9px', fontWeight: 700, lineHeight: '13px', letterSpacing: '0.5px', textTransform: 'uppercase', color: TMColors.label_normal, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' },
|
|
20
|
+
value: { display: 'block', width: '100%', fontSize: '12.5px', fontWeight: 500, color: TMColors.text_normal, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', userSelect: 'text', cursor: 'text', minHeight: '17px', lineHeight: '17px' },
|
|
21
|
+
emptyValue: { color: TMColors.disabled, fontWeight: 400 },
|
|
22
|
+
// Pulsante di copia: pastiglia sul bordo superiore della card, come la caption
|
|
23
|
+
// La posizione sta sull'ancora e non sul pulsante: è il contenitore del tooltip, che deve stare
|
|
24
|
+
// dove si vede il pulsante, altrimenti il tooltip si aprirebbe altrove
|
|
25
|
+
copyBtnAnchor: { position: 'absolute', top: '-9px', right: '6px', transition: 'opacity 0.15s ease' },
|
|
26
|
+
copyBtn: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '18px', height: '18px', padding: 0, borderRadius: '50%', border: `1px solid ${TMColors.card_background}`, background: TMColors.default_background, color: TMColors.label_normal, cursor: 'pointer', transition: 'background 0.15s ease, color 0.15s ease, border-color 0.15s ease' },
|
|
27
|
+
placeholder: { gridColumn: '1 / -1', padding: '6px 2px', color: TMColors.label_normal, fontSize: '12px' },
|
|
28
|
+
// Barra di ricerca
|
|
29
|
+
searchBar: { display: 'flex', alignItems: 'center', gap: '8px', padding: '12px 14px 0', flexShrink: 0 },
|
|
30
|
+
searchBox: { position: 'relative', display: 'flex', alignItems: 'center', flex: 1, minWidth: 0, maxWidth: '300px', height: '26px', borderRadius: '13px', border: `1px solid ${TMColors.card_background}`, background: TMColors.toolbar_background, transition: 'border-color 0.15s ease, box-shadow 0.15s ease' },
|
|
31
|
+
searchIcon: { flexShrink: 0, margin: '0 3px 0 9px', color: TMColors.label_normal, display: 'flex' },
|
|
32
|
+
searchInput: { flex: 1, minWidth: 0, height: '100%', padding: '0 2px', margin: 0, border: 'none', outline: 'none', background: 'transparent', fontSize: '12px', color: TMColors.text_normal },
|
|
33
|
+
searchClear: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '18px', height: '18px', marginRight: '5px', padding: 0, border: 'none', borderRadius: '50%', background: 'transparent', color: TMColors.label_normal, cursor: 'pointer', flexShrink: 0, transition: 'background 0.15s ease, color 0.15s ease' },
|
|
34
|
+
searchCount: { fontSize: '11px', fontWeight: 600, color: TMColors.label_normal, whiteSpace: 'nowrap', flexShrink: 0 },
|
|
35
|
+
// Pulsante "mostra tutti / comprimi"
|
|
36
|
+
footer: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '2px 10px 9px', flexShrink: 0 },
|
|
37
|
+
showAllBtn: { display: 'inline-flex', alignItems: 'center', gap: '6px', height: '24px', padding: '0 13px', borderRadius: '12px', border: `1px solid ${TMColors.primary_container}`, background: TMColors.primary_container, color: TMColors.primary, fontSize: '11.5px', fontWeight: 700, letterSpacing: '0.2px', cursor: 'pointer', transition: 'background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease' },
|
|
38
|
+
};
|
|
39
|
+
// Sui dispositivi touch l'hover non esiste: il pulsante di copia deve restare sempre visibile
|
|
40
|
+
const SUPPORTS_HOVER = typeof window === 'undefined' || window.matchMedia?.('(hover: hover)')?.matches !== false;
|
|
41
|
+
// Colori del pulsante di copia nei suoi tre stati
|
|
42
|
+
const COPY_BTN_IDLE = { background: TMColors.default_background, borderColor: TMColors.card_background, color: TMColors.label_normal };
|
|
43
|
+
const COPY_BTN_HOVER = { background: TMColors.primary_container, borderColor: TMColors.primary, color: TMColors.primary };
|
|
44
|
+
const COPY_BTN_COPIED = { background: TMColors.default_background, borderColor: TMColors.success, color: TMColors.success };
|
|
45
|
+
// Card di un singolo metadato: hover e feedback della copia sono locali, così non si ridisegna tutta la griglia
|
|
46
|
+
const MetadataCard = ({ caption, copyText, children }) => {
|
|
47
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
48
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
49
|
+
// Il feedback "copiato" si spegne da solo: il timer va annullato se la card sparisce prima
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!isCopied)
|
|
52
|
+
return;
|
|
53
|
+
const timerID = setTimeout(() => setIsCopied(false), 1400);
|
|
54
|
+
return () => clearTimeout(timerID);
|
|
55
|
+
}, [isCopied]);
|
|
56
|
+
const copyAsync = async () => {
|
|
57
|
+
try {
|
|
58
|
+
await navigator.clipboard.writeText(copyText);
|
|
59
|
+
setIsCopied(true);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
ShowAlert({ message: SDKUI_Localizator.FailedToCopyToClipboard, mode: 'error', title: SDKUI_Localizator.CopyToClipboard, duration: 3000 });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
// Il pulsante resta visibile durante il feedback e quando ha il focus (accessibilità da tastiera)
|
|
66
|
+
const isCopyVisible = copyText !== '' && (!SUPPORTS_HOVER || isHovered || isCopied);
|
|
67
|
+
return (_jsxs("div", { style: styles.item, onMouseEnter: (e) => { setIsHovered(true); Object.assign(e.currentTarget.style, { borderColor: TMColors.primary, boxShadow: '0 2px 8px rgba(37, 89, 165, 0.14)' }); }, onMouseLeave: (e) => { setIsHovered(false); Object.assign(e.currentTarget.style, { borderColor: TMColors.card_background, boxShadow: 'none' }); }, children: [_jsx(TMTooltip, { content: caption, parentStyle: { ...styles.label, maxWidth: isCopyVisible ? 'calc(100% - 38px)' : 'calc(100% - 16px)' }, childStyle: { maxWidth: '100%', minWidth: 0 }, children: _jsx("span", { style: styles.labelText, children: caption }) }), children, copyText !== '' && (_jsx(TMTooltip, { content: isCopied ? SDKUI_Localizator.CopiedSuccessfully : SDKUI_Localizator.CopyToClipboard, parentStyle: { ...styles.copyBtnAnchor, opacity: isCopyVisible ? 1 : 0, pointerEvents: isCopyVisible ? 'auto' : 'none' }, children: _jsx("button", { type: 'button', style: { ...styles.copyBtn, ...(isCopied ? COPY_BTN_COPIED : COPY_BTN_IDLE) }, "aria-label": SDKUI_Localizator.CopyToClipboard, onClick: copyAsync, onFocus: () => setIsHovered(true), onBlur: () => setIsHovered(false), ...hoverStyle(isCopied ? COPY_BTN_COPIED : COPY_BTN_HOVER, isCopied ? COPY_BTN_COPIED : COPY_BTN_IDLE), children: isCopied ? _jsx(IconSuccess, { fontSize: 11 }) : _jsx(IconCopy, { fontSize: 11 }) }) }))] }));
|
|
68
|
+
};
|
|
69
|
+
// Riepilogo dei metadati di un documento in card compatte
|
|
70
|
+
const TMMasterInfoFields = ({ dtd, dcmt, getValuesByMidAsync, reloadToken, isExpandedView = false }) => {
|
|
71
|
+
const { renderDataListCell, loadDataListsAsync, getDataListItem } = useDataListItem();
|
|
72
|
+
const [rows, setRows] = useState([]);
|
|
73
|
+
// Finché la prima lettura non è conclusa non si mostra "nessun dato" (evita il lampo al primo render)
|
|
74
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
75
|
+
const [filter, setFilter] = useState('');
|
|
76
|
+
const [showAll, setShowAll] = useState(false);
|
|
77
|
+
// Carica i metadati del documento (valori + liste dati referenziate).
|
|
78
|
+
// getValuesByMidAsync è volutamente fuori dalle dipendenze: il chiamante la ricrea a ogni render
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
let cancelled = false;
|
|
81
|
+
const loadAsync = async () => {
|
|
82
|
+
try {
|
|
83
|
+
if (!dcmt?.TID || !dcmt?.DID) {
|
|
84
|
+
setRows([]);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const metadata = getUserMetadataSorted(dtd);
|
|
88
|
+
// Precarica le liste dati referenziate dai metadati, così le card mostrano subito il valore leggibile
|
|
89
|
+
const dataListIDs = new Set();
|
|
90
|
+
metadata.forEach(md => { if (md.dataDomain === MetadataDataDomains.DataList && md.dataListID)
|
|
91
|
+
dataListIDs.add(md.dataListID); });
|
|
92
|
+
await loadDataListsAsync(dataListIDs);
|
|
93
|
+
const valueByMid = await getValuesByMidAsync();
|
|
94
|
+
if (cancelled)
|
|
95
|
+
return;
|
|
96
|
+
setRows(metadata.map(md => ({
|
|
97
|
+
mid: md.id,
|
|
98
|
+
caption: (SDK_Globals.useLocalizedName ? md.nameLoc : md.name) ?? md.name ?? '',
|
|
99
|
+
value: valueByMid.get(md.id),
|
|
100
|
+
dataListID: (md.dataDomain === MetadataDataDomains.DataList && md.dataListID) ? md.dataListID : 0,
|
|
101
|
+
viewMode: md.dataListViewMode ?? DataListViewModes.None,
|
|
102
|
+
dataType: md.dataType,
|
|
103
|
+
format: md.format?.format,
|
|
104
|
+
formatCulture: md.format?.formatCulture,
|
|
105
|
+
})));
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
if (!cancelled)
|
|
109
|
+
setRows([]);
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
if (!cancelled)
|
|
113
|
+
setIsLoaded(true);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
// Cambiando documento/tipo documento il filtro non ha più senso: si riparte dall'anteprima
|
|
117
|
+
setFilter('');
|
|
118
|
+
setShowAll(false);
|
|
119
|
+
loadAsync();
|
|
120
|
+
return () => { cancelled = true; };
|
|
121
|
+
}, [dtd?.id, dcmt?.TID, dcmt?.DID, reloadToken]);
|
|
122
|
+
// La barra di ricerca esiste solo nella vista ingrandita: tornando in linea il filtro non è più
|
|
123
|
+
// visibile e resterebbe attivo, nascondendo i primi metadati dell'anteprima
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
if (isExpandedView)
|
|
126
|
+
return;
|
|
127
|
+
setFilter('');
|
|
128
|
+
setShowAll(false);
|
|
129
|
+
}, [isExpandedView]);
|
|
130
|
+
// Testo su cui cerca il filtro: valore visualizzato del metadato (per le liste dati il nome dell'item)
|
|
131
|
+
const getSearchText = (item) => {
|
|
132
|
+
if (item.value === undefined || item.value === null || item.value === '')
|
|
133
|
+
return '';
|
|
134
|
+
if (item.dataListID > 0) {
|
|
135
|
+
const dataListItem = getDataListItem(item.dataListID, item.value);
|
|
136
|
+
return dataListItem ? `${dataListItem.name ?? ''} ${dataListItem.value ?? ''}` : String(item.value);
|
|
137
|
+
}
|
|
138
|
+
return formatScalarValue(item.value, item.dataType, item.format, item.formatCulture);
|
|
139
|
+
};
|
|
140
|
+
// Testo copiato negli appunti: quello che l'utente vede nella card (per le liste dati il nome dell'item)
|
|
141
|
+
const getCopyText = (item) => {
|
|
142
|
+
if (item.value === undefined || item.value === null || item.value === '')
|
|
143
|
+
return '';
|
|
144
|
+
if (item.dataListID > 0) {
|
|
145
|
+
const dataListItem = getDataListItem(item.dataListID, item.value);
|
|
146
|
+
return dataListItem?.name ?? String(item.value);
|
|
147
|
+
}
|
|
148
|
+
return formatScalarValue(item.value, item.dataType, item.format, item.formatCulture);
|
|
149
|
+
};
|
|
150
|
+
// Ricerca case insensitive su nome e valore del metadato
|
|
151
|
+
const query = filter.trim().toLowerCase();
|
|
152
|
+
const filteredRows = useMemo(() => {
|
|
153
|
+
if (!query)
|
|
154
|
+
return rows;
|
|
155
|
+
return rows.filter(item => item.caption.toLowerCase().includes(query) || getSearchText(item).toLowerCase().includes(query));
|
|
156
|
+
}, [rows, query]);
|
|
157
|
+
const renderCard = (item) => {
|
|
158
|
+
const hasValue = item.value !== undefined && item.value !== null && item.value !== '';
|
|
159
|
+
const displayNode = item.dataListID > 0 && hasValue ? renderDataListCell(item.value, item.dataListID, item.viewMode) : (hasValue ? formatScalarValue(item.value, item.dataType, item.format, item.formatCulture) : '');
|
|
160
|
+
return (_jsx(MetadataCard, { caption: item.caption, copyText: getCopyText(item), children: hasValue
|
|
161
|
+
? (
|
|
162
|
+
// Tooltip con il valore esteso (utile quando è troncato)
|
|
163
|
+
_jsx(TMTooltip, { content: displayNode, parentStyle: { flex: 1, minWidth: 0 }, childStyle: { maxWidth: '100%', minWidth: 0 }, children: _jsx("span", { style: { ...styles.value, minWidth: 0 }, children: displayNode }) }))
|
|
164
|
+
// Segnaposto per i metadati vuoti: la card mantiene la stessa altezza
|
|
165
|
+
: _jsx("span", { style: { ...styles.value, ...styles.emptyValue }, children: "\u2014" }) }, item.mid));
|
|
166
|
+
};
|
|
167
|
+
// Ricerca dei metadati: solo nella vista ingrandita e solo quando sono troppi per essere trovati a vista
|
|
168
|
+
const renderSearchBar = () => (_jsxs("div", { style: styles.searchBar, children: [_jsxs("div", { style: styles.searchBox, children: [_jsx(IconSearch, { fontSize: 13, style: styles.searchIcon }), _jsx("input", { type: 'text', value: filter, placeholder: `${SDKUI_Localizator.SearchAction}...`, style: styles.searchInput, onChange: (e) => setFilter(e.target.value),
|
|
169
|
+
// Esc svuota il filtro senza propagare la chiusura del modale
|
|
170
|
+
onKeyDown: (e) => { if (e.key === 'Escape' && filter !== '') {
|
|
171
|
+
e.preventDefault();
|
|
172
|
+
e.stopPropagation();
|
|
173
|
+
setFilter('');
|
|
174
|
+
} }, onFocus: (e) => Object.assign(e.currentTarget.parentElement?.style ?? {}, { borderColor: TMColors.primary, boxShadow: '0 0 0 2px rgba(37, 89, 165, 0.14)' }), onBlur: (e) => Object.assign(e.currentTarget.parentElement?.style ?? {}, { borderColor: TMColors.card_background, boxShadow: 'none' }) }), filter !== '' && (_jsx(TMTooltip, { content: SDKUI_Localizator.Clear, parentStyle: { display: 'flex', flexShrink: 0 }, children: _jsx("button", { type: 'button', style: styles.searchClear, "aria-label": SDKUI_Localizator.Clear, onClick: () => setFilter(''), ...hoverStyle({ background: TMColors.primary_container, color: TMColors.primary }, { background: 'transparent', color: TMColors.label_normal }), children: _jsx(IconClearButton, { fontSize: 13 }) }) }))] }), _jsxs("span", { style: styles.searchCount, children: [filteredRows.length, "/", rows.length] })] }));
|
|
175
|
+
// La ricerca sta solo nella vista ingrandita: in linea lo spazio è poco e l'elenco è limitato
|
|
176
|
+
// all'anteprima, con il pulsante per aprirlo tutto
|
|
177
|
+
const hasSearch = isExpandedView && rows.length > PREVIEW_COUNT;
|
|
178
|
+
const isCapped = !isExpandedView && !showAll && filteredRows.length > PREVIEW_COUNT;
|
|
179
|
+
const canCollapse = !isExpandedView && showAll && filteredRows.length > PREVIEW_COUNT;
|
|
180
|
+
const visibleRows = isCapped ? filteredRows.slice(0, PREVIEW_COUNT) : filteredRows;
|
|
181
|
+
const hiddenCount = filteredRows.length - visibleRows.length;
|
|
182
|
+
return (_jsxs("div", { style: { ...styles.wrapper, ...(isExpandedView ? { borderTop: 'none' } : {}) }, children: [hasSearch && renderSearchBar(), _jsx("div", { style: { ...styles.body, ...(isExpandedView ? { padding: '18px 14px 14px' } : {}) }, children: visibleRows.length > 0
|
|
183
|
+
? visibleRows.map(renderCard)
|
|
184
|
+
: (isLoaded && _jsx("span", { style: styles.placeholder, children: SDKUI_Localizator.NoDataToDisplay })) }), (isCapped || canCollapse) && (_jsx("div", { style: styles.footer, children: _jsxs("button", { type: 'button', style: styles.showAllBtn, onClick: () => setShowAll(!showAll), ...hoverStyle({ background: TMColors.primary, borderColor: TMColors.primary, color: '#ffffff', boxShadow: '0 2px 6px rgba(37, 89, 165, 0.25)' }, { background: TMColors.primary_container, borderColor: TMColors.primary_container, color: TMColors.primary, boxShadow: 'none' }), children: [isCapped ? `${SDKUI_Localizator.ShowAll} (+${hiddenCount})` : SDKUI_Localizator.Collapse, _jsx(IconChevronDown, { fontSize: 13, style: { transform: isCapped ? 'none' : 'rotate(180deg)', transition: 'transform 0.2s ease' } })] }) }))] }));
|
|
185
|
+
};
|
|
186
|
+
export default TMMasterInfoFields;
|
|
@@ -18,8 +18,7 @@ interface ITMMergeToPdfFormProps {
|
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Form per l'unione di più documenti PDF in un singolo file.
|
|
21
|
-
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
|
|
22
|
-
* con TMCopyToFolderForm.
|
|
21
|
+
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared con TMCopyToFolderForm.
|
|
23
22
|
*/
|
|
24
23
|
declare const TMMergeToPdfForm: (props: ITMMergeToPdfFormProps) => React.JSX.Element;
|
|
25
24
|
export default TMMergeToPdfForm;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
3
|
import { DownloadTypes } from '../../../ts';
|
|
4
4
|
import { calcResponsiveSizes, getExceptionMessage, IconFolderOpen, IconPlay, IconUndo, SDKUI_Globals, SDKUI_Localizator, } from '../../../helper';
|
|
5
|
-
import { DcmtOpers, FileFormats, GeneralRetrieveFormats, ResultTypes, RetrieveFileOptions, ValidationItem, } from '@topconsultnpm/sdk-ts';
|
|
5
|
+
import { DcmtOpers, FileFormats, GeneralRetrieveFormats, InvoiceRetrieveFormats, OrderRetrieveFormats, ResultTypes, RetrieveFileOptions, ValidationItem, } from '@topconsultnpm/sdk-ts';
|
|
6
6
|
import TMModal from '../../base/TMModal';
|
|
7
7
|
import { useDeviceType } from '../../base/TMDeviceProvider';
|
|
8
8
|
import TMTextBox from '../../editors/TMTextBox';
|
|
@@ -18,10 +18,35 @@ import ShowAlert from '../../base/TMAlert';
|
|
|
18
18
|
import TMTooltip from '../../base/TMTooltip';
|
|
19
19
|
import MergePdfManager from '../../../helper/MergePdfManager';
|
|
20
20
|
import { TMResultManager } from '../../forms/TMResultDialog';
|
|
21
|
+
/**
|
|
22
|
+
* Converte il formato di visualizzazione fatture impostato dall'utente nel corrispondente formato PDF:
|
|
23
|
+
* il foglio di stile SDI resta SDI, in tutti gli altri casi si usa ASW.
|
|
24
|
+
*/
|
|
25
|
+
const toPdfInvoiceRetrieveFormat = (format) => {
|
|
26
|
+
switch (format) {
|
|
27
|
+
case InvoiceRetrieveFormats.SDI_HTML:
|
|
28
|
+
case InvoiceRetrieveFormats.SDI_PDF:
|
|
29
|
+
return InvoiceRetrieveFormats.SDI_PDF;
|
|
30
|
+
default:
|
|
31
|
+
return InvoiceRetrieveFormats.ASW_PDF;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Converte il formato di visualizzazione ordini impostato dall'utente nel corrispondente formato PDF:
|
|
36
|
+
* il foglio di stile NSO resta NSO, in tutti gli altri casi si usa ER.
|
|
37
|
+
*/
|
|
38
|
+
const toPdfOrderRetrieveFormat = (format) => {
|
|
39
|
+
switch (format) {
|
|
40
|
+
case OrderRetrieveFormats.NSO_HTML:
|
|
41
|
+
case OrderRetrieveFormats.NSO_PDF:
|
|
42
|
+
return OrderRetrieveFormats.NSO_PDF;
|
|
43
|
+
default:
|
|
44
|
+
return OrderRetrieveFormats.ER_PDF;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
21
47
|
/**
|
|
22
48
|
* Form per l'unione di più documenti PDF in un singolo file.
|
|
23
|
-
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
|
|
24
|
-
* con TMCopyToFolderForm.
|
|
49
|
+
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared con TMCopyToFolderForm.
|
|
25
50
|
*/
|
|
26
51
|
const TMMergeToPdfForm = (props) => {
|
|
27
52
|
const { mode, selectedDcmtInfos, selectedItemsFull, onClose, showTMRelationViewer, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers } = props;
|
|
@@ -169,8 +194,8 @@ const TMMergeToPdfForm = (props) => {
|
|
|
169
194
|
rfo.retrieveReason = DcmtOpers.None;
|
|
170
195
|
rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
|
|
171
196
|
rfo.cvtFormat = FileFormats.PDF;
|
|
172
|
-
rfo.invoiceRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat;
|
|
173
|
-
rfo.orderRetrieveFormat = SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat;
|
|
197
|
+
rfo.invoiceRetrieveFormat = toPdfInvoiceRetrieveFormat(SDKUI_Globals.userSettings?.searchSettings.invoiceRetrieveFormat);
|
|
198
|
+
rfo.orderRetrieveFormat = toPdfOrderRetrieveFormat(SDKUI_Globals.userSettings?.searchSettings.orderRetrieveFormat);
|
|
174
199
|
const collectFileForMerge = async (file, dcmtInfo) => {
|
|
175
200
|
pdfFilesMap.set(`${dcmtInfo.TID}_${dcmtInfo.DID}`, file);
|
|
176
201
|
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { DcmtTypeDescriptor, HomeBlogPost, ObjectRef, TaskDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
|
+
import { DcmtInfo, IGraphometricManagerProp, TaskContext } from "../../../ts";
|
|
4
|
+
import { IntesiCertificateData } from "../../../helper";
|
|
5
|
+
interface TMMultiMasterDetailDcmtsFormProps {
|
|
6
|
+
/** Tipo documento del master (per individuare le relazioni di dettaglio) */
|
|
7
|
+
dtd: DcmtTypeDescriptor;
|
|
8
|
+
/** Documento master da cui parte l'archiviazione dei dettagli */
|
|
9
|
+
masterDcmt: DcmtInfo;
|
|
10
|
+
/** Funzione per la chiusura del modale */
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
/** true se nella lista da cui è stato aperto il modale c'è un documento precedente/successivo */
|
|
13
|
+
canNavigateMaster?: (dir: 'next' | 'prev') => boolean;
|
|
14
|
+
/** Sposta il focus della lista di provenienza: il master del modale segue quel documento.
|
|
15
|
+
* Senza questa callback le frecce di navigazione non si mostrano */
|
|
16
|
+
onNavigateMaster?: (dir: 'next' | 'prev') => void;
|
|
17
|
+
allTasks?: Array<TaskDescriptor>;
|
|
18
|
+
getAllTasks?: () => Promise<void>;
|
|
19
|
+
deleteTaskByIdsCallback?: (deletedTaskIds: Array<number>) => Promise<void>;
|
|
20
|
+
addTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
21
|
+
editTaskCallback?: (task: TaskDescriptor) => Promise<void>;
|
|
22
|
+
handleNavigateToWGs?: (value: HomeBlogPost | number) => Promise<void>;
|
|
23
|
+
handleNavigateToDossiers?: (value: HomeBlogPost | number) => Promise<void>;
|
|
24
|
+
showDcmtFormSidebar?: boolean;
|
|
25
|
+
showTodoDcmtForm?: boolean;
|
|
26
|
+
openFileUploaderPdfEditor?: (fromDTD?: DcmtTypeDescriptor, file?: File | null, handleFile?: (file: File) => void) => void;
|
|
27
|
+
graphometricManager?: IGraphometricManagerProp;
|
|
28
|
+
editPdfForm?: boolean;
|
|
29
|
+
openS4TViewer?: boolean;
|
|
30
|
+
showToppyDraggableHelpCenter?: boolean;
|
|
31
|
+
toppyHelpCenterUsePortal?: boolean;
|
|
32
|
+
fetchRemoteCertificates?: (email: string) => Promise<IntesiCertificateData[]>;
|
|
33
|
+
onOpenS4TViewerRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: () => Promise<void>) => void;
|
|
34
|
+
onOpenPdfEditorRequest?: (dcmtInfo: Array<DcmtInfo>, refreshDocumentPreview?: () => Promise<void>) => void;
|
|
35
|
+
onReferenceClick?: (ref: ObjectRef) => void;
|
|
36
|
+
onTaskCreateRequest?: (taskContext: TaskContext, onTaskCreated?: (task?: TaskDescriptor) => void) => void;
|
|
37
|
+
onRefreshAfterAddDcmtToFavs?: () => void;
|
|
38
|
+
onFileOpened?: (blob: File | undefined) => void;
|
|
39
|
+
passToArchiveCallback?: (outputMids: Array<{
|
|
40
|
+
mid: number;
|
|
41
|
+
value: string;
|
|
42
|
+
}>, tid?: number) => void;
|
|
43
|
+
openWGsCopyMoveForm?: (mode: "copyToWgDraft" | "copyToWgArchivedDoc", dcmtTypeDescriptor: DcmtTypeDescriptor, documents: Array<DcmtInfo>) => void;
|
|
44
|
+
}
|
|
45
|
+
declare const TMMultiMasterDetailDcmtsForm: (props: TMMultiMasterDetailDcmtsFormProps) => React.JSX.Element | null;
|
|
46
|
+
export default TMMultiMasterDetailDcmtsForm;
|