@topconsultnpm/sdkui-react 6.20.0-dev1.44 → 6.20.0-dev1.45
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/editors/TMMetadataValues.js +3 -3
- package/lib/components/features/documents/TMDcmtForm.js +105 -43
- package/lib/components/features/search/TMSearchResult.js +6 -4
- package/lib/helper/helpers.d.ts +2 -1
- package/lib/helper/helpers.js +5 -1
- package/lib/hooks/useWorkflowApprove.d.ts +4 -0
- package/lib/hooks/useWorkflowApprove.js +14 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
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
3
|
import styled from "styled-components";
|
|
4
|
-
import { AccessLevels, DcmtTypeListCacheService, LayoutGroupBorderStyles, LayoutGroupOrientations, LayoutItemTypes, LayoutModes, MetadataDataDomains, MetadataDataTypes, SDK_Globals, SystemMIDsAsNumber, SystemTIDs,
|
|
5
|
-
import { IconUndo, IconPencil, IconFunction, IconMenuVertical, IconDataList, SDKUI_Localizator, IconNull, stringIsNullOrEmpty, deepCompare, SDKUI_Globals, IconDcmtTypeSys } from "../../helper";
|
|
4
|
+
import { AccessLevels, DcmtTypeListCacheService, LayoutGroupBorderStyles, LayoutGroupOrientations, LayoutItemTypes, LayoutModes, MetadataDataDomains, MetadataDataTypes, SDK_Globals, SystemMIDsAsNumber, SystemTIDs, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
|
|
5
|
+
import { IconUndo, IconPencil, IconFunction, IconMenuVertical, IconDataList, SDKUI_Localizator, IconNull, stringIsNullOrEmpty, deepCompare, SDKUI_Globals, IconDcmtTypeSys, isApprovalWorkflowView } from "../../helper";
|
|
6
6
|
import { TMColors } from "../../utils/theme";
|
|
7
7
|
import TMButton from "../base/TMButton";
|
|
8
8
|
import TMDropDownMenu from "../base/TMDropDownMenu";
|
|
@@ -568,7 +568,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
568
568
|
if (allSystem) {
|
|
569
569
|
return metadataValues.map((item) => renderMetadataItem(item, true));
|
|
570
570
|
}
|
|
571
|
-
if (currentDTD
|
|
571
|
+
if (isApprovalWorkflowView(currentDTD) && !isReadOnly) {
|
|
572
572
|
return layoutWorkItem;
|
|
573
573
|
}
|
|
574
574
|
switch (currentDTD?.id) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import TMDcmtPreview from './TMDcmtPreview';
|
|
4
|
-
import { AccessLevels, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataTypes, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States,
|
|
4
|
+
import { AccessLevels, ArchiveConstraints, ArchiveEngineByID, DcmtTypeListCacheService, LayoutCacheService, LayoutModes, MetadataDataTypes, ObjectClasses, ResultTypes, SDK_Globals, SDK_Localizator, SystemMIDsAsNumber, SystemTIDs, Task_States, TID_DID, UpdateEngineByID, UserListCacheService, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
|
|
5
5
|
import { WorkFlowApproveRejectPopUp, WorkFlowMoreInfoPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../workflow/TMWorkflowPopup';
|
|
6
6
|
import { DownloadTypes, FormModes, DcmtOperationTypes } from '../../../ts';
|
|
7
7
|
import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
|
|
8
8
|
import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
|
|
9
9
|
import { useRelatedDocuments } from '../../../hooks/useRelatedDocuments';
|
|
10
10
|
import { getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
|
|
11
|
-
import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, IconDownload, calcIsModified, IconMenuVertical, Globalization, getListMaxItems, getSystemMetadata, IconBoxArchiveIn, IconClear, IconUndo, SDKUI_Globals, IconPreview, isTaskMoreInfo, IconWorkflow, IconSearch, deepCompare, IconCheck, IconActivity, TMImageLibrary, IconStar, IconRelation, IconInfo, IconArchiveDoc, IconDelete, IconPair, IconUnpair, IconArchiveMaster, IconArchiveDetail, getDcmtCicoStatus, IconFileDots, IconCustom } from '../../../helper';
|
|
11
|
+
import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, IconDownload, calcIsModified, IconMenuVertical, Globalization, getListMaxItems, getSystemMetadata, IconBoxArchiveIn, IconClear, IconUndo, SDKUI_Globals, IconPreview, isTaskMoreInfo, IconWorkflow, IconSearch, deepCompare, IconCheck, IconActivity, TMImageLibrary, IconStar, IconRelation, IconInfo, IconArchiveDoc, IconDelete, IconPair, IconUnpair, IconArchiveMaster, IconArchiveDetail, getExceptionMessage, isApprovalWorkflowView, getDcmtCicoStatus, IconFileDots, IconCustom } from '../../../helper';
|
|
12
12
|
import { hasDetailRelations, hasMasterRelations, isXMLFileExt } from '../../../helper/dcmtsHelper';
|
|
13
13
|
import { Gutters, TMColors } from '../../../utils/theme';
|
|
14
14
|
import { StyledFormButtonsContainer, StyledLoadingContainer, StyledModalContainer, StyledReferenceButton, StyledSpinner, StyledToolbarCardContainer } from '../../base/Styled';
|
|
@@ -119,6 +119,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
119
119
|
const [dcmtReferences, setDcmtReferences] = useState(undefined);
|
|
120
120
|
// Stato per triggerare il refresh del blog dall'esterno
|
|
121
121
|
const [refreshBlogTrigger, setRefreshBlogTrigger] = useState(0);
|
|
122
|
+
const [wfError, setWfError] = useState(null);
|
|
122
123
|
const triggerBlogRefresh = useCallback(async () => {
|
|
123
124
|
setRefreshBlogTrigger(prev => prev + 1);
|
|
124
125
|
}, []);
|
|
@@ -135,7 +136,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
135
136
|
}, [allowButtonsRefs]);
|
|
136
137
|
const { openConfirmAttachmentsDialog, ConfirmAttachmentsDialog } = useInputAttachmentsDialog();
|
|
137
138
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync } = useDcmtOperations();
|
|
138
|
-
const { workflowApproveData } = useWorkflowApprove();
|
|
139
|
+
const { workflowApproveData, getWorkItemsByDID } = useWorkflowApprove();
|
|
139
140
|
const currentSearchResults = useMemo(() => {
|
|
140
141
|
if (!formData || formData.length === 0 || !TID || !DID)
|
|
141
142
|
return [];
|
|
@@ -453,74 +454,110 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
453
454
|
return;
|
|
454
455
|
copyCheckoutPathToClipboardCallback({ TID: currentDcmt.tid, DID: currentDcmt.did, FILEEXT: currentDcmt.fileExt }, fromDTD?.name ?? SDKUI_Localizator.SearchResult);
|
|
455
456
|
};
|
|
457
|
+
// useEffect per il caricamento dei dati del workflow
|
|
456
458
|
useEffect(() => {
|
|
459
|
+
// Funzione helper per caricare le informazioni del workflow
|
|
460
|
+
const loadWorkflowInfo = async (tid) => {
|
|
461
|
+
await WorkflowCacheService.GetWFInfoAsync(tid)
|
|
462
|
+
.then((result) => {
|
|
463
|
+
if (result) {
|
|
464
|
+
setWorkflows([result]);
|
|
465
|
+
setWfError(null);
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
setWorkflows([]);
|
|
469
|
+
setWfError("Workflow info not found");
|
|
470
|
+
}
|
|
471
|
+
})
|
|
472
|
+
.catch(error => {
|
|
473
|
+
setWorkflows([]);
|
|
474
|
+
console.log("Error fetching workflow info:", error);
|
|
475
|
+
setWfError(getExceptionMessage(error));
|
|
476
|
+
});
|
|
477
|
+
};
|
|
457
478
|
const loadAllWfData = async () => {
|
|
458
|
-
|
|
479
|
+
// FASE 1: Validazione prerequisiti
|
|
480
|
+
if (layoutMode !== LayoutModes.Update || !DID) {
|
|
459
481
|
setWorkItems([]);
|
|
460
482
|
setWorkflows([]);
|
|
461
483
|
return;
|
|
462
484
|
}
|
|
463
485
|
setIsWFDataLoading(true);
|
|
464
486
|
try {
|
|
465
|
-
//
|
|
466
|
-
const itemsToProcess =
|
|
467
|
-
|
|
468
|
-
for (const dataRow of workflow.dtdResult?.rows ?? []) {
|
|
469
|
-
const did = Number(dataRow?.[1]);
|
|
470
|
-
if (did === Number(DID)) {
|
|
471
|
-
const tid = Number(dataRow?.[0]);
|
|
472
|
-
itemsToProcess.push({ tid, did });
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
487
|
+
// FASE 2: Raccolta work items: array di tutti i possibili work items che matchano il DID corrente
|
|
488
|
+
const itemsToProcess = getWorkItemsByDID(Number(DID));
|
|
489
|
+
// Se non ci sono work items per questo DID, resetta e esci
|
|
476
490
|
if (itemsToProcess.length === 0) {
|
|
477
491
|
setWorkItems([]);
|
|
478
492
|
setWorkflows([]);
|
|
479
493
|
setIsWFDataLoading(false);
|
|
480
494
|
return;
|
|
481
495
|
}
|
|
482
|
-
//
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
496
|
+
// FASE 3: Ricerca work item specifico
|
|
497
|
+
// Cerca prima un match esatto con TID e DID correnti
|
|
498
|
+
const foundItem = itemsToProcess.find(item => item.tid === Number(TID) && item.did === Number(DID));
|
|
499
|
+
if (foundItem) {
|
|
500
|
+
// SCENARIO A: Match esatto trovato (TID e DID corrispondono)
|
|
501
|
+
// Il documento corrente è esattamente il work item nel workflow
|
|
502
|
+
let setID = undefined;
|
|
503
|
+
// Prova a usare il setID già presente nei metadati (più veloce)
|
|
504
|
+
if (workItemSetIDValue !== undefined) {
|
|
505
|
+
setID = workItemSetIDValue;
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
// Altrimenti caricalo dal server
|
|
509
|
+
setID = await getWorkItemSetIDAsync(foundItem.tid, foundItem.did);
|
|
510
|
+
}
|
|
511
|
+
// Imposta un singolo work item con il setID caricato
|
|
512
|
+
setWorkItems([{ ...foundItem, setID }]);
|
|
513
|
+
// Carica le informazioni complete del workflow
|
|
514
|
+
await loadWorkflowInfo(foundItem.tid);
|
|
487
515
|
}
|
|
488
516
|
else {
|
|
489
|
-
//
|
|
490
|
-
|
|
517
|
+
// SCENARIO B: Nessun match esatto, cerca solo per DID
|
|
518
|
+
const itemsByDID = itemsToProcess.filter(item => item.did === Number(DID));
|
|
519
|
+
if (itemsByDID.length === 1) {
|
|
520
|
+
// SCENARIO B.1: Un solo item trovato per DID
|
|
521
|
+
// Situazione sicura: sappiamo esattamente quale work item usare
|
|
522
|
+
const singleItem = itemsByDID[0];
|
|
523
|
+
let setID;
|
|
524
|
+
// Carica il setID (da cache o da server)
|
|
525
|
+
if (workItemSetIDValue !== undefined) {
|
|
526
|
+
setID = workItemSetIDValue;
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
setID = await getWorkItemSetIDAsync(singleItem.tid, singleItem.did);
|
|
530
|
+
}
|
|
531
|
+
setWorkItems([{ ...singleItem, setID }]);
|
|
532
|
+
// Carica le informazioni del workflow
|
|
533
|
+
await loadWorkflowInfo(singleItem.tid);
|
|
534
|
+
}
|
|
535
|
+
else if (itemsByDID.length > 1) {
|
|
536
|
+
// SCENARIO B.2: Più item trovati per lo stesso DID
|
|
537
|
+
// Ambiguità: lo stesso documento appare in più workflow diversi
|
|
538
|
+
const finalWorkItems = itemsByDID.map((item, index) => ({ ...item, setID: undefined }));
|
|
539
|
+
setWorkItems(finalWorkItems);
|
|
540
|
+
setWorkflows([]); // Non carichiamo il workflow in caso di ambiguità
|
|
541
|
+
}
|
|
491
542
|
}
|
|
492
|
-
// Crea un array di Promise per tutte le chiamate a GetWFInfoAsync
|
|
493
|
-
const workflowInfoPromises = itemsToProcess.map(item => WorkflowCacheService.GetWFInfoAsync(item.tid));
|
|
494
|
-
// Esegui tutte le chiamate in parallelo e attendi i risultati
|
|
495
|
-
const setIDResults = await Promise.all(setIDPromises);
|
|
496
|
-
const workflowInfoResults = await Promise.all(workflowInfoPromises);
|
|
497
|
-
// Combina i risultati
|
|
498
|
-
const finalWorkItems = itemsToProcess.map((item, index) => ({
|
|
499
|
-
...item,
|
|
500
|
-
setID: setIDResults[index],
|
|
501
|
-
}));
|
|
502
|
-
const validWorkflows = workflowInfoResults.filter(Boolean);
|
|
503
|
-
// Aggiorna lo stato una sola volta con i dati finali
|
|
504
|
-
setWorkItems(finalWorkItems);
|
|
505
|
-
setWorkflows(validWorkflows);
|
|
506
543
|
}
|
|
507
544
|
catch (error) {
|
|
545
|
+
// FASE 4: Gestione errori
|
|
508
546
|
TMExceptionBoxManager.show({ exception: error });
|
|
509
547
|
setWorkItems([]);
|
|
510
548
|
setWorkflows([]);
|
|
511
549
|
}
|
|
512
550
|
finally {
|
|
551
|
+
// Garantisce sempre il reset del flag di loading
|
|
513
552
|
setIsWFDataLoading(false);
|
|
514
553
|
}
|
|
515
554
|
};
|
|
516
|
-
// Usa hasFormData invece di formDataRef.current
|
|
517
555
|
if (!hasFormData || !fromDTD?.id) {
|
|
518
|
-
// console.log("formData is empty or fromDTD not loaded, skipping loadAllWfData");
|
|
519
556
|
return;
|
|
520
557
|
}
|
|
521
558
|
if (workItemSetIDValue !== undefined || workflowApproveData.length > 0)
|
|
522
559
|
loadAllWfData();
|
|
523
|
-
}, [hasFormData, workItemSetIDValue, workflowApproveData, DID, layoutMode, fromDTD?.templateTID, fromDTD?.id]);
|
|
560
|
+
}, [hasFormData, workItemSetIDValue, workflowApproveData, getWorkItemsByDID, TID, DID, layoutMode, fromDTD?.templateTID, fromDTD?.id]);
|
|
524
561
|
const getSelectionDcmtInfo = useCallback(() => {
|
|
525
562
|
let dcmts = [];
|
|
526
563
|
dcmts.push({ TID: TID ?? 0, DID: DID ?? 0 });
|
|
@@ -551,7 +588,11 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
551
588
|
const showToppyForCompleteMoreInfo = useMemo(() => layoutMode === LayoutModes.Update && !!isTaskMoreInfo(taskMoreInfo?.name) && taskMoreInfo?.state !== Task_States.Completed, [layoutMode, taskMoreInfo?.name, taskMoreInfo?.state]);
|
|
552
589
|
const showToppyForReferences = useMemo(() => allowButtonsRefs && layoutMode === LayoutModes.Update && !!(dcmtReferences && dcmtReferences.length > 0) && !isOpenDetails && !isOpenMaster, [allowButtonsRefs, layoutMode, dcmtReferences, isOpenDetails, isOpenMaster]);
|
|
553
590
|
const isMobile = useMemo(() => deviceType === DeviceType.MOBILE, [deviceType]);
|
|
554
|
-
const isApprView = useMemo(() =>
|
|
591
|
+
const isApprView = useMemo(() => {
|
|
592
|
+
if (!fromDTD)
|
|
593
|
+
return false;
|
|
594
|
+
return isApprovalWorkflowView(fromDTD);
|
|
595
|
+
}, [fromDTD?.id]);
|
|
555
596
|
const workitemSetID = useMemo(() => workItems.find(o => o.did === Number(DID))?.setID || formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [workItems, DID, formData]);
|
|
556
597
|
const approvalVID = useMemo(() => workItems.length > 0 ? Number(workItems[0].tid) : -1, [workItems]);
|
|
557
598
|
//here
|
|
@@ -586,11 +627,12 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
586
627
|
disabled: false,
|
|
587
628
|
onClick: () => {
|
|
588
629
|
const dcmt = getDcmts()[0];
|
|
630
|
+
const name = `${fromDTD?.name ?? '-'} (DID: ${dcmt.DID})`;
|
|
589
631
|
const taskContext = {
|
|
590
632
|
document: {
|
|
591
633
|
tid: dcmt.TID,
|
|
592
634
|
did: dcmt.DID,
|
|
593
|
-
name:
|
|
635
|
+
name: name
|
|
594
636
|
}
|
|
595
637
|
};
|
|
596
638
|
onTaskCreateRequest(taskContext);
|
|
@@ -1182,7 +1224,27 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
1182
1224
|
fontSize: '1.1rem',
|
|
1183
1225
|
color: TMColors.primaryColor,
|
|
1184
1226
|
textAlign: 'center',
|
|
1185
|
-
|
|
1227
|
+
display: 'flex',
|
|
1228
|
+
flexDirection: 'column',
|
|
1229
|
+
alignItems: 'center',
|
|
1230
|
+
gap: '12px',
|
|
1231
|
+
}, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [_jsx("span", { children: SDKUI_Localizator.WorkflowDiagramNotAuthorized }), wfError && (_jsx(TMTooltip, { content: 'Visualizza errore', children: _jsx("i", { className: "dx-icon-info", style: { fontSize: 20, cursor: 'pointer', color: '#dc3545' }, onClick: () => {
|
|
1232
|
+
TMMessageBoxManager.show({
|
|
1233
|
+
title: 'Dettagli Errore Workflow',
|
|
1234
|
+
initialWidth: !isMobile ? '700px' : undefined,
|
|
1235
|
+
message: (_jsx("pre", { style: {
|
|
1236
|
+
whiteSpace: 'pre-wrap',
|
|
1237
|
+
background: '#f5f5f5',
|
|
1238
|
+
padding: '12px',
|
|
1239
|
+
borderRadius: '6px',
|
|
1240
|
+
userSelect: 'text',
|
|
1241
|
+
cursor: 'text',
|
|
1242
|
+
}, children: wfError })),
|
|
1243
|
+
resizable: true,
|
|
1244
|
+
showToppy: false,
|
|
1245
|
+
buttons: [ButtonNames.OK],
|
|
1246
|
+
});
|
|
1247
|
+
} }) }))] }) }))
|
|
1186
1248
|
: _jsx("div", { style: {
|
|
1187
1249
|
position: 'absolute',
|
|
1188
1250
|
top: '50%',
|
|
@@ -1442,7 +1504,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
1442
1504
|
} }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 0, onClose: () => setShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, isReject: 1, onClose: () => setShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, TID: approvalVID, DID: DID, onClose: () => setShowMoreInfoPopup(false) }), (isModal && onClose) && _jsx("div", { id: "TMDcmtFormShowConfirmForClose-" + id })] }) }), _jsx(ToppyDraggableHelpCenter, { initialIsCollapsed: false, deviceType: deviceType, isVisible: (showToppyForApprove || showToppyForCompleteMoreInfo || showToppyForReferences) && !openS4TViewer, content: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '10px' }, children: [showToppyForApprove && (workItems.length === 1 ?
|
|
1443
1505
|
_jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true), dtd: fromDTD })
|
|
1444
1506
|
:
|
|
1445
|
-
_jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`
|
|
1507
|
+
_jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`Questo documento è associato a ${workItems.length} workitem.`, _jsx("br", {}), `Per approvare, vai alla pagina "Approvazione workflow".`] })), showToppyForCompleteMoreInfo && (_jsxs(_Fragment, { children: [_jsx("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: `${SDKUI_Localizator.MoreInfoCompleteRequestSentBy} ${taskMoreInfo?.fromName}!` }), _jsx(TMButton, { caption: SDKUI_Localizator.CommentAndComplete, color: 'success', showTooltip: false, onClick: () => {
|
|
1446
1508
|
setShowCommentForm(true);
|
|
1447
1509
|
} })] })), (showToppyForReferences && (dcmtReferences && dcmtReferences.length > 0)) && dcmtReferences
|
|
1448
1510
|
.filter(ref => ref.objClass === ObjectClasses.Dossier || ref.objClass === ObjectClasses.WorkingGroup) // keep only known objClass types
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes,
|
|
3
|
+
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, DcmtTypeListCacheService, SystemMIDsAsNumber, RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats, AccessLevelsEx, LayoutCacheService, UserListCacheService } from '@topconsultnpm/sdk-ts';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
import { getAllFieldSelectedDcmtsOrFocused, getCommandsMenuItems, getSelectedDcmtsOrFocused } from './TMSearchResultsMenuItems';
|
|
6
|
-
import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, deepCompare, generateUniqueColumnKeys, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMImageLibrary, convertSearchResultDescriptorToFileItems, IconCustom } from '../../../helper';
|
|
6
|
+
import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, deepCompare, generateUniqueColumnKeys, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMImageLibrary, convertSearchResultDescriptorToFileItems, IconCustom, isApprovalWorkflowView } from '../../../helper';
|
|
7
7
|
import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
|
|
8
8
|
import { useInputAttachmentsDialog, useInputCvtFormatDialog } from '../../../hooks/useInputDialog';
|
|
9
9
|
import { useRelatedDocuments } from '../../../hooks/useRelatedDocuments';
|
|
@@ -261,7 +261,7 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
|
|
|
261
261
|
try {
|
|
262
262
|
const dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(item.TID, item?.DID);
|
|
263
263
|
if (dtd) {
|
|
264
|
-
const isWorkItem = dtd
|
|
264
|
+
const isWorkItem = isApprovalWorkflowView(dtd);
|
|
265
265
|
const name = `${dtd.name ?? '-'} (DID: ${item.DID})`;
|
|
266
266
|
onTaskCreateRequest?.(isWorkItem
|
|
267
267
|
? { workItem: { tid: item.TID, did: item.DID, name } }
|
|
@@ -582,7 +582,9 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
|
|
|
582
582
|
const handleSavedAsyncCallback = useCallback(async (tid, did, metadataResult) => {
|
|
583
583
|
await refreshFocusedDataRowAsync(tid, did, true, metadataResult);
|
|
584
584
|
}, [refreshFocusedDataRowAsync]);
|
|
585
|
-
const showToppyForApprove = (
|
|
585
|
+
const showToppyForApprove = useMemo(() => {
|
|
586
|
+
return Boolean(isVisible && fromDTD && isApprovalWorkflowView(fromDTD) && !isOpenDcmtForm && !isOpenDetails && !isOpenMaster);
|
|
587
|
+
}, [isVisible, fromDTD, isOpenDcmtForm, isOpenDetails, isOpenMaster]);
|
|
586
588
|
const floatingMenuItems = useMemo(() => {
|
|
587
589
|
return getCommandsMenuItems(isMobile, fromDTD, allUsers, selectedItems, focusedItem, context, showFloatingBar, workingGroupContext, showSearch, setShowFloatingBar, openFormHandler, openSharedArchiveHandler, showSharedDcmtsHandler, downloadDcmtsAsync, runOperationAsync, onRefreshSearchAsync, refreshSelectionDataRowsAsync, onRefreshAfterAddDcmtToFavs, confirmFormat, openConfirmAttachmentsDialog, openTaskFormHandler, openDetailDcmtsFormHandler, openMasterDcmtsFormHandler, openBatchUpdateFormHandler, openExportForm, handleToggleSearch, handleSignApprove, openSignSettingsForm, handleCheckOutOperationCallback, handleCheckInOperationCallback, showCheckoutInformationFormCallback, showHistoryCallback, copyCheckoutPathToClipboardOperationCallback, openWGsCopyMoveForm, openCommentFormCallback, openEditPdf, openAddDocumentForm, passToArchiveCallback, archiveMasterDocuments, archiveDetailDocuments, currentTIDHasMasterRelations, currentTIDHasDetailRelations, canArchiveMasterRelation, canArchiveDetailRelation, pairManyToMany, hasManyToManyRelation).concat([customButtonMenuItems()]);
|
|
588
590
|
}, [
|
package/lib/helper/helpers.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Colors as ColorsType } from "../components/base/TMEditorBase";
|
|
2
2
|
import { DeviceType } from "../components";
|
|
3
|
-
import { AppModules, DataColumnDescriptor, ITopMediaSession, MetadataDescriptor, QueryDescriptor, SearchResultDescriptor } from "@topconsultnpm/sdk-ts";
|
|
3
|
+
import { AppModules, DataColumnDescriptor, DcmtTypeDescriptor, ITopMediaSession, MetadataDescriptor, QueryDescriptor, SearchResultDescriptor } from "@topconsultnpm/sdk-ts";
|
|
4
4
|
import { FileExtensionHandler, FormModes, moduleTypes } from "../ts";
|
|
5
5
|
declare const TABLET_WIDTH = 1024;
|
|
6
6
|
declare const MOBILE_WIDTH = 640;
|
|
@@ -89,3 +89,4 @@ export declare class AreaHelper {
|
|
|
89
89
|
static ExtractAreaInfo_1(areaPath: string): AreaValues;
|
|
90
90
|
static ExtractAreaInfo_2(areaPath: string, extractFileName: boolean): AreaValues;
|
|
91
91
|
}
|
|
92
|
+
export declare const isApprovalWorkflowView: (dtd: DcmtTypeDescriptor) => boolean;
|
package/lib/helper/helpers.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Colors } from "../utils/theme";
|
|
3
3
|
import { ButtonNames, DeviceType, TMExceptionBoxManager, TMMessageBoxManager, TMSpinner } from "../components";
|
|
4
|
-
import { AccessLevels, MetadataDataDomains, MetadataDataTypes, MetadataDescriptor, MetadataFormatDescriptor, MetadataFormats, MetadataPermission, SDK_Globals, SetGlobalsInfoAsync, SystemMIDs, SystemMIDsAsNumber, TopMediaServer } from "@topconsultnpm/sdk-ts";
|
|
4
|
+
import { AccessLevels, MetadataDataDomains, MetadataDataTypes, MetadataDescriptor, MetadataFormatDescriptor, MetadataFormats, MetadataPermission, SDK_Globals, SetGlobalsInfoAsync, SystemMIDs, SystemMIDsAsNumber, TopMediaServer, WorkItemMetadataNames } from "@topconsultnpm/sdk-ts";
|
|
5
5
|
import { Buffer } from 'buffer';
|
|
6
6
|
import { buildTypes, FileExtensionHandler, FormModes, moduleTypes } from "../ts";
|
|
7
7
|
import { SDKUI_Localizator } from "./SDKUI_Localizator";
|
|
@@ -856,3 +856,7 @@ export class AreaHelper {
|
|
|
856
856
|
}
|
|
857
857
|
AreaHelper.AreaPathPrefix = "tmarea:\\\\";
|
|
858
858
|
AreaHelper.AreaFolderNamePrefix = "AID_";
|
|
859
|
+
export const isApprovalWorkflowView = (dtd) => {
|
|
860
|
+
return Boolean(dtd?.isView &&
|
|
861
|
+
dtd.metadata?.some(data => data.name === WorkItemMetadataNames.WI_DID));
|
|
862
|
+
};
|
|
@@ -14,6 +14,19 @@ export const useWorkflowApprove = () => {
|
|
|
14
14
|
const calculateTotalDcmtsFound = useCallback((data) => {
|
|
15
15
|
return data.reduce((sum, item) => sum + (item.dcmtsFound || 0), 0);
|
|
16
16
|
}, []);
|
|
17
|
+
/**
|
|
18
|
+
* Ottiene tutti i work items che corrispondono a un determinato DID.
|
|
19
|
+
* Restituisce un array di oggetti { tid, did }.
|
|
20
|
+
*/
|
|
21
|
+
const getWorkItemsByDID = useCallback((targetDID) => {
|
|
22
|
+
return workflowApproveData
|
|
23
|
+
.flatMap(workflow => workflow.dtdResult?.rows ?? [])
|
|
24
|
+
.filter(dataRow => Number(dataRow?.[1]) === targetDID)
|
|
25
|
+
.map(dataRow => ({
|
|
26
|
+
tid: Number(dataRow[0]),
|
|
27
|
+
did: targetDID
|
|
28
|
+
}));
|
|
29
|
+
}, [workflowApproveData]);
|
|
17
30
|
/**
|
|
18
31
|
* Esegue il fetch dei dati dal workflow, aggiorna lo stato globale
|
|
19
32
|
* e notifica gli altri componenti tramite un evento.
|
|
@@ -53,5 +66,5 @@ export const useWorkflowApprove = () => {
|
|
|
53
66
|
window.removeEventListener('onWorkflowApproveChange', handleUpdate);
|
|
54
67
|
};
|
|
55
68
|
}, [calculateTotalDcmtsFound]);
|
|
56
|
-
return { workflowApproveData, isLoading, refreshWorkflowApprove, totalDcmtsFound };
|
|
69
|
+
return { workflowApproveData, isLoading, refreshWorkflowApprove, totalDcmtsFound, getWorkItemsByDID };
|
|
57
70
|
};
|