@topconsultnpm/sdkui-react 6.22.0-dev3.9 → 6.22.0-dev4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/base/TMAlert.js +6 -8
- package/lib/components/base/TMAreaManager.js +53 -55
- package/lib/components/base/TMButton.js +4 -2
- package/lib/components/base/TMCounterContainer.d.ts +3 -1
- package/lib/components/base/TMCounterContainer.js +16 -1
- package/lib/components/base/TMCustomButton.js +40 -48
- package/lib/components/base/TMDataGrid.js +24 -4
- package/lib/components/base/TMPanel.js +173 -170
- package/lib/components/base/TMSpinner.d.ts +2 -1
- package/lib/components/base/TMSpinner.js +9 -7
- package/lib/components/base/TMTabControl.d.ts +5 -0
- package/lib/components/base/TMTabControl.js +18 -7
- package/lib/components/base/TMTreeView.js +20 -0
- package/lib/components/base/TMWaitPanel.js +1 -1
- package/lib/components/base/waitPanel/TMWaitPanelConfirm.d.ts +12 -0
- package/lib/components/base/waitPanel/TMWaitPanelConfirm.js +185 -0
- package/lib/components/base/waitPanel/TMWaitPanelManager.d.ts +179 -0
- package/lib/components/base/waitPanel/TMWaitPanelManager.js +373 -0
- package/lib/components/base/waitPanel/TMWaitPanelView.d.ts +58 -0
- package/lib/components/base/waitPanel/TMWaitPanelView.js +346 -0
- package/lib/components/base/waitPanel/index.d.ts +1 -0
- package/lib/components/base/waitPanel/index.js +1 -0
- package/lib/components/choosers/TMDistinctValues.js +3 -3
- package/lib/components/choosers/TMPathChooser.js +17 -34
- package/lib/components/editors/TMTextBox.d.ts +4 -0
- package/lib/components/editors/TMTextBox.js +99 -11
- package/lib/components/features/archive/TMArchive.js +7 -2
- package/lib/components/features/assistant/TMHelpOnLineChat.d.ts +28 -0
- package/lib/components/features/assistant/TMHelpOnLineChat.js +1231 -0
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +2 -2
- package/lib/components/features/documents/TMBatchUpdateForm.js +3 -4
- package/lib/components/features/documents/TMCopyToFolderForm.js +53 -84
- package/lib/components/features/documents/TMDcmtForm.js +50 -61
- package/lib/components/features/documents/TMDcmtIcon.d.ts +1 -3
- package/lib/components/features/documents/TMDcmtIcon.js +3 -5
- package/lib/components/features/documents/TMDcmtPreview.js +5 -3
- package/lib/components/features/documents/TMDcmtTasks.js +2 -9
- package/lib/components/features/documents/TMFileUploader.js +26 -26
- package/lib/components/features/documents/TMMasterDetailDcmts.d.ts +2 -0
- package/lib/components/features/documents/TMMasterDetailDcmts.js +53 -148
- package/lib/components/features/documents/TMMasterInfoFields.js +3 -2
- package/lib/components/features/documents/TMMergeToPdfForm.js +52 -56
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsForm.js +14 -15
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.d.ts +1 -1
- package/lib/components/features/documents/TMMultiMasterDetailDcmtsUtils.js +3 -3
- package/lib/components/features/documents/TMRelationViewer.d.ts +13 -14
- package/lib/components/features/documents/TMRelationViewer.js +206 -143
- package/lib/components/features/documents/relationTreeState.d.ts +32 -0
- package/lib/components/features/documents/relationTreeState.js +89 -0
- package/lib/components/features/search/TMSearch.js +3 -4
- package/lib/components/features/search/TMSearchQueryPanel.js +0 -4
- package/lib/components/features/search/TMSearchResult.d.ts +5 -0
- package/lib/components/features/search/TMSearchResult.js +51 -24
- package/lib/components/features/search/TMTreeSelector.js +23 -27
- package/lib/components/features/search/TMViewHistoryDcmt.js +15 -26
- package/lib/components/features/tasks/TMTasksView.js +97 -90
- package/lib/components/features/wg/TMWGsCopyMoveForm.js +104 -100
- package/lib/components/forms/TMResultDialog.js +1 -1
- package/lib/components/grids/TMBlogsPost.js +93 -97
- package/lib/components/index.d.ts +5 -1
- package/lib/components/index.js +4 -1
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +16 -15
- package/lib/components/layout/panelManager/TMPanelManagerContext.d.ts +1 -0
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +5 -1
- package/lib/components/layout/panelManager/TMPanelManagerLoader.d.ts +6 -0
- package/lib/components/layout/panelManager/TMPanelManagerLoader.js +18 -0
- package/lib/components/layout/panelManager/TMPanelManagerToolbar.js +4 -8
- package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.d.ts +1 -1
- package/lib/components/layout/panelManager/TMPanelManagerWithPersistenceProvider.js +2 -1
- package/lib/components/pages/TMPage.js +32 -31
- package/lib/components/query/TMQueryEditor.d.ts +3 -0
- package/lib/components/query/TMQueryEditor.js +2 -1
- package/lib/components/sidebar/TMHeader.d.ts +1 -0
- package/lib/components/sidebar/TMHeader.js +2 -2
- package/lib/helper/Enum_Localizator.js +1 -0
- package/lib/helper/SDKUI_Globals.d.ts +7 -2
- package/lib/helper/SDKUI_Globals.js +7 -2
- package/lib/helper/SDKUI_Localizator.d.ts +31 -6
- package/lib/helper/SDKUI_Localizator.js +301 -51
- package/lib/helper/ZipManager.d.ts +1 -1
- package/lib/helper/ZipManager.js +2 -1
- package/lib/helper/checkinCheckoutManager.js +2 -3
- package/lib/helper/dcmtsHelper.d.ts +2 -0
- package/lib/helper/dcmtsHelper.js +3 -1
- package/lib/hooks/useCheckInOutOperations.d.ts +0 -6
- package/lib/hooks/useCheckInOutOperations.js +16 -37
- package/lib/hooks/useDcmtOperations.d.ts +3 -19
- package/lib/hooks/useDcmtOperations.js +175 -229
- package/lib/hooks/useDocumentOperations.d.ts +1 -0
- package/lib/hooks/useDocumentOperations.js +16 -29
- package/lib/hooks/useMultiMasterDetailDcmts.d.ts +0 -15
- package/lib/hooks/useMultiMasterDetailDcmts.js +70 -68
- package/lib/hooks/usePreventFileDrop.js +9 -0
- package/lib/hooks/useWorkflowApprove.js +33 -17
- package/lib/services/caseflow/CaseFlowService.d.ts +69 -9
- package/lib/services/caseflow/CaseFlowService.js +126 -58
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { LocalizeDcmtOperationTypes } from '../helper/Enum_Localizator';
|
|
3
3
|
import { SDK_Globals, RetrieveFileOptions, DcmtOpers, ResultTypes, RecentCategories, MetadataDataTypes, MetadataDataDomains, DataListCacheService, DcmtTypeListCacheService, TemplateTIDs } from '@topconsultnpm/sdk-ts';
|
|
4
|
-
import { ShowAlert, TMResultManager, FormulaHelper, TMExceptionBoxManager, TMSpinner } from '../components';
|
|
4
|
+
import { ShowAlert, TMResultManager, FormulaHelper, TMExceptionBoxManager, TMSpinner, TMWaitPanelManager } from '../components';
|
|
5
5
|
import { Globalization, getExceptionMessage, dialogConfirmOperation, extensionHandler, downloadBase64File, SDKUI_Globals, dcmtsFileCacheDownload, CACHE_SIZE_LIMIT, clearDcmtsFileCache, dcmtsFileCachePreview, isDcmtFileInCache, removeDcmtsFileCache, SDKUI_Localizator, ZipManager } from '../helper';
|
|
6
6
|
import { DcmtOperationTypes, DownloadTypes, FileExtensionHandler } from '../ts';
|
|
7
7
|
import { useFileDialog, useFileSourceDialog } from './useInputDialog';
|
|
@@ -9,10 +9,6 @@ import { importCertificatesAsync } from '../helper/certificateImportHelper';
|
|
|
9
9
|
import { isXMLFileExt } from '../helper/dcmtsHelper';
|
|
10
10
|
import { ShowConfirm } from '../components/base/TMConfirm';
|
|
11
11
|
import { generateTargetFileName } from '../components/features/documents/copyAndMergeDcmtsShared';
|
|
12
|
-
/** Limite massimo di download paralleli accettato da `downloadDcmtsAsync`. */
|
|
13
|
-
const MAX_DOWNLOAD_CONCURRENCY = 8;
|
|
14
|
-
/** Intervallo minimo (ms) fra due aggiornamenti della progress bar di download. */
|
|
15
|
-
const DOWNLOAD_PROGRESS_THROTTLE_MS = 100;
|
|
16
12
|
const isScannerLicenseConfigured = () => {
|
|
17
13
|
try {
|
|
18
14
|
const scannerLicense = SDKUI_Globals.userSettings.advancedSettings.scannerLicense;
|
|
@@ -111,16 +107,24 @@ const getDownloadFileName = (file, dcmtInfo, useInputFileName = false) => {
|
|
|
111
107
|
return `${baseFileName.slice(0, firstDot)}(${count})${baseFileName.slice(firstDot)}`;
|
|
112
108
|
};
|
|
113
109
|
export const useDcmtOperations = () => {
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
110
|
+
// Pannello imperativo: l'avanzamento non passa da uno stato React.
|
|
111
|
+
const waitPanelRef = useRef(null);
|
|
112
|
+
/** Apre il wait panel dell'operazione. Interrompi agisce sull'abortController del ciclo. */
|
|
113
|
+
const openWaitPanel = (options) => {
|
|
114
|
+
waitPanelRef.current?.close();
|
|
115
|
+
const panel = TMWaitPanelManager.show({ cancelable: true, onAbort: () => abortController.abort(), ...options });
|
|
116
|
+
waitPanelRef.current = panel;
|
|
117
|
+
return panel;
|
|
118
|
+
};
|
|
119
|
+
const closeWaitPanel = (panel) => {
|
|
120
|
+
panel.close();
|
|
121
|
+
if (waitPanelRef.current === panel)
|
|
122
|
+
waitPanelRef.current = null;
|
|
123
|
+
};
|
|
124
|
+
/** Messaggio per il popover delle pill del pannello: il DID dice a quale documento si riferisce. */
|
|
125
|
+
const panelMessage = (dcmt, message) => `DID ${dcmt.DID}: ${message}`;
|
|
126
|
+
// Il pannello vive fuori dall'albero del chiamante: allo smontaggio va chiuso a mano.
|
|
127
|
+
useEffect(() => () => { waitPanelRef.current?.close(); waitPanelRef.current = null; }, []);
|
|
124
128
|
const { OpenFileDialog } = useFileDialog();
|
|
125
129
|
const [selectFileSource, FileSourceDialog] = useFileSourceDialog();
|
|
126
130
|
const copyCompliantDcmtsAsync = async (inputDcmt, onFileDownloaded) => {
|
|
@@ -133,8 +137,14 @@ export const useDcmtOperations = () => {
|
|
|
133
137
|
let returnDcmtInfos = [];
|
|
134
138
|
const rfo = new RetrieveFileOptions();
|
|
135
139
|
rfo.retrieveReason = DcmtOpers.ShowFile;
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
// Gira dentro runOperationAsync: i byte vanno sulla barra secondaria del pannello gia' aperto.
|
|
141
|
+
const publishSecondary = (pd, label) => {
|
|
142
|
+
const max = pd.ProgressBarMaximum ?? 0;
|
|
143
|
+
const completed = pd.ProgressBarValue === pd.ProgressBarMaximum;
|
|
144
|
+
waitPanelRef.current?.setSecondary(completed
|
|
145
|
+
? { value: 0, max: 0, text: '' }
|
|
146
|
+
: { value: pd.ProgressBarValue, max, text: `${label} ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(max, true)}` });
|
|
147
|
+
};
|
|
138
148
|
let signerInfoDescriptor = undefined;
|
|
139
149
|
if (inputDcmt?.FILEEXT == undefined || inputDcmt.FILEEXT == '') {
|
|
140
150
|
throw new Error('WARNING#' + SDKUI_Localizator.MetadataOnlyDocument);
|
|
@@ -183,21 +193,7 @@ export const useDcmtOperations = () => {
|
|
|
183
193
|
else
|
|
184
194
|
throw new Error('IdC non firmato e non marcato temporalmente!');
|
|
185
195
|
//Ricerca dell'impronta SHA256 nel contenuto dell'IdC
|
|
186
|
-
let fileIdC = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(serachResultIdC.dtdResult.rows[0][0], serachResultIdC.dtdResult.rows[0][1], rfo, abortController.signal, (pd) =>
|
|
187
|
-
if (firstBlock) {
|
|
188
|
-
maxFileSize = pd.ProgressBarMaximum ?? 0;
|
|
189
|
-
setWaitPanelMaxValueSecondary(maxFileSize);
|
|
190
|
-
firstBlock = false;
|
|
191
|
-
}
|
|
192
|
-
setWaitPanelValueSecondary(pd.ProgressBarValue);
|
|
193
|
-
setWaitPanelTextSecondary(`Downloading IdC... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
|
|
194
|
-
if (pd.ProgressBarValue === pd.ProgressBarMaximum) {
|
|
195
|
-
setWaitPanelMaxValueSecondary(0);
|
|
196
|
-
setWaitPanelValueSecondary(0);
|
|
197
|
-
setWaitPanelTextSecondary('');
|
|
198
|
-
firstBlock = true;
|
|
199
|
-
}
|
|
200
|
-
});
|
|
196
|
+
let fileIdC = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(serachResultIdC.dtdResult.rows[0][0], serachResultIdC.dtdResult.rows[0][1], rfo, abortController.signal, (pd) => publishSecondary(pd, 'Downloading IdC...'));
|
|
201
197
|
let hashOk = false;
|
|
202
198
|
if (fileIdC) {
|
|
203
199
|
try {
|
|
@@ -214,21 +210,7 @@ export const useDcmtOperations = () => {
|
|
|
214
210
|
throw new Error('Impronta non trovata nel file IdC o non corrispondente a quella del documento');
|
|
215
211
|
}
|
|
216
212
|
let file;
|
|
217
|
-
file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(inputDcmt.TID, inputDcmt.DID, rfo, abortController.signal, (pd) =>
|
|
218
|
-
if (firstBlock) {
|
|
219
|
-
maxFileSize = pd.ProgressBarMaximum ?? 0;
|
|
220
|
-
setWaitPanelMaxValueSecondary(maxFileSize);
|
|
221
|
-
firstBlock = false;
|
|
222
|
-
}
|
|
223
|
-
setWaitPanelValueSecondary(pd.ProgressBarValue);
|
|
224
|
-
setWaitPanelTextSecondary(`Downloading... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
|
|
225
|
-
if (pd.ProgressBarValue === pd.ProgressBarMaximum) {
|
|
226
|
-
setWaitPanelMaxValueSecondary(0);
|
|
227
|
-
setWaitPanelValueSecondary(0);
|
|
228
|
-
setWaitPanelTextSecondary('');
|
|
229
|
-
firstBlock = true;
|
|
230
|
-
}
|
|
231
|
-
});
|
|
213
|
+
file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(inputDcmt.TID, inputDcmt.DID, rfo, abortController.signal, (pd) => publishSecondary(pd, 'Downloading...'));
|
|
232
214
|
if (file && fileIdC) {
|
|
233
215
|
returnDcmtFiles.push(file);
|
|
234
216
|
returnDcmtInfos.push(inputDcmt);
|
|
@@ -261,7 +243,7 @@ export const useDcmtOperations = () => {
|
|
|
261
243
|
ShowAlert({ message: SDKUI_Localizator.ZipCreatedSavedInFolder.replaceParams(zipFileName, "Zip creato con successo"), mode: 'success', duration: 5000, title: SDKUI_Localizator.CompressToZipFile });
|
|
262
244
|
}
|
|
263
245
|
};
|
|
264
|
-
const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true, useInputFileName = false
|
|
246
|
+
const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true, useInputFileName = false) => {
|
|
265
247
|
if (inputDcmts === undefined)
|
|
266
248
|
return;
|
|
267
249
|
if (inputDcmts.length <= 0)
|
|
@@ -285,86 +267,61 @@ export const useDcmtOperations = () => {
|
|
|
285
267
|
}
|
|
286
268
|
}
|
|
287
269
|
let operationTitle = 'Download File';
|
|
288
|
-
setShowWaitPanel(true);
|
|
289
|
-
setShowPrimary(inputDcmts.length > 1);
|
|
290
|
-
setShowSecondary(true);
|
|
291
|
-
setWaitPanelTitle(operationTitle);
|
|
292
270
|
abortController = new AbortController();
|
|
293
|
-
// Riferimento const: il narrowing su inputDcmts non sopravvive dentro le closure
|
|
271
|
+
// Riferimento const: il narrowing su inputDcmts non sopravvive dentro le closure.
|
|
294
272
|
const dcmts = inputDcmts;
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
if (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
setWaitPanelTextSecondary(pendingSecondary.text);
|
|
325
|
-
pendingSecondary = undefined;
|
|
326
|
-
};
|
|
327
|
-
const publishSecondaryProgress = () => {
|
|
328
|
-
let loaded = 0;
|
|
329
|
-
let total = 0;
|
|
330
|
-
for (const bytes of inFlightBytes.values()) {
|
|
331
|
-
loaded += bytes.loaded;
|
|
332
|
-
total += bytes.total;
|
|
333
|
-
}
|
|
334
|
-
pendingSecondary = total > 0
|
|
335
|
-
? { value: loaded, max: total, text: `Downloading... ${Globalization.getNumberDisplayValue(loaded, true)} / ${Globalization.getNumberDisplayValue(total, true)}` }
|
|
336
|
-
: { value: 0, max: 0, text: '' };
|
|
337
|
-
if (secondaryTimer === undefined)
|
|
338
|
-
secondaryTimer = setTimeout(flushSecondaryProgress, DOWNLOAD_PROGRESS_THROTTLE_MS);
|
|
273
|
+
// Con un solo documento c'e' un avanzamento solo, quello dei byte, e sta sulla barra
|
|
274
|
+
// principale: la doppia barra (documenti + byte) serve solo all'elaborazione multipla.
|
|
275
|
+
const isBatch = dcmts.length > 1;
|
|
276
|
+
const panel = openWaitPanel({
|
|
277
|
+
title: operationTitle,
|
|
278
|
+
max: isBatch ? dcmts.length : 0,
|
|
279
|
+
showSecondary: isBatch,
|
|
280
|
+
showCounters: isBatch,
|
|
281
|
+
primaryLabel: isBatch ? SDKUI_Localizator.Documents : undefined,
|
|
282
|
+
secondaryLabel: isBatch ? 'File corrente' : undefined,
|
|
283
|
+
});
|
|
284
|
+
const rfo = new RetrieveFileOptions();
|
|
285
|
+
rfo.retrieveReason = retrieveOptions?.retrieveReason ?? DcmtOpers.ShowFile;
|
|
286
|
+
if (retrieveOptions?.cvtFormat !== undefined)
|
|
287
|
+
rfo.cvtFormat = retrieveOptions.cvtFormat;
|
|
288
|
+
if (retrieveOptions?.generalRetrieveFormat !== undefined)
|
|
289
|
+
rfo.generalRetrieveFormat = retrieveOptions.generalRetrieveFormat;
|
|
290
|
+
rfo.invoiceRetrieveFormat = retrieveOptions?.invoiceRetrieveFormat ?? SDKUI_Globals.userSettings.searchSettings.invoiceRetrieveFormat;
|
|
291
|
+
rfo.orderRetrieveFormat = retrieveOptions?.orderRetrieveFormat ?? SDKUI_Globals.userSettings.searchSettings.orderRetrieveFormat;
|
|
292
|
+
const results = [];
|
|
293
|
+
// Il pannello coalesce le scritture in un flush per frame: nessun throttle serve.
|
|
294
|
+
const publishBytes = (loaded, total) => {
|
|
295
|
+
const text = total > 0
|
|
296
|
+
? `Downloading... ${Globalization.getNumberDisplayValue(loaded, true)} / ${Globalization.getNumberDisplayValue(total, true)}`
|
|
297
|
+
: '';
|
|
298
|
+
if (isBatch)
|
|
299
|
+
panel.setSecondary({ value: loaded, max: total, text });
|
|
300
|
+
else
|
|
301
|
+
panel.update({ value: loaded, max: total, subtitle: text });
|
|
339
302
|
};
|
|
340
|
-
// ----
|
|
341
|
-
let nextIndex = 0;
|
|
342
|
-
let started = 0;
|
|
303
|
+
// ---- Download sequenziale: un documento per volta ----
|
|
343
304
|
let completed = 0;
|
|
344
|
-
let abortReported = false;
|
|
345
305
|
const downloadOne = async (i) => {
|
|
346
|
-
|
|
347
|
-
|
|
306
|
+
if (isBatch)
|
|
307
|
+
panel.setSubtitle(`Download file ${i + 1} di ${dcmts.length}`);
|
|
348
308
|
let file;
|
|
349
309
|
const cacheKey = `${dcmts[i].TID}-${dcmts[i].DID}`;
|
|
350
310
|
if (useCache && dcmtsFileCacheDownload.has(cacheKey)) {
|
|
351
311
|
file = dcmtsFileCacheDownload.get(cacheKey);
|
|
352
312
|
}
|
|
353
313
|
else {
|
|
354
|
-
inFlightBytes.set(i, { loaded: 0, total: 0 });
|
|
355
314
|
try {
|
|
356
|
-
file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(dcmts[i].TID, dcmts[i].DID,
|
|
357
|
-
inFlightBytes.set(i, { loaded: pd.ProgressBarValue, total: pd.ProgressBarMaximum ?? 0 });
|
|
358
|
-
publishSecondaryProgress();
|
|
359
|
-
});
|
|
315
|
+
file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(dcmts[i].TID, dcmts[i].DID, rfo, abortController.signal, (pd) => publishBytes(pd.ProgressBarValue, pd.ProgressBarMaximum ?? 0));
|
|
360
316
|
}
|
|
361
317
|
finally {
|
|
362
|
-
|
|
363
|
-
|
|
318
|
+
if (isBatch)
|
|
319
|
+
publishBytes(0, 0);
|
|
364
320
|
}
|
|
365
321
|
}
|
|
366
322
|
completed++;
|
|
367
|
-
|
|
323
|
+
if (isBatch)
|
|
324
|
+
panel.setValue(completed);
|
|
368
325
|
if (downloadMode === "openInNewWindow") {
|
|
369
326
|
if (onFileDownloaded && file) {
|
|
370
327
|
onFileDownloaded(file, dcmts[i]);
|
|
@@ -400,48 +357,34 @@ export const useDcmtOperations = () => {
|
|
|
400
357
|
}
|
|
401
358
|
dcmtsFileCacheDownload.set(cacheKey, file);
|
|
402
359
|
}
|
|
403
|
-
results
|
|
360
|
+
results.push({ rowIndex: i, id1: dcmts[i].TID, id2: dcmts[i].DID, resultType: ResultTypes.SUCCESS });
|
|
404
361
|
};
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
}
|
|
362
|
+
for (let i = 0; i < dcmts.length; i++) {
|
|
363
|
+
// Con la conferma di interruzione aperta il ciclo si ferma qui invece di
|
|
364
|
+
// continuare a scaricare dietro al dialogo.
|
|
365
|
+
await panel.waitWhilePaused();
|
|
366
|
+
if (abortController.signal.aborted) {
|
|
367
|
+
const description = SDKUI_Localizator.OperationDcmtsInterrupted.replaceParams(completed);
|
|
368
|
+
results.push({ rowIndex: i, id1: dcmts[i].TID, id2: dcmts[i].DID, resultType: ResultTypes.WARNING, description });
|
|
369
|
+
panel.warning(1, description);
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
try {
|
|
373
|
+
await downloadOne(i);
|
|
374
|
+
panel.ok();
|
|
375
|
+
}
|
|
376
|
+
catch (ex) {
|
|
377
|
+
const description = getExceptionMessage(ex);
|
|
378
|
+
results.push({ rowIndex: i, id1: dcmts[i].TID, id2: dcmts[i].DID, resultType: ResultTypes.ERROR, description });
|
|
379
|
+
panel.error(1, panelMessage(dcmts[i], description));
|
|
380
|
+
const err = ex;
|
|
381
|
+
if (err.name === 'CanceledError') {
|
|
382
|
+
ShowAlert({ message: err.message, mode: 'warning', duration: 3000, title: 'Abort' });
|
|
427
383
|
}
|
|
428
384
|
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const workers = Math.max(1, Math.min(Math.trunc(downloadConcurrency) || 1, MAX_DOWNLOAD_CONCURRENCY, dcmts.length));
|
|
433
|
-
await Promise.all(Array.from({ length: workers }, () => runWorker()));
|
|
434
|
-
if (secondaryTimer !== undefined)
|
|
435
|
-
clearTimeout(secondaryTimer);
|
|
436
|
-
const result = results.filter((r) => r !== undefined);
|
|
437
|
-
setWaitPanelTextPrimary('');
|
|
438
|
-
setWaitPanelMaxValuePrimary(0);
|
|
439
|
-
setWaitPanelValuePrimary(0);
|
|
440
|
-
setWaitPanelTextSecondary('');
|
|
441
|
-
setWaitPanelMaxValueSecondary(0);
|
|
442
|
-
setWaitPanelValueSecondary(0);
|
|
443
|
-
setShowWaitPanel(false);
|
|
444
|
-
TMResultManager.show(result, operationTitle, "TID", "DID", undefined, undefined, showSuccessAlert);
|
|
385
|
+
}
|
|
386
|
+
closeWaitPanel(panel);
|
|
387
|
+
TMResultManager.show(results, operationTitle, "TID", "DID", undefined, undefined, showSuccessAlert);
|
|
445
388
|
};
|
|
446
389
|
const _downloadAttachmentsAsync = async (inputDcmts, confirmAttachments, showSuccessAlert = true) => {
|
|
447
390
|
if (inputDcmts === undefined)
|
|
@@ -482,7 +425,7 @@ export const useDcmtOperations = () => {
|
|
|
482
425
|
// Download the selected files
|
|
483
426
|
for (let i = 0; i < selectedFiles.length; i++) {
|
|
484
427
|
if (abortController.signal.aborted) {
|
|
485
|
-
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.WARNING, description:
|
|
428
|
+
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.WARNING, description: SDKUI_Localizator.OperationItemsInterrupted.replaceParams(i) });
|
|
486
429
|
break;
|
|
487
430
|
}
|
|
488
431
|
let fd = files.find(f => f.name === selectedFiles[i]);
|
|
@@ -505,13 +448,12 @@ export const useDcmtOperations = () => {
|
|
|
505
448
|
};
|
|
506
449
|
const downloadDcmtsAsync = async (params) => {
|
|
507
450
|
const { inputDcmts, downloadType = DownloadTypes.Attachment, downloadMode = "download", onFileDownloaded, confirmAttachments, skipConfirmation = false, retrieveOptions, useCache = true, showSuccessAlert = true, useInputFileName = false, // Default: usa il nome dal backend
|
|
508
|
-
downloadConcurrency = 1, // Default: sequenziale
|
|
509
451
|
} = params;
|
|
510
452
|
switch (downloadType) {
|
|
511
453
|
// Per il download di documenti, passa useInputFileName per controllare la priorità del nome
|
|
512
|
-
case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName
|
|
454
|
+
case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName);
|
|
513
455
|
case DownloadTypes.Attachment: return await _downloadAttachmentsAsync(inputDcmts, confirmAttachments, showSuccessAlert);
|
|
514
|
-
default: return await _downloadDcmtsAsync(inputDcmts, undefined, undefined, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName
|
|
456
|
+
default: return await _downloadDcmtsAsync(inputDcmts, undefined, undefined, skipConfirmation, retrieveOptions, useCache, showSuccessAlert, useInputFileName);
|
|
515
457
|
}
|
|
516
458
|
};
|
|
517
459
|
const uploadDcmtsAsync = async (inputDcmts, operationTitle, operType, actionAfterOperationAsync) => {
|
|
@@ -576,64 +518,69 @@ export const useDcmtOperations = () => {
|
|
|
576
518
|
}
|
|
577
519
|
if (!file)
|
|
578
520
|
return;
|
|
579
|
-
setShowWaitPanel(true);
|
|
580
|
-
setShowPrimary(inputDcmts.length > 1);
|
|
581
|
-
setShowSecondary(true);
|
|
582
|
-
setWaitPanelTitle(operationTitle);
|
|
583
521
|
abortController = new AbortController();
|
|
522
|
+
// Come nel download: con un solo documento resta il solo avanzamento in byte.
|
|
523
|
+
const isBatch = inputDcmts.length > 1;
|
|
524
|
+
const panel = openWaitPanel({
|
|
525
|
+
title: operationTitle,
|
|
526
|
+
max: isBatch ? inputDcmts.length : 0,
|
|
527
|
+
showSecondary: isBatch,
|
|
528
|
+
showCounters: isBatch,
|
|
529
|
+
primaryLabel: isBatch ? SDKUI_Localizator.Documents : undefined,
|
|
530
|
+
secondaryLabel: isBatch ? 'File corrente' : undefined,
|
|
531
|
+
});
|
|
532
|
+
const publishBytes = (loaded, total) => {
|
|
533
|
+
const text = total > 0
|
|
534
|
+
? `Uploading... ${Globalization.getNumberDisplayValue(loaded, true)} / ${Globalization.getNumberDisplayValue(total, true)}`
|
|
535
|
+
: '';
|
|
536
|
+
if (isBatch)
|
|
537
|
+
panel.setSecondary({ value: loaded, max: total, text });
|
|
538
|
+
else
|
|
539
|
+
panel.update({ value: loaded, max: total, subtitle: text });
|
|
540
|
+
};
|
|
584
541
|
let result = [];
|
|
585
|
-
setWaitPanelMaxValuePrimary(inputDcmts.length);
|
|
586
|
-
let firstBlock = true;
|
|
587
|
-
let maxFileSize = 0;
|
|
588
542
|
for (let i = 0; i < inputDcmts.length; i++) {
|
|
543
|
+
await panel.waitWhilePaused();
|
|
589
544
|
if (abortController.signal.aborted) {
|
|
590
|
-
|
|
545
|
+
const description = SDKUI_Localizator.OperationDcmtsInterrupted.replaceParams(i);
|
|
546
|
+
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.WARNING, description });
|
|
547
|
+
panel.warning(1, description);
|
|
591
548
|
break;
|
|
592
549
|
}
|
|
593
550
|
try {
|
|
594
|
-
|
|
551
|
+
if (isBatch)
|
|
552
|
+
panel.setSubtitle(`${SDKUI_Localizator.FileUpload} ${i + 1} di ${inputDcmts.length}`);
|
|
595
553
|
const cacheKey = `${inputDcmts[i].TID}-${inputDcmts[i].DID}`;
|
|
596
|
-
|
|
597
|
-
removeDcmtsFileCache(cacheKey);
|
|
554
|
+
removeDcmtsFileCache(cacheKey);
|
|
598
555
|
let ue = SDK_Globals.tmSession?.NewUpdateEngineByID();
|
|
599
556
|
if (ue) {
|
|
600
557
|
ue.TID = inputDcmts[i].TID;
|
|
601
558
|
ue.DID = inputDcmts[i].DID;
|
|
602
|
-
await ue.SubstituteFileAsync(file, operType, undefined, abortController.signal,
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
setWaitPanelMaxValueSecondary(0);
|
|
612
|
-
setWaitPanelValueSecondary(0);
|
|
613
|
-
setWaitPanelTextSecondary('');
|
|
614
|
-
firstBlock = true;
|
|
615
|
-
}
|
|
616
|
-
});
|
|
559
|
+
await ue.SubstituteFileAsync(file, operType, undefined, abortController.signal,
|
|
560
|
+
// Byte finiti ma il server elabora ancora: la barra si azzera invece di restare al 100%.
|
|
561
|
+
(pd) => pd.ProgressBarValue === pd.ProgressBarMaximum
|
|
562
|
+
? publishBytes(0, 0)
|
|
563
|
+
: publishBytes(pd.ProgressBarValue, pd.ProgressBarMaximum ?? 0));
|
|
564
|
+
}
|
|
565
|
+
if (isBatch) {
|
|
566
|
+
publishBytes(0, 0);
|
|
567
|
+
panel.setValue(i + 1);
|
|
617
568
|
}
|
|
618
|
-
setWaitPanelValuePrimary(i + 1);
|
|
619
569
|
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.SUCCESS });
|
|
570
|
+
panel.ok();
|
|
620
571
|
}
|
|
621
572
|
catch (ex) {
|
|
622
|
-
|
|
573
|
+
const description = getExceptionMessage(ex);
|
|
574
|
+
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.ERROR, description });
|
|
575
|
+
panel.error(1, panelMessage(inputDcmts[i], description));
|
|
623
576
|
const err = ex;
|
|
624
577
|
if (err.name === 'CanceledError') {
|
|
625
578
|
ShowAlert({ message: err.message, mode: 'warning', duration: 3000, title: 'Abort' });
|
|
626
579
|
}
|
|
627
580
|
}
|
|
628
581
|
}
|
|
629
|
-
|
|
630
|
-
setWaitPanelMaxValuePrimary(0);
|
|
631
|
-
setWaitPanelValuePrimary(0);
|
|
632
|
-
setWaitPanelTextSecondary('');
|
|
633
|
-
setWaitPanelMaxValueSecondary(0);
|
|
634
|
-
setWaitPanelValueSecondary(0);
|
|
582
|
+
closeWaitPanel(panel);
|
|
635
583
|
actionAfterOperationAsync?.();
|
|
636
|
-
setShowWaitPanel(false);
|
|
637
584
|
TMResultManager.show(result, operationTitle, "TID", "DID");
|
|
638
585
|
};
|
|
639
586
|
const getDcmtFileAsync = async (inputDcmt, rfo, operationTitle, keepWaitPanelPrimary, bypassCache = false) => {
|
|
@@ -644,29 +591,21 @@ export const useDcmtOperations = () => {
|
|
|
644
591
|
const cacheKey = `${inputDcmt.TID}-${inputDcmt.DID}`;
|
|
645
592
|
if (!bypassCache && dcmtsFileCachePreview.has(cacheKey))
|
|
646
593
|
return { file: dcmtsFileCachePreview.get(cacheKey), isFromCache: true };
|
|
647
|
-
setShowWaitPanel(true);
|
|
648
|
-
setShowPrimary(keepWaitPanelPrimary);
|
|
649
|
-
setShowSecondary(true);
|
|
650
|
-
setWaitPanelTitle(operationTitle);
|
|
651
594
|
abortController = new AbortController();
|
|
652
|
-
|
|
653
|
-
|
|
595
|
+
// Un file solo: l'unico avanzamento e' quello in byte e sta sulla barra principale.
|
|
596
|
+
const panel = openWaitPanel({
|
|
597
|
+
title: operationTitle,
|
|
598
|
+
subtitle: extensionHandler(inputDcmt.FILEEXT ?? '') === FileExtensionHandler.CONVERTIBLE ? 'Conversione file in corso...' : 'Recupero file in corso...',
|
|
599
|
+
showCounters: false,
|
|
600
|
+
});
|
|
654
601
|
try {
|
|
655
|
-
setWaitPanelTextSecondary(extensionHandler(inputDcmt.FILEEXT ?? '') === FileExtensionHandler.CONVERTIBLE ? 'Conversione file in corso...' : 'Recupero file in corso...');
|
|
656
602
|
const file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(inputDcmt?.TID, inputDcmt?.DID, rfo, abortController.signal, (pd) => {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
setWaitPanelTextSecondary(`Downloading... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(maxFileSize, true)}`);
|
|
664
|
-
if (pd.ProgressBarValue === pd.ProgressBarMaximum) {
|
|
665
|
-
setWaitPanelMaxValueSecondary(0);
|
|
666
|
-
setWaitPanelValueSecondary(0);
|
|
667
|
-
setWaitPanelTextSecondary('');
|
|
668
|
-
firstBlock = true;
|
|
669
|
-
}
|
|
603
|
+
const max = pd.ProgressBarMaximum ?? 0;
|
|
604
|
+
panel.update({
|
|
605
|
+
value: pd.ProgressBarValue,
|
|
606
|
+
max,
|
|
607
|
+
subtitle: `Downloading... ${Globalization.getNumberDisplayValue(pd.ProgressBarValue, true)} / ${Globalization.getNumberDisplayValue(max, true)}`,
|
|
608
|
+
});
|
|
670
609
|
});
|
|
671
610
|
if (dcmtsFileCachePreview.size >= CACHE_SIZE_LIMIT) {
|
|
672
611
|
const oldestKey = dcmtsFileCachePreview.keys().next().value;
|
|
@@ -678,10 +617,7 @@ export const useDcmtOperations = () => {
|
|
|
678
617
|
return { file: file, isFromCache: false };
|
|
679
618
|
}
|
|
680
619
|
finally {
|
|
681
|
-
|
|
682
|
-
setWaitPanelMaxValueSecondary(0);
|
|
683
|
-
setWaitPanelValueSecondary(0);
|
|
684
|
-
setShowWaitPanel(false);
|
|
620
|
+
closeWaitPanel(panel);
|
|
685
621
|
}
|
|
686
622
|
};
|
|
687
623
|
const getDisplayValueMetadataValueDescriptor = async (mvd) => {
|
|
@@ -738,19 +674,27 @@ export const useDcmtOperations = () => {
|
|
|
738
674
|
return;
|
|
739
675
|
}
|
|
740
676
|
let zipEntries = [];
|
|
741
|
-
setShowWaitPanel(true);
|
|
742
|
-
setShowPrimary(true);
|
|
743
|
-
setShowSecondary(false);
|
|
744
|
-
setWaitPanelTitle(operationTitle);
|
|
745
677
|
abortController = new AbortController();
|
|
678
|
+
// La copia conforme scarica due file per documento: e' l'unica operazione del ciclo
|
|
679
|
+
// con un avanzamento di dettaglio, e gli serve la seconda barra.
|
|
680
|
+
const isCopyCompliant = dcmtOperationType === DcmtOperationTypes.CopyCompliant;
|
|
681
|
+
const panel = openWaitPanel({
|
|
682
|
+
title: operationTitle,
|
|
683
|
+
max: inputDcmts.length,
|
|
684
|
+
showSecondary: isCopyCompliant,
|
|
685
|
+
primaryLabel: isCopyCompliant ? SDKUI_Localizator.Documents : undefined,
|
|
686
|
+
secondaryLabel: isCopyCompliant ? 'File corrente' : undefined,
|
|
687
|
+
});
|
|
746
688
|
let result = [];
|
|
747
|
-
setWaitPanelMaxValuePrimary(inputDcmts.length);
|
|
748
689
|
for (let i = 0; i < inputDcmts.length; i++) {
|
|
690
|
+
await panel.waitWhilePaused();
|
|
749
691
|
if (abortController.signal.aborted) {
|
|
750
|
-
|
|
692
|
+
const description = SDKUI_Localizator.OperationDcmtsInterrupted.replaceParams(i);
|
|
693
|
+
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.WARNING, description });
|
|
694
|
+
panel.warning(1, description);
|
|
751
695
|
break;
|
|
752
696
|
}
|
|
753
|
-
|
|
697
|
+
panel.setSubtitle(`Documento ${i + 1} di ${inputDcmts.length}`);
|
|
754
698
|
try {
|
|
755
699
|
switch (dcmtOperationType) {
|
|
756
700
|
case DcmtOperationTypes.AddToFavs:
|
|
@@ -855,33 +799,36 @@ export const useDcmtOperations = () => {
|
|
|
855
799
|
const importWarnings = await importCertificatesAsync(inputDcmts[i], i, fetchRemoteCertificates, abortController.signal);
|
|
856
800
|
if (importWarnings) {
|
|
857
801
|
result.push(...importWarnings);
|
|
802
|
+
importWarnings.forEach(w => panel.warning(1, panelMessage(inputDcmts[i], w.description ?? '')));
|
|
858
803
|
}
|
|
859
804
|
break;
|
|
860
805
|
}
|
|
861
806
|
}
|
|
862
807
|
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.SUCCESS });
|
|
808
|
+
panel.ok();
|
|
863
809
|
}
|
|
864
810
|
catch (ex) {
|
|
865
811
|
let msg = getExceptionMessage(ex);
|
|
866
812
|
if (msg.startsWith('WARNING#')) {
|
|
867
|
-
|
|
813
|
+
const description = msg.replace('WARNING#', '');
|
|
814
|
+
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.WARNING, description });
|
|
815
|
+
panel.warning(1, panelMessage(inputDcmts[i], description));
|
|
868
816
|
}
|
|
869
|
-
else
|
|
817
|
+
else {
|
|
870
818
|
result.push({ rowIndex: i, id1: inputDcmts[i].TID, id2: inputDcmts[i].DID, resultType: ResultTypes.ERROR, description: msg });
|
|
819
|
+
panel.error(1, panelMessage(inputDcmts[i], msg));
|
|
820
|
+
}
|
|
871
821
|
const err = ex;
|
|
872
822
|
if (err.name === 'CanceledError') {
|
|
873
823
|
ShowAlert({ message: err.message, mode: 'warning', duration: 3000, title: 'Abort' });
|
|
874
824
|
}
|
|
875
825
|
}
|
|
876
|
-
|
|
826
|
+
panel.setValue(i + 1);
|
|
877
827
|
}
|
|
878
828
|
if (zipEntries.length > 0) {
|
|
879
829
|
await zipDocuments(zipEntries, dcmtOperationType, inputDcmts[0].TID);
|
|
880
830
|
}
|
|
881
|
-
|
|
882
|
-
setWaitPanelValuePrimary(0);
|
|
883
|
-
setWaitPanelTextPrimary('');
|
|
884
|
-
setShowWaitPanel(false);
|
|
831
|
+
closeWaitPanel(panel);
|
|
885
832
|
actionAfterOperationAsync?.();
|
|
886
833
|
TMResultManager.show(result, operationTitle, "TID", "DID");
|
|
887
834
|
};
|
|
@@ -894,7 +841,6 @@ export const useDcmtOperations = () => {
|
|
|
894
841
|
}
|
|
895
842
|
};
|
|
896
843
|
return {
|
|
897
|
-
abortController, showWaitPanel, showPrimary, waitPanelTitle, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary,
|
|
898
844
|
downloadDcmtsAsync, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache, runOperationAsync, FileSourceDialog
|
|
899
845
|
};
|
|
900
846
|
};
|
|
@@ -63,6 +63,7 @@ export interface UIConfigProps {
|
|
|
63
63
|
toppyHelpCenterUsePortal?: boolean;
|
|
64
64
|
inputDcmtFormLayoutMode?: LayoutModes;
|
|
65
65
|
graphometricManager?: IGraphometricManagerProp;
|
|
66
|
+
showSelector?: boolean;
|
|
66
67
|
}
|
|
67
68
|
export interface TasksProps {
|
|
68
69
|
allTasks?: Array<TaskDescriptor>;
|