@topconsultnpm/sdkui-react 6.19.0-hotfix1 → 6.19.0-hotfix2
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 +2 -2
|
@@ -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";
|
|
@@ -536,7 +536,7 @@ const TMMetadataValues = ({ showCheckBoxes = ShowCheckBoxesMode.Never, checkPerm
|
|
|
536
536
|
if (allSystem) {
|
|
537
537
|
return metadataValues.map((item) => renderMetadataItem(item, true));
|
|
538
538
|
}
|
|
539
|
-
if (currentDTD
|
|
539
|
+
if (isApprovalWorkflowView(currentDTD) && !isReadOnly) {
|
|
540
540
|
return layoutWorkItem;
|
|
541
541
|
}
|
|
542
542
|
switch (currentDTD?.id) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, 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, ValidationItem, WorkflowCacheService, WorkItemMetadataNames } from '@topconsultnpm/sdk-ts';
|
|
5
5
|
import { ContextMenu } from 'devextreme-react';
|
|
6
6
|
import { WorkFlowApproveRejectPopUp, WorkFlowMoreInfoPopUp, WorkFlowOperationButtons, WorkFlowReAssignPopUp } from '../workflow/TMWorkflowPopup';
|
|
7
7
|
import { DownloadTypes, FormModes, DcmtOperationTypes } from '../../../ts';
|
|
@@ -9,7 +9,7 @@ import { DeviceType, useDeviceType } from '../../base/TMDeviceProvider';
|
|
|
9
9
|
import { useDcmtOperations } from '../../../hooks/useDcmtOperations';
|
|
10
10
|
import { useRelatedDocuments } from '../../../hooks/useRelatedDocuments';
|
|
11
11
|
import { getWorkItemSetIDAsync, handleArchiveVisibility, searchResultToMetadataValues } from '../../../helper/queryHelper';
|
|
12
|
-
import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, svgToString, 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 } from '../../../helper';
|
|
12
|
+
import { genUniqueId, IconShow, SDKUI_Localizator, updateMruTids, IconBoard, IconDcmtTypeSys, IconDetailDcmts, svgToString, 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 } from '../../../helper';
|
|
13
13
|
import { hasDetailRelations, hasMasterRelations, isXMLFileExt } from '../../../helper/dcmtsHelper';
|
|
14
14
|
import { Gutters, TMColors } from '../../../utils/theme';
|
|
15
15
|
import { StyledFormButtonsContainer, StyledLoadingContainer, StyledModalContainer, StyledReferenceButton, StyledSpinner, StyledToolbarCardContainer } from '../../base/Styled';
|
|
@@ -96,6 +96,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
96
96
|
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
|
97
97
|
const [isNavigating, setIsNavigating] = useState(false);
|
|
98
98
|
const [dcmtReferences, setDcmtReferences] = useState(undefined);
|
|
99
|
+
const [wfError, setWfError] = useState(null);
|
|
99
100
|
// Dcmt Blog states
|
|
100
101
|
const [blogsDatasource, setBlogsDatasource] = useState([]);
|
|
101
102
|
const [hasLoadedDataOnce, setHasLoadedDataOnce] = useState(false); //traccia se *qualsiasi* dato è stato caricato per la prima volta
|
|
@@ -106,7 +107,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
106
107
|
}, [allowButtonsRefs]);
|
|
107
108
|
const { openConfirmAttachmentsDialog, ConfirmAttachmentsDialog } = useInputAttachmentsDialog();
|
|
108
109
|
const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync } = useDcmtOperations();
|
|
109
|
-
const { workflowApproveData } = useWorkflowApprove();
|
|
110
|
+
const { workflowApproveData, getWorkItemsByDID } = useWorkflowApprove();
|
|
110
111
|
const currentSearchResults = useMemo(() => {
|
|
111
112
|
if (!formData || formData.length === 0 || !TID || !DID)
|
|
112
113
|
return [];
|
|
@@ -410,74 +411,110 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
410
411
|
const workItemSetIDValue = useMemo(() => formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [formData]);
|
|
411
412
|
// Valore derivato: true se formData ha elementi validi
|
|
412
413
|
const hasFormData = useMemo(() => formData.length > 0 && formData.some(md => md.mid && md.mid > 99), [formData]);
|
|
414
|
+
// useEffect per il caricamento dei dati del workflow
|
|
413
415
|
useEffect(() => {
|
|
416
|
+
// Funzione helper per caricare le informazioni del workflow
|
|
417
|
+
const loadWorkflowInfo = async (tid) => {
|
|
418
|
+
await WorkflowCacheService.GetWFInfoAsync(tid)
|
|
419
|
+
.then((result) => {
|
|
420
|
+
if (result) {
|
|
421
|
+
setWorkflows([result]);
|
|
422
|
+
setWfError(null);
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
setWorkflows([]);
|
|
426
|
+
setWfError("Workflow info not found");
|
|
427
|
+
}
|
|
428
|
+
})
|
|
429
|
+
.catch(error => {
|
|
430
|
+
setWorkflows([]);
|
|
431
|
+
console.log("Error fetching workflow info:", error);
|
|
432
|
+
setWfError(getExceptionMessage(error));
|
|
433
|
+
});
|
|
434
|
+
};
|
|
414
435
|
const loadAllWfData = async () => {
|
|
415
|
-
|
|
436
|
+
// FASE 1: Validazione prerequisiti
|
|
437
|
+
if (layoutMode !== LayoutModes.Update || !DID) {
|
|
416
438
|
setWorkItems([]);
|
|
417
439
|
setWorkflows([]);
|
|
418
440
|
return;
|
|
419
441
|
}
|
|
420
442
|
setIsWFDataLoading(true);
|
|
421
443
|
try {
|
|
422
|
-
//
|
|
423
|
-
const itemsToProcess =
|
|
424
|
-
|
|
425
|
-
for (const dataRow of workflow.dtdResult?.rows ?? []) {
|
|
426
|
-
const did = Number(dataRow?.[1]);
|
|
427
|
-
if (did === Number(DID)) {
|
|
428
|
-
const tid = Number(dataRow?.[0]);
|
|
429
|
-
itemsToProcess.push({ tid, did });
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
444
|
+
// FASE 2: Raccolta work items: array di tutti i possibili work items che matchano il DID corrente
|
|
445
|
+
const itemsToProcess = getWorkItemsByDID(Number(DID));
|
|
446
|
+
// Se non ci sono work items per questo DID, resetta e esci
|
|
433
447
|
if (itemsToProcess.length === 0) {
|
|
434
448
|
setWorkItems([]);
|
|
435
449
|
setWorkflows([]);
|
|
436
450
|
setIsWFDataLoading(false);
|
|
437
451
|
return;
|
|
438
452
|
}
|
|
439
|
-
//
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
453
|
+
// FASE 3: Ricerca work item specifico
|
|
454
|
+
// Cerca prima un match esatto con TID e DID correnti
|
|
455
|
+
const foundItem = itemsToProcess.find(item => item.tid === Number(TID) && item.did === Number(DID));
|
|
456
|
+
if (foundItem) {
|
|
457
|
+
// SCENARIO A: Match esatto trovato (TID e DID corrispondono)
|
|
458
|
+
// Il documento corrente è esattamente il work item nel workflow
|
|
459
|
+
let setID = undefined;
|
|
460
|
+
// Prova a usare il setID già presente nei metadati (più veloce)
|
|
461
|
+
if (workItemSetIDValue !== undefined) {
|
|
462
|
+
setID = workItemSetIDValue;
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
// Altrimenti caricalo dal server
|
|
466
|
+
setID = await getWorkItemSetIDAsync(foundItem.tid, foundItem.did);
|
|
467
|
+
}
|
|
468
|
+
// Imposta un singolo work item con il setID caricato
|
|
469
|
+
setWorkItems([{ ...foundItem, setID }]);
|
|
470
|
+
// Carica le informazioni complete del workflow
|
|
471
|
+
await loadWorkflowInfo(foundItem.tid);
|
|
444
472
|
}
|
|
445
473
|
else {
|
|
446
|
-
//
|
|
447
|
-
|
|
474
|
+
// SCENARIO B: Nessun match esatto, cerca solo per DID
|
|
475
|
+
const itemsByDID = itemsToProcess.filter(item => item.did === Number(DID));
|
|
476
|
+
if (itemsByDID.length === 1) {
|
|
477
|
+
// SCENARIO B.1: Un solo item trovato per DID
|
|
478
|
+
// Situazione sicura: sappiamo esattamente quale work item usare
|
|
479
|
+
const singleItem = itemsByDID[0];
|
|
480
|
+
let setID;
|
|
481
|
+
// Carica il setID (da cache o da server)
|
|
482
|
+
if (workItemSetIDValue !== undefined) {
|
|
483
|
+
setID = workItemSetIDValue;
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
setID = await getWorkItemSetIDAsync(singleItem.tid, singleItem.did);
|
|
487
|
+
}
|
|
488
|
+
setWorkItems([{ ...singleItem, setID }]);
|
|
489
|
+
// Carica le informazioni del workflow
|
|
490
|
+
await loadWorkflowInfo(singleItem.tid);
|
|
491
|
+
}
|
|
492
|
+
else if (itemsByDID.length > 1) {
|
|
493
|
+
// SCENARIO B.2: Più item trovati per lo stesso DID
|
|
494
|
+
// Ambiguità: lo stesso documento appare in più workflow diversi
|
|
495
|
+
const finalWorkItems = itemsByDID.map((item, index) => ({ ...item, setID: undefined }));
|
|
496
|
+
setWorkItems(finalWorkItems);
|
|
497
|
+
setWorkflows([]); // Non carichiamo il workflow in caso di ambiguità
|
|
498
|
+
}
|
|
448
499
|
}
|
|
449
|
-
// Crea un array di Promise per tutte le chiamate a GetWFInfoAsync
|
|
450
|
-
const workflowInfoPromises = itemsToProcess.map(item => WorkflowCacheService.GetWFInfoAsync(item.tid));
|
|
451
|
-
// Esegui tutte le chiamate in parallelo e attendi i risultati
|
|
452
|
-
const setIDResults = await Promise.all(setIDPromises);
|
|
453
|
-
const workflowInfoResults = await Promise.all(workflowInfoPromises);
|
|
454
|
-
// Combina i risultati
|
|
455
|
-
const finalWorkItems = itemsToProcess.map((item, index) => ({
|
|
456
|
-
...item,
|
|
457
|
-
setID: setIDResults[index],
|
|
458
|
-
}));
|
|
459
|
-
const validWorkflows = workflowInfoResults.filter(Boolean);
|
|
460
|
-
// Aggiorna lo stato una sola volta con i dati finali
|
|
461
|
-
setWorkItems(finalWorkItems);
|
|
462
|
-
setWorkflows(validWorkflows);
|
|
463
500
|
}
|
|
464
501
|
catch (error) {
|
|
502
|
+
// FASE 4: Gestione errori
|
|
465
503
|
TMExceptionBoxManager.show({ exception: error });
|
|
466
504
|
setWorkItems([]);
|
|
467
505
|
setWorkflows([]);
|
|
468
506
|
}
|
|
469
507
|
finally {
|
|
508
|
+
// Garantisce sempre il reset del flag di loading
|
|
470
509
|
setIsWFDataLoading(false);
|
|
471
510
|
}
|
|
472
511
|
};
|
|
473
|
-
// Usa hasFormData invece di formDataRef.current
|
|
474
512
|
if (!hasFormData || !fromDTD?.id) {
|
|
475
|
-
// console.log("formData is empty or fromDTD not loaded, skipping loadAllWfData");
|
|
476
513
|
return;
|
|
477
514
|
}
|
|
478
515
|
if (workItemSetIDValue !== undefined || workflowApproveData.length > 0)
|
|
479
516
|
loadAllWfData();
|
|
480
|
-
}, [hasFormData, workItemSetIDValue, workflowApproveData, DID, layoutMode, fromDTD?.templateTID, fromDTD?.id]);
|
|
517
|
+
}, [hasFormData, workItemSetIDValue, workflowApproveData, getWorkItemsByDID, TID, DID, layoutMode, fromDTD?.templateTID, fromDTD?.id]);
|
|
481
518
|
const getSelectionDcmtInfo = useCallback(() => {
|
|
482
519
|
let dcmts = [];
|
|
483
520
|
dcmts.push({ TID: TID ?? 0, DID: DID ?? 0 });
|
|
@@ -508,7 +545,11 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
508
545
|
const showToppyForCompleteMoreInfo = useMemo(() => layoutMode === LayoutModes.Update && !!isTaskMoreInfo(taskMoreInfo?.name) && taskMoreInfo?.state !== Task_States.Completed, [layoutMode, taskMoreInfo?.name, taskMoreInfo?.state]);
|
|
509
546
|
const showToppyForReferences = useMemo(() => allowButtonsRefs && layoutMode === LayoutModes.Update && !!(dcmtReferences && dcmtReferences.length > 0) && !isOpenDetails && !isOpenMaster, [allowButtonsRefs, layoutMode, dcmtReferences, isOpenDetails, isOpenMaster]);
|
|
510
547
|
const isMobile = useMemo(() => deviceType === DeviceType.MOBILE, [deviceType]);
|
|
511
|
-
const isApprView = useMemo(() =>
|
|
548
|
+
const isApprView = useMemo(() => {
|
|
549
|
+
if (!fromDTD)
|
|
550
|
+
return false;
|
|
551
|
+
return isApprovalWorkflowView(fromDTD);
|
|
552
|
+
}, [fromDTD?.id]);
|
|
512
553
|
const workitemSetID = useMemo(() => workItems.find(o => o.did === Number(DID))?.setID || formData.find(o => o.md?.name === WorkItemMetadataNames.WI_SetID)?.value, [workItems, DID, formData]);
|
|
513
554
|
const approvalVID = useMemo(() => workItems.length > 0 ? Number(workItems[0].tid) : -1, [workItems]);
|
|
514
555
|
//here
|
|
@@ -547,11 +588,12 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
547
588
|
disabled: false,
|
|
548
589
|
onClick: () => {
|
|
549
590
|
const dcmt = getDcmts()[0];
|
|
591
|
+
const name = `${fromDTD?.name ?? '-'} (DID: ${dcmt.DID})`;
|
|
550
592
|
const taskContext = {
|
|
551
593
|
document: {
|
|
552
594
|
tid: dcmt.TID,
|
|
553
595
|
did: dcmt.DID,
|
|
554
|
-
name:
|
|
596
|
+
name: name
|
|
555
597
|
}
|
|
556
598
|
};
|
|
557
599
|
onTaskCreateRequest(taskContext);
|
|
@@ -1106,7 +1148,27 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
1106
1148
|
fontSize: '1.1rem',
|
|
1107
1149
|
color: TMColors.primaryColor,
|
|
1108
1150
|
textAlign: 'center',
|
|
1109
|
-
|
|
1151
|
+
display: 'flex',
|
|
1152
|
+
flexDirection: 'column',
|
|
1153
|
+
alignItems: 'center',
|
|
1154
|
+
gap: '12px',
|
|
1155
|
+
}, 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: () => {
|
|
1156
|
+
TMMessageBoxManager.show({
|
|
1157
|
+
title: 'Dettagli Errore Workflow',
|
|
1158
|
+
initialWidth: !isMobile ? '700px' : undefined,
|
|
1159
|
+
message: (_jsx("pre", { style: {
|
|
1160
|
+
whiteSpace: 'pre-wrap',
|
|
1161
|
+
background: '#f5f5f5',
|
|
1162
|
+
padding: '12px',
|
|
1163
|
+
borderRadius: '6px',
|
|
1164
|
+
userSelect: 'text',
|
|
1165
|
+
cursor: 'text',
|
|
1166
|
+
}, children: wfError })),
|
|
1167
|
+
resizable: true,
|
|
1168
|
+
showToppy: false,
|
|
1169
|
+
buttons: [ButtonNames.OK],
|
|
1170
|
+
});
|
|
1171
|
+
} }) }))] }) }))
|
|
1110
1172
|
: _jsx("div", { style: {
|
|
1111
1173
|
position: 'absolute',
|
|
1112
1174
|
top: '50%',
|
|
@@ -1366,7 +1428,7 @@ const TMDcmtForm = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, addTa
|
|
|
1366
1428
|
} }), 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 ?
|
|
1367
1429
|
_jsx(WorkFlowOperationButtons, { deviceType: deviceType, onApprove: () => setShowApprovePopup(true), onSignApprove: handleSignApprove, onReject: () => setShowRejectPopup(true), onReAssign: () => setShowReAssignPopup(true), onMoreInfo: () => setShowMoreInfoPopup(true), dtd: fromDTD })
|
|
1368
1430
|
:
|
|
1369
|
-
_jsxs("div", { style: { padding: 10, color: 'white', maxWidth: '180px', borderRadius: 10, background: '#1B1464 0% 0% no-repeat padding-box', border: '1px solid #FFFFFF' }, children: [`
|
|
1431
|
+
_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: () => {
|
|
1370
1432
|
setShowCommentForm(true);
|
|
1371
1433
|
} })] })), (showToppyForReferences && (dcmtReferences && dcmtReferences.length > 0)) && dcmtReferences
|
|
1372
1434
|
.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, useState } from 'react';
|
|
3
|
-
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes,
|
|
3
|
+
import { SDK_Globals, DataColumnTypes, MetadataDataDomains, DataListViewModes, MetadataFormats, LayoutModes, DcmtTypeListCacheService, AccessLevels, SystemMIDsAsNumber, RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats, AccessLevelsEx, ResultTypes, 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, IconDetailDcmts, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, IconDownload, deepCompare, generateUniqueColumnKeys, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMCommandsContextMenu, getExceptionMessage, IconCheck, svgToString, TMImageLibrary } from '../../../helper';
|
|
6
|
+
import { genUniqueId, IconShow, IconBoard, IconDcmtTypeSys, IconDetailDcmts, SDKUI_Localizator, IconDelete, IconRefresh, IconMenuVertical, IconDownload, deepCompare, generateUniqueColumnKeys, searchResultDescriptorToSimpleArray, searchResultToMetadataValues, IconSearchCheck, TMCommandsContextMenu, getExceptionMessage, IconCheck, svgToString, TMImageLibrary, 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';
|
|
@@ -259,7 +259,7 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
|
|
|
259
259
|
try {
|
|
260
260
|
const dtd = await DcmtTypeListCacheService.GetWithNotGrantedAsync(item.TID, item?.DID);
|
|
261
261
|
if (dtd) {
|
|
262
|
-
const isWorkItem = dtd
|
|
262
|
+
const isWorkItem = isApprovalWorkflowView(dtd);
|
|
263
263
|
const name = `${dtd.name ?? '-'} (DID: ${item.DID})`;
|
|
264
264
|
onTaskCreateRequest?.(isWorkItem
|
|
265
265
|
? { workItem: { tid: item.TID, did: item.DID, name } }
|
|
@@ -645,7 +645,9 @@ const TMSearchResult = ({ allTasks = [], getAllTasks, deleteTaskByIdsCallback, a
|
|
|
645
645
|
const handleSavedAsyncCallback = useCallback(async (tid, did, metadataResult) => {
|
|
646
646
|
await refreshFocusedDataRowAsync(tid, did, true, metadataResult);
|
|
647
647
|
}, []);
|
|
648
|
-
const showToppyForApprove = (
|
|
648
|
+
const showToppyForApprove = useMemo(() => {
|
|
649
|
+
return Boolean(isVisible && fromDTD && isApprovalWorkflowView(fromDTD) && !isOpenDcmtForm && !isOpenDetails && !isOpenMaster);
|
|
650
|
+
}, [isVisible, fromDTD, isOpenDcmtForm, isOpenDetails, isOpenMaster]);
|
|
649
651
|
const tmSearchResult = useMemo(() => (!searchResults || searchResults.length <= 0)
|
|
650
652
|
? _jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%' }, children: [_jsx(IconBoard, { fontSize: 96 }), _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 }) })] })
|
|
651
653
|
:
|
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";
|
|
@@ -851,3 +851,7 @@ export class AreaHelper {
|
|
|
851
851
|
}
|
|
852
852
|
AreaHelper.AreaPathPrefix = "tmarea:\\\\";
|
|
853
853
|
AreaHelper.AreaFolderNamePrefix = "AID_";
|
|
854
|
+
export const isApprovalWorkflowView = (dtd) => {
|
|
855
|
+
return Boolean(dtd?.isView &&
|
|
856
|
+
dtd.metadata?.some(data => data.name === WorkItemMetadataNames.WI_DID));
|
|
857
|
+
};
|
|
@@ -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
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topconsultnpm/sdkui-react",
|
|
3
|
-
"version": "6.19.0-
|
|
3
|
+
"version": "6.19.0-hotfix2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"lib"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@topconsultnpm/sdk-ts": "6.19.0",
|
|
42
|
+
"@topconsultnpm/sdk-ts": "^6.19.0",
|
|
43
43
|
"buffer": "^6.0.3",
|
|
44
44
|
"devextreme": "25.1.7",
|
|
45
45
|
"devextreme-react": "25.1.7",
|