@topconsultnpm/sdkui-react 6.21.0-dev5.1 → 6.21.0-dev5.10
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/FloatingMenuBar/styles.d.ts +4 -4
- package/lib/components/base/Styled.d.ts +1 -1
- package/lib/components/base/TMCounterBar.d.ts +2 -2
- package/lib/components/base/TMCounterContainer.d.ts +1 -2
- package/lib/components/base/TMCustomButton.d.ts +1 -1
- package/lib/components/base/TMDataGridExportForm.d.ts +1 -2
- package/lib/components/base/TMFileManager.d.ts +1 -2
- package/lib/components/base/TMFileManagerDataGridView.d.ts +1 -2
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +1 -1
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +1 -1
- package/lib/components/base/TMLayout.d.ts +4 -4
- package/lib/components/base/TMList.d.ts +1 -2
- package/lib/components/base/TMListView.d.ts +1 -1
- package/lib/components/base/TMSpinner.d.ts +1 -2
- package/lib/components/base/TMTab.d.ts +3 -4
- package/lib/components/base/TMTooltip.d.ts +1 -1
- package/lib/components/base/TMTreeView.d.ts +1 -1
- package/lib/components/base/TMUserAvatar.d.ts +1 -2
- package/lib/components/base/TMVilViewer.d.ts +1 -2
- package/lib/components/base/TMWaitPanel.d.ts +2 -3
- package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
- package/lib/components/choosers/TMInvoiceRetrieveFormats.d.ts +1 -2
- package/lib/components/choosers/TMOrderRetrieveFormats.d.ts +1 -2
- package/lib/components/choosers/TMRelationChooser.d.ts +3 -3
- package/lib/components/choosers/TMUserChooser.d.ts +2 -2
- package/lib/components/editors/TMFormulaEditor.d.ts +1 -1
- package/lib/components/editors/TMHtmlContentDisplay.d.ts +1 -2
- package/lib/components/editors/TMHtmlEditor.d.ts +1 -2
- package/lib/components/editors/TMTreeDropDown.d.ts +1 -1
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +1 -1
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +1 -2
- package/lib/components/features/documents/TMDcmtFormActionButtons.d.ts +1 -1
- package/lib/components/features/documents/TMDcmtIcon.d.ts +1 -2
- package/lib/components/features/documents/TMDcmtPreview.d.ts +1 -1
- package/lib/components/features/documents/TMDcmtTasks.d.ts +1 -2
- package/lib/components/features/documents/TMDragDropOverlay.d.ts +1 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.js +117 -2
- package/lib/components/features/documents/TMMergeToPdfForm.d.ts +1 -2
- package/lib/components/features/documents/TMMergeToPdfForm.js +6 -3
- package/lib/components/features/documents/TMRelationViewer.d.ts +3 -0
- package/lib/components/features/documents/TMRelationViewer.js +147 -98
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +0 -1
- package/lib/components/features/documents/mergePdfUtils.js +21 -11
- package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +1 -2
- package/lib/components/features/search/TMMetadataOutputForm.d.ts +1 -2
- package/lib/components/features/search/TMMetadataSorterForm.d.ts +1 -2
- package/lib/components/features/search/TMSavedQuerySelector.d.ts +2 -2
- package/lib/components/features/search/TMSearchResultFloatingActionButton.d.ts +1 -1
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +1 -2
- package/lib/components/features/search/TMViewHistoryDcmt.d.ts +1 -2
- package/lib/components/features/tasks/TMTaskForm.d.ts +1 -1
- package/lib/components/features/tasks/TMTaskFormUtils.d.ts +10 -10
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksHeader.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksPanelContent.d.ts +1 -1
- package/lib/components/features/tasks/TMTasksUtilsView.d.ts +5 -5
- package/lib/components/features/tasks/TMTasksView.d.ts +1 -1
- package/lib/components/features/wg/TMWGsCopyMoveForm.d.ts +2 -3
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +7 -8
- package/lib/components/forms/Login/Chooser.d.ts +2 -2
- package/lib/components/forms/TMChooserForm.d.ts +1 -2
- package/lib/components/forms/TMSaveForm.d.ts +4 -4
- package/lib/components/grids/TMBlogAttachments.d.ts +1 -2
- package/lib/components/grids/TMBlogHeader.d.ts +1 -1
- package/lib/components/grids/TMBlogsPost.d.ts +1 -1
- package/lib/components/grids/TMBlogsPostUtils.d.ts +9 -9
- package/lib/components/grids/TMValidationItemsList.d.ts +1 -2
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -2
- package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +1 -1
- package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +2 -2
- package/lib/components/layout/panelManager/TMPanelWrapper.d.ts +2 -2
- package/lib/components/pages/TMPage.d.ts +1 -1
- package/lib/components/settings/SettingsAppearance.d.ts +1 -2
- package/lib/components/sidebar/TMAboutApp.d.ts +1 -2
- package/lib/components/sidebar/TMHeader.d.ts +3 -3
- package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -3
- package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +2 -3
- package/lib/components/viewers/TMMidViewer.d.ts +2 -2
- package/lib/components/viewers/TMTidViewer.d.ts +2 -2
- package/lib/helper/TMCommandsContextMenu.d.ts +1 -1
- package/lib/helper/TMIcons.d.ts +279 -278
- package/lib/helper/TMIcons.js +3 -0
- package/lib/helper/TMPdfViewer.d.ts +1 -2
- package/lib/helper/TMToppyMessage.d.ts +2 -2
- package/lib/helper/TMUtils.d.ts +1 -1
- package/lib/helper/helpers.d.ts +4 -1
- package/lib/helper/helpers.js +20 -1
- package/lib/hooks/useDocumentOperations.js +2 -2
- package/lib/hooks/useInputDialog.d.ts +1 -2
- package/lib/services/platform_services.d.ts +2 -3
- package/package.json +2 -2
|
@@ -14,10 +14,11 @@ import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/p
|
|
|
14
14
|
import TMSearchResult from '../search/TMSearchResult';
|
|
15
15
|
import TMDcmtForm from './TMDcmtForm';
|
|
16
16
|
import { TMNothingToShow } from './TMDcmtPreview';
|
|
17
|
-
import {
|
|
17
|
+
import { TMButton, TMLayoutWaitingContainer } from '../..';
|
|
18
18
|
import { useDocumentOperations } from '../../../hooks/useDocumentOperations';
|
|
19
19
|
import TMToppyMessage from '../../../helper/TMToppyMessage';
|
|
20
20
|
import TMPanel from '../../base/TMPanel';
|
|
21
|
+
import sixLogo from '../../../assets/six.png';
|
|
21
22
|
const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, deviceType, inputDcmts, isForMaster, showCurrentDcmtIndicator = true, allowNavigation, canNext, canPrev, onNext, onPrev, onBack, appendMasterDcmts, onTaskCreateRequest, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, datagridUtility, dcmtUtility, fetchRemoteCertificates }) => {
|
|
22
23
|
const floatingBarContainerRef = useRef(null);
|
|
23
24
|
const [focusedItem, setFocusedItem] = useState();
|
|
@@ -31,6 +32,10 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
31
32
|
const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
|
|
32
33
|
// Track if TMRelationViewer is loading (used to disable context menu during loading)
|
|
33
34
|
const [isRelationViewerLoading, setIsRelationViewerLoading] = useState(false);
|
|
35
|
+
// Track if loading has ever been TRUE (to distinguish initial false from post-load false)
|
|
36
|
+
const hasLoadingBeenTrueRef = useRef(false);
|
|
37
|
+
// Track the previous loading state to detect transitions
|
|
38
|
+
const prevIsRelationViewerLoadingRef = useRef(false);
|
|
34
39
|
const [dtdFocused, setDtdFocused] = useState();
|
|
35
40
|
const [refreshKey, setRefreshKey] = useState(0);
|
|
36
41
|
// Separate refresh key for TMFormOrResultWrapper only (doesn't affect tmTreeView)
|
|
@@ -39,6 +44,21 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
39
44
|
const [focusedItemFormData, setFocusedItemFormData] = useState([]);
|
|
40
45
|
// Trigger operationItems refresh (after file substitution, etc.)
|
|
41
46
|
const [refreshOperationsTrigger, setRefreshOperationsTrigger] = useState(0);
|
|
47
|
+
// Safety net: when TMRelationViewer finishes loading (transition from TRUE to FALSE),
|
|
48
|
+
// hide the spinner regardless of whether a document was focused or not.
|
|
49
|
+
// This handles edge cases where no document gets isRoot=true.
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const prevLoading = prevIsRelationViewerLoadingRef.current;
|
|
52
|
+
prevIsRelationViewerLoadingRef.current = isRelationViewerLoading;
|
|
53
|
+
if (isRelationViewerLoading) {
|
|
54
|
+
// Loading started - mark that we've seen a true state
|
|
55
|
+
hasLoadingBeenTrueRef.current = true;
|
|
56
|
+
}
|
|
57
|
+
else if (prevLoading && hasLoadingBeenTrueRef.current && isCheckingFirstLoad) {
|
|
58
|
+
// Transition from TRUE to FALSE (loading completed) - hide spinner
|
|
59
|
+
setIsCheckingFirstLoad(false);
|
|
60
|
+
}
|
|
61
|
+
}, [isRelationViewerLoading, isCheckingFirstLoad]);
|
|
42
62
|
// Increments trigger counter to force operationItems to re-calculate
|
|
43
63
|
const onRefreshOperationsDatagrid = useCallback(async () => {
|
|
44
64
|
setRefreshOperationsTrigger(prev => prev + 1);
|
|
@@ -258,6 +278,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
258
278
|
useEffect(() => {
|
|
259
279
|
if (noRelationsOnFirstLoad) {
|
|
260
280
|
setNoRelationsOnFirstLoad(false);
|
|
281
|
+
setIsCheckingFirstLoad(false); // Hide spinner before navigating back
|
|
261
282
|
ShowAlert({
|
|
262
283
|
message: SDKUI_Localizator.RelatedDcmtsNotFound,
|
|
263
284
|
title: SDKUI_Localizator.RelationsNotFound,
|
|
@@ -392,7 +413,10 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
392
413
|
toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
|
|
393
414
|
}
|
|
394
415
|
], [tmTreeView, tmFormOrResult, focusedItem?.isDcmt, dtdMaster]);
|
|
395
|
-
return (_jsxs("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: [isCheckingFirstLoad && (_jsx(
|
|
416
|
+
return (_jsxs("div", { style: { width: '100%', height: '100%', position: 'relative' }, children: [isCheckingFirstLoad && (_jsx(TMLoadingOverlay, { onCancel: () => {
|
|
417
|
+
setIsCheckingFirstLoad(false);
|
|
418
|
+
onBack?.();
|
|
419
|
+
} })), _jsxs("div", { style: isCheckingFirstLoad ? { position: 'absolute', width: 0, height: 0, overflow: 'hidden', opacity: 0, pointerEvents: 'none' } : { width: '100%', height: '100%' }, children: [_jsx(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showWaitPanel, showWaitPanelPrimary: showPrimary, showWaitPanelSecondary: showSecondary, waitPanelTitle: waitPanelTitle, waitPanelTextPrimary: waitPanelTextPrimary, waitPanelValuePrimary: waitPanelValuePrimary, waitPanelMaxValuePrimary: waitPanelMaxValuePrimary, waitPanelTextSecondary: waitPanelTextSecondary, waitPanelValueSecondary: waitPanelValueSecondary, waitPanelMaxValueSecondary: waitPanelMaxValueSecondary, isCancelable: true, abortController: abortController, children: _jsx(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmTreeView', children: _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", showToolbar: true }) }) }), renderDcmtOperations, renderFloatingBar] })] }));
|
|
396
420
|
};
|
|
397
421
|
export default TMMasterDetailDcmts;
|
|
398
422
|
/**
|
|
@@ -471,3 +495,94 @@ const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCrea
|
|
|
471
495
|
}, fetchRemoteCertificates: fetchRemoteCertificates }, refreshKey) :
|
|
472
496
|
focusedItem?.searchResult === undefined ? (_jsx(TMPanel, { title: SDKUI_Localizator.SearchResult, children: _jsx(TMToppyMessage, { message: SDKUI_Localizator.SelectDocumentToViewSearchResults }) })) : (_jsx(TMSearchResult, { groupId: 'tmFormOrResult', isClosable: deviceType !== DeviceType.MOBILE, context: SearchResultContext.METADATA_SEARCH, allowFloatingBar: false, allowRelations: false, openDcmtFormAsModal: true, searchResults: focusedItem?.searchResult ?? [], showSearchResultSidebar: false, showDcmtFormSidebar: false, autoFocusFirstRow: false, onTaskCreateRequest: onTaskCreateRequest, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, editPdfForm: editPdfForm, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, enablePinIcons: false, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, showBackButton: false, onRefreshSearchAsyncDatagrid: onRefreshSearchResults, onReferenceClick: handleNavigateToReference, fetchRemoteCertificates: fetchRemoteCertificates }, refreshKey)) }));
|
|
473
497
|
};
|
|
498
|
+
const TMLoadingOverlay = ({ onCancel, description, cancelText }) => {
|
|
499
|
+
return (_jsx("div", { style: {
|
|
500
|
+
position: 'absolute',
|
|
501
|
+
top: 0,
|
|
502
|
+
left: 0,
|
|
503
|
+
width: '100%',
|
|
504
|
+
height: '100%',
|
|
505
|
+
backgroundColor: 'rgba(248, 250, 252, 0.92)',
|
|
506
|
+
zIndex: 1000,
|
|
507
|
+
display: 'flex',
|
|
508
|
+
justifyContent: 'center',
|
|
509
|
+
alignItems: 'center',
|
|
510
|
+
}, children: _jsxs("div", { style: {
|
|
511
|
+
display: 'flex',
|
|
512
|
+
flexDirection: 'column',
|
|
513
|
+
alignItems: 'center',
|
|
514
|
+
gap: '16px',
|
|
515
|
+
padding: '24px 32px',
|
|
516
|
+
background: '#fcfcfc',
|
|
517
|
+
borderRadius: '8px',
|
|
518
|
+
boxShadow: '0 4px 16px rgba(0, 0, 0, 0.1)',
|
|
519
|
+
}, children: [_jsxs("div", { style: { position: 'relative', width: '80px', height: '80px' }, children: [_jsx("img", { style: {
|
|
520
|
+
position: 'absolute',
|
|
521
|
+
top: '50%',
|
|
522
|
+
left: '50%',
|
|
523
|
+
transform: 'translate(-54%, -54%)'
|
|
524
|
+
}, src: sixLogo, width: 35, alt: "" }), _jsx("style", { children: `
|
|
525
|
+
@keyframes tmSpinnerRotate {
|
|
526
|
+
0% { transform: rotate(0deg); }
|
|
527
|
+
100% { transform: rotate(360deg); }
|
|
528
|
+
}
|
|
529
|
+
.tm-spinner-animation {
|
|
530
|
+
display: inline-block;
|
|
531
|
+
width: 80px;
|
|
532
|
+
height: 80px;
|
|
533
|
+
position: absolute;
|
|
534
|
+
top: 50%;
|
|
535
|
+
left: 50%;
|
|
536
|
+
transform: translate(-50%, -50%);
|
|
537
|
+
}
|
|
538
|
+
.tm-spinner-animation div {
|
|
539
|
+
animation: tmSpinnerRotate 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
|
540
|
+
transform-origin: 40px 40px;
|
|
541
|
+
}
|
|
542
|
+
.tm-spinner-animation div:after {
|
|
543
|
+
content: " ";
|
|
544
|
+
display: block;
|
|
545
|
+
position: absolute;
|
|
546
|
+
width: 7px;
|
|
547
|
+
height: 7px;
|
|
548
|
+
border-radius: 50%;
|
|
549
|
+
background: #0c448e;
|
|
550
|
+
margin: -4px 0 0 -4px;
|
|
551
|
+
}
|
|
552
|
+
.tm-spinner-animation div:nth-child(1) { animation-delay: -0.036s; }
|
|
553
|
+
.tm-spinner-animation div:nth-child(1):after { top: 63px; left: 63px; background: #f7a51f; }
|
|
554
|
+
.tm-spinner-animation div:nth-child(2) { animation-delay: -0.072s; }
|
|
555
|
+
.tm-spinner-animation div:nth-child(2):after { top: 68px; left: 56px; background: #f7a51f; }
|
|
556
|
+
.tm-spinner-animation div:nth-child(3) { animation-delay: -0.108s; }
|
|
557
|
+
.tm-spinner-animation div:nth-child(3):after { top: 71px; left: 48px; background: #d3237b; }
|
|
558
|
+
.tm-spinner-animation div:nth-child(4) { animation-delay: -0.144s; }
|
|
559
|
+
.tm-spinner-animation div:nth-child(4):after { top: 72px; left: 40px; background: #d3237b; }
|
|
560
|
+
.tm-spinner-animation div:nth-child(5) { animation-delay: -0.18s; }
|
|
561
|
+
.tm-spinner-animation div:nth-child(5):after { top: 71px; left: 32px; background: #d12a1c; }
|
|
562
|
+
.tm-spinner-animation div:nth-child(6) { animation-delay: -0.216s; }
|
|
563
|
+
.tm-spinner-animation div:nth-child(6):after { top: 68px; left: 24px; background: #d12a1c; }
|
|
564
|
+
.tm-spinner-animation div:nth-child(7) { animation-delay: -0.252s; }
|
|
565
|
+
.tm-spinner-animation div:nth-child(7):after { top: 63px; left: 17px; background: #782b7d; }
|
|
566
|
+
.tm-spinner-animation div:nth-child(8) { animation-delay: -0.288s; }
|
|
567
|
+
.tm-spinner-animation div:nth-child(8):after { top: 56px; left: 12px; background: #782b7d; }
|
|
568
|
+
` }), _jsxs("div", { className: "tm-spinner-animation", children: [_jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {}), _jsx("div", {})] })] }), _jsx("span", { style: { fontSize: '14px', color: '#334155', textAlign: 'center' }, children: description ?? SDKUI_Localizator.Loading }), onCancel && (_jsx("button", { onClick: onCancel, style: {
|
|
569
|
+
marginTop: '4px',
|
|
570
|
+
padding: '8px 24px',
|
|
571
|
+
fontSize: '13px',
|
|
572
|
+
fontWeight: 500,
|
|
573
|
+
color: '#64748b',
|
|
574
|
+
background: 'transparent',
|
|
575
|
+
border: '1.5px solid #cbd5e1',
|
|
576
|
+
borderRadius: '6px',
|
|
577
|
+
cursor: 'pointer',
|
|
578
|
+
transition: 'all 0.2s ease',
|
|
579
|
+
}, onMouseEnter: (e) => {
|
|
580
|
+
e.currentTarget.style.background = '#f1f5f9';
|
|
581
|
+
e.currentTarget.style.borderColor = '#94a3b8';
|
|
582
|
+
e.currentTarget.style.color = '#475569';
|
|
583
|
+
}, onMouseLeave: (e) => {
|
|
584
|
+
e.currentTarget.style.background = 'transparent';
|
|
585
|
+
e.currentTarget.style.borderColor = '#cbd5e1';
|
|
586
|
+
e.currentTarget.style.color = '#64748b';
|
|
587
|
+
}, children: cancelText ?? SDKUI_Localizator.Cancel }))] }) }));
|
|
588
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { DcmtInfo } from '../../../ts';
|
|
3
2
|
import { HomeBlogPost, TaskDescriptor } from '@topconsultnpm/sdk-ts';
|
|
4
3
|
import { TMCopyToFolderMode } from '../../../hooks/useDocumentOperations';
|
|
@@ -21,5 +20,5 @@ interface ITMMergeToPdfFormProps {
|
|
|
21
20
|
* Condivide TMDownloadRelationViewerSection e gli helper in copyAndMergeDcmtsShared
|
|
22
21
|
* con TMCopyToFolderForm.
|
|
23
22
|
*/
|
|
24
|
-
declare const TMMergeToPdfForm: (props: ITMMergeToPdfFormProps) =>
|
|
23
|
+
declare const TMMergeToPdfForm: (props: ITMMergeToPdfFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
25
24
|
export default TMMergeToPdfForm;
|
|
@@ -100,15 +100,18 @@ const TMMergeToPdfForm = (props) => {
|
|
|
100
100
|
});
|
|
101
101
|
return null;
|
|
102
102
|
}
|
|
103
|
-
|
|
103
|
+
// Permetti merge anche con 1 solo file se convertibile o metadata-only
|
|
104
|
+
if (!hasEnoughPdfForMerge) {
|
|
104
105
|
TMMessageBoxManager.show({
|
|
105
106
|
message: SDKUI_Localizator.OnlyOnePdfOrConvertibleFileMergeBlocked.replaceParams(MIN_PDF_FOR_MERGE.toString()),
|
|
106
107
|
buttons: [ButtonNames.OK]
|
|
107
108
|
});
|
|
108
109
|
return null;
|
|
109
110
|
}
|
|
110
|
-
// Mappa per lookup veloce di FILECOUNT e FILEEXT
|
|
111
|
-
const fileInfoMap = new Map(
|
|
111
|
+
// Mappa per lookup veloce di FILECOUNT e FILEEXT
|
|
112
|
+
const fileInfoMap = new Map(showTMRelationViewer
|
|
113
|
+
? selectedItemsRelationViewer.map(d => [`${d.tid}_${d.did}`, { fileExt: d.fileExt ?? null, fileCount: d.fileCount ?? null }])
|
|
114
|
+
: selectedItemsFull.map(d => [`${d.TID}_${d.DID}`, { fileExt: d.FILEEXT, fileCount: d.FILECOUNT }]));
|
|
112
115
|
// Mappa per i risultati: mantiene l'ordine originale
|
|
113
116
|
const pdfFilesMap = new Map();
|
|
114
117
|
// Identifica documenti di soli metadati e documenti con file
|
|
@@ -24,6 +24,7 @@ export interface RelationTreeItem extends ITMTreeItem {
|
|
|
24
24
|
searchResult?: SearchResultDescriptor[];
|
|
25
25
|
itemsCount?: number;
|
|
26
26
|
fileExt?: string;
|
|
27
|
+
fileCount?: number;
|
|
27
28
|
}
|
|
28
29
|
/**
|
|
29
30
|
* Props for TMRelationViewer component
|
|
@@ -146,6 +147,8 @@ export declare const hasMasterRelations: (dTID: number | undefined) => Promise<b
|
|
|
146
147
|
export declare const getDisplayValueByColumn: (col: DataColumnDescriptor | undefined, value: any) => any;
|
|
147
148
|
/**
|
|
148
149
|
* Convert SearchResultDescriptor to structured data source with metadata
|
|
150
|
+
* For each document, fetches complete metadata using GetMetadataAsync to ensure
|
|
151
|
+
* all metadata properties (isSpecialSearchOutput, permissions, etc.) are available
|
|
149
152
|
*/
|
|
150
153
|
export declare const searchResultToDataSource: (searchResult: SearchResultDescriptor | undefined, hideSysMetadata?: boolean) => Promise<any[]>;
|
|
151
154
|
export declare const DEFAULT_RELATION_EXPAND_LEVEL = 4;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import { DcmtTypeListCacheService, SDK_Globals, DataColumnTypes, MetadataFormats, MetadataDataDomains, RelationCacheService, RelationTypes, UserListCacheService } from "@topconsultnpm/sdk-ts";
|
|
4
|
-
import { genUniqueId, IconFolder, IconBackhandIndexPointingRight, IconCircleInfo, getDcmtCicoStatus, IconChevronDown, IconChevronRight, SDKUI_Localizator, buildDcmtDisplayName, SDKUI_Globals } from '../../../helper';
|
|
3
|
+
import { DcmtTypeListCacheService, SDK_Globals, DataColumnTypes, MetadataFormats, MetadataDataDomains, RelationCacheService, RelationTypes, UserListCacheService, LayoutModes } from "@topconsultnpm/sdk-ts";
|
|
4
|
+
import { genUniqueId, IconFolder, IconBackhandIndexPointingRight, IconCircleInfo, getDcmtCicoStatus, IconChevronDown, IconChevronRight, SDKUI_Localizator, buildDcmtDisplayName, SDKUI_Globals, searchResultToMetadataValues } from '../../../helper';
|
|
5
5
|
import ShowAlert from '../../base/TMAlert';
|
|
6
6
|
import TMToppyMessage from '../../../helper/TMToppyMessage';
|
|
7
7
|
import { TMColors } from '../../../utils/theme';
|
|
@@ -88,41 +88,77 @@ export const getDisplayValueByColumn = (col, value) => {
|
|
|
88
88
|
};
|
|
89
89
|
/**
|
|
90
90
|
* Convert SearchResultDescriptor to structured data source with metadata
|
|
91
|
+
* For each document, fetches complete metadata using GetMetadataAsync to ensure
|
|
92
|
+
* all metadata properties (isSpecialSearchOutput, permissions, etc.) are available
|
|
91
93
|
*/
|
|
92
94
|
export const searchResultToDataSource = async (searchResult, hideSysMetadata) => {
|
|
93
95
|
const rows = searchResult?.dtdResult?.rows ?? [];
|
|
94
|
-
const tid = searchResult?.fromTID;
|
|
95
|
-
// IMPORTANT: Pass true to get full metadata with all properties (isSpecialSearchOutput, etc.)
|
|
96
|
-
const dtd = await DcmtTypeListCacheService.GetAsync(tid, true);
|
|
97
96
|
const output = [];
|
|
97
|
+
// Find TID and DID column indices
|
|
98
|
+
const columns = searchResult?.dtdResult?.columns ?? [];
|
|
99
|
+
const tidColIndex = columns.findIndex(col => col.caption?.toUpperCase() === 'TID');
|
|
100
|
+
const didColIndex = columns.findIndex(col => col.caption?.toUpperCase() === 'DID');
|
|
98
101
|
for (let index = 0; index < rows.length; index++) {
|
|
99
|
-
const item = { rowIndex: index };
|
|
100
102
|
const row = rows[index];
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
// Extract TID and DID from row
|
|
104
|
+
const tid = tidColIndex >= 0 ? Number(row[tidColIndex]) : searchResult?.fromTID;
|
|
105
|
+
const did = didColIndex >= 0 ? Number(row[didColIndex]) : undefined;
|
|
106
|
+
// Fetch complete metadata for this specific document (like getFilteredMetadata does)
|
|
107
|
+
const metadata = await SDK_Globals.tmSession?.NewSearchEngine().GetMetadataAsync(tid, did, true);
|
|
108
|
+
if (metadata) {
|
|
109
|
+
// Get full DTD with metadata for this document
|
|
110
|
+
const dtdResult = metadata.dtdResult;
|
|
111
|
+
const metadataRows = dtdResult?.rows?.[0] ?? [];
|
|
112
|
+
const mids = metadata.selectMIDs;
|
|
113
|
+
const dtdWithMetadata = await DcmtTypeListCacheService.GetWithNotGrantedAsync(tid, did, metadata);
|
|
114
|
+
const mdList = dtdWithMetadata?.metadata ?? [];
|
|
115
|
+
// Convert to MetadataValueDescriptorEx array
|
|
116
|
+
const metadataList = searchResultToMetadataValues(tid, dtdResult, metadataRows, mids, mdList, LayoutModes.Update);
|
|
117
|
+
// Convert to DcmtMetadataMap format (like getFilteredMetadata does)
|
|
118
|
+
const item = { rowIndex: index };
|
|
119
|
+
for (const mvd of metadataList) {
|
|
120
|
+
if (hideSysMetadata && mvd.mid !== undefined && mvd.mid < 100)
|
|
121
|
+
continue;
|
|
122
|
+
const key = mvd.mid !== undefined && mvd.mid <= 100
|
|
123
|
+
? (mvd.md?.name ?? '').toUpperCase()
|
|
124
|
+
: (mvd.md?.name ?? '');
|
|
125
|
+
if (key) {
|
|
126
|
+
item[key] = {
|
|
127
|
+
md: mvd.md,
|
|
128
|
+
value: mvd.value
|
|
129
|
+
};
|
|
130
|
+
}
|
|
111
131
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
132
|
+
output.push(item);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// Fallback: use original row data with basic parsing
|
|
136
|
+
const item = { rowIndex: index };
|
|
137
|
+
const fallbackTid = searchResult?.fromTID;
|
|
138
|
+
const dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(fallbackTid, undefined, searchResult);
|
|
139
|
+
for (let i = 0; i < row.length; i++) {
|
|
140
|
+
const column = searchResult?.dtdResult?.columns?.[i];
|
|
141
|
+
const mid = Number(column?.extendedProperties?.["MID"] ?? "0");
|
|
142
|
+
if (hideSysMetadata && mid < 100)
|
|
143
|
+
continue;
|
|
144
|
+
let key = column?.caption ?? '';
|
|
145
|
+
if (mid <= 100) {
|
|
146
|
+
key = key.toUpperCase();
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
if (item[key] !== undefined && item[key]?.md?.id !== mid) {
|
|
150
|
+
key = `${key}_${mid}`;
|
|
151
|
+
}
|
|
116
152
|
}
|
|
153
|
+
const value = row[i];
|
|
154
|
+
const md = dtd?.metadata?.find(o => o.id == mid);
|
|
155
|
+
item[key] = {
|
|
156
|
+
md: md,
|
|
157
|
+
value: getDisplayValueByColumn(column, value)
|
|
158
|
+
};
|
|
117
159
|
}
|
|
118
|
-
|
|
119
|
-
const md = dtd?.metadata?.find(o => o.id == mid);
|
|
120
|
-
item[key] = {
|
|
121
|
-
md: md,
|
|
122
|
-
value: getDisplayValueByColumn(column, value)
|
|
123
|
-
};
|
|
160
|
+
output.push(item);
|
|
124
161
|
}
|
|
125
|
-
output.push(item);
|
|
126
162
|
}
|
|
127
163
|
return output;
|
|
128
164
|
};
|
|
@@ -273,6 +309,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
273
309
|
hidden: false,
|
|
274
310
|
name: row?.SYS_Abstract?.value || row?.SYS_SUBJECT?.value || `Documento ${did}`,
|
|
275
311
|
fileExt: row?.FILEEXT?.value,
|
|
312
|
+
fileCount: row?.FILECOUNT?.value,
|
|
276
313
|
// Note: Recursive loading on expansion is handled by calculateItemsForNode
|
|
277
314
|
});
|
|
278
315
|
}
|
|
@@ -282,7 +319,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
282
319
|
}
|
|
283
320
|
}
|
|
284
321
|
catch (error) {
|
|
285
|
-
console.error('
|
|
322
|
+
console.error('Error loading detail documents:', error);
|
|
286
323
|
}
|
|
287
324
|
return items;
|
|
288
325
|
}, [allowedTIDs]);
|
|
@@ -357,6 +394,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
357
394
|
values: row,
|
|
358
395
|
searchResult: [searchResult],
|
|
359
396
|
fileExt: row?.FILEEXT?.value,
|
|
397
|
+
fileCount: row?.FILECOUNT?.value,
|
|
360
398
|
// Leave items and itemsCount undefined so TMTreeView shows expand arrow based on isExpandible
|
|
361
399
|
// Children will be loaded lazily by calculateItemsForNode when expanded
|
|
362
400
|
expanded: false,
|
|
@@ -437,71 +475,82 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
437
475
|
const setupInitialTreeExpansion = (tree) => {
|
|
438
476
|
if (tree.length === 0)
|
|
439
477
|
return tree;
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
expanded: true,
|
|
448
|
-
isRoot: true
|
|
449
|
-
};
|
|
450
|
-
// 2. Find first document/container and expand it
|
|
451
|
-
const firstRootItems = newFirstContainer.items;
|
|
452
|
-
if (firstRootItems && firstRootItems.length > 0) {
|
|
453
|
-
const firstDocOrContainer = firstRootItems[0];
|
|
454
|
-
if (firstDocOrContainer.isDcmt) {
|
|
455
|
-
// First item is a document - expand it and mark as root for focus
|
|
456
|
-
let newFirstDoc = {
|
|
457
|
-
...firstDocOrContainer,
|
|
458
|
-
expanded: true,
|
|
459
|
-
isRoot: true
|
|
460
|
-
};
|
|
461
|
-
// 3. Expand first correlation folder ONLY if there's exactly one
|
|
462
|
-
const docItems = newFirstDoc.items;
|
|
463
|
-
const containerChildren = docItems?.filter(child => child.isContainer) ?? [];
|
|
464
|
-
if (containerChildren.length === 1 && docItems && docItems.length > 0 && docItems[0].isContainer) {
|
|
465
|
-
const newFirstCorrelation = { ...docItems[0], expanded: true };
|
|
466
|
-
newFirstDoc = {
|
|
467
|
-
...newFirstDoc,
|
|
468
|
-
items: [newFirstCorrelation, ...docItems.slice(1)]
|
|
469
|
-
};
|
|
478
|
+
// Find the first container with documents (not empty)
|
|
479
|
+
// This ensures we focus on an actual document, not an empty container
|
|
480
|
+
const findFirstNonEmptyContainerIndex = () => {
|
|
481
|
+
for (let i = 0; i < tree.length; i++) {
|
|
482
|
+
const container = tree[i];
|
|
483
|
+
if (!container.isZero && container.items && Array.isArray(container.items) && container.items.length > 0) {
|
|
484
|
+
return i;
|
|
470
485
|
}
|
|
471
|
-
// Update the container's items
|
|
472
|
-
newFirstContainer = {
|
|
473
|
-
...newFirstContainer,
|
|
474
|
-
items: [newFirstDoc, ...firstRootItems.slice(1)]
|
|
475
|
-
};
|
|
476
486
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
487
|
+
return 0; // Fallback to first container if all are empty
|
|
488
|
+
};
|
|
489
|
+
const targetContainerIndex = findFirstNonEmptyContainerIndex();
|
|
490
|
+
// Process all containers, but only mark the target one for focus
|
|
491
|
+
const result = tree.map((container, index) => {
|
|
492
|
+
const isTargetContainer = index === targetContainerIndex;
|
|
493
|
+
const isFirstContainer = index === 0;
|
|
494
|
+
// Always expand the first container (even if empty, to show infoMessage)
|
|
495
|
+
// Also expand the target container if different
|
|
496
|
+
const shouldExpand = isFirstContainer || isTargetContainer;
|
|
497
|
+
if (!shouldExpand && !isTargetContainer) {
|
|
498
|
+
return container; // Keep non-target containers as-is
|
|
499
|
+
}
|
|
500
|
+
// Create a copy with expanded state
|
|
501
|
+
let newContainer = {
|
|
502
|
+
...container,
|
|
503
|
+
expanded: shouldExpand,
|
|
504
|
+
isRoot: isTargetContainer // Only mark target container as root
|
|
505
|
+
};
|
|
506
|
+
// Only process items for the target container (the one with documents)
|
|
507
|
+
if (isTargetContainer) {
|
|
508
|
+
const containerItems = newContainer.items;
|
|
509
|
+
if (containerItems && containerItems.length > 0) {
|
|
510
|
+
const firstDocOrContainer = containerItems[0];
|
|
511
|
+
if (firstDocOrContainer.isDcmt) {
|
|
512
|
+
// First item is a document - expand it and mark as root for focus
|
|
513
|
+
let newFirstDoc = {
|
|
514
|
+
...firstDocOrContainer,
|
|
515
|
+
expanded: true,
|
|
516
|
+
isRoot: true
|
|
517
|
+
};
|
|
518
|
+
// NOTE: Le cartelle di correlazione rimangono con expanded: false.
|
|
519
|
+
// Verranno espanse solo tramite il pulsante "espandi n livelli" o espansione manuale.
|
|
520
|
+
// Update the container's items
|
|
521
|
+
newContainer = {
|
|
522
|
+
...newContainer,
|
|
523
|
+
items: [newFirstDoc, ...containerItems.slice(1)]
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
else if (firstDocOrContainer.isContainer) {
|
|
527
|
+
// First item is a container (correlation folder)
|
|
528
|
+
// NOTE: Le cartelle di correlazione rimangono con expanded: false.
|
|
529
|
+
// Verranno espanse solo tramite il pulsante "espandi n livelli" o espansione manuale.
|
|
530
|
+
let newFirstCorrelation = {
|
|
531
|
+
...firstDocOrContainer,
|
|
532
|
+
expanded: false
|
|
533
|
+
};
|
|
534
|
+
// Find first document inside this container and mark for focus
|
|
535
|
+
const correlationItems = newFirstCorrelation.items;
|
|
536
|
+
if (correlationItems && correlationItems.length > 0 && correlationItems[0].isDcmt) {
|
|
537
|
+
const newFirstDoc = { ...correlationItems[0], isRoot: true };
|
|
538
|
+
newFirstCorrelation = {
|
|
539
|
+
...newFirstCorrelation,
|
|
540
|
+
items: [newFirstDoc, ...correlationItems.slice(1)]
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
// Update the container's items
|
|
544
|
+
newContainer = {
|
|
545
|
+
...newContainer,
|
|
546
|
+
items: [newFirstCorrelation, ...containerItems.slice(1)]
|
|
547
|
+
};
|
|
548
|
+
}
|
|
494
549
|
}
|
|
495
|
-
// Update the container's items
|
|
496
|
-
newFirstContainer = {
|
|
497
|
-
...newFirstContainer,
|
|
498
|
-
items: [newFirstCorrelation, ...firstRootItems.slice(1)]
|
|
499
|
-
};
|
|
500
550
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
return [newFirstContainer, ...tree.slice(1)];
|
|
551
|
+
return newContainer;
|
|
552
|
+
});
|
|
553
|
+
return result;
|
|
505
554
|
};
|
|
506
555
|
/**
|
|
507
556
|
* Main data loading function
|
|
@@ -670,7 +719,8 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
670
719
|
searchResult: result ? [result] : [],
|
|
671
720
|
items: relatedDocs,
|
|
672
721
|
itemsCount: relatedDocs.length,
|
|
673
|
-
fileExt: docRow?.FILEEXT?.value
|
|
722
|
+
fileExt: docRow?.FILEEXT?.value,
|
|
723
|
+
fileCount: docRow?.FILECOUNT?.value
|
|
674
724
|
};
|
|
675
725
|
// Check if a type container for this TID already exists in the tree
|
|
676
726
|
const existingContainer = tree.find(c => c.tid === dcmt.TID && c.isContainer);
|
|
@@ -1130,9 +1180,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1130
1180
|
transition: 'opacity 0.2s ease-in-out',
|
|
1131
1181
|
textDecoration: isLogicallyDeleted ? 'line-through' : 'none'
|
|
1132
1182
|
};
|
|
1133
|
-
const documentStyle = customDocumentStyle
|
|
1134
|
-
? { ...defaultDocumentStyle, ...customDocumentStyle(item) }
|
|
1135
|
-
: defaultDocumentStyle;
|
|
1183
|
+
const documentStyle = customDocumentStyle ? { ...defaultDocumentStyle, ...customDocumentStyle(item) } : defaultDocumentStyle;
|
|
1136
1184
|
const textDecoration = isLogicallyDeleted ? 'line-through' : 'none';
|
|
1137
1185
|
const textColor = isLogicallyDeleted ? 'gray' : undefined;
|
|
1138
1186
|
const defaultMetadataContent = item.values && (() => {
|
|
@@ -1165,9 +1213,7 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1165
1213
|
}, children: value }))] }, `${key}_${index}`));
|
|
1166
1214
|
}) }));
|
|
1167
1215
|
})();
|
|
1168
|
-
const metadataContent = customDocumentContent
|
|
1169
|
-
? customDocumentContent(item, defaultMetadataContent || _jsx(_Fragment, {}))
|
|
1170
|
-
: defaultMetadataContent;
|
|
1216
|
+
const metadataContent = customDocumentContent ? customDocumentContent(item, defaultMetadataContent || _jsx(_Fragment, {})) : defaultMetadataContent;
|
|
1171
1217
|
// Calculate checkout status for non-root documents
|
|
1172
1218
|
let checkoutStatusIcon = null;
|
|
1173
1219
|
if (item.values && item.dtd) {
|
|
@@ -1225,6 +1271,8 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1225
1271
|
/**
|
|
1226
1272
|
* Recursively set the `expanded` property on every node that has children loaded.
|
|
1227
1273
|
* Nodes without `items` are left untouched (will be loaded lazily on user click).
|
|
1274
|
+
* NOTE: Solo i nodi con figli già caricati (isLoaded o hasChildren) vengono espansi.
|
|
1275
|
+
* I nodi con isExpandible ma senza figli caricati rimangono chiusi.
|
|
1228
1276
|
*/
|
|
1229
1277
|
const setExpandedRecursively = useCallback((nodes, expanded) => {
|
|
1230
1278
|
if (!nodes || !Array.isArray(nodes))
|
|
@@ -1232,8 +1280,9 @@ const TMRelationViewer = ({ inputDcmts, isForMaster = false, showCurrentDcmtIndi
|
|
|
1232
1280
|
return nodes.map(node => {
|
|
1233
1281
|
const hasChildren = Array.isArray(node.items) && node.items.length > 0;
|
|
1234
1282
|
const newItems = hasChildren ? setExpandedRecursively(node.items, expanded) : node.items;
|
|
1235
|
-
// Only toggle expansion if the node
|
|
1236
|
-
|
|
1283
|
+
// Only toggle expansion if the node has children already loaded.
|
|
1284
|
+
// Nodes with isExpandible but no loaded children stay collapsed (will be loaded lazily).
|
|
1285
|
+
const canExpand = hasChildren || node.isLoaded;
|
|
1237
1286
|
return { ...node, expanded: canExpand ? expanded : node.expanded, items: newItems };
|
|
1238
1287
|
});
|
|
1239
1288
|
}, []);
|
|
@@ -224,7 +224,6 @@ export const generateTargetFileName = async (file, dcmtInfo, options) => {
|
|
|
224
224
|
case 'onlyCustomMetadata': {
|
|
225
225
|
try {
|
|
226
226
|
const filteredMetadata = await getFilteredMetadata(dcmtInfo.TID, dcmtInfo.DID, separatorChar);
|
|
227
|
-
console.log("filteredMetadata for TID:", dcmtInfo.TID, "DID:", dcmtInfo.DID, "is", filteredMetadata);
|
|
228
227
|
if (filteredMetadata) {
|
|
229
228
|
if (fileNamingMode === 'documentTypeAndCustomMetadata') {
|
|
230
229
|
const typeName = await getTypeName(dcmtInfo.TID);
|
|
@@ -17,11 +17,15 @@ export const isMetadataOnlyDcmt = (fileExt, fileCount) => {
|
|
|
17
17
|
* @param showTMRelationViewer - Se true, usa selectedItemsRelationViewer, altrimenti selectedDcmtInfos
|
|
18
18
|
*/
|
|
19
19
|
export const getMergePdfSelectionStats = (selectedDcmtInfos, selectedItemsFull, selectedItemsRelationViewer, showTMRelationViewer) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Pre-calcola info documenti selezionati in base alla sorgente dati:
|
|
22
|
+
* - RelationViewer (showTMRelationViewer=true): usa IRelatedDcmt con itemsCount/fileExt
|
|
23
|
+
* - Griglia documenti (showTMRelationViewer=false): usa DcmtInfo + lookup FILECOUNT da selectedItemsFull
|
|
24
|
+
*/
|
|
25
|
+
let docs;
|
|
26
|
+
if (showTMRelationViewer) {
|
|
27
|
+
// Sorgente: RelationViewer - itemsCount e fileExt disponibili direttamente su IRelatedDcmt
|
|
28
|
+
docs = selectedItemsRelationViewer
|
|
25
29
|
.filter(i => i.isDcmt)
|
|
26
30
|
.map(i => {
|
|
27
31
|
const ext = i.fileExt ?? undefined;
|
|
@@ -30,21 +34,25 @@ export const getMergePdfSelectionStats = (selectedDcmtInfos, selectedItemsFull,
|
|
|
30
34
|
ext,
|
|
31
35
|
isPdf: isPdfExt(ext),
|
|
32
36
|
isConvertible: isConvertibleToPdfExt(ext),
|
|
33
|
-
isMetadataOnly: isMetadataOnlyDcmt(ext,
|
|
37
|
+
isMetadataOnly: isMetadataOnlyDcmt(ext, i.fileCount)
|
|
34
38
|
};
|
|
35
|
-
})
|
|
36
|
-
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Sorgente: Griglia documenti - FILECOUNT richiede lookup da selectedItemsFull
|
|
43
|
+
const fileCountMap = new Map(selectedItemsFull.map(d => [`${d.TID}_${d.DID}`, d.FILECOUNT]));
|
|
44
|
+
docs = selectedDcmtInfos.map(d => {
|
|
37
45
|
const ext = d.FILEEXT ?? undefined;
|
|
38
46
|
const key = `${d.TID}_${d.DID}`;
|
|
39
|
-
const fileCount = fileCountMap.get(key);
|
|
40
47
|
return {
|
|
41
48
|
key,
|
|
42
49
|
ext,
|
|
43
50
|
isPdf: isPdfExt(ext),
|
|
44
51
|
isConvertible: isConvertibleToPdfExt(ext),
|
|
45
|
-
isMetadataOnly: isMetadataOnlyDcmt(ext,
|
|
52
|
+
isMetadataOnly: isMetadataOnlyDcmt(ext, fileCountMap.get(key))
|
|
46
53
|
};
|
|
47
54
|
});
|
|
55
|
+
}
|
|
48
56
|
// Elementi convertibili: file con estensione convertibile (esclusi documenti di soli metadati)
|
|
49
57
|
const convertibleSelectedItems = docs
|
|
50
58
|
.filter(i => i.isConvertible && !i.isMetadataOnly)
|
|
@@ -68,7 +76,9 @@ export const getMergePdfSelectionStats = (selectedDcmtInfos, selectedItemsFull,
|
|
|
68
76
|
metadataOnlySelectedItems,
|
|
69
77
|
hasMetadataOnlySelected: metadataOnlySelectedItems.length > 0,
|
|
70
78
|
mergeableSelectedCount,
|
|
71
|
-
|
|
79
|
+
// Merge possibile se: >= 2 file unibili OPPURE >= 1 file convertibile/metadata-only (verrà trasformato in PDF)
|
|
80
|
+
hasEnoughPdfForMerge: mergeableSelectedCount >= MIN_PDF_FOR_MERGE ||
|
|
81
|
+
(mergeableSelectedCount >= 1 && (convertibleSelectedItems.length > 0 || metadataOnlySelectedItems.length > 0)),
|
|
72
82
|
};
|
|
73
83
|
};
|
|
74
84
|
// LAZY LOADING pdf-lib
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { DcmtInfo } from "../../../ts";
|
|
3
2
|
interface TMDcmtCheckoutInfoFormProps {
|
|
4
3
|
dtdName: string;
|
|
5
4
|
selectedDcmtOrFocused: DcmtInfo;
|
|
6
5
|
onClose: () => void;
|
|
7
6
|
}
|
|
8
|
-
declare const TMDcmtCheckoutInfoForm: (props: TMDcmtCheckoutInfoFormProps) =>
|
|
7
|
+
declare const TMDcmtCheckoutInfoForm: (props: TMDcmtCheckoutInfoFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
8
|
export default TMDcmtCheckoutInfoForm;
|