@topconsultnpm/sdkui-react 6.21.0-dev4.9 → 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/base/TMTreeView.d.ts +16 -13
- package/lib/components/base/TMTreeView.js +230 -64
- package/lib/components/features/documents/TMDcmtIcon.d.ts +3 -1
- package/lib/components/features/documents/TMDcmtIcon.js +5 -32
- package/lib/components/features/documents/TMFileUploader.js +1 -1
- package/lib/components/features/documents/TMMasterDetailDcmts.js +165 -11
- package/lib/components/features/documents/TMMergeToPdfForm.js +6 -3
- package/lib/components/features/documents/TMRelationViewer.d.ts +15 -10
- package/lib/components/features/documents/TMRelationViewer.js +532 -179
- package/lib/components/features/documents/copyAndMergeDcmtsShared.d.ts +4 -3
- package/lib/components/features/documents/copyAndMergeDcmtsShared.js +46 -23
- package/lib/components/features/documents/mergePdfUtils.js +21 -11
- package/lib/components/features/search/TMSearchResult.js +20 -5
- package/lib/components/viewers/TMTidViewer.js +14 -2
- package/lib/helper/SDKUI_Globals.d.ts +1 -0
- package/lib/helper/SDKUI_Globals.js +1 -0
- package/lib/helper/SDKUI_Localizator.d.ts +28 -0
- package/lib/helper/SDKUI_Localizator.js +280 -0
- package/lib/helper/TMIcons.d.ts +1 -0
- package/lib/helper/TMIcons.js +3 -0
- package/lib/helper/TMUtils.d.ts +33 -1
- package/lib/helper/TMUtils.js +104 -1
- package/lib/helper/helpers.d.ts +3 -0
- package/lib/helper/helpers.js +29 -1
- package/lib/hooks/useDocumentOperations.js +2 -2
- package/package.json +3 -4
|
@@ -7,15 +7,18 @@ import { IconMultipleSelection, IconCheckFile, IconDetailDcmts, SDKUI_Localizato
|
|
|
7
7
|
import { FormModes, SearchResultContext } from '../../../ts';
|
|
8
8
|
import { TMColors } from '../../../utils/theme';
|
|
9
9
|
import ShowAlert from '../../base/TMAlert';
|
|
10
|
-
import { DeviceType } from '../../base/TMDeviceProvider';
|
|
10
|
+
import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
|
|
11
11
|
import { TMSaveFormButtonPrevious, TMSaveFormButtonNext } from '../../forms/TMSaveForm';
|
|
12
12
|
import TMPanelManagerContainer from '../../layout/panelManager/TMPanelManagerContainer';
|
|
13
13
|
import { TMPanelManagerProvider, useTMPanelManagerContext } from '../../layout/panelManager/TMPanelManagerContext';
|
|
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
|
+
import TMToppyMessage from '../../../helper/TMToppyMessage';
|
|
20
|
+
import TMPanel from '../../base/TMPanel';
|
|
21
|
+
import sixLogo from '../../../assets/six.png';
|
|
19
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 }) => {
|
|
20
23
|
const floatingBarContainerRef = useRef(null);
|
|
21
24
|
const [focusedItem, setFocusedItem] = useState();
|
|
@@ -27,6 +30,12 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
27
30
|
const [isCheckingFirstLoad, setIsCheckingFirstLoad] = useState(true);
|
|
28
31
|
const [contextMenuVisible, setContextMenuVisible] = useState(false);
|
|
29
32
|
const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
|
|
33
|
+
// Track if TMRelationViewer is loading (used to disable context menu during loading)
|
|
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);
|
|
30
39
|
const [dtdFocused, setDtdFocused] = useState();
|
|
31
40
|
const [refreshKey, setRefreshKey] = useState(0);
|
|
32
41
|
// Separate refresh key for TMFormOrResultWrapper only (doesn't affect tmTreeView)
|
|
@@ -35,6 +44,21 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
35
44
|
const [focusedItemFormData, setFocusedItemFormData] = useState([]);
|
|
36
45
|
// Trigger operationItems refresh (after file substitution, etc.)
|
|
37
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]);
|
|
38
62
|
// Increments trigger counter to force operationItems to re-calculate
|
|
39
63
|
const onRefreshOperationsDatagrid = useCallback(async () => {
|
|
40
64
|
setRefreshOperationsTrigger(prev => prev + 1);
|
|
@@ -213,6 +237,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
213
237
|
onRefreshAfterAddDcmtToFavs,
|
|
214
238
|
},
|
|
215
239
|
});
|
|
240
|
+
const { dcmtOperations: { abortController, showWaitPanel, showPrimary, waitPanelTitle, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, }, } = features;
|
|
216
241
|
// Load dtdMaster when inputDcmts changes
|
|
217
242
|
useEffect(() => {
|
|
218
243
|
const loadDtdMaster = async () => {
|
|
@@ -253,6 +278,7 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
253
278
|
useEffect(() => {
|
|
254
279
|
if (noRelationsOnFirstLoad) {
|
|
255
280
|
setNoRelationsOnFirstLoad(false);
|
|
281
|
+
setIsCheckingFirstLoad(false); // Hide spinner before navigating back
|
|
256
282
|
ShowAlert({
|
|
257
283
|
message: SDKUI_Localizator.RelatedDcmtsNotFound,
|
|
258
284
|
title: SDKUI_Localizator.RelationsNotFound,
|
|
@@ -265,14 +291,14 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
265
291
|
const commandsMenuItems = [
|
|
266
292
|
{
|
|
267
293
|
icon: _jsx(IconMultipleSelection, { color: allowMultipleSelection ? TMColors.tertiary : TMColors.text_normal }),
|
|
268
|
-
name:
|
|
294
|
+
name: allowMultipleSelection ? SDKUI_Localizator.DisableMultipleSelection : SDKUI_Localizator.EnableMultipleSelection,
|
|
269
295
|
onClick: () => {
|
|
270
296
|
setAllowMultipleSelection(prev => !prev);
|
|
271
297
|
}
|
|
272
298
|
},
|
|
273
299
|
{
|
|
274
|
-
icon: _jsx(IconCheckFile, {}),
|
|
275
|
-
name:
|
|
300
|
+
icon: _jsx(IconCheckFile, { color: showZeroDcmts ? TMColors.tertiary : TMColors.text_normal }),
|
|
301
|
+
name: showZeroDcmts ? SDKUI_Localizator.HideDetailsWithZeroDocs : SDKUI_Localizator.ShowDetailsWithZeroDocs,
|
|
276
302
|
onClick: () => {
|
|
277
303
|
setShowZeroDcmts(prev => !prev);
|
|
278
304
|
}
|
|
@@ -294,17 +320,22 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
294
320
|
_jsx(TMNothingToShow, { text: getTitle(), secondText: SDKUI_Localizator.NoDataToDisplay, icon: isForMaster ? _jsx(IconDetailDcmts, { fontSize: 96, transform: 'scale(-1, 1)' }) : _jsx(IconDetailDcmts, { fontSize: 96 }) })
|
|
295
321
|
:
|
|
296
322
|
_jsxs("div", { ref: floatingBarContainerRef, style: { width: "100%", height: "100%" }, onContextMenu: (e) => {
|
|
323
|
+
// Disable context menu when loading
|
|
324
|
+
if (isRelationViewerLoading) {
|
|
325
|
+
e.preventDefault();
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
297
328
|
// Mostra context menu anche sullo spazio bianco (quando non si clicca su un item)
|
|
298
329
|
e.preventDefault();
|
|
299
330
|
setContextMenuPosition({ x: e.clientX, y: e.clientY });
|
|
300
331
|
setContextMenuVisible(true);
|
|
301
332
|
}, children: [_jsx(TMRelationViewerWrapper, { refreshKey: refreshKey, inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, showZeroDcmts: showZeroDcmts,
|
|
302
333
|
// customItemRender={customItemRender}
|
|
303
|
-
allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound, onItemContextMenu: onItemContextMenu, focusedItemFormData: focusedItemFormData }), _jsx(TMContextMenu, { items: operationItems, externalControl: {
|
|
334
|
+
allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: handleSelectedItemsChanged, onNoRelationsFound: handleNoRelationsFound, onItemContextMenu: isRelationViewerLoading ? undefined : onItemContextMenu, focusedItemFormData: focusedItemFormData, onLoadingStateChanged: setIsRelationViewerLoading }), _jsx(TMContextMenu, { items: operationItems, externalControl: {
|
|
304
335
|
visible: contextMenuVisible,
|
|
305
336
|
position: contextMenuPosition,
|
|
306
337
|
onClose: () => setContextMenuVisible(false)
|
|
307
|
-
} })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData]);
|
|
338
|
+
} })] }) }), [inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, allowMultipleSelection, focusedItem, selectedItems, handleFocusedItemChanged, handleSelectedItemsChanged, handleNoRelationsFound, onItemContextMenu, contextMenuVisible, contextMenuPosition, refreshKey, focusedItemFormData, isRelationViewerLoading]);
|
|
308
339
|
const tmFormOrResult = useMemo(() => _jsx(TMFormOrResultWrapper, { refreshKey: refreshKeyFormOrResult, deviceType: deviceType, focusedItem: focusedItem, onTaskCreateRequest: onTaskCreateRequest, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, handleNavigateToReference: handleNavigateToReference, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, editPdfForm: editPdfForm, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onRefreshSearchResults: onRefreshAllPanels }), [focusedItem, deviceType, allTasks, handleNavigateToWGs, handleNavigateToDossiers, handleNavigateToReference, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshAfterAddDcmtToFavs, refreshKeyFormOrResult]);
|
|
309
340
|
const initialPanelDimensions = {
|
|
310
341
|
'tmTreeView': { width: '50%', height: '100%' },
|
|
@@ -382,7 +413,10 @@ const TMMasterDetailDcmts = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallba
|
|
|
382
413
|
toolbarOptions: { icon: _jsx(IconSearchCheck, { fontSize: 24 }), visible: false, orderNumber: 2, isActive: allInitialPanelVisibility['tmFormOrResult'] }
|
|
383
414
|
}
|
|
384
415
|
], [tmTreeView, tmFormOrResult, focusedItem?.isDcmt, dtdMaster]);
|
|
385
|
-
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] })] }));
|
|
386
420
|
};
|
|
387
421
|
export default TMMasterDetailDcmts;
|
|
388
422
|
/**
|
|
@@ -391,8 +425,37 @@ export default TMMasterDetailDcmts;
|
|
|
391
425
|
* - Panel visibility toggling
|
|
392
426
|
* - Focus delay handling
|
|
393
427
|
*/
|
|
394
|
-
const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound, onItemContextMenu, focusedItemFormData }) => {
|
|
428
|
+
const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurrentDcmtIndicator, showZeroDcmts, customItemRender, allowMultipleSelection, focusedItem, selectedItems, onFocusedItemChanged, onSelectedItemsChanged, onNoRelationsFound, onItemContextMenu, focusedItemFormData, onLoadingStateChanged }) => {
|
|
395
429
|
const { setPanelVisibilityById, setToolbarButtonVisibility } = useTMPanelManagerContext();
|
|
430
|
+
// Monitor device type changes to restore panel visibility when switching from mobile to desktop
|
|
431
|
+
const deviceType = useDeviceType();
|
|
432
|
+
const prevDeviceTypeRef = useRef(deviceType);
|
|
433
|
+
// Restore panel visibility when switching from mobile to desktop
|
|
434
|
+
useEffect(() => {
|
|
435
|
+
const prevDeviceType = prevDeviceTypeRef.current;
|
|
436
|
+
prevDeviceTypeRef.current = deviceType;
|
|
437
|
+
// When switching from mobile to desktop, restore panel visibility based on current focused item
|
|
438
|
+
if (prevDeviceType === DeviceType.MOBILE && deviceType !== DeviceType.MOBILE) {
|
|
439
|
+
// Small delay to let the panel manager complete its internal state update
|
|
440
|
+
setTimeout(() => {
|
|
441
|
+
// Force tmFormOrResult panel to be visible
|
|
442
|
+
setPanelVisibilityById('tmFormOrResult', true);
|
|
443
|
+
// Restore child panel visibility based on focused item
|
|
444
|
+
if (focusedItem?.isDcmt) {
|
|
445
|
+
setPanelVisibilityById('tmSearchResult', false);
|
|
446
|
+
setPanelVisibilityById('tmDcmtForm', true);
|
|
447
|
+
setToolbarButtonVisibility('tmSearchResult', false);
|
|
448
|
+
setToolbarButtonVisibility('tmDcmtForm', true);
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
setPanelVisibilityById('tmSearchResult', true);
|
|
452
|
+
setPanelVisibilityById('tmDcmtForm', false);
|
|
453
|
+
setToolbarButtonVisibility('tmSearchResult', true);
|
|
454
|
+
setToolbarButtonVisibility('tmDcmtForm', false);
|
|
455
|
+
}
|
|
456
|
+
}, 50);
|
|
457
|
+
}
|
|
458
|
+
}, [deviceType, focusedItem, setPanelVisibilityById, setToolbarButtonVisibility]);
|
|
396
459
|
// Handle focused item changes with panel visibility management
|
|
397
460
|
const handleFocusedItemChanged = useCallback((item) => {
|
|
398
461
|
onFocusedItemChanged?.(item);
|
|
@@ -422,7 +485,7 @@ const TMRelationViewerWrapper = ({ refreshKey, inputDcmts, isForMaster, showCurr
|
|
|
422
485
|
onItemContextMenu?.(item, e);
|
|
423
486
|
}, 100);
|
|
424
487
|
}, [onItemContextMenu, handleFocusedItemChanged]);
|
|
425
|
-
return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, showExpandAllButton: true, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData }, refreshKey));
|
|
488
|
+
return (_jsx(TMRelationViewer, { inputDcmts: inputDcmts, isForMaster: isForMaster, showCurrentDcmtIndicator: showCurrentDcmtIndicator, initialShowZeroDcmts: showZeroDcmts, customItemRender: customItemRender, allowMultipleSelection: allowMultipleSelection, focusedItem: focusedItem, selectedItems: selectedItems, onFocusedItemChanged: handleFocusedItemChanged, onSelectedItemsChanged: onSelectedItemsChanged, maxDepthLevel: 1, invertMasterNavigation: false, showExpandAllButton: true, onNoRelationsFound: onNoRelationsFound, onItemContextMenu: onContextMenu, focusedItemFormData: focusedItemFormData, onLoadingStateChanged: onLoadingStateChanged }, refreshKey));
|
|
426
489
|
};
|
|
427
490
|
const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCreateRequest, allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback, handleNavigateToWGs, handleNavigateToDossiers, onRefreshAfterAddDcmtToFavs, editPdfForm, openS4TViewer, onOpenS4TViewerRequest, onOpenPdfEditorRequest, onRefreshSearchAsyncDatagrid, onRefreshSearchResults, handleNavigateToReference, fetchRemoteCertificates }) => {
|
|
428
491
|
const { setPanelVisibilityById } = useTMPanelManagerContext();
|
|
@@ -430,5 +493,96 @@ const TMFormOrResultWrapper = ({ refreshKey, deviceType, focusedItem, onTaskCrea
|
|
|
430
493
|
_jsx(TMDcmtForm, { groupId: 'tmFormOrResult', TID: focusedItem?.tid, DID: focusedItem.did, allowButtonsRefs: true, isClosable: deviceType !== DeviceType.MOBILE, allowNavigation: false, allowRelations: deviceType !== DeviceType.MOBILE, showDcmtFormSidebar: false, onClose: () => { setPanelVisibilityById('tmTreeView', true); }, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, onReferenceClick: handleNavigateToReference, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.tid, focusedItem?.did), openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, datagridUtility: {
|
|
431
494
|
onRefreshSearchAsyncDatagrid,
|
|
432
495
|
}, fetchRemoteCertificates: fetchRemoteCertificates }, refreshKey) :
|
|
433
|
-
_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) }));
|
|
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)) }));
|
|
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 }))] }) }));
|
|
434
588
|
};
|
|
@@ -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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { DcmtTypeDescriptor, SearchResultDescriptor, DataColumnDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
|
+
import { DcmtMetadataMap } from '../../../helper';
|
|
3
4
|
import { DcmtInfo, MetadataValueDescriptorEx } from '../../../ts';
|
|
4
5
|
import { ITMTreeItem } from '../../base/TMTreeView';
|
|
5
6
|
/**
|
|
@@ -19,10 +20,11 @@ export interface RelationTreeItem extends ITMTreeItem {
|
|
|
19
20
|
isSeparator?: boolean;
|
|
20
21
|
isInfoMessage?: boolean;
|
|
21
22
|
isLogDel?: number;
|
|
22
|
-
values?:
|
|
23
|
+
values?: DcmtMetadataMap;
|
|
23
24
|
searchResult?: SearchResultDescriptor[];
|
|
24
25
|
itemsCount?: number;
|
|
25
26
|
fileExt?: string;
|
|
27
|
+
fileCount?: number;
|
|
26
28
|
}
|
|
27
29
|
/**
|
|
28
30
|
* Props for TMRelationViewer component
|
|
@@ -72,7 +74,10 @@ export interface TMRelationViewerProps {
|
|
|
72
74
|
* Value rendering respects DataDomain (uses TMDataListItemViewer for lists, TMDataUserIdItemViewer for users, etc.)
|
|
73
75
|
*/
|
|
74
76
|
showMetadataNames?: boolean;
|
|
75
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* Maximum depth level for recursive loading (default: 2).
|
|
79
|
+
* Use 0 for unlimited depth (expand as much as possible).
|
|
80
|
+
*/
|
|
76
81
|
maxDepthLevel?: number;
|
|
77
82
|
/**
|
|
78
83
|
* If true (default), when isForMaster=true shows: detail doc → master docs as children (inverted navigation)
|
|
@@ -122,6 +127,11 @@ export interface TMRelationViewerProps {
|
|
|
122
127
|
* (root container + first document + first correlation folder).
|
|
123
128
|
*/
|
|
124
129
|
defaultExpandAll?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Callback invoked when loading state changes.
|
|
132
|
+
* Useful to disable interactions (like context menu) during loading.
|
|
133
|
+
*/
|
|
134
|
+
onLoadingStateChanged?: (isLoading: boolean) => void;
|
|
125
135
|
}
|
|
126
136
|
/**
|
|
127
137
|
* Check if document type has detail relations
|
|
@@ -131,21 +141,16 @@ export declare const hasDetailRelations: (mTID: number | undefined) => Promise<b
|
|
|
131
141
|
* Check if document type has master relations
|
|
132
142
|
*/
|
|
133
143
|
export declare const hasMasterRelations: (dTID: number | undefined) => Promise<boolean>;
|
|
134
|
-
/**
|
|
135
|
-
* Get metadata keys excluding system metadata
|
|
136
|
-
*/
|
|
137
|
-
export declare const getMetadataKeys: (obj: any) => string[];
|
|
138
|
-
/**
|
|
139
|
-
* Get display value keys for a document (max 5, prioritize SYS_Abstract)
|
|
140
|
-
*/
|
|
141
|
-
export declare const getDcmtDisplayValue: (obj: any) => string[];
|
|
142
144
|
/**
|
|
143
145
|
* Get display value formatted by column type
|
|
144
146
|
*/
|
|
145
147
|
export declare const getDisplayValueByColumn: (col: DataColumnDescriptor | undefined, value: any) => any;
|
|
146
148
|
/**
|
|
147
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
|
|
148
152
|
*/
|
|
149
153
|
export declare const searchResultToDataSource: (searchResult: SearchResultDescriptor | undefined, hideSysMetadata?: boolean) => Promise<any[]>;
|
|
154
|
+
export declare const DEFAULT_RELATION_EXPAND_LEVEL = 4;
|
|
150
155
|
declare const TMRelationViewer: React.FC<TMRelationViewerProps>;
|
|
151
156
|
export default TMRelationViewer;
|