@topconsultnpm/sdkui-react 6.22.0-dev2.2 → 6.22.0-dev2.21
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 +277 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +354 -0
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +234 -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 +24 -0
- package/lib/helper/SDKUI_Localizator.js +240 -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 +98 -0
- package/lib/hooks/useMultiMasterDetailDcmts.js +567 -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
|
@@ -3,11 +3,11 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
import { LoadIndicator } from 'devextreme-react';
|
|
5
5
|
import { AppModules, DataColumnTypes, DataListViewModes, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataDomains, SDK_Globals, SystemMIDsAsNumber, UserListCacheService, } from '@topconsultnpm/sdk-ts';
|
|
6
|
-
import { deepCompare, formatDateTimeByMetadataFormat, formatNumberByMetadataFormat, generateUniqueColumnKeys, genUniqueId, getColumnFormatInfo, getSearchToolbarVisibility, IconAll, IconBoard, IconDcmtTypeSys, IconDelete, IconMenuVertical, IconPlatform, IconRefresh, IconSearchCheck, IconShow, isApprovalWorkflowView, isSign4TopEnabled, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, SDKUI_Globals, SDKUI_Localizator } from '../../../helper';
|
|
6
|
+
import { customizeSearchByDisplayText, deepCompare, formatDateTimeByMetadataFormat, formatNumberByMetadataFormat, generateUniqueColumnKeys, genUniqueId, getColumnFormatInfo, getDateDisplayText, getNumberDisplayText, getSearchToolbarVisibility, IconAll, IconBoard, IconDcmtTypeSys, IconDelete, IconDuplicate, IconEdit, IconMenuVertical, IconPlatform, IconRefresh, IconSearchCheck, IconShow, isApprovalWorkflowView, isSign4TopEnabled, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, SDKUI_Globals, SDKUI_Localizator, IconCloseOutline } from '../../../helper';
|
|
7
7
|
import { CounterItemKey } from '../../base/TMCounterContainer';
|
|
8
8
|
import { getDcmtCicoStatus } from '../../../helper/checkinCheckoutManager';
|
|
9
9
|
import { DcmtOperationTypes, SearchResultContext, } from '../../../ts';
|
|
10
|
-
import { Gutters } from '../../../utils/theme';
|
|
10
|
+
import { Gutters, TMColors } from '../../../utils/theme';
|
|
11
11
|
import { useDataListItem } from '../../../hooks/useDataListItem';
|
|
12
12
|
import { useDataUserIdItem } from '../../../hooks/useDataUserIdItem';
|
|
13
13
|
import { getSelectedDcmtsOrFocused, useDocumentOperations } from '../../../hooks/useDocumentOperations';
|
|
@@ -55,9 +55,11 @@ const TMSearchResult = ({
|
|
|
55
55
|
// Data
|
|
56
56
|
groupId, searchResults = [], context = SearchResultContext.METADATA_SEARCH, title, selectedSearchResultTID, floatingActionConfig, workingGroupContext = undefined, inputDID,
|
|
57
57
|
// Boolean flags to enable/disable features
|
|
58
|
-
autoFocusFirstRow = true, formAutoOpen, isVisible = true, allowRelations = true, openDcmtFormAsModal = false, showSearchResultSidebar = true, showDcmtFormSidebar = true, showSelector = false, isClosable = false, allowFloatingBar = true, showToolbarHeader = true, showBackButton = true, disableAccordionIfSingleCategory = false, editPdfForm = false, openS4TViewer = false, showTodoDcmtForm = false, showToppyDraggableHelpCenter = true, toppyHelpCenterUsePortal = false, showNoDcmtFoundMessage = true, enablePinIcons = true,
|
|
58
|
+
autoFocusFirstRow = true, formAutoOpen, isVisible = true, allowRelations = true, openDcmtFormAsModal = false, showSearchResultSidebar = true, showDcmtFormSidebar = true, showSelector = false, isClosable = false, allowFloatingBar = true, showToolbarHeader = true, showBackButton = true, showToolbarCloseButton = false, disableAccordionIfSingleCategory = false, editPdfForm = false, openS4TViewer = false, showTodoDcmtForm = false, showToppyDraggableHelpCenter = true, toppyHelpCenterUsePortal = false, showNoDcmtFoundMessage = true, enablePinIcons = true, showCounterConfig = true, showActionsColumn = false, compactPager = false,
|
|
59
|
+
// Counters
|
|
60
|
+
counterConfig,
|
|
59
61
|
// Callbacks (optional)
|
|
60
|
-
openInOffice, onRefreshAfterAddDcmtToFavs, onRefreshSearchAsyncDatagrid, onSelectedTIDChanged, onWFOperationCompleted, onClose, onFileOpened, onTaskCreateRequest, openWGsCopyMoveForm, openCommentFormCallback, openAddDocumentForm, onOpenS4TViewerRequest, onOpenPdfEditorRequest, openFileUploaderPdfEditor, passToArchiveCallback, onReferenceClick,
|
|
62
|
+
openInOffice, onRefreshAfterAddDcmtToFavs, onRefreshSearchAsyncDatagrid, onSelectedTIDChanged, onSelectedTIDCleared, onWFOperationCompleted, onClose, onFileOpened, onTaskCreateRequest, openWGsCopyMoveForm, openCommentFormCallback, openAddDocumentForm, onOpenS4TViewerRequest, onOpenPdfEditorRequest, openFileUploaderPdfEditor, passToArchiveCallback, onReferenceClick,
|
|
61
63
|
// Tasks
|
|
62
64
|
allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTaskCallback, editTaskCallback,
|
|
63
65
|
// Navigation
|
|
@@ -69,13 +71,19 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
69
71
|
// Quando l'utente seleziona manualmente, il ref viene settato a false e il focus automatico
|
|
70
72
|
// torna al comportamento normale.
|
|
71
73
|
const isFirstAutoFocusRef = useRef(true);
|
|
74
|
+
// Mostra il pannello lista. È una ref perché il TMPanelManagerProvider sta dentro al JSX di
|
|
75
|
+
// questo componente, quindi qui il context non si può usare: la riempie ShowMainPanelBridge.
|
|
76
|
+
const showMainPanelRef = useRef(null);
|
|
72
77
|
// ID state to force remount of components
|
|
73
78
|
const [id, setID] = useState('');
|
|
74
79
|
// Document type descriptor of the currently document
|
|
75
80
|
const [fromDTD, setFromDTD] = useState();
|
|
76
81
|
const [currentDcmt, setCurrentDcmt] = useState();
|
|
77
|
-
//
|
|
78
|
-
|
|
82
|
+
// Passo corrente. Su mobile decide anche quale pannello è a schermo (vedi isSteppedLayout).
|
|
83
|
+
// 'auto' -> l'utente non ha ancora scelto: si può selezionare il primo tipo documento
|
|
84
|
+
// 'selector' -> è tornato indietro col back: non selezionare niente al posto suo
|
|
85
|
+
// 'results' -> è sulla griglia del tipo scelto
|
|
86
|
+
const [navStep, setNavStep] = useState('auto');
|
|
79
87
|
// State to control the selected search result
|
|
80
88
|
const [selectedSearchResult, setSelectedSearchResult] = useState();
|
|
81
89
|
// State to control the search results to show in the datagrid
|
|
@@ -303,7 +311,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
303
311
|
createTaskFromDocumentOrWorkItem();
|
|
304
312
|
}
|
|
305
313
|
};
|
|
306
|
-
const { operationItems, renderFloatingBar, renderDcmtOperations, features, } = useDocumentOperations({
|
|
314
|
+
const { operationItems, selectedDcmtInfos, renderFloatingBar, renderDcmtOperations, features, } = useDocumentOperations({
|
|
307
315
|
context: context,
|
|
308
316
|
documentData: {
|
|
309
317
|
dtd: fromDTD,
|
|
@@ -377,9 +385,60 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
377
385
|
openTaskFormHandler,
|
|
378
386
|
},
|
|
379
387
|
});
|
|
380
|
-
const { isOpenDcmtForm, openFormHandler, dcmtFormLayoutMode, onDcmtFormOpenChange, showSearchTMDatagrid,
|
|
388
|
+
const { isOpenDcmtForm, openFormHandler, dcmtFormLayoutMode, onDcmtFormOpenChange, showSearchTMDatagrid, showDcmtTypesSelection, showExportForm, updateBatchUpdateForm, closeDcmtFormHandler, handleSignApprove, checkoutInfo: { showCicoWaitPanel, cicoWaitPanelTitle, showCicoPrimaryProgress, cicoPrimaryProgressText, cicoPrimaryProgressValue, cicoPrimaryProgressMax, }, dcmtOperations: { abortController, showWaitPanel, showPrimary, waitPanelTitle, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync, }, relatedDocumentsInfo: { isOpenDetails, isOpenMaster, checkRelatedDcmtsArchiveCapability, checkManyToManyCapability, }, toppyOperations: { showApprovePopup, showRejectPopup, showReAssignPopup, showMoreInfoPopup, updateShowApprovePopup, updateShowRejectPopup, updateShowReAssignPopup, updateShowMoreInfoPopup } } = features;
|
|
389
|
+
// ----- Azioni della colonna di riga (showActionsColumn) -----------------------------------------
|
|
390
|
+
// Le voci di operationItems agiscono sui documenti selezionati o, in mancanza, su quello a fuoco:
|
|
391
|
+
// non accettano una riga come argomento. Il click sull'icona quindi azzera la selezione e porta il
|
|
392
|
+
// fuoco sulla riga cliccata, poi attende. L'attesa non è sul fuoco ma su selectedDcmtInfos, che
|
|
393
|
+
// l'hook ricalcola in un effect (un render più tardi): lanciare l'operazione prima significherebbe
|
|
394
|
+
// eseguirla sulla riga precedente.
|
|
395
|
+
const pendingRowActionRef = useRef(undefined);
|
|
396
|
+
const requestRowAction = useCallback((operationId, rowData) => {
|
|
397
|
+
if (!showActionsColumn)
|
|
398
|
+
return;
|
|
399
|
+
if (rowData?.TID === undefined || rowData?.DID === undefined) {
|
|
400
|
+
ShowAlert({ message: SDKUI_Localizator.InvalidDcmt, mode: "warning", duration: 3000 });
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
pendingRowActionRef.current = { operationId, TID: rowData.TID, DID: rowData.DID };
|
|
404
|
+
isFirstAutoFocusRef.current = false;
|
|
405
|
+
setSelectedItems([]);
|
|
406
|
+
setFocusedItem(rowData);
|
|
407
|
+
}, [showActionsColumn]);
|
|
408
|
+
// La richiesta viene scartata se il documento sparisce dai risultati (es. refresh dopo
|
|
409
|
+
// un'eliminazione): senza questo resterebbe appesa e partirebbe al prossimo cambio di fuoco.
|
|
410
|
+
useEffect(() => { pendingRowActionRef.current = undefined; }, [selectedSearchResult, lastUpdateSearchTime]);
|
|
411
|
+
useEffect(() => {
|
|
412
|
+
if (!showActionsColumn)
|
|
413
|
+
return;
|
|
414
|
+
const pending = pendingRowActionRef.current;
|
|
415
|
+
if (!pending)
|
|
416
|
+
return;
|
|
417
|
+
// L'hook non ha ancora recepito la riga richiesta: si riproverà al prossimo aggiornamento
|
|
418
|
+
if (selectedDcmtInfos.length !== 1)
|
|
419
|
+
return;
|
|
420
|
+
if (selectedDcmtInfos[0].TID !== pending.TID || selectedDcmtInfos[0].DID !== pending.DID)
|
|
421
|
+
return;
|
|
422
|
+
pendingRowActionRef.current = undefined;
|
|
423
|
+
const operation = findOperationItemById(operationItems, pending.operationId);
|
|
424
|
+
// Ora che il fuoco è sulla riga, `disabled` riflette i permessi per quel documento
|
|
425
|
+
if (!operation || operation.disabled || operation.visible === false)
|
|
426
|
+
return;
|
|
427
|
+
operation.onClick?.();
|
|
428
|
+
}, [showActionsColumn, selectedDcmtInfos, operationItems]);
|
|
381
429
|
const deviceType = useDeviceType();
|
|
382
430
|
const isMobile = deviceType === DeviceType.MOBILE;
|
|
431
|
+
const hasSingleDcmtType = currentSearchResults.length === 1;
|
|
432
|
+
// Su mobile si vede un pannello per volta; su desktop selettore e griglia sono affiancati
|
|
433
|
+
const isSteppedLayout = showSelector && isMobile;
|
|
434
|
+
// Un solo tipo documento su desktop: non c'è niente da scegliere, quindi il selettore sparisce
|
|
435
|
+
// (larghezza 0, nessun separatore) e lo spazio va tutto alla griglia. Il menu "Altro" permette
|
|
436
|
+
// di riaprirlo (vedi canToggleDcmtTypesSelection nell'hook).
|
|
437
|
+
const isSelectorCollapsed = showSelector && !isSteppedLayout && hasSingleDcmtType && !showDcmtTypesSelection;
|
|
438
|
+
// Senza selettore lo spazio va tutto alla griglia; altrimenti a step su mobile, affiancati su desktop
|
|
439
|
+
const splitterSizes = (!showSelector || isSelectorCollapsed) ? ['0%', '100%']
|
|
440
|
+
: isSteppedLayout ? (navStep === 'results' ? ['0', '100%'] : ['100%', '0'])
|
|
441
|
+
: ['30%', '70%'];
|
|
383
442
|
const selectedDocs = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
|
|
384
443
|
// Disable the "Sign/Approve" button if:
|
|
385
444
|
// 1. No document or multiple documents are selected, OR
|
|
@@ -400,8 +459,14 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
400
459
|
setSelectedSearchResult(undefined);
|
|
401
460
|
return;
|
|
402
461
|
}
|
|
462
|
+
// Un solo tipo documento: selezionalo e vai ai risultati, a meno che l'utente sia tornato indietro
|
|
403
463
|
if (searchResults.length === 1) {
|
|
464
|
+
if (navStep === 'selector') {
|
|
465
|
+
setSelectedSearchResult(undefined);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
404
468
|
setSelectedSearchResult(searchResults[0]);
|
|
469
|
+
setNavStep('results');
|
|
405
470
|
return;
|
|
406
471
|
}
|
|
407
472
|
// Se il TID precedentemente selezionato esiste ancora nei nuovi risultati, mantienilo.
|
|
@@ -415,6 +480,11 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
415
480
|
return;
|
|
416
481
|
}
|
|
417
482
|
}
|
|
483
|
+
// L'utente è sul selettore
|
|
484
|
+
if (isMobile && navStep !== 'results') {
|
|
485
|
+
setSelectedSearchResult(undefined);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
418
488
|
// Altrimenti seleziona il primo risultato ordinato
|
|
419
489
|
setSelectedSearchResult(orderByName(searchResults)[0]);
|
|
420
490
|
}, [searchResults]);
|
|
@@ -471,7 +541,9 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
471
541
|
return;
|
|
472
542
|
if (focusedItem?.DID != inputDID)
|
|
473
543
|
return;
|
|
474
|
-
|
|
544
|
+
if (focusedItem?.TID === undefined)
|
|
545
|
+
return;
|
|
546
|
+
onDcmtFormOpenChange(true, LayoutModes.Update);
|
|
475
547
|
}, [inputDID, formAutoOpen, focusedItem]);
|
|
476
548
|
// Quando openS4TViewer è true, apri automaticamente il viewer S4T
|
|
477
549
|
useEffect(() => {
|
|
@@ -531,47 +603,75 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
531
603
|
let counters = (showSelector && disableAccordionIfSingleCategory && searchResults.length > 1) ? getSearchResultCountersSingleCategory(searchResults) : "";
|
|
532
604
|
if (title)
|
|
533
605
|
return title + counters;
|
|
534
|
-
|
|
606
|
+
// Nome del tipo documento selezionato, accodato al titolo
|
|
607
|
+
const selectedDcmtTypeName = selectedSearchResult?.fromName ?? (searchResults?.length === 1 ? searchResults[0]?.fromName : undefined);
|
|
608
|
+
const withSelectedDcmtTypeName = (baseTitle) => selectedDcmtTypeName ? `${baseTitle} - ${selectedDcmtTypeName}` : baseTitle;
|
|
609
|
+
let titleHeader = withSelectedDcmtTypeName('Ricerca per metadati');
|
|
535
610
|
switch (context) {
|
|
536
611
|
case SearchResultContext.MASTER_DETAIL:
|
|
537
612
|
case SearchResultContext.METADATA_SEARCH:
|
|
538
613
|
titleHeader = `${searchResults?.length > 1 ? selectedSearchResult?.fromName ?? 'Ricerca per metadati' : searchResults[0]?.fromName ?? 'Ricerca per metadati'}`;
|
|
539
614
|
break;
|
|
540
615
|
case SearchResultContext.FAVORITES_AND_RECENTS:
|
|
541
|
-
titleHeader = SDKUI_Localizator.FavoritesAndRecentDcmts;
|
|
616
|
+
titleHeader = withSelectedDcmtTypeName(SDKUI_Localizator.FavoritesAndRecentDcmts);
|
|
542
617
|
break;
|
|
543
618
|
case SearchResultContext.WORKFLOW_APPROVE:
|
|
544
|
-
titleHeader = SDKUI_Localizator.WorkflowApproval;
|
|
619
|
+
titleHeader = withSelectedDcmtTypeName(SDKUI_Localizator.WorkflowApproval);
|
|
545
620
|
break;
|
|
546
621
|
case SearchResultContext.FREE_SEARCH:
|
|
547
|
-
titleHeader =
|
|
622
|
+
titleHeader = withSelectedDcmtTypeName('Risultato della ricerca full text');
|
|
548
623
|
break;
|
|
549
624
|
}
|
|
550
625
|
return titleHeader + counters;
|
|
551
626
|
};
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
setSelectedSearchResult(undefined);
|
|
570
|
-
}
|
|
571
|
-
setSplitterSize(['100%', '0']);
|
|
572
|
-
onClose?.();
|
|
627
|
+
// Dai risultati si risale al selettore dei tipi documento
|
|
628
|
+
const canGoBackToSelector = isSteppedLayout && navStep === 'results' && selectedSearchResult !== undefined;
|
|
629
|
+
/**
|
|
630
|
+
* Back di tutti i pannelli (e X di chiusura se isClosable). Su mobile risale un livello alla volta:
|
|
631
|
+
* pannello secondario -> lista dei risultati -> selettore dei tipi documento -> uscita.
|
|
632
|
+
* Su desktop i pannelli sono affiancati, quindi resta solo l'uscita.
|
|
633
|
+
*
|
|
634
|
+
* @param fromSecondaryPanel - true se il back arriva da un pannello secondario
|
|
635
|
+
*/
|
|
636
|
+
const onBack = useCallback((fromSecondaryPanel = false) => {
|
|
637
|
+
// Non è previsto nessun modo di uscire: non fare niente
|
|
638
|
+
if (!showBackButton && !isClosable)
|
|
639
|
+
return;
|
|
640
|
+
// Torna alla lista senza toccare gli stati: l'utente deve ritrovare la sua selezione
|
|
641
|
+
if (fromSecondaryPanel) {
|
|
642
|
+
showMainPanelRef.current?.();
|
|
643
|
+
return;
|
|
573
644
|
}
|
|
574
|
-
|
|
645
|
+
// Sia il ritorno al selettore sia l'uscita ripartono da una lista pulita
|
|
646
|
+
setSelectedSearchResult(undefined);
|
|
647
|
+
setFocusedItem(undefined);
|
|
648
|
+
setSelectedItems([]);
|
|
649
|
+
setSelectedRowKeysFromDataGrid([]);
|
|
650
|
+
setCurrentDcmt(undefined);
|
|
651
|
+
setCurrentMetadataValues([]);
|
|
652
|
+
setShowIndexingInfo(false);
|
|
653
|
+
isFirstAutoFocusRef.current = true;
|
|
654
|
+
// Il chiamante può tenere allineato il suo TID selezionato (es. selectedSearchResultTID)
|
|
655
|
+
onSelectedTIDCleared?.();
|
|
656
|
+
// [2] l'utente ha chiesto la lista: resta lì finché non sceglie lui, niente auto-selezione.
|
|
657
|
+
// [1] si esce: si riparte da capo, quindi l'auto-selezione torna permessa.
|
|
658
|
+
setNavStep(canGoBackToSelector ? 'selector' : 'auto');
|
|
659
|
+
// [2] C'è ancora un livello sopra: restiamo dentro, sul selettore
|
|
660
|
+
if (canGoBackToSelector)
|
|
661
|
+
return;
|
|
662
|
+
// [1] Si esce e si avvisa il chiamante
|
|
663
|
+
onClose?.();
|
|
664
|
+
}, [canGoBackToSelector, showBackButton, isClosable, onClose, onSelectedTIDCleared]);
|
|
665
|
+
/**
|
|
666
|
+
* Back del pannello lista. `undefined` = freccia non renderizzata, quindi la mostriamo solo se
|
|
667
|
+
* ha dove tornare: uno step intermedio, o un onClose per uscire. Con `isClosable` basta la X.
|
|
668
|
+
*/
|
|
669
|
+
const backHandler = (showBackButton && !isClosable && (canGoBackToSelector || onClose !== undefined)) ? onBack : undefined;
|
|
670
|
+
/**
|
|
671
|
+
* Back dei pannelli secondari: la stessa onBack marcata come livello [3]. Solo su mobile:
|
|
672
|
+
* su desktop stanno affiancati alla lista e non c'è niente da cui tornare.
|
|
673
|
+
*/
|
|
674
|
+
const backHandlerSecondary = useMemo(() => (isMobile && backHandler) ? () => backHandler(true) : undefined, [isMobile, backHandler]);
|
|
575
675
|
const refreshDataGridAfterRemoveAsync = async () => {
|
|
576
676
|
let index = selectedSearchResult?.dtdResult?.columns?.findIndex(col => col.caption === 'DID');
|
|
577
677
|
let selectedRows = [];
|
|
@@ -603,21 +703,6 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
603
703
|
return newResults;
|
|
604
704
|
});
|
|
605
705
|
};
|
|
606
|
-
/**
|
|
607
|
-
* Restituisce l'handler onBack per i pannelli, evitando duplicazione di codice.
|
|
608
|
-
* @param isMainPanel - Se true, è il pannello principale dei risultati di ricerca
|
|
609
|
-
*/
|
|
610
|
-
const getOnBackHandler = (isMainPanel = false) => {
|
|
611
|
-
// Se showBackButton è false, non mostrare mai il back
|
|
612
|
-
if (showBackButton === false)
|
|
613
|
-
return undefined;
|
|
614
|
-
// Mobile: mostra back su tutti i pannelli (se showBackButton è definito e non è closable)
|
|
615
|
-
if (isMobile) {
|
|
616
|
-
return (showBackButton !== undefined && !isClosable) ? onBack : undefined;
|
|
617
|
-
}
|
|
618
|
-
// Desktop: mostra back solo sul pannello principale dei risultati (se showBackButton è definito e non è closable)
|
|
619
|
-
return (showBackButton !== undefined && isMainPanel && !isClosable) ? onBack : undefined;
|
|
620
|
-
};
|
|
621
706
|
const removeDcmtFromFavsOrRecents = async () => {
|
|
622
707
|
switch (selectedSearchResult?.category) {
|
|
623
708
|
case "Favorites":
|
|
@@ -634,9 +719,9 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
634
719
|
};
|
|
635
720
|
const onSearchResultSelectionChanged = (e) => {
|
|
636
721
|
setSelectedSearchResult(e);
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
722
|
+
// Scelto il tipo documento si passa ai risultati (a livello di layout è ignorato se i due
|
|
723
|
+
// step sono affiancati, ma vale comunque come "l'utente non è più fermo sul selettore")
|
|
724
|
+
setNavStep('results');
|
|
640
725
|
onSelectedTIDChanged?.(e.fromTID);
|
|
641
726
|
};
|
|
642
727
|
const showToppyForApprove = useMemo(() => {
|
|
@@ -660,14 +745,15 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
660
745
|
&& !showTodoDcmtForm);
|
|
661
746
|
}, [showToppyForApprove, showToppyDraggableHelpCenter, selectedDocs, showApprovePopup, showRejectPopup, showReAssignPopup, showMoreInfoPopup, editPdfForm, openS4TViewer, showTodoDcmtForm]);
|
|
662
747
|
const searchResutlToolbar = _jsxs(_Fragment, { children: [context === SearchResultContext.FAVORITES_AND_RECENTS &&
|
|
663
|
-
_jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (selectedSearchResult?.category === "Favorites" ? '"Preferiti"' : '"Recenti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsyncDatagrid }), _jsx(TMContextMenu, { items: operationItems, trigger: "left", children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) })
|
|
748
|
+
_jsx("div", { style: { display: 'flex', alignItems: 'center', gap: '5px' }, children: _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconDelete, { color: 'white' }), caption: "Rimuovi da " + (selectedSearchResult?.category === "Favorites" ? '"Preferiti"' : '"Recenti"'), disabled: getSelectedDcmtsOrFocused(selectedItems, focusedItem).length <= 0, onClick: removeDcmtFromFavsOrRecents }) }), _jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconRefresh, { color: 'white' }), caption: SDKUI_Localizator.Refresh, onClick: onRefreshSearchAsyncDatagrid }), _jsx(TMContextMenu, { items: operationItems, trigger: "left", children: _jsx(IconMenuVertical, { color: 'white', cursor: 'pointer' }) }), showToolbarCloseButton && onClose &&
|
|
749
|
+
_jsx(TMButton, { btnStyle: 'icon', icon: _jsx(IconCloseOutline, { color: 'white' }), caption: SDKUI_Localizator.Close, onClick: onClose })] });
|
|
664
750
|
const tmSearchResult = useMemo(() => (!searchResults || searchResults.length <= 0)
|
|
665
751
|
? _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%' }, children: [_jsx(IconBoard, { fontSize: 96 }), showNoDcmtFoundMessage && _jsx("div", { style: { fontSize: "15px", marginTop: "10px" }, children: SDKUI_Localizator.NoDcmtFound }), openAddDocumentForm && _jsx("div", { style: { marginTop: "10px" }, children: _jsx(TMButton, { fontSize: "15px", icon: _jsx("i", { className: 'dx-icon-share' }), caption: SDKUI_Localizator.Share, onClick: openAddDocumentForm }) })] })
|
|
666
752
|
:
|
|
667
|
-
_jsxs(_Fragment, { children: [_jsxs(TMLayoutItem, { height: '100%', children: [_jsxs("div", { ref: floatingBarContainerRef, style: { position: 'relative', height: '100%', width: '100%' }, children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: Gutters.getGutters(), separatorActiveColor: 'transparent', separatorColor: 'transparent', min: ['0', '0'], showSeparator: showSelector &&
|
|
668
|
-
_jsx(TMLayoutItem, { children: _jsx(TMSearchResultSelector, { searchResults: currentSearchResults, disableAccordionIfSingleCategory: disableAccordionIfSingleCategory, selectedTID: selectedSearchResultTID, selectedSearchResult: selectedSearchResult, autoSelectFirst: !isMobile ||
|
|
753
|
+
_jsxs(_Fragment, { children: [_jsxs(TMLayoutItem, { height: '100%', children: [_jsxs("div", { ref: floatingBarContainerRef, style: { position: 'relative', height: '100%', width: '100%' }, children: [_jsxs(TMSplitterLayout, { direction: 'horizontal', overflow: 'visible', separatorSize: Gutters.getGutters(), separatorActiveColor: 'transparent', separatorColor: 'transparent', min: ['0', '0'], showSeparator: showSelector && !isSteppedLayout && !isSelectorCollapsed, start: splitterSizes, children: [showSelector ?
|
|
754
|
+
_jsx(TMLayoutItem, { children: _jsx(TMSearchResultSelector, { searchResults: currentSearchResults, disableAccordionIfSingleCategory: disableAccordionIfSingleCategory, selectedTID: selectedSearchResultTID, selectedSearchResult: selectedSearchResult, autoSelectFirst: !isMobile || hasSingleDcmtType, onSelectionChanged: onSearchResultSelectionChanged }) })
|
|
669
755
|
:
|
|
670
|
-
_jsx(_Fragment, {}), _jsx(TMLayoutItem, { children: _jsx(TMSearchResultGrid, { openInOffice: openInOffice, fromDTD: fromDTD, operationItems: operationItems, allUsers: allUsers, inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, showExportForm: showExportForm, onFocusedItemChanged: handleFocusedItemChangedFromGrid, onDownloadDcmtsAsync: async (inputDcmts, downloadType, downloadMode, _y, confirmAttachments) => await downloadDcmtsAsync({ inputDcmts, downloadType, downloadMode, onFileDownloaded: onFileOpened, confirmAttachments }), lastUpdateSearchTime: lastUpdateSearchTime, searchResult: searchResults.length > 1 ? selectedSearchResult : searchResults[0], onSelectionChanged: (items) => { setSelectedItems(items); }, onDblClick: () => openFormHandler(LayoutModes.Update), showSearchTMDatagrid: showSearchTMDatagrid, onVisibleItemChanged: setVisibleItems, updateDataColumnsFromDataGrid: updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid: updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid: updateSelectedRowKeysFromDataGrid, disableAutoFocus: autoFocusFirstRow === false && isFirstAutoFocusRef.current, dcmtsReturned: dcmtsReturned, dcmtsFound: dcmtsFound }) })] }), renderFloatingBar] }), _jsx(TMToppyDraggableHelpCenter, { usePortal: toppyHelpCenterUsePortal, isVisible: isToppyHelpCenterVisible, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, onApprove: () => {
|
|
756
|
+
_jsx(_Fragment, {}), _jsx(TMLayoutItem, { children: _jsx(TMSearchResultGrid, { openInOffice: openInOffice, fromDTD: fromDTD, operationItems: operationItems, allUsers: allUsers, inputFocusedItem: focusedItem, inputSelectedItems: selectedItems, showExportForm: showExportForm, onFocusedItemChanged: handleFocusedItemChangedFromGrid, onDownloadDcmtsAsync: async (inputDcmts, downloadType, downloadMode, _y, confirmAttachments) => await downloadDcmtsAsync({ inputDcmts, downloadType, downloadMode, onFileDownloaded: onFileOpened, confirmAttachments }), lastUpdateSearchTime: lastUpdateSearchTime, searchResult: searchResults.length > 1 ? selectedSearchResult : searchResults[0], onSelectionChanged: (items) => { setSelectedItems(items); }, onDblClick: () => openFormHandler(LayoutModes.Update), showSearchTMDatagrid: showSearchTMDatagrid, onVisibleItemChanged: setVisibleItems, updateDataColumnsFromDataGrid: updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid: updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid: updateSelectedRowKeysFromDataGrid, disableAutoFocus: autoFocusFirstRow === false && isFirstAutoFocusRef.current, dcmtsReturned: dcmtsReturned, dcmtsFound: dcmtsFound, showCounterConfig: showCounterConfig, counterConfig: counterConfig, showActionsColumn: showActionsColumn, compactPager: compactPager, onRowActionRequest: requestRowAction }) })] }), renderFloatingBar] }), _jsx(TMToppyDraggableHelpCenter, { usePortal: toppyHelpCenterUsePortal, isVisible: isToppyHelpCenterVisible, content: _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: _jsx(WorkFlowOperationButtons, { dtd: fromDTD, deviceType: deviceType, onApprove: () => {
|
|
671
757
|
updateShowApprovePopup(true);
|
|
672
758
|
}, onSignApprove: () => {
|
|
673
759
|
handleSignApprove();
|
|
@@ -687,7 +773,6 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
687
773
|
showApprovePopup,
|
|
688
774
|
showRejectPopup,
|
|
689
775
|
showReAssignPopup,
|
|
690
|
-
isOpenBatchUpdate,
|
|
691
776
|
isOpenDetails,
|
|
692
777
|
isOpenMaster,
|
|
693
778
|
isOpenDcmtForm,
|
|
@@ -698,6 +783,10 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
698
783
|
openS4TViewer,
|
|
699
784
|
showBackButton,
|
|
700
785
|
isMobile,
|
|
786
|
+
navStep,
|
|
787
|
+
isSteppedLayout,
|
|
788
|
+
isSelectorCollapsed,
|
|
789
|
+
currentSearchResults,
|
|
701
790
|
currentMetadataValues,
|
|
702
791
|
onRefreshSearchAsyncDatagrid,
|
|
703
792
|
handleNavigateToWGs,
|
|
@@ -707,7 +796,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
707
796
|
]);
|
|
708
797
|
const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: focusedItem?.TID, did: focusedItem?.DID, fetchBlogDataTrigger: refreshBlogTrigger, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers }), [focusedItem, allTasks, refreshBlogTrigger, handleNavigateToWGs, handleNavigateToDossiers, onRefreshBlogDatagrid]);
|
|
709
798
|
const tmSysMetadata = useMemo(() => _jsx(TMMetadataValues, { layoutMode: LayoutModes.Update, openChooserBySingleClick: true, TID: focusedItem?.TID, isReadOnly: true, deviceType: deviceType, metadataValues: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), metadataValuesOrig: currentMetadataValues.filter(o => (o.mid != undefined && o.mid <= 100)), validationItems: [] }), [focusedItem, currentMetadataValues, deviceType]);
|
|
710
|
-
const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { refreshPreviewTrigger: refreshPreviewTrigger, currentDcmt: currentDcmt, onBack:
|
|
799
|
+
const tmDcmtPreview = useMemo(() => _jsx(TMDcmtPreviewWrapper, { refreshPreviewTrigger: refreshPreviewTrigger, currentDcmt: currentDcmt, onBack: backHandlerSecondary }), [currentDcmt, refreshPreviewTrigger, backHandlerSecondary]);
|
|
711
800
|
// Auto-fetch indexing info when drawer is open and focusedItem changes
|
|
712
801
|
useEffect(() => {
|
|
713
802
|
if (!focusedItem || !showIndexingInfo)
|
|
@@ -786,9 +875,10 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
786
875
|
component: tmSearchResult,
|
|
787
876
|
panelContainer: {
|
|
788
877
|
title: getTitleHeader(),
|
|
878
|
+
enableTitleMarquee: true,
|
|
789
879
|
showHeader: showToolbarHeader,
|
|
790
880
|
allowMaximize: !isMobile,
|
|
791
|
-
onBack:
|
|
881
|
+
onBack: backHandler,
|
|
792
882
|
onClose: isClosable ? onBack : undefined,
|
|
793
883
|
toolbar: searchResutlToolbar
|
|
794
884
|
},
|
|
@@ -803,7 +893,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
803
893
|
panelContainer: {
|
|
804
894
|
title: SDKUI_Localizator.BlogCase,
|
|
805
895
|
allowMaximize: !isMobile,
|
|
806
|
-
onBack:
|
|
896
|
+
onBack: backHandlerSecondary,
|
|
807
897
|
}
|
|
808
898
|
},
|
|
809
899
|
toolbarOptions: { icon: _jsx(IconBoard, { fontSize: 24 }), visible: getSearchToolbarVisibility(SDK_Globals.tmSession?.SessionDescr?.appModuleID ?? AppModules.SURFER).tmBlog, orderNumber: 2, isActive: allInitialPanelVisibility['tmBlog'] }
|
|
@@ -816,7 +906,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
816
906
|
panelContainer: {
|
|
817
907
|
title: SDKUI_Localizator.MetadataSystem,
|
|
818
908
|
allowMaximize: !isMobile,
|
|
819
|
-
onBack:
|
|
909
|
+
onBack: backHandlerSecondary,
|
|
820
910
|
}
|
|
821
911
|
},
|
|
822
912
|
toolbarOptions: { icon: _jsx(IconDcmtTypeSys, { fontSize: 24 }), visible: getSearchToolbarVisibility(SDK_Globals.tmSession?.SessionDescr?.appModuleID ?? AppModules.SURFER).tmSysMetadata, orderNumber: 3, isActive: allInitialPanelVisibility['tmSysMetadata'] }
|
|
@@ -830,7 +920,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
830
920
|
panelContainer: {
|
|
831
921
|
title: SDKUI_Localizator.ResultDetails,
|
|
832
922
|
allowMaximize: !isMobile,
|
|
833
|
-
onBack:
|
|
923
|
+
onBack: backHandlerSecondary,
|
|
834
924
|
}
|
|
835
925
|
},
|
|
836
926
|
toolbarOptions: { icon: _jsx(IconPlatform, { fontSize: 20 }), visible: getSearchToolbarVisibility(SDK_Globals.tmSession?.SessionDescr?.appModuleID ?? AppModules.SURFER).tmFullTextSearch, orderNumber: 4, isActive: allInitialPanelVisibility['tmFullTextSearch'] }
|
|
@@ -844,7 +934,7 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
844
934
|
},
|
|
845
935
|
toolbarOptions: { icon: _jsx(IconShow, { fontSize: 24 }), visible: getSearchToolbarVisibility(SDK_Globals.tmSession?.SessionDescr?.appModuleID ?? AppModules.SURFER).tmDcmtPreview, orderNumber: context === SearchResultContext.FREE_SEARCH ? 5 : 4, isActive: allInitialPanelVisibility['tmDcmtPreview'] }
|
|
846
936
|
}
|
|
847
|
-
], [tmSearchResult, tmBlog, tmSysMetadata, tmDcmtPreview, tmFullTextSearch, showToolbarHeader, context, isMobile]);
|
|
937
|
+
], [tmSearchResult, tmBlog, tmSysMetadata, tmDcmtPreview, tmFullTextSearch, showToolbarHeader, context, isMobile, backHandler, backHandlerSecondary, isClosable, onBack]);
|
|
848
938
|
return (_jsxs(StyledMultiViewPanel, { "$isVisible": isVisible, children: [_jsx(StyledMultiViewPanel, { "$isVisible": !isOpenDcmtForm && !isOpenDetails && !isOpenMaster, style: {
|
|
849
939
|
display: 'flex',
|
|
850
940
|
flexDirection: isMobile ? 'column' : 'row',
|
|
@@ -853,12 +943,38 @@ handleNavigateToWGs, handleNavigateToDossiers, fetchRemoteCertificates, graphome
|
|
|
853
943
|
width: '100%',
|
|
854
944
|
height: '100%',
|
|
855
945
|
}, 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(TMLayoutWaitingContainer, { direction: 'vertical', showWaitPanel: showCicoWaitPanel, showWaitPanelPrimary: showCicoPrimaryProgress, waitPanelTitle: cicoWaitPanelTitle, waitPanelTextPrimary: cicoPrimaryProgressText, waitPanelValuePrimary: cicoPrimaryProgressValue, waitPanelMaxValuePrimary: cicoPrimaryProgressMax, isCancelable: true, abortController: abortControllerLocal, children: (groupId && groupId.length > 0) ?
|
|
856
|
-
_jsxs(_Fragment, { children: [_jsx(PanelDisabledStateHandler, { isBoardDisabled: isBoardDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })] })
|
|
946
|
+
_jsxs(_Fragment, { children: [_jsx(PanelDisabledStateHandler, { isBoardDisabled: isBoardDisabled }), _jsx(ShowMainPanelBridge, { showMainPanelRef: showMainPanelRef }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })] })
|
|
857
947
|
:
|
|
858
|
-
_jsxs(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmSearchResult', children: [_jsx(PanelDisabledStateHandler, { isBoardDisabled: isBoardDisabled }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })] }) }) }) }), renderDcmtOperations] }));
|
|
948
|
+
_jsxs(TMPanelManagerProvider, { panels: initialPanels, initialVisibility: allInitialPanelVisibility, defaultDimensions: initialPanelDimensions, initialDimensions: initialPanelDimensions, initialMobilePanelId: 'tmSearchResult', children: [_jsx(PanelDisabledStateHandler, { isBoardDisabled: isBoardDisabled }), _jsx(ShowMainPanelBridge, { showMainPanelRef: showMainPanelRef }), _jsx(TMPanelManagerContainer, { panels: initialPanels, direction: "horizontal", parentId: groupId, showToolbar: showSearchResultSidebar })] }) }) }) }), renderDcmtOperations] }));
|
|
859
949
|
};
|
|
860
950
|
export default TMSearchResult;
|
|
861
|
-
|
|
951
|
+
/** Cerca una voce di operazione per id, anche dentro i sottomenu */
|
|
952
|
+
const findOperationItemById = (items, id) => {
|
|
953
|
+
for (const item of items) {
|
|
954
|
+
if (item.id === id)
|
|
955
|
+
return item;
|
|
956
|
+
const found = item.submenu ? findOperationItemById(item.submenu, id) : undefined;
|
|
957
|
+
if (found)
|
|
958
|
+
return found;
|
|
959
|
+
}
|
|
960
|
+
return undefined;
|
|
961
|
+
};
|
|
962
|
+
/**
|
|
963
|
+
* Azioni della colonna di riga. Gli id sono quelli di useDocumentOperations, così il comportamento è
|
|
964
|
+
* lo stesso del menu contestuale; icone e colori sono allineati alle altre griglie mentre il tooltip
|
|
965
|
+
* resta il nome dell'operazione. "Cancella" è la cancellazione logica: ripristino ed eliminazione
|
|
966
|
+
* fisica restano nel menu contestuale, dove la scelta è esplicita.
|
|
967
|
+
*/
|
|
968
|
+
const rowActions = [
|
|
969
|
+
{ operationId: 'open-form', icon: _jsx(IconEdit, { fontSize: 18, color: TMColors.primary }) },
|
|
970
|
+
{ operationId: 'dup', icon: _jsx(IconDuplicate, { fontSize: 18, color: TMColors.tertiary }) },
|
|
971
|
+
{ operationId: 'del-log', icon: _jsx(IconDelete, { fontSize: 18, color: TMColors.error }) },
|
|
972
|
+
];
|
|
973
|
+
const rowActionsStyles = {
|
|
974
|
+
cell: { display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '14px' },
|
|
975
|
+
icon: { cursor: 'pointer', display: 'flex' },
|
|
976
|
+
};
|
|
977
|
+
const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, inputFocusedItem, allowMultipleSelection = true, showExportForm = false, onFocusedItemChanged, onDownloadDcmtsAsync, onVisibleItemChanged, inputSelectedItems = [], lastUpdateSearchTime, searchResult, onSelectionChanged, onDblClick, showSearchTMDatagrid, updateDataColumnsFromDataGrid, updateDataSourceFromDataGrid, updateSelectedRowKeysFromDataGrid, disableAutoFocus = false, dcmtsReturned, dcmtsFound, showCounterConfig = true, counterConfig, showActionsColumn = false, compactPager = false, onRowActionRequest, }) => {
|
|
862
978
|
const [dataSource, setDataSource] = useState();
|
|
863
979
|
const [columns, setColumns] = useState([]);
|
|
864
980
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
|
@@ -879,8 +995,8 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
|
|
|
879
995
|
useEffect(() => {
|
|
880
996
|
updateDataSourceFromDataGrid(dataSource ?? []);
|
|
881
997
|
}, [dataSource]);
|
|
882
|
-
const { loadDataListsAsync, renderDataListCell, dataListsCache } = useDataListItem();
|
|
883
|
-
const { loadUsersAsync, renderUserIdViewer, usersCache } = useDataUserIdItem();
|
|
998
|
+
const { loadDataListsAsync, renderDataListCell, dataListsCache, getDataListItem } = useDataListItem();
|
|
999
|
+
const { loadUsersAsync, renderUserIdViewer, usersCache, getUserItem, getCompleteUserName } = useDataUserIdItem();
|
|
884
1000
|
useEffect(() => {
|
|
885
1001
|
// Sincronizza focusedItem con inputFocusedItem dal padre
|
|
886
1002
|
if (deepCompare(inputFocusedItem, focusedItem))
|
|
@@ -1112,6 +1228,57 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
|
|
|
1112
1228
|
});
|
|
1113
1229
|
return cols;
|
|
1114
1230
|
}, [searchResult, dataType, cellRender, getDisplayFormat, dataListsCache, usersCache]);
|
|
1231
|
+
/**
|
|
1232
|
+
* Colonne in cui il testo mostrato è diverso dal valore archiviato: date e numeri formattati, descrizioni
|
|
1233
|
+
* di liste dati e utenti. Su queste la ricerca della griglia va fatta sul testo mostrato, altrimenti non
|
|
1234
|
+
* trova nulla (es. cercando 29/01/2023 su una data, che nei dati è una stringa ISO).
|
|
1235
|
+
* Le cache sono ref lette al momento della ricerca: a quel punto sono già popolate.
|
|
1236
|
+
*/
|
|
1237
|
+
const searchTextGetters = useMemo(() => {
|
|
1238
|
+
const getters = new Map();
|
|
1239
|
+
const columnsOfResult = searchResult?.dtdResult?.columns;
|
|
1240
|
+
if (!columnsOfResult)
|
|
1241
|
+
return getters;
|
|
1242
|
+
const uniqueKeys = generateUniqueColumnKeys(columnsOfResult, searchResult?.fromTID);
|
|
1243
|
+
columnsOfResult.forEach((col, index) => {
|
|
1244
|
+
const dataField = uniqueKeys[index];
|
|
1245
|
+
if (!dataField)
|
|
1246
|
+
return;
|
|
1247
|
+
const dataDomain = MetadataDataDomains[(col.extendedProperties?.["DataDomain"] ?? "None")];
|
|
1248
|
+
const dataListID = Number(col.extendedProperties?.["DataListID"]);
|
|
1249
|
+
if (dataDomain === MetadataDataDomains.DataList && dataListID) {
|
|
1250
|
+
getters.set(dataField, (rowData) => getDataListItem(dataListID, rowData?.[dataField])?.name ?? String(rowData?.[dataField] ?? ''));
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
if (dataDomain === MetadataDataDomains.UserID) {
|
|
1254
|
+
getters.set(dataField, (rowData) => {
|
|
1255
|
+
const rawValue = rowData?.[dataField];
|
|
1256
|
+
// Un campo utente vuoto non mostra nulla: senza questo controllo Number('') darebbe 0, cioè l'utente di sistema
|
|
1257
|
+
if (rawValue === undefined || rawValue === null || rawValue === '')
|
|
1258
|
+
return '';
|
|
1259
|
+
const userId = Number(rawValue);
|
|
1260
|
+
if (Number.isNaN(userId))
|
|
1261
|
+
return String(rawValue);
|
|
1262
|
+
if (userId === 0)
|
|
1263
|
+
return SDKUI_Localizator.SystemUser ?? '';
|
|
1264
|
+
const ud = getUserItem(userId);
|
|
1265
|
+
return (ud ? getCompleteUserName(ud.domain, ud.name) : undefined) ?? String(rawValue);
|
|
1266
|
+
});
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
// Data e numero vengono mostrati con il formato definito sulle proprietà estese della colonna
|
|
1270
|
+
const { format, formatCulture } = getColumnFormatInfo(col);
|
|
1271
|
+
if (col.dataType === DataColumnTypes.DateTime) {
|
|
1272
|
+
getters.set(dataField, (rowData) => getDateDisplayText(rowData?.[dataField], format, formatCulture));
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
if (col.dataType === DataColumnTypes.Number) {
|
|
1276
|
+
getters.set(dataField, (rowData) => getNumberDisplayText(rowData?.[dataField], format, formatCulture));
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
return getters;
|
|
1280
|
+
}, [searchResult, getDataListItem, getUserItem, getCompleteUserName]);
|
|
1281
|
+
const customizeColumns = useMemo(() => customizeSearchByDisplayText(searchTextGetters), [searchTextGetters]);
|
|
1115
1282
|
/**
|
|
1116
1283
|
* Effect che carica i dati necessari e genera le colonne della griglia.
|
|
1117
1284
|
* Esegue il caricamento delle cache (DataList e UserID) in parallelo prima di generare le colonne,
|
|
@@ -1203,6 +1370,9 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
|
|
|
1203
1370
|
// Era sull'icona, non fare nulla
|
|
1204
1371
|
return;
|
|
1205
1372
|
}
|
|
1373
|
+
// Due click rapidi su un'icona della colonna azioni non devono aprire anche il form
|
|
1374
|
+
if (e.event?.target.closest('.tm-row-actions'))
|
|
1375
|
+
return;
|
|
1206
1376
|
// Verifica che il documento abbia TID e DID validi prima di procedere
|
|
1207
1377
|
if (!e.data.TID || !e.data.DID) {
|
|
1208
1378
|
ShowAlert({
|
|
@@ -1216,8 +1386,41 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
|
|
|
1216
1386
|
onFocusedItemChanged?.(e.data);
|
|
1217
1387
|
onDblClick();
|
|
1218
1388
|
}, [onDblClick]);
|
|
1389
|
+
/**
|
|
1390
|
+
* Colonna delle azioni di riga, in testa alla griglia (subito dopo la checkbox di selezione, che
|
|
1391
|
+
* DevExtreme tiene sempre per prima). Vive solo qui e non nello stato `columns`, che è quello
|
|
1392
|
+
* sincronizzato col padre per l'esportazione: una colonna senza dataField finirebbe in Excel come
|
|
1393
|
+
* colonna vuota.
|
|
1394
|
+
*
|
|
1395
|
+
* Le operazioni sono lette da una ref perché `operationItems` è ricostruito a ogni render del
|
|
1396
|
+
* padre: usarlo come dipendenza renderebbe nuova la colonna, e con essa `dataColumns`, ad ogni
|
|
1397
|
+
* giro. La cellRender le rilegge a ogni ridisegno della griglia, quindi resta comunque aggiornata.
|
|
1398
|
+
*/
|
|
1399
|
+
const operationItemsRef = useRef(operationItems);
|
|
1400
|
+
operationItemsRef.current = operationItems;
|
|
1401
|
+
const actionsColumn = useMemo(() => ({
|
|
1402
|
+
caption: '',
|
|
1403
|
+
width: 110,
|
|
1404
|
+
alignment: 'center',
|
|
1405
|
+
allowSorting: false,
|
|
1406
|
+
allowFiltering: false,
|
|
1407
|
+
allowHeaderFiltering: false,
|
|
1408
|
+
allowResizing: false,
|
|
1409
|
+
allowReordering: false,
|
|
1410
|
+
allowHiding: false,
|
|
1411
|
+
allowExporting: false,
|
|
1412
|
+
showInColumnChooser: false,
|
|
1413
|
+
cssClass: 'tm-row-actions',
|
|
1414
|
+
cellRender: (cellData) => (_jsx("div", { style: rowActionsStyles.cell, children: rowActions.map(action => {
|
|
1415
|
+
const operation = findOperationItemById(operationItemsRef.current, action.operationId);
|
|
1416
|
+
if (!operation || operation.visible === false)
|
|
1417
|
+
return null;
|
|
1418
|
+
return (_jsx("span", { style: rowActionsStyles.icon, title: operation.name, onClick: () => onRowActionRequest?.(action.operationId, cellData.data), children: action.icon }, action.operationId));
|
|
1419
|
+
}) })),
|
|
1420
|
+
}), [onRowActionRequest]);
|
|
1219
1421
|
const dataColumns = useMemo(() => {
|
|
1220
1422
|
return [
|
|
1423
|
+
...(showActionsColumn ? [actionsColumn] : []),
|
|
1221
1424
|
{
|
|
1222
1425
|
dataType: "object",
|
|
1223
1426
|
dataField: 'FILEEXT',
|
|
@@ -1231,7 +1434,7 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
|
|
|
1231
1434
|
},
|
|
1232
1435
|
...columns.filter(col => col.dataField !== 'FILEEXT')
|
|
1233
1436
|
];
|
|
1234
|
-
}, [columns, onDownloadDcmtsAsync, openInOffice]);
|
|
1437
|
+
}, [columns, onDownloadDcmtsAsync, openInOffice, showActionsColumn, actionsColumn]);
|
|
1235
1438
|
const onContentReady = useCallback((e) => {
|
|
1236
1439
|
if (e === undefined)
|
|
1237
1440
|
return;
|
|
@@ -1242,21 +1445,24 @@ const TMSearchResultGrid = ({ openInOffice, fromDTD, operationItems, allUsers, i
|
|
|
1242
1445
|
setVisibleItems(visibleData);
|
|
1243
1446
|
}, []);
|
|
1244
1447
|
useEffect(() => { onVisibleItemChanged?.(visibleItems); }, [visibleItems]);
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1448
|
+
const gridCounterConfig = useMemo(() => {
|
|
1449
|
+
if (!showCounterConfig)
|
|
1450
|
+
return { show: false };
|
|
1451
|
+
const defaultItems = dcmtsReturned !== undefined && dcmtsFound !== undefined
|
|
1452
|
+
? new Map([
|
|
1453
|
+
[CounterItemKey.allItems, {
|
|
1454
|
+
key: CounterItemKey.allItems,
|
|
1455
|
+
show: true,
|
|
1456
|
+
caption: `${dcmtsReturned} restituiti su ${dcmtsFound} trovati`,
|
|
1457
|
+
value: `${dcmtsReturned}/${dcmtsFound}`,
|
|
1458
|
+
icon: _jsx(IconAll, {}),
|
|
1459
|
+
order: -1
|
|
1460
|
+
}]
|
|
1461
|
+
])
|
|
1462
|
+
: undefined;
|
|
1463
|
+
return { ...counterConfig, show: true, items: counterConfig?.items ?? defaultItems };
|
|
1464
|
+
}, [showCounterConfig, counterConfig, dcmtsReturned, dcmtsFound]);
|
|
1465
|
+
return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [!isDataGridReady && (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', gap: '10px' }, children: [_jsx(LoadIndicator, { height: 60, width: 60 }), _jsx("div", { children: SDKUI_Localizator.Loading })] })), isDataGridReady && _jsx(TMDataGrid, { ref: dataGridRef, id: "tm-search-result", keyExpr: "rowIndex", dataColumns: dataColumns, dataSource: dataSource, customizeColumns: customizeColumns, repaintChangesOnly: true, selectedRowKeys: selectedRowKeys, focusedRowKey: disableAutoFocus ? undefined : Number(focusedItem?.rowIndex ?? 0), showSearchPanel: showSearchTMDatagrid, showFilterPanel: true, sorting: { mode: "multiple" }, selection: { mode: allowMultipleSelection ? 'multiple' : 'single' }, pageSize: pageSize, compactPager: compactPager, onSelectionChanged: handleSelectionChange, onFocusedRowChanged: handleFocusedRowChange, onRowDblClick: onRowDblClick, onContentReady: onContentReady, showHeaderColumnChooser: true, onKeyDown: onKeyDown, customContextMenuItems: operationItems, counterConfig: gridCounterConfig })] });
|
|
1260
1466
|
};
|
|
1261
1467
|
//#region TMSearchResultSelector
|
|
1262
1468
|
const StyledItemTemplate = styled.div `
|
|
@@ -1317,14 +1523,29 @@ const TMSearchResultSelector = ({ searchResults = [], disableAccordionIfSingleCa
|
|
|
1317
1523
|
}
|
|
1318
1524
|
}
|
|
1319
1525
|
}, [sortedCategories.length, autoSelectFirst]);
|
|
1526
|
+
// La preselezione esterna va applicata una volta per valore: riapplicarla a ogni cambio di
|
|
1527
|
+
// searchResults faceva sì che un refresh annullasse la navigazione dell'utente.
|
|
1528
|
+
const appliedSelectedTIDRef = useRef(undefined);
|
|
1320
1529
|
useEffect(() => {
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1530
|
+
// Richiesta ritirata: dimentichiamo il valore applicato, così se il chiamante richiede di
|
|
1531
|
+
// nuovo lo stesso TID la preselezione riparte
|
|
1532
|
+
if (selectedTID === undefined) {
|
|
1533
|
+
appliedSelectedTIDRef.current = undefined;
|
|
1534
|
+
return;
|
|
1324
1535
|
}
|
|
1536
|
+
if (appliedSelectedTIDRef.current === selectedTID)
|
|
1537
|
+
return;
|
|
1538
|
+
const found = searchResults.find(r => Number(r.fromTID) === selectedTID);
|
|
1539
|
+
if (!found)
|
|
1540
|
+
return; // risultati non ancora arrivati: riproviamo al prossimo giro
|
|
1541
|
+
appliedSelectedTIDRef.current = selectedTID;
|
|
1542
|
+
handleSelect(found);
|
|
1325
1543
|
}, [selectedTID, searchResults]);
|
|
1326
|
-
|
|
1327
|
-
|
|
1544
|
+
// force = true per i click dell'utente: la selezione va notificata anche se il tipo documento è già quello selezionato
|
|
1545
|
+
const handleSelect = useCallback((result, force = false) => {
|
|
1546
|
+
if (result === undefined)
|
|
1547
|
+
return;
|
|
1548
|
+
if (selectedResult !== result || force) {
|
|
1328
1549
|
setSelectedResult(result);
|
|
1329
1550
|
onSelectionChanged?.(result);
|
|
1330
1551
|
}
|
|
@@ -1369,14 +1590,24 @@ const TMSearchResultSelector = ({ searchResults = [], disableAccordionIfSingleCa
|
|
|
1369
1590
|
renderItem: (result, isSelected) => (_jsxs("div", { style: { width: '100%', padding: '5px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, children: [_jsx(TMTidViewer, { tid: result.fromTID, did: Number(result.dtdResult?.rows?.[0]?.[1]), showIcon: true }), _jsx("div", { style: { padding: 3, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'white', color: 'gray', borderRadius: 3 }, children: result.dcmtsReturned })] })),
|
|
1370
1591
|
itemHeight: 40
|
|
1371
1592
|
})), [sortedCategories, groupedResults, searchResults]);
|
|
1372
|
-
const renderCategoryItems = (category) => (_jsx("div", { style: { padding: '5px', height: '100%', overflow: 'auto' }, children: groupedResults[category].map((result, index) => (_jsx(MemoizedStyledItemTemplate, { "$isSelected": selectedResult === result, onClick: () => handleSelect(result), children: renderItemTemplate(result) }, index))) }));
|
|
1593
|
+
const renderCategoryItems = (category) => (_jsx("div", { style: { padding: '5px', height: '100%', overflow: 'auto' }, children: groupedResults[category].map((result, index) => (_jsx(MemoizedStyledItemTemplate, { "$isSelected": selectedResult === result, onClick: () => handleSelect(result, true), children: renderItemTemplate(result) }, index))) }));
|
|
1373
1594
|
if (disableAccordionIfSingleCategory && sortedCategories.length === 1) {
|
|
1374
1595
|
const category = sortedCategories[0];
|
|
1375
1596
|
return renderCategoryItems(category);
|
|
1376
1597
|
}
|
|
1377
|
-
return (_jsx(TMAccordionNew, { groups: accordionGroups, selectedItem: selectedResult, onSelectedItemChange: (result) => handleSelect(result) }));
|
|
1598
|
+
return (_jsx(TMAccordionNew, { groups: accordionGroups, selectedItem: selectedResult, onSelectedItemChange: (result) => handleSelect(result, true) }));
|
|
1378
1599
|
};
|
|
1379
1600
|
//#endregion TMSearchResultSelector
|
|
1601
|
+
/** Senza UI: vive dentro il provider e passa a onBack, via ref, l'azione "mostra il pannello lista". */
|
|
1602
|
+
const ShowMainPanelBridge = ({ showMainPanelRef }) => {
|
|
1603
|
+
const { setPanelVisibilityById } = useTMPanelManagerContext();
|
|
1604
|
+
useEffect(() => {
|
|
1605
|
+
// Su mobile mostrare un pannello nasconde gli altri; su desktop la lista è già visibile
|
|
1606
|
+
showMainPanelRef.current = () => setPanelVisibilityById('tmSearchResult', true);
|
|
1607
|
+
return () => { showMainPanelRef.current = null; };
|
|
1608
|
+
}, [setPanelVisibilityById, showMainPanelRef]);
|
|
1609
|
+
return null;
|
|
1610
|
+
};
|
|
1380
1611
|
const PanelDisabledStateHandler = ({ isBoardDisabled }) => {
|
|
1381
1612
|
const { setPanelVisibilityById, setToolbarButtonDisabled } = useTMPanelManagerContext();
|
|
1382
1613
|
useEffect(() => {
|