@topconsultnpm/sdkui-react 6.22.0-dev2.2 → 6.22.0-dev2.20
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/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
- 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 +68 -4
- package/lib/components/base/TMEditorBase.d.ts +2 -0
- package/lib/components/base/TMModal.d.ts +4 -0
- package/lib/components/base/TMModal.js +42 -11
- package/lib/components/base/TMPanel.d.ts +1 -0
- package/lib/components/base/TMPanel.js +79 -20
- package/lib/components/base/TMTooltip.d.ts +2 -1
- package/lib/components/base/TMTooltip.js +23 -6
- 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 +12 -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/TMDropDown.d.ts +3 -0
- package/lib/components/editors/TMDropDown.js +197 -5
- package/lib/components/editors/TMMetadataEditor.d.ts +5 -1
- package/lib/components/editors/TMMetadataEditor.js +8 -3
- package/lib/components/editors/TMTextBox.js +15 -15
- package/lib/components/features/documents/TMBatchUpdateForm.js +19 -5
- package/lib/components/features/documents/TMDcmtForm.d.ts +7 -0
- package/lib/components/features/documents/TMDcmtForm.js +104 -42
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +11 -0
- package/lib/components/features/documents/TMDcmtFormActionButtons.js +74 -7
- package/lib/components/features/documents/TMMasterDetailDcmts.js +95 -33
- package/lib/components/features/documents/TMMasterInfoFields.d.ts +19 -0
- package/lib/components/features/documents/TMMasterInfoFields.js +172 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.d.ts +40 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +256 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +352 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +221 -0
- package/lib/components/features/documents/TMRelationViewer.d.ts +14 -1
- package/lib/components/features/documents/TMRelationViewer.js +69 -20
- package/lib/components/features/search/TMSearch.js +29 -16
- package/lib/components/features/search/TMSearchQueryEditor.js +5 -3
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -1
- package/lib/components/features/search/TMSearchQueryPanel.js +28 -7
- package/lib/components/features/search/TMSearchResult.d.ts +9 -0
- package/lib/components/features/search/TMSearchResult.js +323 -92
- package/lib/components/features/search/TMTreeSelector.js +18 -5
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +10 -0
- package/lib/components/features/workflow/TMWorkflowPopup.js +8 -4
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +24 -14
- package/lib/components/layout/panelManager/TMPanelWrapper.js +2 -2
- package/lib/components/layout/panelManager/types.d.ts +3 -0
- package/lib/components/viewers/TMMidViewer.js +4 -1
- package/lib/components/viewers/TMTidViewer.js +25 -11
- package/lib/helper/SDKUI_Globals.d.ts +55 -0
- package/lib/helper/SDKUI_Globals.js +82 -0
- package/lib/helper/SDKUI_Localizator.d.ts +23 -0
- package/lib/helper/SDKUI_Localizator.js +230 -0
- package/lib/helper/TMIcons.d.ts +1 -0
- package/lib/helper/TMIcons.js +3 -0
- 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 +20 -0
- package/lib/helper/helpers.js +40 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/helper/queryHelper.d.ts +2 -0
- package/lib/helper/queryHelper.js +3 -1
- 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 +2 -0
- package/lib/hooks/useDocumentOperations.js +28 -5
- package/lib/hooks/useMultiMasterDetailDcmts.d.ts +97 -0
- package/lib/hooks/useMultiMasterDetailDcmts.js +555 -0
- package/lib/hooks/useRelatedDocuments.js +2 -26
- 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 +1 -0
- package/lib/index.js +1 -0
- 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 +66 -66
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useMemo, useState } from "react";
|
|
3
|
+
import { LayoutModes } from "@topconsultnpm/sdk-ts";
|
|
4
|
+
import { LoadIndicator } from "devextreme-react/load-indicator";
|
|
5
|
+
import { SearchResultContext } from "../../../ts";
|
|
6
|
+
import { getFullFileExtension, getMultiDetailPanelStates, hasMultiDetailPanelStates, hoverStyle, IconArchive, IconDelete, IconDuplicate, IconEdit, IconEraser, IconMenuVertical, IconRefresh, IconSearch, IconSearchCheck, saveMultiDetailPanelStates, SDKUI_Localizator } from "../../../helper";
|
|
7
|
+
import { TMColors } from "../../../utils/theme";
|
|
8
|
+
import { TMLayoutWaitingContainer } from "../../base/TMWaitPanel";
|
|
9
|
+
import TMModal from "../../base/TMModal";
|
|
10
|
+
import TMDataGrid from "../../base/TMDataGrid";
|
|
11
|
+
import TMTooltip from "../../base/TMTooltip";
|
|
12
|
+
import { TMDcmtTypeIcon } from "../../viewers/TMTidViewer";
|
|
13
|
+
import { ContextMenu } from "../../NewComponents/ContextMenu";
|
|
14
|
+
import { TMPanelManagerWithPersistenceProvider } from "../../layout/panelManager/TMPanelManagerWithPersistenceProvider";
|
|
15
|
+
import TMPanelManagerContainer from "../../layout/panelManager/TMPanelManagerContainer";
|
|
16
|
+
import TMSearchResult from "../search/TMSearchResult";
|
|
17
|
+
import TMDcmtForm from "./TMDcmtForm";
|
|
18
|
+
import TMDcmtIcon from "./TMDcmtIcon";
|
|
19
|
+
import TMMasterInfoFields from "./TMMasterInfoFields";
|
|
20
|
+
import { MultiDetailArchivePhase, useMultiMasterDetailDcmts } from "../../../hooks/useMultiMasterDetailDcmts";
|
|
21
|
+
import { accordionStyles, getDtdDisplayName, INLINE_EDITABLE_CELL_CLASS, multiDetailStyles, PANEL_GUTTER_PX, renderAccordionHeader, renderSelectDcmtType, renderStepper, SECTION_HEADER_HEIGHT_PX, sectionPanelHeights, TMSectionPanelsHeights, TMSummarySectionSlot } from "./TMMultiMasterDetailDcmtsUtils";
|
|
22
|
+
// Stili delle sezioni in TMMultiMasterDetailDcmtsUtils (vedi accordionStyles e multiDetailStyles)
|
|
23
|
+
const styles = {
|
|
24
|
+
content: { display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 },
|
|
25
|
+
header: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '6px 12px', borderBottom: `1px solid ${TMColors.card_background}`, flexShrink: 0 },
|
|
26
|
+
// Opzioni nella barra del titolo: stesse misure e colore della chiusura DevExtreme (.dx-popup-title .dx-closebutton)
|
|
27
|
+
titleMenuIcon: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: '18px', height: '18px', margin: '1px 0 0', color: `var(--dx-color-text, ${TMColors.text_normal})`, cursor: 'pointer' },
|
|
28
|
+
loader: { display: 'flex', flex: 1, alignItems: 'center', justifyContent: 'center' },
|
|
29
|
+
summaryContainer: { display: 'flex', flexDirection: 'column', flex: 1, padding: '8px 12px 10px', minHeight: 0, gap: '8px' },
|
|
30
|
+
// I pannelli ripartiscono l'altezza in percentuale: serve un'altezza definita che non dipenda dal
|
|
31
|
+
// contenuto, da qui il riempimento in posizione assoluta dello spazio residuo
|
|
32
|
+
panelsHost: { position: 'relative', flex: 1, minHeight: 0, minWidth: 0 },
|
|
33
|
+
panelsHostFill: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, display: 'flex' },
|
|
34
|
+
gridWrapper: { position: 'relative', flex: 1, minHeight: 0 },
|
|
35
|
+
actionsCell: { display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '14px' },
|
|
36
|
+
actionIcon: { cursor: 'pointer', display: 'flex' },
|
|
37
|
+
fileCell: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },
|
|
38
|
+
fab: { position: 'absolute', bottom: '18px', right: '20px', width: '42px', height: '42px', borderRadius: '50%', backgroundColor: TMColors.button_floating_background, color: '#fff', border: 'none', cursor: 'pointer', boxShadow: '0 2px 6px rgba(0,0,0,0.2)', zIndex: 1000, transition: 'background-color 0.3s ease, transform 0.2s ease', display: 'flex', justifyContent: 'center', alignItems: 'center' },
|
|
39
|
+
footer: { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center', flexWrap: 'wrap', gap: '14px', paddingTop: '8px', borderTop: `1px solid ${TMColors.card_background}`, flexShrink: 0 },
|
|
40
|
+
footerLabel: { display: 'inline-flex', alignItems: 'center', gap: '8px', cursor: 'pointer', color: TMColors.label_normal, fontSize: '12px', userSelect: 'none', padding: '5px 10px', borderRadius: '16px', background: 'transparent', border: `1px solid ${TMColors.card_background}`, transition: 'all 0.15s ease' },
|
|
41
|
+
archiveButton: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: '8px', height: '38px', padding: '0 22px', border: 'none', borderRadius: '10px', fontSize: '14px', fontWeight: 600, letterSpacing: '0.2px', color: '#ffffff', cursor: 'pointer', transition: 'transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease' },
|
|
42
|
+
checkbox: { width: '16px', height: '16px', accentColor: TMColors.primary, cursor: 'pointer', margin: 0 },
|
|
43
|
+
};
|
|
44
|
+
const TMMultiMasterDetailDcmtsForm = (props) => {
|
|
45
|
+
const { dtd, masterDcmt, onClose, allTasks, getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, showDcmtFormSidebar, showTodoDcmtForm, openFileUploaderPdfEditor, graphometricManager, editPdfForm, openS4TViewer, showToppyDraggableHelpCenter, toppyHelpCenterUsePortal, fetchRemoteCertificates, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onReferenceClick, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, onFileOpened, passToArchiveCallback, openWGsCopyMoveForm } = props;
|
|
46
|
+
const { isLoading, isSummaryReady, phase, setPhase, detailRelationItems, selectedRelation, selectedItem, hasMultipleTypes, selectRelation, backToTypeSelection, isBackLocked, closeModal, sectionsOpen, setSectionOpen, clearLayout, layoutResetToken, canUpdateMaster, masterFieldsCount, getMasterMetadataAsync, masterInfoReloadToken, isOpenMasterForm, setIsOpenMasterForm, handleMasterSavedAsync, archivedDetailResults, archivedDetailsCount, isLoadingArchivedDetails, refreshArchivedDetailsAsync, detailColumns, detailSupportsFile, archiveRows, currentRows, focusedRowKey, setFocusedRowKey, selectedRowKeys, setSelectedRowKeys, isOpenAddForm, editingRowId, editingRow, formInputMids, openAddForm, openEditForm, closeAddForm, deleteRow, duplicateRow, upsertRow, updateRowValues, stopOnFirstError, setStopOnFirstError, isArchiving, archiveAllAsync, waitPanel, abortController, } = useMultiMasterDetailDcmts({ dtd, masterDcmt, onClose });
|
|
47
|
+
// Ricerca nella griglia dei dettagli da archiviare, come in TMSearch (vedi useDocumentOperations)
|
|
48
|
+
const [showGridSearch, setShowGridSearch] = useState(false);
|
|
49
|
+
const toggleGridSearchItem = {
|
|
50
|
+
name: showGridSearch ? SDKUI_Localizator.HideSearch : SDKUI_Localizator.ShowSearch,
|
|
51
|
+
icon: _jsx(IconSearch, { fontSize: 18 }),
|
|
52
|
+
beginGroup: true,
|
|
53
|
+
onClick: () => setShowGridSearch(prev => !prev),
|
|
54
|
+
};
|
|
55
|
+
const isSummaryPhase = phase === MultiDetailArchivePhase.ArchiveSummary;
|
|
56
|
+
const baseTitle = SDKUI_Localizator.ArchiveMultipleDetailDocuments;
|
|
57
|
+
// Con un solo tipo il nome è mostrato direttamente nel titolo del modale
|
|
58
|
+
const modalTitle = !hasMultipleTypes && selectedItem ? `${baseTitle}: ${getDtdDisplayName(selectedItem.detailDtd)}` : baseTitle;
|
|
59
|
+
const isArchiveDisabled = isArchiving || currentRows.length === 0;
|
|
60
|
+
const archiveButtonCaption = currentRows.length > 0
|
|
61
|
+
? `${SDKUI_Localizator.Archive} ${currentRows.length} ${currentRows.length === 1 ? 'dettaglio' : 'dettagli'}`
|
|
62
|
+
: SDKUI_Localizator.Archive;
|
|
63
|
+
const steps = [
|
|
64
|
+
...(hasMultipleTypes ? [{ phase: MultiDetailArchivePhase.SelectDcmtType, label: SDKUI_Localizator.DcmtType }] : []),
|
|
65
|
+
{
|
|
66
|
+
phase: MultiDetailArchivePhase.ArchiveSummary,
|
|
67
|
+
// Nel riepilogo lo step mostra il tipo selezionato (icona + nome)
|
|
68
|
+
label: selectedItem
|
|
69
|
+
? (_jsxs("span", { style: multiDetailStyles.stepTypeLabel, children: [_jsx(TMDcmtTypeIcon, { dtd: selectedItem.detailDtd }), _jsx("span", { style: multiDetailStyles.stepTypeLabelText, children: getDtdDisplayName(selectedItem.detailDtd) })] }))
|
|
70
|
+
: SDKUI_Localizator.Summary,
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
// Colonne della griglia: icona del documento, metadati del tipo, file e azioni
|
|
74
|
+
const gridColumns = useMemo(() => {
|
|
75
|
+
const iconColumn = {
|
|
76
|
+
caption: '', width: 50, alignment: 'center',
|
|
77
|
+
allowSorting: false, allowFiltering: false, allowResizing: false, allowReordering: false, allowHiding: false, allowEditing: false,
|
|
78
|
+
cellRender: (cell) => {
|
|
79
|
+
const file = cell.data?.__file;
|
|
80
|
+
return _jsx(TMDcmtIcon, { fileExtension: file ? getFullFileExtension(file.name) : undefined, fileCount: file ? 1 : 0, tooltipContent: file?.name });
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
const fileColumn = {
|
|
84
|
+
caption: 'File', width: 220, allowSorting: false, allowEditing: false,
|
|
85
|
+
cellRender: (cell) => {
|
|
86
|
+
const file = cell.data?.__file;
|
|
87
|
+
return _jsx("span", { style: { ...styles.fileCell, color: file ? TMColors.text_normal : TMColors.label_normal }, children: file ? file.name : '' });
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
const actionsColumn = {
|
|
91
|
+
caption: '', width: 110, alignment: 'center',
|
|
92
|
+
allowSorting: false, allowFiltering: false, allowHeaderFiltering: false, allowResizing: false,
|
|
93
|
+
allowReordering: false, allowHiding: false, showInColumnChooser: false, allowEditing: false,
|
|
94
|
+
cssClass: 'tm-row-actions',
|
|
95
|
+
cellRender: (cell) => (_jsxs("div", { style: styles.actionsCell, children: [_jsx("span", { style: styles.actionIcon, title: SDKUI_Localizator.Update, onClick: () => openEditForm(cell.data), children: _jsx(IconEdit, { fontSize: 18, color: TMColors.primary }) }), _jsx("span", { style: styles.actionIcon, title: SDKUI_Localizator.Duplicate, onClick: () => duplicateRow(cell.data), children: _jsx(IconDuplicate, { fontSize: 18, color: TMColors.tertiary }) }), _jsx("span", { style: styles.actionIcon, title: SDKUI_Localizator.Deletion, onClick: () => deleteRow(cell.data), children: _jsx(IconDelete, { fontSize: 18, color: TMColors.error }) })] })),
|
|
96
|
+
};
|
|
97
|
+
return [actionsColumn, iconColumn, ...detailColumns, ...(detailSupportsFile ? [fileColumn] : [])];
|
|
98
|
+
}, [detailColumns, detailSupportsFile]);
|
|
99
|
+
// ----- Griglia dei dettagli: opzioni e callback con identità stabile -------------------------
|
|
100
|
+
// Un nuovo riferimento a ogni render farebbe rifare a DevExtreme il setup di selezione/editing
|
|
101
|
+
const gridSelection = useMemo(() => ({ mode: 'single', showCheckBoxesMode: 'none' }), []);
|
|
102
|
+
const gridEditing = useMemo(() => ({
|
|
103
|
+
mode: 'cell', allowUpdating: true, allowAdding: false, allowDeleting: false, startEditAction: 'click', selectTextOnEditStart: true,
|
|
104
|
+
}), []);
|
|
105
|
+
const handleSelectionChanged = useCallback((e) => {
|
|
106
|
+
setSelectedRowKeys(e.selectedRowKeys ?? []);
|
|
107
|
+
}, [setSelectedRowKeys]);
|
|
108
|
+
const handleFocusedRowChanged = useCallback((e) => {
|
|
109
|
+
setFocusedRowKey(e.row?.key);
|
|
110
|
+
}, [setFocusedRowKey]);
|
|
111
|
+
const handleRowUpdating = useCallback((e) => {
|
|
112
|
+
updateRowValues(e.key, e.newData);
|
|
113
|
+
}, [updateRowValues]);
|
|
114
|
+
// Il doppio clic apre il form della riga, tranne su azioni e celle modificabili in linea
|
|
115
|
+
const handleCellDblClick = useCallback((e) => {
|
|
116
|
+
if (e.rowType !== 'data')
|
|
117
|
+
return;
|
|
118
|
+
const cssClass = e.column?.cssClass ?? '';
|
|
119
|
+
if (cssClass === 'tm-row-actions' || cssClass === INLINE_EDITABLE_CELL_CLASS)
|
|
120
|
+
return;
|
|
121
|
+
openEditForm(e.data);
|
|
122
|
+
}, [openEditForm]);
|
|
123
|
+
// Menu contestuale con le stesse azioni della colonna
|
|
124
|
+
const contextMenuItems = useMemo(() => [
|
|
125
|
+
{ name: SDKUI_Localizator.Update, icon: _jsx(IconEdit, { fontSize: 18, color: TMColors.primary }), operationType: 'singleRow', onClick: (id) => openEditForm(archiveRows.find(r => r.id === id)) },
|
|
126
|
+
{ name: SDKUI_Localizator.Duplicate, icon: _jsx(IconDuplicate, { fontSize: 18, color: TMColors.tertiary }), operationType: 'singleRow', onClick: (id) => duplicateRow(archiveRows.find(r => r.id === id)) },
|
|
127
|
+
{ name: SDKUI_Localizator.Deletion, icon: _jsx(IconDelete, { fontSize: 18, color: TMColors.error }), operationType: 'singleRow', beginGroup: true, onClick: (id) => deleteRow(archiveRows.find(r => r.id === id)) },
|
|
128
|
+
toggleGridSearchItem,
|
|
129
|
+
], [archiveRows, showGridSearch]);
|
|
130
|
+
// Menu delle opzioni del modale, aperto dal pulsante a tre punti nella barra del titolo
|
|
131
|
+
const optionsMenuItems = useMemo(() => [
|
|
132
|
+
{ name: 'Cancella layout', icon: _jsx(IconEraser, { fontSize: 18, color: TMColors.error }), onClick: clearLayout },
|
|
133
|
+
], [clearLayout]);
|
|
134
|
+
// Le opzioni riguardano i pannelli del riepilogo: fuori da quella fase non hanno effetto
|
|
135
|
+
const renderOptionsMenu = () => {
|
|
136
|
+
if (!isSummaryPhase)
|
|
137
|
+
return undefined;
|
|
138
|
+
return (_jsx(ContextMenu, { trigger: 'left', items: optionsMenuItems, children: _jsx("span", { style: styles.titleMenuIcon, title: SDKUI_Localizator.Options, "aria-label": SDKUI_Localizator.Options, children: _jsx(IconMenuVertical, { fontSize: 16, color: "white" }) }) }));
|
|
139
|
+
};
|
|
140
|
+
// ----- Sezione: informazioni del master -----------------------------------------------------
|
|
141
|
+
const renderMasterInfo = (panel) => {
|
|
142
|
+
const isOpen = sectionsOpen.masterInfo;
|
|
143
|
+
const editMasterButton = canUpdateMaster
|
|
144
|
+
? (_jsx("button", { type: 'button', onClick: (e) => { e.stopPropagation(); setIsOpenMasterForm(true); }, style: accordionStyles.accordionExpandBtn, title: `${SDKUI_Localizator.Update}: ${getDtdDisplayName(dtd)}`, ...hoverStyle({ background: TMColors.primary_container, color: TMColors.primary }, { background: 'transparent', color: TMColors.label_normal }), children: _jsx(IconEdit, { fontSize: 16 }) }))
|
|
145
|
+
: undefined;
|
|
146
|
+
return (_jsxs("div", { style: { ...accordionStyles.accordion, ...accordionStyles.accordionInPanel }, children: [renderAccordionHeader({
|
|
147
|
+
section: 'masterInfo',
|
|
148
|
+
isOpen,
|
|
149
|
+
tooltip: isOpen ? SDKUI_Localizator.HideMasterInfo : SDKUI_Localizator.ShowMasterInfo,
|
|
150
|
+
count: masterFieldsCount,
|
|
151
|
+
title: (_jsxs(_Fragment, { children: [_jsx(TMDcmtTypeIcon, { dtd: dtd }), _jsxs("span", { style: multiDetailStyles.stepTypeLabelText, children: ["Master: ", getDtdDisplayName(dtd)] })] })),
|
|
152
|
+
actions: editMasterButton,
|
|
153
|
+
panel,
|
|
154
|
+
onToggleOpen: setSectionOpen,
|
|
155
|
+
}), isOpen && (_jsx(TMMasterInfoFields, { dtd: dtd, dcmt: masterDcmt, getValuesByMidAsync: getMasterMetadataAsync, reloadToken: masterInfoReloadToken, isExpandedView: panel.isMaximized }))] }));
|
|
156
|
+
};
|
|
157
|
+
// ----- Sezione: dettagli già archiviati -----------------------------------------------------
|
|
158
|
+
const renderArchivedDetails = (panel) => {
|
|
159
|
+
const isOpen = sectionsOpen.archivedDetails;
|
|
160
|
+
const hasResults = archivedDetailResults.length > 0 && archivedDetailsCount > 0;
|
|
161
|
+
// Ricarica i dettagli già archiviati: la sezione va aperta, altrimenti l'esito non sarebbe visibile
|
|
162
|
+
const refreshArchivedButton = (_jsx("button", { type: 'button', onClick: (e) => { e.stopPropagation(); setSectionOpen('archivedDetails', true); refreshArchivedDetailsAsync(); }, disabled: isLoadingArchivedDetails, style: { ...accordionStyles.accordionExpandBtn, ...(isLoadingArchivedDetails ? { cursor: 'default', opacity: 0.5 } : {}) }, title: SDKUI_Localizator.Refresh, "aria-label": SDKUI_Localizator.Refresh, ...(isLoadingArchivedDetails ? {} : hoverStyle({ background: TMColors.primary_container, color: TMColors.primary }, { background: 'transparent', color: TMColors.label_normal })), children: _jsx(IconRefresh, { fontSize: 16 }) }));
|
|
163
|
+
return (_jsxs("div", { style: { ...accordionStyles.accordion, ...accordionStyles.accordionInPanel }, children: [renderAccordionHeader({
|
|
164
|
+
section: 'archivedDetails',
|
|
165
|
+
isOpen,
|
|
166
|
+
tooltip: isOpen ? SDKUI_Localizator.HideArchivedDetails : SDKUI_Localizator.ShowArchivedDetails,
|
|
167
|
+
count: archivedDetailsCount,
|
|
168
|
+
title: (_jsxs(_Fragment, { children: [_jsx(IconSearchCheck, { fontSize: 15 }), _jsx("span", { style: multiDetailStyles.stepTypeLabelText, children: SDKUI_Localizator.ArchivedDetails })] })),
|
|
169
|
+
actions: refreshArchivedButton,
|
|
170
|
+
panel,
|
|
171
|
+
onToggleOpen: setSectionOpen,
|
|
172
|
+
}), isOpen && (_jsx("div", { style: { ...accordionStyles.accordionListBody, ...(panel.isMaximized ? { borderTop: 'none' } : {}) }, children: isLoadingArchivedDetails
|
|
173
|
+
? _jsxs("div", { style: accordionStyles.accordionListPlaceholder, children: [_jsx(LoadIndicator, { height: 30, width: 30 }), SDKUI_Localizator.Loading] })
|
|
174
|
+
: (hasResults
|
|
175
|
+
? _jsx(TMSearchResult, { showToolbarHeader: false, showCounterConfig: false, showActionsColumn: true, compactPager: !panel.isMaximized, context: SearchResultContext.METADATA_SEARCH, searchResults: archivedDetailResults, onClose: () => setSectionOpen('archivedDetails', false), showBackButton: false, showToolbarCloseButton: false, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, showSearchResultSidebar: false, showDcmtFormSidebar: true, autoFocusFirstRow: false, onRefreshSearchAsyncDatagrid: refreshArchivedDetailsAsync, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, showTodoDcmtForm: showTodoDcmtForm, openFileUploaderPdfEditor: openFileUploaderPdfEditor, graphometricManager: graphometricManager, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, showToppyDraggableHelpCenter: showToppyDraggableHelpCenter, toppyHelpCenterUsePortal: toppyHelpCenterUsePortal, fetchRemoteCertificates: fetchRemoteCertificates, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onReferenceClick: onReferenceClick, onTaskCreateRequest: onTaskCreateRequest, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, onFileOpened: onFileOpened, passToArchiveCallback: passToArchiveCallback, openWGsCopyMoveForm: openWGsCopyMoveForm })
|
|
176
|
+
: _jsx("div", { style: accordionStyles.accordionListPlaceholder, children: SDKUI_Localizator.NoDataToDisplay })) }))] }));
|
|
177
|
+
};
|
|
178
|
+
// ----- Sezione: dettagli da archiviare ------------------------------------------------------
|
|
179
|
+
const renderArchiveList = (panel) => {
|
|
180
|
+
const isOpen = sectionsOpen.archiveList;
|
|
181
|
+
return (_jsxs("div", { style: { ...accordionStyles.accordion, ...accordionStyles.accordionInPanel }, children: [renderAccordionHeader({
|
|
182
|
+
section: 'archiveList',
|
|
183
|
+
isOpen,
|
|
184
|
+
tooltip: isOpen ? SDKUI_Localizator.HideDetailsToArchive : SDKUI_Localizator.ShowDetailsToArchive,
|
|
185
|
+
count: currentRows.length,
|
|
186
|
+
title: (_jsxs(_Fragment, { children: [_jsx(IconArchive, { fontSize: 15 }), _jsx("span", { style: multiDetailStyles.stepTypeLabelText, children: SDKUI_Localizator.DetailsToArchive })] })),
|
|
187
|
+
panel,
|
|
188
|
+
onToggleOpen: setSectionOpen,
|
|
189
|
+
}), isOpen && (_jsxs("div", { style: { ...styles.gridWrapper, ...(panel.isMaximized ? {} : { borderTop: `1px solid ${TMColors.card_background}` }) }, children: [_jsx(TMDataGrid, { dataColumns: gridColumns, dataSource: currentRows, keyExpr: "id", height: "100%", showSearchPanel: showGridSearch, showGroupPanel: false, showFilterPanel: false, showHeaderFilter: true, selection: gridSelection, selectedRowKeys: selectedRowKeys, onSelectionChanged: handleSelectionChanged, focusedRowKey: focusedRowKey, onFocusedRowChanged: handleFocusedRowChanged, onCellDblClick: handleCellDblClick, editing: gridEditing, onRowUpdating: handleRowUpdating, customContextMenuItems: contextMenuItems }), _jsx("button", { type: "button", onClick: openAddForm, style: styles.fab, ...hoverStyle({ backgroundColor: '#D94A9F', transform: 'scale(1.1)', boxShadow: '0 4px 12px rgba(37, 89, 165, 0.6)' }, { backgroundColor: TMColors.button_floating_background, transform: 'scale(1)', boxShadow: '0 2px 6px rgba(0,0,0,0.2)' }), children: _jsx(TMTooltip, { content: SDKUI_Localizator.Add, children: _jsx("i", { className: "dx-icon-add", style: { fontSize: '22px' } }) }) })] }))] }));
|
|
190
|
+
};
|
|
191
|
+
// ----- Pannelli del riepilogo, uno per sezione ----------------------------------------------
|
|
192
|
+
const renderSectionsInPanels = () => {
|
|
193
|
+
const definitions = [
|
|
194
|
+
{ section: 'masterInfo', name: `Master: ${getDtdDisplayName(dtd)}`, render: renderMasterInfo },
|
|
195
|
+
...(selectedRelation?.detailTID !== undefined
|
|
196
|
+
? [{ section: 'archivedDetails', name: SDKUI_Localizator.ArchivedDetails, render: renderArchivedDetails }]
|
|
197
|
+
: []),
|
|
198
|
+
{ section: 'archiveList', name: SDKUI_Localizator.DetailsToArchive, render: renderArchiveList },
|
|
199
|
+
];
|
|
200
|
+
const panels = definitions.map(definition => ({
|
|
201
|
+
id: definition.section,
|
|
202
|
+
name: definition.name,
|
|
203
|
+
currentGroupDirection: 'vertical',
|
|
204
|
+
contentOptions: {
|
|
205
|
+
// Ingrandire una sezione collassata la apre: altrimenti il pannello a tutto schermo sarebbe vuoto
|
|
206
|
+
component: _jsx(TMSummarySectionSlot, { section: definition.section, render: definition.render, onBeforeMaximize: (section) => setSectionOpen(section, true) }),
|
|
207
|
+
// Una sezione chiusa vale 0% di altezza: è questo minimo a tenerne a schermo la testata
|
|
208
|
+
minHeight: `${SECTION_HEADER_HEIGHT_PX}px`,
|
|
209
|
+
// La sezione collassata è alta quanto la sua testata: i separatori non la ingrandiscono
|
|
210
|
+
isCollapsed: !sectionsOpen[definition.section],
|
|
211
|
+
},
|
|
212
|
+
}));
|
|
213
|
+
const sections = panels.map(panel => panel.id);
|
|
214
|
+
// Le altezze salvate sono il punto di partenza, ma è il collasso corrente a decidere le quote
|
|
215
|
+
const savedStates = getMultiDetailPanelStates();
|
|
216
|
+
const savedDimensions = hasMultiDetailPanelStates()
|
|
217
|
+
? sections.reduce((acc, section) => {
|
|
218
|
+
if (savedStates[section])
|
|
219
|
+
acc[section] = { width: savedStates[section].width, height: savedStates[section].height };
|
|
220
|
+
return acc;
|
|
221
|
+
}, {})
|
|
222
|
+
: undefined;
|
|
223
|
+
const initialDimensions = sectionPanelHeights(sections, sectionsOpen, savedDimensions);
|
|
224
|
+
const initialVisibility = sections.reduce((acc, section) => { acc[section] = true; return acc; }, {});
|
|
225
|
+
return (_jsx("div", { style: styles.panelsHost, children: _jsx("div", { style: styles.panelsHostFill, children: _jsxs(TMPanelManagerWithPersistenceProvider
|
|
226
|
+
// Le dimensioni sono lette solo al montaggio: dopo la cancellazione del layout i pannelli vanno rimontati
|
|
227
|
+
, { panels: panels, initialVisibility: initialVisibility, defaultDimensions: initialDimensions, initialDimensions: initialDimensions, initialMobilePanelId: 'archiveList', isPersistenceEnabled: true, persistPanelStates: saveMultiDetailPanelStates, children: [_jsx(TMSectionPanelsHeights, { sections: sections, sectionsOpen: sectionsOpen }), _jsx(TMPanelManagerContainer, { panels: panels, direction: 'vertical', showToolbar: false, minPanelSizePx: SECTION_HEADER_HEIGHT_PX, gutterSizePx: PANEL_GUTTER_PX })] }, layoutResetToken) }) }));
|
|
228
|
+
};
|
|
229
|
+
const renderArchiveSummary = () => (_jsxs("div", { style: styles.summaryContainer, children: [renderSectionsInPanels(), _jsxs("div", { style: styles.footer, children: [_jsxs("label", { style: styles.footerLabel, ...hoverStyle({ borderColor: TMColors.primary, color: TMColors.text_normal }, { borderColor: TMColors.card_background, color: TMColors.label_normal }), children: [_jsx("input", { type: "checkbox", checked: stopOnFirstError, onChange: (e) => setStopOnFirstError(e.target.checked), style: styles.checkbox }), "Ferma l'archiviazione al primo errore"] }), _jsxs("button", { type: "button", onClick: archiveAllAsync, disabled: isArchiveDisabled, style: {
|
|
230
|
+
...styles.archiveButton,
|
|
231
|
+
background: isArchiveDisabled ? TMColors.disabled : TMColors.success,
|
|
232
|
+
boxShadow: isArchiveDisabled ? 'none' : `0 4px 14px ${TMColors.success}55`,
|
|
233
|
+
cursor: isArchiveDisabled ? 'default' : 'pointer',
|
|
234
|
+
opacity: isArchiveDisabled ? 0.6 : 1,
|
|
235
|
+
}, ...(isArchiveDisabled ? {} : hoverStyle({ transform: 'translateY(-2px)', boxShadow: `0 6px 20px ${TMColors.success}77`, filter: 'brightness(1.06)' }, { transform: 'translateY(0)', boxShadow: `0 4px 14px ${TMColors.success}55`, filter: 'brightness(1)' })), children: [_jsx(IconArchive, {}), archiveButtonCaption] })] })] }));
|
|
236
|
+
// ----- Render principale --------------------------------------------------------------------
|
|
237
|
+
if (isLoading)
|
|
238
|
+
return null;
|
|
239
|
+
return _jsxs(_Fragment, { children: [_jsx(TMLayoutWaitingContainer, { direction: 'vertical', ...waitPanel, isCancelable: true, abortController: abortController, usePortal: true, children: _jsx(TMModal, { width: isSummaryPhase ? '95%' : '720px', height: isSummaryPhase ? '95%' : 'auto', onClose: closeModal, title: modalTitle, hidePopup: false, askClosingConfirm: archiveRows.length > 0, recenterOnResize: true, titleActions: renderOptionsMenu(), children: _jsxs("div", { style: styles.content, children: [hasMultipleTypes && _jsx("div", { style: styles.header, children: renderStepper({
|
|
240
|
+
steps,
|
|
241
|
+
phase,
|
|
242
|
+
hasMultipleTypes,
|
|
243
|
+
isBackLocked,
|
|
244
|
+
showBackArrow: isSummaryPhase,
|
|
245
|
+
onBack: backToTypeSelection,
|
|
246
|
+
onStepClick: (stepPhase) => (stepPhase === MultiDetailArchivePhase.SelectDcmtType ? backToTypeSelection() : setPhase(stepPhase)),
|
|
247
|
+
}) }), !isSummaryPhase
|
|
248
|
+
? renderSelectDcmtType({ detailRelationItems, selectedRelation, onSelectRelation: selectRelation })
|
|
249
|
+
: (isSummaryReady
|
|
250
|
+
? renderArchiveSummary()
|
|
251
|
+
: _jsx("div", { style: styles.loader, children: _jsx(LoadIndicator, { height: 40, width: 40 }) }))] }) }) }), isOpenAddForm && selectedRelation?.detailTID && (_jsx(TMDcmtForm, { isModal: true, titleModal: getDtdDisplayName(selectedItem?.detailDtd), TID: selectedRelation.detailTID, layoutMode: LayoutModes.Ark, showBackButton: false, allowButtonsRefs: false, inputMids: formInputMids, inputFile: editingRow?.__file ?? null, archiveListMode: {
|
|
252
|
+
isEditingRow: editingRowId !== undefined,
|
|
253
|
+
onUpsertRow: (values, file) => upsertRow(values, file),
|
|
254
|
+
}, onClose: closeAddForm, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, showDcmtFormSidebar: showDcmtFormSidebar, showTodoDcmtForm: showTodoDcmtForm, openFileUploaderPdfEditor: openFileUploaderPdfEditor, graphometricManager: graphometricManager })), isOpenMasterForm && masterDcmt?.TID !== undefined && masterDcmt?.DID !== undefined && (_jsx(TMDcmtForm, { isModal: true, titleModal: `${SDKUI_Localizator.Update}: ${getDtdDisplayName(dtd)}`, TID: masterDcmt.TID, DID: masterDcmt.DID, layoutMode: LayoutModes.Update, showBackButton: false, allowRelations: false, allowButtonsRefs: false, onSavedAsyncCallback: handleMasterSavedAsync, onClose: () => setIsOpenMasterForm(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, onTaskCreateRequest: onTaskCreateRequest, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, showDcmtFormSidebar: showDcmtFormSidebar, showTodoDcmtForm: showTodoDcmtForm, openFileUploaderPdfEditor: openFileUploaderPdfEditor, graphometricManager: graphometricManager, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, fetchRemoteCertificates: fetchRemoteCertificates, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onReferenceClick: onReferenceClick }))] });
|
|
255
|
+
};
|
|
256
|
+
export default TMMultiMasterDetailDcmtsForm;
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DataListViewModes, DcmtTypeDescriptor, MetadataDescriptor, RelationDescriptor } from '@topconsultnpm/sdk-ts';
|
|
3
|
+
import { DataGridTypes, IColumnProps } from 'devextreme-react/data-grid';
|
|
4
|
+
import { TMPanelDimensionsMap } from '../../layout/panelManager/types';
|
|
5
|
+
import { DcmtInfo, MetadataValueDescriptorEx } from '../../../ts';
|
|
6
|
+
/** Relazione di dettaglio con il relativo tipo documento */
|
|
7
|
+
export interface DetailRelationItem {
|
|
8
|
+
relation: RelationDescriptor;
|
|
9
|
+
detailDtd: DcmtTypeDescriptor | undefined;
|
|
10
|
+
}
|
|
11
|
+
export interface MultiDetailStep {
|
|
12
|
+
phase: number;
|
|
13
|
+
label: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export type AccordionSection = 'masterInfo' | 'archivedDetails' | 'archiveList';
|
|
16
|
+
/**
|
|
17
|
+
* Stato del pannello che ospita una sezione. Lo espone il panel manager, il cui contesto è leggibile
|
|
18
|
+
* solo dentro l'albero del provider: da qui passa alle testate (vedi TMSummarySectionSlot)
|
|
19
|
+
*/
|
|
20
|
+
export type SectionPanelState = {
|
|
21
|
+
isMaximized: boolean;
|
|
22
|
+
toggleMaximize: () => void;
|
|
23
|
+
};
|
|
24
|
+
/** Valore di un metadato letto da un documento: una cella del risultato di ricerca */
|
|
25
|
+
export type MetadataScalarValue = string | number | boolean | Date | null | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Riga del riepilogo: oltre ai campi di servizio (prefisso `__`) porta i valori dei metadati
|
|
28
|
+
* indicizzati per mid (`String(mid)`), come richiesto dal dataField delle colonne della griglia
|
|
29
|
+
*/
|
|
30
|
+
export interface ArchiveRow {
|
|
31
|
+
/** Chiave della riga in griglia */
|
|
32
|
+
id: number;
|
|
33
|
+
/** Tipo documento di dettaglio a cui appartiene la riga */
|
|
34
|
+
__tid: number;
|
|
35
|
+
/** Valori compilati nel form, nel formato richiesto dall'archiviazione */
|
|
36
|
+
__values: Array<MetadataValueDescriptorEx>;
|
|
37
|
+
/** File da archiviare, se il tipo documento lo prevede */
|
|
38
|
+
__file?: File;
|
|
39
|
+
/** Valore del metadato mostrato in colonna, indicizzato per mid */
|
|
40
|
+
[mid: string]: string | number | Array<MetadataValueDescriptorEx> | File | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Cella nel render delle colonne del riepilogo: i valori dei metadati arrivano dal form come
|
|
44
|
+
* stringhe, quindi il `value` generico di DevExtreme si restringe
|
|
45
|
+
*/
|
|
46
|
+
export type ArchiveRowCell = Omit<DataGridTypes.ColumnCellTemplateData<ArchiveRow, number>, 'value'> & {
|
|
47
|
+
readonly value?: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Modifiche di una riga in arrivo dalla griglia (mid -> nuovo valore): in modifica diretta ci sono
|
|
51
|
+
* solo i metadati testuali (vedi isInlineEditableMetadata) e l'editor svuotato restituisce null
|
|
52
|
+
*/
|
|
53
|
+
export type ArchiveRowChanges = Record<string, string | null | undefined>;
|
|
54
|
+
/** Aggiornamento di una riga della griglia, con le sole modifiche possibili in linea */
|
|
55
|
+
export type ArchiveRowUpdatingEvent = Omit<DataGridTypes.RowUpdatingEvent<ArchiveRow, number>, 'newData'> & {
|
|
56
|
+
newData: ArchiveRowChanges;
|
|
57
|
+
};
|
|
58
|
+
export declare const SECTION_WEIGHTS: Record<AccordionSection, number>;
|
|
59
|
+
export declare const SECTION_HEADER_HEIGHT_PX = 30;
|
|
60
|
+
export declare const PANEL_GUTTER_PX = 10;
|
|
61
|
+
/** Il master è modificabile solo se il tipo documento lo consente */
|
|
62
|
+
export declare const canUpdateMasterCallback: (dtd?: DcmtTypeDescriptor, masterDcmt?: DcmtInfo) => boolean;
|
|
63
|
+
/** Permesso di archiviazione sul tipo documento di dettaglio */
|
|
64
|
+
export declare const canArchive: (dtd?: DcmtTypeDescriptor) => boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Marcatore delle celle modificabili direttamente in griglia: il doppio clic le porta in modifica,
|
|
67
|
+
* quindi non deve aprire anche il form della riga
|
|
68
|
+
*/
|
|
69
|
+
export declare const INLINE_EDITABLE_CELL_CLASS = "tm-cell-inline-editable";
|
|
70
|
+
/**
|
|
71
|
+
* Modifica diretta in griglia: solo il testo libero. Liste dati, calcolati, numeratori e speciali
|
|
72
|
+
* hanno editor e vincoli propri, date e numeri una formattazione dedicata: restano al form
|
|
73
|
+
*/
|
|
74
|
+
export declare const isInlineEditableMetadata: (md: MetadataDescriptor) => boolean;
|
|
75
|
+
/** Colonne della griglia di riepilogo dai metadati (utente) del tipo documento */
|
|
76
|
+
export declare const buildColumnsFromDtd: (dtd: DcmtTypeDescriptor | undefined, renderDataListCell: (value: string | Date | number | undefined, dataListID: number, viewMode: DataListViewModes) => React.ReactElement) => Array<IColumnProps>;
|
|
77
|
+
export declare const getDetailDtdAsync: (detailTID: number | undefined) => Promise<DcmtTypeDescriptor | undefined>;
|
|
78
|
+
/** Nome visualizzato del tipo documento (localizzato se richiesto) */
|
|
79
|
+
export declare const getDtdDisplayName: (dtd: DcmtTypeDescriptor | undefined) => string;
|
|
80
|
+
/** Messaggio del blocco: con righe inserite il tipo documento non è più modificabile */
|
|
81
|
+
export declare const getBackLockedTitle: () => string;
|
|
82
|
+
/**
|
|
83
|
+
* Altezze dei pannelli impilati a partire dalle sezioni aperte:
|
|
84
|
+
* una sezione chiusa vale 0% e resta a schermo con la sola testata
|
|
85
|
+
* le aperte si spartiscono tutto lo spazio
|
|
86
|
+
*/
|
|
87
|
+
export declare const sectionPanelHeights: (sections: Array<AccordionSection>, sectionsOpen: Record<AccordionSection, boolean>, currentDimensions?: TMPanelDimensionsMap) => TMPanelDimensionsMap;
|
|
88
|
+
export declare const multiDetailStyles: {
|
|
89
|
+
stepper: {
|
|
90
|
+
display: "flex";
|
|
91
|
+
alignItems: "center";
|
|
92
|
+
justifyContent: "center";
|
|
93
|
+
gap: string;
|
|
94
|
+
};
|
|
95
|
+
backArrow: {
|
|
96
|
+
display: "flex";
|
|
97
|
+
alignItems: "center";
|
|
98
|
+
justifyContent: "center";
|
|
99
|
+
width: string;
|
|
100
|
+
height: string;
|
|
101
|
+
borderRadius: string;
|
|
102
|
+
border: string;
|
|
103
|
+
color: string;
|
|
104
|
+
cursor: "pointer";
|
|
105
|
+
marginRight: string;
|
|
106
|
+
transition: "all 0.18s ease";
|
|
107
|
+
};
|
|
108
|
+
stepPill: {
|
|
109
|
+
display: "flex";
|
|
110
|
+
alignItems: "center";
|
|
111
|
+
gap: string;
|
|
112
|
+
padding: string;
|
|
113
|
+
borderRadius: string;
|
|
114
|
+
transition: "all 0.18s ease";
|
|
115
|
+
};
|
|
116
|
+
stepCircle: {
|
|
117
|
+
width: string;
|
|
118
|
+
height: string;
|
|
119
|
+
borderRadius: string;
|
|
120
|
+
color: "#ffffff";
|
|
121
|
+
display: "flex";
|
|
122
|
+
alignItems: "center";
|
|
123
|
+
justifyContent: "center";
|
|
124
|
+
fontSize: string;
|
|
125
|
+
fontWeight: number;
|
|
126
|
+
flexShrink: number;
|
|
127
|
+
transition: "all 0.18s ease";
|
|
128
|
+
};
|
|
129
|
+
stepLabel: {
|
|
130
|
+
fontSize: string;
|
|
131
|
+
whiteSpace: "nowrap";
|
|
132
|
+
display: "flex";
|
|
133
|
+
alignItems: "center";
|
|
134
|
+
};
|
|
135
|
+
stepConnector: {
|
|
136
|
+
width: string;
|
|
137
|
+
height: string;
|
|
138
|
+
margin: string;
|
|
139
|
+
borderRadius: string;
|
|
140
|
+
flexShrink: number;
|
|
141
|
+
};
|
|
142
|
+
stepTypeLabel: {
|
|
143
|
+
display: "flex";
|
|
144
|
+
alignItems: "center";
|
|
145
|
+
gap: string;
|
|
146
|
+
maxWidth: string;
|
|
147
|
+
};
|
|
148
|
+
stepTypeLabelText: {
|
|
149
|
+
overflow: "hidden";
|
|
150
|
+
textOverflow: "ellipsis";
|
|
151
|
+
whiteSpace: "nowrap";
|
|
152
|
+
};
|
|
153
|
+
selectContainer: {
|
|
154
|
+
display: "flex";
|
|
155
|
+
flexDirection: "column";
|
|
156
|
+
alignItems: "center";
|
|
157
|
+
flex: number;
|
|
158
|
+
gap: string;
|
|
159
|
+
overflow: "auto";
|
|
160
|
+
padding: string;
|
|
161
|
+
};
|
|
162
|
+
selectTitle: {
|
|
163
|
+
fontSize: string;
|
|
164
|
+
fontWeight: number;
|
|
165
|
+
color: string;
|
|
166
|
+
textAlign: "center";
|
|
167
|
+
marginBottom: string;
|
|
168
|
+
};
|
|
169
|
+
selectList: {
|
|
170
|
+
display: "flex";
|
|
171
|
+
flexDirection: "column";
|
|
172
|
+
gap: string;
|
|
173
|
+
width: string;
|
|
174
|
+
maxWidth: string;
|
|
175
|
+
};
|
|
176
|
+
typeCard: {
|
|
177
|
+
display: "flex";
|
|
178
|
+
alignItems: "center";
|
|
179
|
+
gap: string;
|
|
180
|
+
padding: string;
|
|
181
|
+
borderRadius: string;
|
|
182
|
+
cursor: "pointer";
|
|
183
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.06)";
|
|
184
|
+
transition: "all 0.15s ease";
|
|
185
|
+
};
|
|
186
|
+
typeCardIcon: {
|
|
187
|
+
width: string;
|
|
188
|
+
height: string;
|
|
189
|
+
borderRadius: string;
|
|
190
|
+
background: string;
|
|
191
|
+
display: "flex";
|
|
192
|
+
alignItems: "center";
|
|
193
|
+
justifyContent: "center";
|
|
194
|
+
flexShrink: number;
|
|
195
|
+
};
|
|
196
|
+
typeCardName: {
|
|
197
|
+
flex: number;
|
|
198
|
+
fontSize: string;
|
|
199
|
+
fontWeight: number;
|
|
200
|
+
color: string;
|
|
201
|
+
whiteSpace: "normal";
|
|
202
|
+
wordBreak: "break-word";
|
|
203
|
+
lineHeight: number;
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
/** Stili delle sezioni collassabili: qui perché la testata comune (renderAccordionHeader) vive in questo file */
|
|
207
|
+
export declare const accordionStyles: {
|
|
208
|
+
accordion: {
|
|
209
|
+
display: "flex";
|
|
210
|
+
flexDirection: "column";
|
|
211
|
+
minHeight: number;
|
|
212
|
+
borderRadius: string;
|
|
213
|
+
border: string;
|
|
214
|
+
background: string;
|
|
215
|
+
overflow: "hidden";
|
|
216
|
+
};
|
|
217
|
+
accordionInPanel: {
|
|
218
|
+
flex: number;
|
|
219
|
+
};
|
|
220
|
+
accordionHeader: {
|
|
221
|
+
display: "flex";
|
|
222
|
+
alignItems: "center";
|
|
223
|
+
gap: string;
|
|
224
|
+
padding: string;
|
|
225
|
+
cursor: "pointer";
|
|
226
|
+
userSelect: "none";
|
|
227
|
+
transition: "background 0.15s ease";
|
|
228
|
+
outline: string;
|
|
229
|
+
flexShrink: number;
|
|
230
|
+
minHeight: string;
|
|
231
|
+
};
|
|
232
|
+
accordionTitle: {
|
|
233
|
+
flex: number;
|
|
234
|
+
fontSize: string;
|
|
235
|
+
fontWeight: number;
|
|
236
|
+
color: string;
|
|
237
|
+
display: "flex";
|
|
238
|
+
alignItems: "center";
|
|
239
|
+
gap: string;
|
|
240
|
+
minWidth: number;
|
|
241
|
+
};
|
|
242
|
+
accordionBadge: {
|
|
243
|
+
display: "inline-flex";
|
|
244
|
+
alignItems: "center";
|
|
245
|
+
justifyContent: "center";
|
|
246
|
+
minWidth: string;
|
|
247
|
+
height: string;
|
|
248
|
+
padding: string;
|
|
249
|
+
borderRadius: string;
|
|
250
|
+
background: string;
|
|
251
|
+
color: string;
|
|
252
|
+
fontSize: string;
|
|
253
|
+
fontWeight: number;
|
|
254
|
+
flexShrink: number;
|
|
255
|
+
};
|
|
256
|
+
accordionListBody: {
|
|
257
|
+
position: "relative";
|
|
258
|
+
flex: number;
|
|
259
|
+
minHeight: number;
|
|
260
|
+
display: "flex";
|
|
261
|
+
flexDirection: "column";
|
|
262
|
+
borderTop: string;
|
|
263
|
+
};
|
|
264
|
+
accordionListPlaceholder: {
|
|
265
|
+
display: "flex";
|
|
266
|
+
flex: number;
|
|
267
|
+
alignItems: "center";
|
|
268
|
+
justifyContent: "center";
|
|
269
|
+
gap: string;
|
|
270
|
+
padding: string;
|
|
271
|
+
color: string;
|
|
272
|
+
fontSize: string;
|
|
273
|
+
};
|
|
274
|
+
accordionExpandBtn: {
|
|
275
|
+
display: "inline-flex";
|
|
276
|
+
alignItems: "center";
|
|
277
|
+
justifyContent: "center";
|
|
278
|
+
width: string;
|
|
279
|
+
height: string;
|
|
280
|
+
padding: number;
|
|
281
|
+
borderRadius: string;
|
|
282
|
+
border: string;
|
|
283
|
+
background: string;
|
|
284
|
+
color: string;
|
|
285
|
+
cursor: "pointer";
|
|
286
|
+
flexShrink: number;
|
|
287
|
+
transition: "background 0.15s ease, color 0.15s ease";
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
export interface RenderStepperParams {
|
|
291
|
+
/** Passi da mostrare, in ordine di fase */
|
|
292
|
+
steps: Array<MultiDetailStep>;
|
|
293
|
+
/** Fase corrente: i passi con fase minore sono completati */
|
|
294
|
+
phase: number;
|
|
295
|
+
/** Con un solo tipo documento il numero dello step non si mostra */
|
|
296
|
+
hasMultipleTypes: boolean;
|
|
297
|
+
/** Con righe inserite il ritorno alla scelta del tipo è bloccato (freccia e step completato) */
|
|
298
|
+
isBackLocked: boolean;
|
|
299
|
+
/** La freccia di ritorno si mostra solo dove ha senso tornare indietro */
|
|
300
|
+
showBackArrow: boolean;
|
|
301
|
+
/** Ritorno indietro dalla freccia */
|
|
302
|
+
onBack: () => void;
|
|
303
|
+
/** Click su uno step completato: riceve la fase di destinazione */
|
|
304
|
+
onStepClick: (phase: number) => void;
|
|
305
|
+
}
|
|
306
|
+
export declare const renderStepper: ({ steps, phase, hasMultipleTypes, isBackLocked, showBackArrow, onBack, onStepClick }: RenderStepperParams) => import("react/jsx-runtime").JSX.Element;
|
|
307
|
+
export interface RenderSelectDcmtTypeParams {
|
|
308
|
+
/** Relazioni di dettaglio fra cui scegliere */
|
|
309
|
+
detailRelationItems: Array<DetailRelationItem>;
|
|
310
|
+
/** Relazione attualmente selezionata */
|
|
311
|
+
selectedRelation: RelationDescriptor | undefined;
|
|
312
|
+
/** Selezione di una relazione */
|
|
313
|
+
onSelectRelation: (item: DetailRelationItem) => void;
|
|
314
|
+
}
|
|
315
|
+
export declare const renderSelectDcmtType: ({ detailRelationItems, selectedRelation, onSelectRelation }: RenderSelectDcmtTypeParams) => import("react/jsx-runtime").JSX.Element;
|
|
316
|
+
export interface RenderAccordionHeaderParams {
|
|
317
|
+
/** Sezione a cui appartiene la testata */
|
|
318
|
+
section: AccordionSection;
|
|
319
|
+
/** Sezione aperta o collassata */
|
|
320
|
+
isOpen: boolean;
|
|
321
|
+
/** Tooltip del collasso */
|
|
322
|
+
tooltip: string;
|
|
323
|
+
/** Conteggio mostrato nel badge */
|
|
324
|
+
count: number;
|
|
325
|
+
/** Titolo della sezione (icona + testo) */
|
|
326
|
+
title: React.ReactNode;
|
|
327
|
+
/** Pulsanti specifici della sezione, mostrati prima di quello di ingrandimento */
|
|
328
|
+
actions?: React.ReactNode;
|
|
329
|
+
/** Stato del pannello che ospita la sezione: l'ingrandimento è quello del panel manager */
|
|
330
|
+
panel: SectionPanelState;
|
|
331
|
+
/** Apre/chiude la sezione */
|
|
332
|
+
onToggleOpen: (section: AccordionSection, isOpen: boolean) => void;
|
|
333
|
+
}
|
|
334
|
+
export declare const renderAccordionHeader: ({ section, isOpen, tooltip, count, title, actions, panel, onToggleOpen }: RenderAccordionHeaderParams) => import("react/jsx-runtime").JSX.Element;
|
|
335
|
+
/**
|
|
336
|
+
* Contenuto di un pannello: il contesto del panel manager è leggibile solo dentro l'albero del
|
|
337
|
+
* provider, quindi è qui che si prende lo stato di ingrandimento da passare alla sezione
|
|
338
|
+
*/
|
|
339
|
+
export declare const TMSummarySectionSlot: ({ section, render, onBeforeMaximize }: {
|
|
340
|
+
section: AccordionSection;
|
|
341
|
+
render: (panel: SectionPanelState) => React.ReactNode;
|
|
342
|
+
onBeforeMaximize?: (section: AccordionSection) => void;
|
|
343
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
344
|
+
/**
|
|
345
|
+
* Tiene allineate le altezze dei pannelli al collasso delle sezioni: il panel manager non
|
|
346
|
+
* conosce il collasso, quindi è qui che l'apertura di una sezione si traduce nelle nuove quote.
|
|
347
|
+
* Vive dentro il provider perché il contesto è leggibile solo lì
|
|
348
|
+
*/
|
|
349
|
+
export declare const TMSectionPanelsHeights: ({ sections, sectionsOpen }: {
|
|
350
|
+
sections: Array<AccordionSection>;
|
|
351
|
+
sectionsOpen: Record<AccordionSection, boolean>;
|
|
352
|
+
}) => null;
|