@topconsultnpm/sdkui-react 6.19.0-dev1.21 → 6.19.0-dev1.22

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.
@@ -1,11 +1,12 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
- import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, TemplateTIDs, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber, RelationCacheService, RelationTypes, SearchEngine } from '@topconsultnpm/sdk-ts';
3
+ import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, TemplateTIDs, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber } from '@topconsultnpm/sdk-ts';
4
4
  import styled from 'styled-components';
5
5
  import { getCommandsMenuItems, getSelectedDcmtsOrFocused } from './TMSearchResultsMenuItems';
6
- import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, IconDetailDcmts, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, IconDownload, deepCompare, getDataColumnName, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMCommandsContextMenu, IconPair, IconUnpair } from '../../../helper';
6
+ import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, IconDetailDcmts, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, IconDownload, deepCompare, getDataColumnName, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMCommandsContextMenu } from '../../../helper';
7
7
  import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
8
8
  import { useInputAttachmentsDialog, useInputCvtFormatDialog } from '../../../hooks/useInputDialog';
9
+ import { useRelatedDocuments } from '../../../hooks/useRelatedDocuments';
9
10
  import { DcmtOperationTypes, FormModes, SearchResultContext, DownloadTypes } from '../../../ts';
10
11
  import { Gutters, TMColors } from '../../../utils/theme';
11
12
  import { StyledModalContainer, StyledBadge, StyledMultiViewPanel } from '../../base/Styled';
@@ -21,7 +22,6 @@ import TMMetadataValues from '../../editors/TMMetadataValues';
21
22
  import { TMSaveFormButtonPrevious, TMSaveFormButtonNext } from '../../forms/TMSaveForm';
22
23
  import TMDataListItemViewer from '../../viewers/TMDataListItemViewer';
23
24
  import TMTidViewer from '../../viewers/TMTidViewer';
24
- import { hasDetailRelations, hasMasterRelations } from '../../../helper/dcmtsHelper';
25
25
  import TMDcmtPreview from '../documents/TMDcmtPreview';
26
26
  import TMFloatingToolbar from '../../base/TMFloatingToolbar';
27
27
  import { WorkFlowApproveRejectPopUp, WorkFlowMoreInfoPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../workflow/TMWorkflowPopup';
@@ -40,6 +40,7 @@ import ShowAlert from '../../base/TMAlert';
40
40
  import TMSpinner from '../../base/TMSpinner';
41
41
  import TMChooserForm from '../../forms/TMChooserForm';
42
42
  import TMModal from '../../base/TMModal';
43
+ import TMSearch from './TMSearch';
43
44
  //#region Helper Methods
44
45
  export const getSearchResultCountersSingleCategory = (searchResults) => {
45
46
  // let totDcmtTypes = searchResults.length;
@@ -70,30 +71,8 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
70
71
  const [selectedSearchResult, setSelectedSearchResult] = useState();
71
72
  const [currentSearchResults, setCurrentSearchResults] = useState(searchResults || []);
72
73
  const [showSearch, setShowSearch] = useState(false);
73
- // States for Related Documents
74
- const [relatedDcmts, setRelatedDcmts] = useState(undefined);
75
- const [showRelatedDcmtsChooser, setShowRelatedDcmtsChooser] = useState(false);
76
- const [archiveType, setArchiveType] = useState(undefined);
77
- const [isOpenDetails, setIsOpenDetails] = useState(false);
78
- const [isOpenMaster, setIsOpenMaster] = useState(false);
79
- const [isOpenArchiveRelationForm, setIsOpenArchiveRelationForm] = useState(false);
80
- const [archiveRelatedDcmtFormTID, setArchiveRelatedDcmtFormTID] = useState(undefined);
81
- const [archiveRelatedDcmtFormMids, setArchiveRelatedDcmtFormMids] = useState([]);
82
- const [relatedDcmtsChooserDataSource, setRelatedDcmtsChooserDataSource] = useState(undefined);
83
- const [showPairDcmtsModal, setShowPairDcmtsModal] = useState(false);
84
- const [isPairingManyToMany, setIsPairingManyToMany] = useState(false);
85
- const [pairedSearchResults, setPairedSearchResults] = useState([]);
86
- const [manyToManyRelations, setManyToManyRelations] = useState(undefined);
87
- const [selectedManyToManyRelation, setSelectedManyToManyRelation] = useState(undefined);
88
- const [showManyToManyChooser, setShowManyToManyChooser] = useState(false);
89
- const [manyToManyChooserDataSource, setManyToManyChooserDataSource] = useState(undefined);
90
74
  const [secondaryMasterDcmts, setSecondaryMasterDcmts] = useState([]);
91
75
  const [isOpenDcmtForm, setIsOpenDcmtForm] = useState(false);
92
- const [currentTIDHasDetailRelations, setCurrentTIDHasDetailRelations] = useState();
93
- const [currentTIDHasMasterRelations, setCurrentTIDHasMasterRelations] = useState();
94
- const [canArchiveMasterRelation, setCanArchiveMasterRelation] = useState(false);
95
- const [canArchiveDetailRelation, setCanArchiveDetailRelation] = useState(false);
96
- const [hasManyToManyRelation, setHasManyToManyRelation] = useState(false);
97
76
  const [isOpenBatchUpdate, setIsOpenBatchUpdate] = useState(false);
98
77
  const [visibleItems, setVisibleItems] = useState([]);
99
78
  const [focusedItem, setFocusedItem] = useState();
@@ -107,6 +86,8 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
107
86
  const [confirmFormat, ConfirmFormatDialog] = useInputCvtFormatDialog();
108
87
  const { openConfirmAttachmentsDialog, ConfirmAttachmentsDialog } = useInputAttachmentsDialog();
109
88
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync } = useDcmtOperations();
89
+ const relatedDocuments = useRelatedDocuments({ selectedSearchResult, focusedItem, currentSearchResults });
90
+ const { relatedDcmts, showRelatedDcmtsChooser, archiveType, isOpenDetails, isOpenMaster, isOpenArchiveRelationForm, archiveRelatedDcmtFormTID, archiveRelatedDcmtFormMids, relatedDcmtsChooserDataSource, showPairDcmtsModal, isPairingManyToMany, pairedSearchResults, manyToManyRelations, selectedManyToManyRelation, showManyToManyChooser, manyToManyChooserDataSource, showPairSearchModal, pairSearchModalTargetTID, pairSearchModalParentTID, pairSearchModalParentDID, pairSearchModalRelation, pairSearchModalInputMids, currentTIDHasDetailRelations, currentTIDHasMasterRelations, canArchiveMasterRelation, canArchiveDetailRelation, hasManyToManyRelation, setIsOpenDetails, setIsOpenMaster, setShowRelatedDcmtsChooser, setShowManyToManyChooser, setShowPairDcmtsModal, setShowPairSearchModal, setIsOpenArchiveRelationForm, setArchiveType, setArchiveRelatedDcmtFormTID, setArchiveRelatedDcmtFormMids, pairFloatingActionConfig, pairSearchModalFloatingActionConfig, archiveMasterDocuments, archiveDetailDocuments, pairManyToMany, checkRelatedDcmtsArchiveCapability, checkManyToManyCapability, archiveRelatedDcmtHandler, executeManyToManyPairing, } = relatedDocuments;
110
91
  const deviceType = useDeviceType();
111
92
  const isMobile = deviceType === DeviceType.MOBILE;
112
93
  const selectedDocs = getSelectedDcmtsOrFocused(selectedItems, focusedItem);
@@ -136,15 +117,13 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
136
117
  DcmtTypeListCacheService.GetWithNotGrantedAsync(selectedSearchResult?.fromTID, Number(selectedSearchResult?.dtdResult?.rows?.[0]?.[1])).then((dtd) => {
137
118
  setFromDTD(dtd);
138
119
  });
139
- hasDetailRelations(selectedSearchResult?.fromTID).then((value) => setCurrentTIDHasDetailRelations(value));
140
- hasMasterRelations(selectedSearchResult?.fromTID).then((value) => setCurrentTIDHasMasterRelations(value));
141
120
  checkRelatedDcmtsArchiveCapability();
142
121
  checkManyToManyCapability();
143
122
  // Ricava il nuovo dataSource
144
123
  const newDataSource = searchResultDescriptorToSimpleArray(selectedSearchResult);
145
124
  // Se esiste almeno una riga, seleziona la prima
146
125
  setFocusedItem(newDataSource && newDataSource.length > 0 ? newDataSource[0] : undefined);
147
- }, [selectedSearchResult]);
126
+ }, [selectedSearchResult, checkRelatedDcmtsArchiveCapability, checkManyToManyCapability]);
148
127
  useEffect(() => {
149
128
  if (!focusedItem)
150
129
  return;
@@ -426,516 +405,6 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
426
405
  break;
427
406
  }
428
407
  };
429
- //#region Related Documents Archive Section
430
- const pairFloatingActionConfig = useMemo(() => ({
431
- isVisible: true,
432
- type: 'multi',
433
- onClick: async (selected) => {
434
- if (!selectedManyToManyRelation || !focusedItem?.TID || !focusedItem?.DID) {
435
- return;
436
- }
437
- const isMaster = currentSearchResults[0].fromTID === selectedManyToManyRelation.masterTID;
438
- const isDetail = currentSearchResults[0].fromTID === selectedManyToManyRelation.detailTID;
439
- if (!isMaster && !isDetail) {
440
- return;
441
- }
442
- const tms = SDK_Globals.tmSession;
443
- if (!tms) {
444
- return;
445
- }
446
- const se = new SearchEngine(tms);
447
- try {
448
- TMSpinner.show({ description: isPairingManyToMany ? 'Abbinamento in corso...' : 'Disabbinamento in corso...' });
449
- for (const doc of selected) {
450
- if (!doc?.TID || !doc?.DID)
451
- continue;
452
- let masterTID;
453
- let masterDID;
454
- let detailTID;
455
- let detailDID;
456
- if (isMaster) {
457
- masterTID = focusedItem.TID;
458
- masterDID = focusedItem.DID;
459
- detailTID = doc.TID;
460
- detailDID = doc.DID;
461
- }
462
- else {
463
- masterTID = doc.TID;
464
- masterDID = doc.DID;
465
- detailTID = focusedItem.TID;
466
- detailDID = focusedItem.DID;
467
- }
468
- if (isPairingManyToMany) {
469
- await se.ManyToManyRelateAsync(masterTID, masterDID, detailTID, detailDID);
470
- }
471
- else {
472
- await se.ManyToManyUnrelateAsync(masterTID, masterDID, detailTID, detailDID);
473
- }
474
- }
475
- setShowPairDcmtsModal(false);
476
- await onRefreshSearchAsync?.();
477
- }
478
- catch (error) {
479
- console.error('Error in onClick:', error);
480
- TMExceptionBoxManager.show({ exception: error });
481
- }
482
- finally {
483
- TMSpinner.hide();
484
- }
485
- },
486
- iconElement: isPairingManyToMany ? _jsx(IconPair, { fontSize: 26 }) : _jsx(IconUnpair, { fontSize: 26 }),
487
- tooltip: isPairingManyToMany ? 'Abbina' : 'Disabbina',
488
- }), [isPairingManyToMany, pairedSearchResults, selectedManyToManyRelation, focusedItem, onRefreshSearchAsync]);
489
- const getAllRelationsAsync = async () => {
490
- const tmSession = SDK_Globals.tmSession;
491
- try {
492
- TMSpinner.show({ description: SDKUI_Localizator.Loading });
493
- let relations = await RelationCacheService.GetAllAsync(tmSession);
494
- if (!relations)
495
- throw new Error("Impossibile caricare le relazioni.");
496
- return relations;
497
- }
498
- catch (error) {
499
- TMExceptionBoxManager.show({ exception: error });
500
- return undefined;
501
- }
502
- finally {
503
- TMSpinner.hide();
504
- }
505
- };
506
- const checkRelatedDcmtsArchiveCapability = async () => {
507
- const tid = selectedSearchResult?.fromTID;
508
- if (!tid) {
509
- setCanArchiveMasterRelation(false);
510
- setCanArchiveDetailRelation(false);
511
- return;
512
- }
513
- try {
514
- const relations = await getAllRelationsAsync();
515
- if (!relations) {
516
- setCanArchiveMasterRelation(false);
517
- setCanArchiveDetailRelation(false);
518
- return;
519
- }
520
- const detailRelations = relations.filter(r => r.detailTID === tid);
521
- const hasMasterWithAssociations = detailRelations.some(rel => rel.associations && rel.associations.length > 0);
522
- setCanArchiveMasterRelation(hasMasterWithAssociations);
523
- const masterRelations = relations.filter(r => r.masterTID === tid);
524
- const hasDetailWithAssociations = masterRelations.some(rel => rel.associations && rel.associations.length > 0);
525
- setCanArchiveDetailRelation(hasDetailWithAssociations);
526
- }
527
- catch (error) {
528
- console.error("Error checking archive capability:", error);
529
- setCanArchiveMasterRelation(false);
530
- setCanArchiveDetailRelation(false);
531
- }
532
- };
533
- const checkManyToManyCapability = async () => {
534
- const tid = selectedSearchResult?.fromTID;
535
- if (!tid) {
536
- setHasManyToManyRelation(false);
537
- return;
538
- }
539
- try {
540
- const relations = await getAllRelationsAsync();
541
- if (!relations) {
542
- setHasManyToManyRelation(false);
543
- return;
544
- }
545
- const manyToManyRels = relations.filter(r => r.relationType === RelationTypes.ManyToMany &&
546
- (r.masterTID === tid || r.detailTID === tid));
547
- setHasManyToManyRelation(manyToManyRels.length > 0);
548
- }
549
- catch (error) {
550
- console.error("Error checking many-to-many capability:", error);
551
- setHasManyToManyRelation(false);
552
- }
553
- };
554
- const getFocusedItem = () => {
555
- if (!focusedItem || currentSearchResults.length !== 1)
556
- return undefined;
557
- return { mdList: currentSearchResults[0].dtdResult?.rows?.[focusedItem?.rowIndex ?? 0], mids: currentSearchResults[0].selectMIDs ?? [] };
558
- };
559
- const fetchAssociatedValues = (mid) => {
560
- let mdList = getFocusedItem();
561
- if (!mdList)
562
- return;
563
- let index = mdList.mids.findIndex(m => m == mid);
564
- if (index === -1)
565
- return;
566
- return mdList.mdList?.[index];
567
- };
568
- const filterRelationsByType = (relations, tid, type) => {
569
- return type === 'detail'
570
- ? relations.filter(r => r.masterTID == tid)
571
- : relations.filter(r => r.detailTID == tid);
572
- };
573
- const filterRelationsWithAssociations = (relations) => {
574
- return relations.filter(rel => rel.associations && rel.associations.length > 0);
575
- };
576
- const getRelatedDcmt = async (relation, type) => {
577
- return await DcmtTypeListCacheService.GetAsync(type === 'detail' ? relation.detailTID : relation.masterTID);
578
- };
579
- const showNoRelationsAlert = (type) => {
580
- ShowAlert({
581
- message: type === 'detail'
582
- ? "Nessun documento di dettaglio trovato per l'archiviazione."
583
- : "Nessun documento di master trovato per l'archiviazione.",
584
- mode: 'info',
585
- title: type === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster,
586
- duration: 5000
587
- });
588
- };
589
- const showNoAssociationsAlert = (type) => {
590
- ShowAlert({
591
- message: type === 'detail'
592
- ? "Nessuna associazione trovata per i documenti di dettaglio."
593
- : "Nessuna associazione trovata per i documenti di master.",
594
- mode: 'info',
595
- title: type === 'detail' ? SDKUI_Localizator.DcmtsDetail : SDKUI_Localizator.DcmtsMaster,
596
- duration: 5000
597
- });
598
- };
599
- const mapAssociationsToMids = (relation, type) => {
600
- return relation.associations?.map(assoc => ({
601
- mid: type === 'detail' ? (assoc.item2 ?? 0) : (assoc.item1 ?? 0),
602
- value: fetchAssociatedValues(type === 'detail' ? (assoc.item1 ?? 0) : (assoc.item2 ?? 0)) ?? ''
603
- })) ?? [];
604
- };
605
- const archiveRelatedDcmtHandler = (relation, type) => {
606
- const targetTID = type === 'detail' ? relation.detailTID : relation.masterTID;
607
- if (!targetTID)
608
- return;
609
- const mids = mapAssociationsToMids(relation, type);
610
- setArchiveType(type);
611
- setArchiveRelatedDcmtFormTID(targetTID);
612
- setArchiveRelatedDcmtFormMids(mids);
613
- setIsOpenArchiveRelationForm(true);
614
- };
615
- const archiveRelatedDocuments = async (tid, type) => {
616
- try {
617
- TMSpinner.show({ description: SDKUI_Localizator.Loading });
618
- const relations = await getAllRelationsAsync();
619
- if (!relations || !tid)
620
- return;
621
- const filteredRelations = filterRelationsByType(relations, tid, type);
622
- if (!filteredRelations || filteredRelations.length === 0) {
623
- showNoRelationsAlert(type);
624
- return;
625
- }
626
- const withAssociations = filterRelationsWithAssociations(filteredRelations);
627
- if (withAssociations.length === 0) {
628
- showNoAssociationsAlert(type);
629
- return;
630
- }
631
- setRelatedDcmts(withAssociations);
632
- if (withAssociations.length > 1) {
633
- const dataSourcePromises = withAssociations.map(async (rel) => {
634
- const relatedDcmt = await getRelatedDcmt(rel, type);
635
- return { id: rel?.id, name: relatedDcmt?.name };
636
- });
637
- const dataSource = await Promise.all(dataSourcePromises);
638
- setRelatedDcmtsChooserDataSource(dataSource);
639
- setArchiveType(type);
640
- setShowRelatedDcmtsChooser(true);
641
- }
642
- else {
643
- archiveRelatedDcmtHandler(withAssociations[0], type);
644
- }
645
- }
646
- catch (error) {
647
- TMExceptionBoxManager.show({ exception: error });
648
- }
649
- finally {
650
- TMSpinner.hide();
651
- }
652
- };
653
- const archiveDetailDocuments = async (tid) => {
654
- await archiveRelatedDocuments(tid, 'detail');
655
- };
656
- const archiveMasterDocuments = async (tid) => {
657
- await archiveRelatedDocuments(tid, 'master');
658
- };
659
- const getPairedDocuments = async (relation, currentTID, currentDID, searchEngine) => {
660
- if (!relation || !currentDID)
661
- return null;
662
- try {
663
- const isMaster = currentTID === relation.masterTID;
664
- const pairedResults = isMaster
665
- ? await searchEngine.GetAllDetailDcmtsAsync(currentTID, currentDID)
666
- : await searchEngine.GetAllMasterDcmtsAsync(currentTID, currentDID);
667
- if (!pairedResults || pairedResults.length === 0)
668
- return null;
669
- const relationResult = pairedResults.find(r => r.relationID === relation.id);
670
- if (!relationResult?.dtdResult)
671
- return null;
672
- return relationResult;
673
- }
674
- catch (error) {
675
- console.error('getPairedDocuments - Error:', error);
676
- return null;
677
- }
678
- };
679
- const extractPairedDIDs = (relationResult) => {
680
- const pairedDIDs = [];
681
- const rows = relationResult.dtdResult?.rows ?? [];
682
- const columns = relationResult.dtdResult?.columns ?? [];
683
- const didColumnIndex = columns.findIndex(col => {
684
- const caption = col.caption?.toUpperCase();
685
- const mid = col.extendedProperties?.["MID"];
686
- const midNum = typeof mid === 'string' ? Number.parseInt(mid, 10) : mid;
687
- return caption === 'DID' || midNum === 5;
688
- });
689
- if (didColumnIndex === -1)
690
- return [];
691
- for (const row of rows) {
692
- const did = row[didColumnIndex];
693
- if (did) {
694
- const didNumber = typeof did === 'string' ? Number.parseInt(did, 10) : did;
695
- if (!Number.isNaN(didNumber)) {
696
- pairedDIDs.push(didNumber);
697
- }
698
- }
699
- }
700
- return pairedDIDs;
701
- };
702
- const executeManyToManyPairing = async (relation, isPairing) => {
703
- const searchEngine = SDK_Globals.tmSession?.NewSearchEngine();
704
- if (!focusedItem?.TID || !focusedItem?.DID) {
705
- ShowAlert({
706
- message: "Nessun documento selezionato per l'operazione molti-a-molti.",
707
- mode: 'warning',
708
- title: 'Operazione molti-a-molti',
709
- duration: 5000
710
- });
711
- return;
712
- }
713
- setSelectedManyToManyRelation(relation);
714
- let qd;
715
- if (relation.detailTID === selectedSearchResult?.fromTID) {
716
- qd = relation.retrieveMastersQuery;
717
- }
718
- if (relation.masterTID === selectedSearchResult?.fromTID) {
719
- qd = relation.retrieveDetailsQuery;
720
- }
721
- if (!qd) {
722
- ShowAlert({
723
- message: "Nessuna query di recupero associata alla relazione molti-a-molti.",
724
- mode: 'warning',
725
- title: 'Operazione molti-a-molti',
726
- duration: 5000
727
- });
728
- return;
729
- }
730
- qd = structuredClone(qd);
731
- if (qd.select) {
732
- for (const s of qd.select) {
733
- s.visibility = 1;
734
- }
735
- }
736
- const qdRetrieveParamsValue = {
737
- from: { tid: focusedItem.TID },
738
- select: [],
739
- where: [
740
- {
741
- tid: focusedItem.TID,
742
- mid: 5,
743
- leftBrackets: "(",
744
- rightBrackets: ")",
745
- operator: 0,
746
- value1: focusedItem.DID.toString()
747
- }
748
- ]
749
- };
750
- let notMappedMIDs = false;
751
- if (qd.params && qd.params.length > 0) {
752
- for (const param of qd.params) {
753
- if (!param.mappedMID)
754
- continue;
755
- qdRetrieveParamsValue.select.push({
756
- tid: param.mappedTID ?? focusedItem.TID,
757
- mid: param.mappedMID,
758
- visibility: 1
759
- });
760
- const currentRowValue = currentSearchResults[0]?.dtdResult?.rows?.[focusedItem.rowIndex];
761
- const midIndex = currentSearchResults[0]?.selectMIDs?.indexOf(param.mappedMID);
762
- if (currentRowValue && midIndex !== undefined && midIndex >= 0) {
763
- const value = currentRowValue[midIndex];
764
- param.value = value ?? '';
765
- if (param.value === null || param.value === '')
766
- notMappedMIDs = true;
767
- }
768
- else {
769
- notMappedMIDs = true;
770
- }
771
- }
772
- if (notMappedMIDs && qdRetrieveParamsValue.select && qdRetrieveParamsValue.select.length > 0) {
773
- //HERE -> Fetch missing parameter values from the current document to use in the main query
774
- const paramMetadata = await searchEngine.SearchByIDAsync(qdRetrieveParamsValue);
775
- if (paramMetadata?.dtdResult?.rows?.[0]) {
776
- for (const param of qd.params) {
777
- if (!param.mappedMID)
778
- continue;
779
- const colIndex = paramMetadata.selectMIDs?.indexOf(param.mappedMID);
780
- if (colIndex !== undefined && colIndex >= 0) {
781
- const value = paramMetadata.dtdResult.rows[0][colIndex];
782
- param.value = value ?? '';
783
- }
784
- }
785
- }
786
- }
787
- if (qd.where && qd.where.length > 0) {
788
- for (const whereItem of qd.where) {
789
- for (const param of qd.params) {
790
- if (!param.name)
791
- continue;
792
- param.value ??= '';
793
- const paramValue = param.value.toString();
794
- if (whereItem.value1) {
795
- whereItem.value1 = whereItem.value1.replace(param.name, paramValue);
796
- }
797
- if (whereItem.value2) {
798
- whereItem.value2 = whereItem.value2.replace(param.name, paramValue);
799
- }
800
- }
801
- }
802
- }
803
- }
804
- const targetTID = relation.detailTID === selectedSearchResult?.fromTID
805
- ? relation.masterTID
806
- : relation.detailTID;
807
- const systemSelects = [
808
- { tid: targetTID, mid: SystemMIDsAsNumber.DID, visibility: 0 },
809
- { tid: targetTID, mid: SystemMIDsAsNumber.TID, visibility: 0 },
810
- { tid: targetTID, mid: SystemMIDsAsNumber.OwnerID, visibility: 0 },
811
- { tid: targetTID, mid: SystemMIDsAsNumber.UpdaterID, visibility: 0 },
812
- { tid: targetTID, mid: SystemMIDsAsNumber.FileExt, visibility: 0 },
813
- { tid: targetTID, mid: SystemMIDsAsNumber.CreationTime, visibility: 0 },
814
- { tid: targetTID, mid: SystemMIDsAsNumber.LastUpdateTime, visibility: 0 },
815
- { tid: targetTID, mid: SystemMIDsAsNumber.FileCount, visibility: 0 },
816
- { tid: targetTID, mid: SystemMIDsAsNumber.FileSize, visibility: 0 },
817
- { tid: targetTID, mid: SystemMIDsAsNumber.PageCount, visibility: 0 },
818
- ];
819
- if (qd.select) {
820
- qd.select = [...systemSelects, ...qd.select];
821
- }
822
- else {
823
- qd.select = systemSelects;
824
- }
825
- const pairedDocumentsResult = await getPairedDocuments(relation, focusedItem.TID, focusedItem.DID, searchEngine);
826
- if (!isPairing) {
827
- if (!pairedDocumentsResult?.dtdResult?.rows || pairedDocumentsResult.dtdResult.rows.length === 0) {
828
- ShowAlert({
829
- message: "Nessun documento abbinato trovato.",
830
- mode: 'warning',
831
- title: 'Operazione molti-a-molti',
832
- duration: 5000
833
- });
834
- return;
835
- }
836
- const pairedSq = {
837
- fromTID: targetTID,
838
- fromName: await DcmtTypeListCacheService.GetAsync(targetTID).then(d => d?.name ?? ''),
839
- dtdResult: pairedDocumentsResult.dtdResult,
840
- selectMIDs: pairedDocumentsResult.selectMIDs,
841
- relationID: relation.id,
842
- dcmtsReturned: pairedDocumentsResult.dtdResult.rows.length,
843
- dcmtsFound: pairedDocumentsResult.dtdResult.rows.length
844
- };
845
- setPairedSearchResults([pairedSq]);
846
- setIsPairingManyToMany(isPairing);
847
- setShowPairDcmtsModal(true);
848
- return;
849
- }
850
- //HERE -> For pair mode, execute the query and filter out already paired documents
851
- const sq = await searchEngine.SearchByIDAsync(qd);
852
- if (!sq?.dtdResult?.rows || sq.dtdResult.rows.length === 0) {
853
- ShowAlert({
854
- message: "Nessun documento trovato.",
855
- mode: 'warning',
856
- title: 'Operazione molti-a-molti',
857
- duration: 5000
858
- });
859
- return;
860
- }
861
- const pairedDIDs = pairedDocumentsResult ? extractPairedDIDs(pairedDocumentsResult) : [];
862
- const filteredRows = sq.dtdResult.rows.filter(row => {
863
- const did = row[0];
864
- const didNum = typeof did === 'string' ? Number.parseInt(did, 10) : did;
865
- return !pairedDIDs.includes(didNum);
866
- });
867
- const filteredSq = {
868
- ...sq,
869
- dtdResult: {
870
- ...sq.dtdResult,
871
- rows: filteredRows
872
- },
873
- dcmtsReturned: filteredRows.length,
874
- dcmtsFound: filteredRows.length
875
- };
876
- if (filteredRows.length === 0) {
877
- ShowAlert({
878
- message: "Nessun documento da abbinare. Tutti i documenti risultanti dalla query sono già abbinati.",
879
- mode: 'warning',
880
- title: 'Operazione molti-a-molti',
881
- duration: 5000
882
- });
883
- return;
884
- }
885
- setPairedSearchResults([filteredSq]);
886
- setIsPairingManyToMany(isPairing);
887
- setShowPairDcmtsModal(true);
888
- };
889
- const pairManyToMany = async (isPairing) => {
890
- try {
891
- TMSpinner.show({ description: SDKUI_Localizator.Loading });
892
- const relations = await getAllRelationsAsync();
893
- if (!relations)
894
- return;
895
- if (!relations.some(r => r.relationType === RelationTypes.ManyToMany)) {
896
- ShowAlert({
897
- message: "Nessuna relazione molti-a-molti definita nel sistema.",
898
- mode: 'warning',
899
- title: 'Operazione molti-a-molti',
900
- duration: 5000
901
- });
902
- return;
903
- }
904
- const manyToManyRels = relations.filter(r => r.relationType === RelationTypes.ManyToMany);
905
- if (!manyToManyRels.some(r => r.masterTID === selectedSearchResult?.fromTID || r.detailTID === selectedSearchResult?.fromTID)) {
906
- ShowAlert({
907
- message: "Nessuna relazione molti-a-molti definita per il tipo di documento selezionato.",
908
- mode: 'warning',
909
- title: 'Operazione molti-a-molti',
910
- duration: 5000
911
- });
912
- return;
913
- }
914
- const relsManyToMany = manyToManyRels.filter(r => r.masterTID === selectedSearchResult?.fromTID || r.detailTID === selectedSearchResult?.fromTID);
915
- setManyToManyRelations(relsManyToMany);
916
- if (relsManyToMany.length > 1) {
917
- const dataSourcePromises = relsManyToMany.map(async (rel) => {
918
- const targetTID = rel.masterTID === selectedSearchResult?.fromTID ? rel.detailTID : rel.masterTID;
919
- const relatedDcmt = await DcmtTypeListCacheService.GetAsync(targetTID);
920
- return { id: rel?.id, name: relatedDcmt?.name };
921
- });
922
- const dataSource = await Promise.all(dataSourcePromises);
923
- setManyToManyChooserDataSource(dataSource);
924
- setIsPairingManyToMany(isPairing);
925
- setShowManyToManyChooser(true);
926
- }
927
- else {
928
- await executeManyToManyPairing(relsManyToMany[0], isPairing);
929
- }
930
- }
931
- catch (error) {
932
- TMExceptionBoxManager.show({ exception: error });
933
- }
934
- finally {
935
- TMSpinner.hide();
936
- }
937
- };
938
- //#endregion Related Documents Archive Section
939
408
  const searchResutlToolbar = _jsxs(_Fragment, { children: [(dcmtsReturned != dcmtsFound) && _jsx("p", { style: { backgroundColor: `white`, color: TMColors.primaryColor, textAlign: 'center', padding: '1px 4px', borderRadius: '3px', display: 'flex' }, children: `${dcmtsReturned}/${dcmtsFound} restituiti` }), context === SearchResultContext.FAVORITES_AND_RECENTS &&
940
409
  _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: onRefreshSearchAsync }), _jsx(IconMenuVertical, { id: `commands-header-${id}`, color: 'white', cursor: 'pointer' }), _jsx(TMCommandsContextMenu, { target: `#commands-header-${id}`, showEvent: "click", menuItems: getCommandsMenuItems(isMobile, fromDTD, selectedItems, focusedItem, context, showFloatingBar, workingGroupContext, showSearch, setShowFloatingBar, openFormHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openConfirmAttachmentsDialog, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, openExportForm, handleToggleSearch, handleSignApprove, openWGsCopyMoveForm, openCommentFormCallback, openEditPdf, openAddDocumentForm, passToArchiveCallback, archiveMasterDocuments, archiveDetailDocuments, currentTIDHasMasterRelations, currentTIDHasDetailRelations, canArchiveMasterRelation, canArchiveDetailRelation, pairManyToMany, hasManyToManyRelation) })] });
941
410
  const middlePanelToolbar = _jsxs("div", { style: { width: 'max-content', display: 'flex', alignItems: 'center', gap: '10px' }, children: [_jsx(TMSaveFormButtonPrevious, { btnStyle: 'icon', isModified: false, iconColor: TMColors.default_background, formMode: FormModes.ReadOnly, canPrev: canNavigateHandler('prev'), onPrev: () => onNavigateHandler('prev') }), _jsx(TMSaveFormButtonNext, { btnStyle: 'icon', isModified: false, iconColor: TMColors.default_background, formMode: FormModes.ReadOnly, canNext: canNavigateHandler('next'), onNext: () => onNavigateHandler('next') })] });
@@ -1004,7 +473,8 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
1004
473
  TMSpinner.hide();
1005
474
  }
1006
475
  }, onClose: () => setShowManyToManyChooser(false), manageUseLocalizedName: false }), showPairDcmtsModal &&
1007
- _jsx(TMModal, { title: (isPairingManyToMany ? "Abbina" : "Disabbina") + " documenti", onClose: () => setShowPairDcmtsModal(false), children: _jsx(TMSearchResult, { searchResults: pairedSearchResults, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync: onRefreshSearchAsync, onFileOpened: onFileOpened, onTaskCreateRequest: onTaskCreateRequest, openWGsCopyMoveForm: openWGsCopyMoveForm, openEditPdf: openEditPdf, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, passToArchiveCallback: passToArchiveCallback, showTodoDcmtForm: showTodoDcmtForm, floatingActionConfig: pairFloatingActionConfig }) }), (floatingActionConfig && floatingActionConfig.isVisible) && _jsx(TMSearchResultFloatingActionButton, { selectedDcmtsOrFocused: getSelectedDcmtsOrFocused(selectedItems, focusedItem), config: floatingActionConfig })] }), [
476
+ _jsx(TMModal, { title: (isPairingManyToMany ? "Abbina" : "Disabbina") + " documenti", onClose: () => setShowPairDcmtsModal(false), children: _jsx(TMSearchResult, { searchResults: pairedSearchResults, onRefreshAfterAddDcmtToFavs: onRefreshAfterAddDcmtToFavs, onRefreshSearchAsync: onRefreshSearchAsync, onFileOpened: onFileOpened, onTaskCreateRequest: onTaskCreateRequest, openWGsCopyMoveForm: openWGsCopyMoveForm, openEditPdf: openEditPdf, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, passToArchiveCallback: passToArchiveCallback, showTodoDcmtForm: showTodoDcmtForm, floatingActionConfig: pairFloatingActionConfig }) }), showPairSearchModal &&
477
+ _jsx(TMModal, { title: "Ricerca documenti", onClose: () => setShowPairSearchModal(false), children: _jsx(TMSearch, { onlyShowSearchQueryPanel: true, inputTID: pairSearchModalTargetTID, inputMids: pairSearchModalInputMids, floatingActionConfig: pairSearchModalFloatingActionConfig }) }), (floatingActionConfig && floatingActionConfig.isVisible) && _jsx(TMSearchResultFloatingActionButton, { selectedDcmtsOrFocused: getSelectedDcmtsOrFocused(selectedItems, focusedItem), config: floatingActionConfig })] }), [
1008
478
  searchResults,
1009
479
  selectedSearchResult,
1010
480
  lastUpdateSearchTime,
@@ -1042,6 +512,13 @@ const TMSearchResult = ({ context = SearchResultContext.METADATA_SEARCH, isVisib
1042
512
  selectedManyToManyRelation,
1043
513
  pairFloatingActionConfig,
1044
514
  hasManyToManyRelation,
515
+ showPairSearchModal,
516
+ pairSearchModalFloatingActionConfig,
517
+ pairSearchModalTargetTID,
518
+ pairSearchModalParentTID,
519
+ pairSearchModalParentDID,
520
+ pairSearchModalRelation,
521
+ pairSearchModalInputMids,
1045
522
  ]);
1046
523
  const tmBlog = useMemo(() => _jsx(TMDcmtBlog, { tid: focusedItem?.TID, did: focusedItem?.DID }), [focusedItem]);
1047
524
  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]);