@topconsultnpm/sdkui-react 6.21.0-dev1.5 → 6.21.0-dev1.51

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.
Files changed (75) hide show
  1. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +2 -2
  2. package/lib/components/NewComponents/ContextMenu/styles.d.ts +43 -19
  3. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +1 -1
  4. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +79 -27
  5. package/lib/components/base/Styled.d.ts +76 -40
  6. package/lib/components/base/TMAreaManager.js +28 -11
  7. package/lib/components/base/TMFileManagerDataGridView.js +2 -2
  8. package/lib/components/base/TMFileManagerUtils.d.ts +6 -2
  9. package/lib/components/base/TMPanel.js +1 -0
  10. package/lib/components/base/TMTreeView.d.ts +5 -3
  11. package/lib/components/choosers/TMDataListItemChooser.js +25 -2
  12. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +1 -1
  13. package/lib/components/choosers/TMDynDataListItemChooser.js +50 -23
  14. package/lib/components/choosers/TMUserChooser.js +3 -1
  15. package/lib/components/editors/TMDropDown.js +2 -2
  16. package/lib/components/editors/TMEditorStyled.d.ts +42 -10
  17. package/lib/components/editors/TMFormulaEditor.js +15 -3
  18. package/lib/components/editors/TMMetadataEditor.js +4 -3
  19. package/lib/components/editors/TMMetadataValues.js +1 -1
  20. package/lib/components/features/archive/TMArchive.js +1 -1
  21. package/lib/components/features/documents/TMDcmtBlog.d.ts +1 -0
  22. package/lib/components/features/documents/TMDcmtBlog.js +2 -2
  23. package/lib/components/features/documents/TMDcmtForm.js +11 -7
  24. package/lib/components/features/documents/TMDcmtPreview.d.ts +5 -3
  25. package/lib/components/features/documents/TMDragDropOverlay.js +7 -2
  26. package/lib/components/features/documents/TMFileUploader.js +5 -4
  27. package/lib/components/features/documents/TMMasterDetailDcmts.js +74 -21
  28. package/lib/components/features/documents/TMRelationViewer.d.ts +6 -1
  29. package/lib/components/features/documents/TMRelationViewer.js +44 -7
  30. package/lib/components/features/search/TMSavedQuerySelector.js +1 -1
  31. package/lib/components/features/search/TMSearch.js +2 -0
  32. package/lib/components/features/search/TMSearchQueryEditor.js +13 -1
  33. package/lib/components/features/search/TMSearchQueryPanel.d.ts +3 -3
  34. package/lib/components/features/search/TMSearchResult.js +16 -3
  35. package/lib/components/features/search/TMViewHistoryDcmt.js +6 -0
  36. package/lib/components/features/workflow/diagram/DiagramItemForm.js +5 -1
  37. package/lib/components/features/workflow/diagram/WFDiagram.js +7 -1
  38. package/lib/components/features/workflow/diagram/WorkitemRecipientsEditor.d.ts +1 -1
  39. package/lib/components/features/workflow/diagram/xmlParser.js +13 -14
  40. package/lib/components/forms/Login/ChangePasswordInputs.d.ts +1 -1
  41. package/lib/components/forms/Login/TMLoginForm.js +15 -5
  42. package/lib/components/forms/TMChooserForm.js +25 -2
  43. package/lib/components/grids/TMBlogsPost.js +1 -1
  44. package/lib/components/index.d.ts +1 -0
  45. package/lib/components/index.js +1 -0
  46. package/lib/components/layout/panelManager/TMPanelManagerToolbar.d.ts +5 -2
  47. package/lib/components/pages/TMPage.js +4 -2
  48. package/lib/components/query/TMQueryCountButton.d.ts +11 -0
  49. package/lib/components/query/TMQueryCountButton.js +32 -0
  50. package/lib/components/query/TMQueryEditor.d.ts +10 -6
  51. package/lib/components/query/TMQueryEditor.js +41 -4
  52. package/lib/components/query/TMQuerySummary.js +3 -2
  53. package/lib/components/sidebar/TMCommandsPanel.d.ts +4 -2
  54. package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
  55. package/lib/components/viewers/TMDataListItemViewer.js +2 -2
  56. package/lib/helper/SDKUI_Globals.d.ts +2 -0
  57. package/lib/helper/SDKUI_Localizator.d.ts +1 -0
  58. package/lib/helper/SDKUI_Localizator.js +10 -0
  59. package/lib/helper/TMPdfViewer.js +143 -86
  60. package/lib/helper/TMUtils.d.ts +4 -3
  61. package/lib/helper/TMUtils.js +12 -0
  62. package/lib/helper/checkinCheckoutManager.d.ts +7 -2
  63. package/lib/helper/checkinCheckoutManager.js +220 -11
  64. package/lib/hooks/useCheckInOutOperations.d.ts +1 -1
  65. package/lib/hooks/useCheckInOutOperations.js +9 -4
  66. package/lib/hooks/useDcmtOperations.d.ts +1 -0
  67. package/lib/hooks/useDcmtOperations.js +74 -4
  68. package/lib/hooks/useDocumentOperations.js +20 -6
  69. package/lib/hooks/useForm.js +20 -14
  70. package/lib/hooks/useInputDialog.d.ts +2 -0
  71. package/lib/hooks/useInputDialog.js +37 -0
  72. package/lib/hooks/useQueryParametersDialog.js +5 -5
  73. package/lib/services/platform_services.d.ts +1 -1
  74. package/lib/services/platform_services.js +8 -0
  75. package/package.json +54 -55
@@ -105,7 +105,7 @@ export const updateCicoCheckoutStorageItem = (item, type, action = "addOrUpdate"
105
105
  SDKUI_Globals.userSettings.wgDraftCheckoutInfo = currentItems;
106
106
  }
107
107
  };
108
- export const validateCicoFileName = (source, fileName) => {
108
+ export const validateCicoFileName = (source, fileName, checkoutDate) => {
109
109
  const archiveID = SDK_Globals.tmSession?.SessionDescr?.archiveID;
110
110
  let baseName;
111
111
  let tid;
@@ -152,6 +152,7 @@ export const validateCicoFileName = (source, fileName) => {
152
152
  const nameCheck = parts[1];
153
153
  const tidCheck = parts[2];
154
154
  const didCheck = parts[3];
155
+ const timestampCheck = parts[4]; // Timestamp from filename: YYYYMMDDHHmmss
155
156
  // Validation checks
156
157
  const expectedFullName = `${nameCheck}.${fileExtensionCheck}`.toLowerCase();
157
158
  const isValidName = expectedFullName === name.toLowerCase();
@@ -159,9 +160,53 @@ export const validateCicoFileName = (source, fileName) => {
159
160
  const isValidTid = tidCheck ? tid.toString() === parseInt(tidCheck, 10).toString() : false;
160
161
  const isValidArchive = archiveCheck ? archiveCheck === archiveID : false;
161
162
  const isValidExt = ext ? ext.toLowerCase() === fileExtensionCheck.toLowerCase() : false;
163
+ // First phase validation result
164
+ const isFirstPhaseValid = !!(isValidName && isValidArchive && isValidDid && isValidTid && isValidExt);
165
+ // Second phase: validate checkoutDate timestamp (only if first phase passed and checkoutDate is a valid string)
166
+ let checkoutDateValidation;
167
+ let isSecondPhaseValid = true;
168
+ if (isFirstPhaseValid && checkoutDate && typeof checkoutDate === "string") {
169
+ try {
170
+ // Convert checkoutDate to timestamp format YYYYMMDDHHmmss
171
+ const dt = new Date(checkoutDate);
172
+ // Check if date is valid
173
+ if (isNaN(dt.getTime())) {
174
+ // Skip second phase validation if date is invalid
175
+ console.warn("validateCicoFileName: invalid checkoutDate, skipping timestamp validation");
176
+ }
177
+ else {
178
+ const pad = (n) => n.toString().padStart(2, '0');
179
+ const expectedTimestamp = `${dt.getFullYear()}${pad(dt.getMonth() + 1)}${pad(dt.getDate())}${pad(dt.getHours())}${pad(dt.getMinutes())}${pad(dt.getSeconds())}`;
180
+ isSecondPhaseValid = timestampCheck === expectedTimestamp;
181
+ // Format dates for display: readable date + (raw timestamp)
182
+ const expectedDisplayDate = Globalization.getDateTimeDisplayValue(dt);
183
+ // Parse timestampCheck to readable format (YYYYMMDDHHmmss -> Date)
184
+ let currentDisplayDate = timestampCheck;
185
+ if (timestampCheck && timestampCheck.length === 14) {
186
+ const year = parseInt(timestampCheck.substring(0, 4), 10);
187
+ const month = parseInt(timestampCheck.substring(4, 6), 10) - 1;
188
+ const day = parseInt(timestampCheck.substring(6, 8), 10);
189
+ const hours = parseInt(timestampCheck.substring(8, 10), 10);
190
+ const minutes = parseInt(timestampCheck.substring(10, 12), 10);
191
+ const seconds = parseInt(timestampCheck.substring(12, 14), 10);
192
+ const parsedDate = new Date(year, month, day, hours, minutes, seconds);
193
+ currentDisplayDate = Globalization.getDateTimeDisplayValue(parsedDate);
194
+ }
195
+ checkoutDateValidation = {
196
+ expected: `${expectedDisplayDate} (${expectedTimestamp})`,
197
+ current: `${currentDisplayDate} (${timestampCheck})`,
198
+ isValid: isSecondPhaseValid
199
+ };
200
+ }
201
+ }
202
+ catch (error) {
203
+ // If anything goes wrong, skip second phase validation
204
+ console.warn("validateCicoFileName: error processing checkoutDate, skipping timestamp validation", error);
205
+ }
206
+ }
162
207
  // Return validation results as an object
163
208
  return {
164
- isValid: !!(isValidName && isValidArchive && isValidDid && isValidTid && isValidExt),
209
+ isValid: isFirstPhaseValid && isSecondPhaseValid,
165
210
  validationResults: {
166
211
  archiveID: {
167
212
  expected: archiveID,
@@ -187,13 +232,155 @@ export const validateCicoFileName = (source, fileName) => {
187
232
  expected: ext?.toLowerCase(),
188
233
  current: fileExtensionCheck.toLowerCase(),
189
234
  isValid: isValidExt
190
- }
235
+ },
236
+ ...(checkoutDateValidation && { checkoutDate: checkoutDateValidation })
191
237
  }
192
238
  };
193
239
  };
240
+ /**
241
+ * Rimuove il timestamp di checkout e l'estensione dal nome file se presenti.
242
+ * Es: checkout~Z1~(CP) CICO A~10683~9894334~20260420090234.TXT -> checkout~Z1~(CP) CICO A~10683~9894334
243
+ * Non lancia mai errori, ritorna il nome originale in caso di problemi.
244
+ */
245
+ const stripCheckoutTimestamp = (filename) => {
246
+ try {
247
+ if (!filename || typeof filename !== 'string')
248
+ return filename;
249
+ // Check if it's a checkout filename (starts with 'checkout~')
250
+ if (!filename.startsWith('checkout~'))
251
+ return filename;
252
+ // Remove extension if present
253
+ const lastDotIndex = filename.lastIndexOf('.');
254
+ const nameWithoutExt = lastDotIndex !== -1 ? filename.substring(0, lastDotIndex) : filename;
255
+ // Check if the last part is a 14-digit timestamp
256
+ const lastTildeIndex = nameWithoutExt.lastIndexOf('~');
257
+ if (lastTildeIndex === -1)
258
+ return nameWithoutExt;
259
+ const potentialTimestamp = nameWithoutExt.substring(lastTildeIndex + 1);
260
+ // Validate it's a 14-digit number (YYYYMMDDHHmmss)
261
+ if (potentialTimestamp.length === 14 && /^\d{14}$/.test(potentialTimestamp)) {
262
+ // Remove the timestamp part
263
+ return nameWithoutExt.substring(0, lastTildeIndex);
264
+ }
265
+ return nameWithoutExt;
266
+ }
267
+ catch {
268
+ // Never throw, return original
269
+ return filename;
270
+ }
271
+ };
194
272
  export const renderCicoCheckInContent = (source, selectedFilename, isValid, validationItems, color = "#996300") => {
195
273
  const fileName = source.type === 'fileItem' ? source.fileItem.name : (source.dcmtInfo.fileName ?? SDKUI_Localizator.SearchResult);
196
- return _jsxs("div", { style: { width: "100%", height: "100%" }, children: [SDKUI_Localizator.CheckInElementConfirm.replaceParams(fileName), !isValid && _jsxs("div", { style: { width: "100%", height: "100%", marginTop: '15px' }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column' }, children: [_jsx("div", { style: { fontSize: '12px', color, marginBottom: '12px' }, children: SDKUI_Localizator.ElementNameConventionError }), _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '6px' }, children: [_jsxs("div", { style: { color }, children: [_jsx("strong", { style: { color }, children: SDKUI_Localizator.Expected }), ":", ' ', _jsx("span", { style: { fontStyle: 'italic' }, children: getCicoDownloadFileName(source, true, false) })] }), _jsxs("div", { style: { color }, children: [_jsx("strong", { style: { color }, children: SDKUI_Localizator.SelectedSingular }), ":", ' ', _jsx("span", { style: { fontStyle: 'italic' }, children: selectedFilename.name })] })] })] }), validationItems && Object.entries(validationItems).filter(([_, value]) => !value.isValid).length > 0 && (_jsxs("div", { style: { width: "100%", height: "100%", marginTop: '15px' }, children: [_jsx("hr", {}), _jsxs("table", { style: { width: "100%", borderCollapse: "collapse", color }, children: [_jsx("caption", { style: { textAlign: "center", fontWeight: "bold", marginBottom: "5px" }, children: SDKUI_Localizator.Anomalies }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { style: { textAlign: "left", borderBottom: "1px solid #eee" }, children: SDKUI_Localizator.Value }), _jsx("th", { style: { textAlign: "left", borderBottom: "1px solid #eee" }, children: SDKUI_Localizator.Expected }), _jsx("th", { style: { textAlign: "left", borderBottom: "1px solid #eee" }, children: SDKUI_Localizator.Current })] }) }), _jsx("tbody", { children: Object.entries(validationItems).filter(([_, value]) => !value.isValid).map(([key, result]) => (_jsxs("tr", { children: [_jsx("td", { style: { borderBottom: "1px solid #eee" }, children: _jsx("strong", { style: { textTransform: "capitalize" }, children: key }) }), _jsxs("td", { style: { borderBottom: "1px solid #eee" }, children: [" ", result.expected || "-"] }), _jsxs("td", { style: { borderBottom: "1px solid #eee" }, children: [" ", result.current || "-"] })] }, key))) })] }), _jsx("hr", {})] })), _jsx("div", { style: { fontSize: '12px', marginTop: '15px', marginBottom: '15px' }, children: SDKUI_Localizator.ProceedAnyway })] })] });
274
+ const warningBgColor = "#fff8e6";
275
+ const warningBorderColor = "#f5c518";
276
+ return (_jsxs("div", { style: { width: "100%", padding: "8px 0", userSelect: 'text' }, children: [_jsx("div", { style: {
277
+ fontSize: '1rem',
278
+ marginBottom: isValid ? 0 : '16px',
279
+ lineHeight: 1.5
280
+ }, children: SDKUI_Localizator.CheckInElementConfirm.replaceParams(fileName) }), !isValid && (_jsxs("div", { style: {
281
+ background: warningBgColor,
282
+ border: `1px solid ${warningBorderColor}`,
283
+ borderRadius: '8px',
284
+ padding: '16px',
285
+ marginTop: '8px'
286
+ }, children: [_jsxs("div", { style: {
287
+ display: 'flex',
288
+ alignItems: 'center',
289
+ gap: '8px',
290
+ marginBottom: '16px'
291
+ }, children: [_jsx("i", { className: "dx-icon-warning", style: { fontSize: '20px', color } }), _jsx("span", { style: { fontSize: '1rem', fontWeight: 600, color }, children: SDKUI_Localizator.ElementNameConventionError })] }), _jsxs("div", { style: {
292
+ display: 'flex',
293
+ flexDirection: 'column',
294
+ gap: '12px',
295
+ background: '#fff',
296
+ borderRadius: '6px',
297
+ padding: '12px',
298
+ marginBottom: '16px'
299
+ }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'flex-start', gap: '8px' }, children: [_jsxs("span", { style: {
300
+ minWidth: '80px',
301
+ fontWeight: 600,
302
+ color: '#555',
303
+ fontSize: '0.875rem'
304
+ }, children: [SDKUI_Localizator.Expected, ":"] }), _jsx("code", { style: {
305
+ fontFamily: 'monospace',
306
+ fontSize: '0.875rem',
307
+ background: '#e8f5e9',
308
+ padding: '2px 8px',
309
+ borderRadius: '4px',
310
+ color: '#2e7d32',
311
+ wordBreak: 'break-all'
312
+ }, children: getCicoDownloadFileName(source, true, false) })] }), _jsxs("div", { style: { display: 'flex', alignItems: 'flex-start', gap: '8px' }, children: [_jsxs("span", { style: {
313
+ minWidth: '80px',
314
+ fontWeight: 600,
315
+ color: '#555',
316
+ fontSize: '0.875rem'
317
+ }, children: [SDKUI_Localizator.SelectedSingular, ":"] }), _jsx("code", { style: {
318
+ fontFamily: 'monospace',
319
+ fontSize: '0.875rem',
320
+ background: '#ffebee',
321
+ padding: '2px 8px',
322
+ borderRadius: '4px',
323
+ color: '#c62828',
324
+ wordBreak: 'break-all'
325
+ }, children: stripCheckoutTimestamp(selectedFilename.name) })] })] }), validationItems && Object.entries(validationItems).filter(([_, value]) => !value.isValid).length > 0 && (_jsxs("div", { style: {
326
+ background: '#fff',
327
+ borderRadius: '6px',
328
+ padding: '12px',
329
+ marginBottom: '16px'
330
+ }, children: [_jsx("div", { style: {
331
+ fontWeight: 600,
332
+ marginBottom: '12px',
333
+ color: '#555',
334
+ fontSize: '0.875rem',
335
+ textTransform: 'uppercase',
336
+ letterSpacing: '0.5px'
337
+ }, children: SDKUI_Localizator.Anomalies }), _jsxs("table", { style: {
338
+ width: "100%",
339
+ borderCollapse: "separate",
340
+ borderSpacing: 0,
341
+ fontSize: '0.875rem'
342
+ }, children: [_jsx("thead", { children: _jsxs("tr", { style: { background: '#f5f5f5' }, children: [_jsx("th", { style: {
343
+ textAlign: "left",
344
+ padding: '10px 12px',
345
+ borderBottom: "2px solid #ddd",
346
+ fontWeight: 600,
347
+ color: '#333'
348
+ }, children: SDKUI_Localizator.Value }), _jsx("th", { style: {
349
+ textAlign: "left",
350
+ padding: '10px 12px',
351
+ borderBottom: "2px solid #ddd",
352
+ fontWeight: 600,
353
+ color: '#2e7d32'
354
+ }, children: SDKUI_Localizator.Expected }), _jsx("th", { style: {
355
+ textAlign: "left",
356
+ padding: '10px 12px',
357
+ borderBottom: "2px solid #ddd",
358
+ fontWeight: 600,
359
+ color: '#c62828'
360
+ }, children: SDKUI_Localizator.Current })] }) }), _jsx("tbody", { children: Object.entries(validationItems)
361
+ .filter(([_, value]) => !value.isValid)
362
+ .map(([key, result], index, arr) => (_jsxs("tr", { style: {
363
+ background: index % 2 === 0 ? '#fafafa' : '#fff'
364
+ }, children: [_jsx("td", { style: {
365
+ padding: '10px 12px',
366
+ borderBottom: index === arr.length - 1 ? 'none' : "1px solid #eee",
367
+ fontWeight: 500,
368
+ textTransform: "capitalize"
369
+ }, children: key.toUpperCase() }), _jsx("td", { style: {
370
+ padding: '10px 12px',
371
+ borderBottom: index === arr.length - 1 ? 'none' : "1px solid #eee",
372
+ color: '#2e7d32',
373
+ fontFamily: 'monospace'
374
+ }, children: result.expected || "-" }), _jsx("td", { style: {
375
+ padding: '10px 12px',
376
+ borderBottom: index === arr.length - 1 ? 'none' : "1px solid #eee",
377
+ color: '#c62828',
378
+ fontFamily: 'monospace'
379
+ }, children: result.current || "-" })] }, key))) })] })] }))] })), !isValid && (_jsx("div", { style: {
380
+ fontSize: '1rem',
381
+ lineHeight: 1.5,
382
+ marginTop: '16px'
383
+ }, children: SDKUI_Localizator.ProceedAnyway }))] }));
197
384
  };
198
385
  export const getDcmtCicoInfo = (dtd) => {
199
386
  const cico = {
@@ -245,7 +432,7 @@ export const getDcmtCicoStatus = (dcmt, allUsers, dtd) => {
245
432
  if (dcmt === undefined || dtd === undefined) {
246
433
  return {
247
434
  cicoEnabled: false,
248
- checkoutStatus: { isCheckedOut: false, mode: '', version: 1, icon: null, editLockTooltipText: null }
435
+ checkoutStatus: { isCheckedOut: false, mode: '', version: 1, icon: null, editLockTooltipText: null, checkoutUserId: undefined, checkoutDate: undefined, fileExt: null, isMetadata: false }
249
436
  };
250
437
  }
251
438
  // ========================================================================
@@ -259,8 +446,9 @@ export const getDcmtCicoStatus = (dcmt, allUsers, dtd) => {
259
446
  let checkoutDate;
260
447
  let version = 1;
261
448
  let fileExt;
449
+ let isMetadata = false;
262
450
  // ========================================================================
263
- // CASO 1: Documento come Array di MetadataValueDescriptorEx
451
+ // CASO 1: Documento come Array di MetadataValueDescriptorEx: Form del documento
264
452
  // ========================================================================
265
453
  // Questo formato viene utilizzato quando il documento proviene da query
266
454
  // o liste dove ogni metadato è un oggetto separato con proprietà 'md' e 'value'
@@ -279,9 +467,11 @@ export const getDcmtCicoStatus = (dcmt, allUsers, dtd) => {
279
467
  version = (versionRaw != null && !isNaN(Number(versionRaw))) ? Number(versionRaw) : 1;
280
468
  const fileExtProperty = dcmtsArray.find((item) => item.mid === SystemMIDsAsNumber.FileExt);
281
469
  fileExt = fileExtProperty?.value ? fileExtProperty.value.toString() : null;
470
+ const fileCountProperty = dcmtsArray.find((item) => item.mid === SystemMIDsAsNumber.FileCount);
471
+ isMetadata = !(fileCountProperty?.value && Number(fileCountProperty.value) > 0);
282
472
  }
283
473
  // ========================================================================
284
- // CASO 2: Documento come Oggetto Piatto (formato standard)
474
+ // CASO 2: Documento come Oggetto Piatto (formato standard): Risultato della ricerca
285
475
  // ========================================================================
286
476
  // Questo formato viene utilizzato quando il documento ha proprietà dirette
287
477
  // nel formato chiave-valore: TID, DID, e "TID_MetadataID" per i metadati
@@ -290,6 +480,8 @@ export const getDcmtCicoStatus = (dcmt, allUsers, dtd) => {
290
480
  const CICO_CheckoutUserID_Meta = dtd.metadata?.find(md => md.name === CICO_MetadataNames.CICO_CheckoutUserID);
291
481
  const CICO_CheckoutDate_Meta = dtd.metadata?.find(md => md.name === CICO_MetadataNames.CICO_CheckoutDate);
292
482
  const CICO_Version_Meta = dtd.metadata?.find(md => md.name === CICO_MetadataNames.CICO_Version);
483
+ const fileCountValue = dcmt.FILECOUNT != null ? Number(dcmt.FILECOUNT) : NaN;
484
+ isMetadata = isNaN(fileCountValue) || fileCountValue <= 0;
293
485
  fileExt = dcmt.FILEEXT ? dcmt.FILEEXT.toString() : null;
294
486
  // Estrai l'ID dell'utente che ha effettuato il checkout
295
487
  if (CICO_CheckoutUserID_Meta?.id) {
@@ -310,6 +502,15 @@ export const getDcmtCicoStatus = (dcmt, allUsers, dtd) => {
310
502
  }
311
503
  }
312
504
  // ========================================================================
505
+ // EARLY RETURN: Documento di soli metadati (senza file)
506
+ // ========================================================================
507
+ if (isMetadata) {
508
+ return {
509
+ cicoEnabled: false,
510
+ checkoutStatus: { isCheckedOut: false, mode: '', version: 1, icon: null, editLockTooltipText: null, checkoutUserId: undefined, checkoutDate: undefined, fileExt: fileExt, isMetadata: true }
511
+ };
512
+ }
513
+ // ========================================================================
313
514
  // COSTRUZIONE DELLO STATO DI CHECKOUT
314
515
  // ========================================================================
315
516
  let checkoutStatus = {
@@ -317,7 +518,11 @@ export const getDcmtCicoStatus = (dcmt, allUsers, dtd) => {
317
518
  mode: '',
318
519
  version: version,
319
520
  icon: null,
320
- editLockTooltipText: null
521
+ editLockTooltipText: null,
522
+ checkoutUserId: checkoutUserId,
523
+ checkoutDate: checkoutDate,
524
+ fileExt: fileExt,
525
+ isMetadata: isMetadata
321
526
  };
322
527
  // Verifica se il documento è effettivamente in stato di checkout
323
528
  if (userID && checkoutUserId && !isNaN(checkoutUserId) && checkoutUserId > 0) {
@@ -338,15 +543,19 @@ export const getDcmtCicoStatus = (dcmt, allUsers, dtd) => {
338
543
  mode: mode,
339
544
  icon: icon,
340
545
  version: version,
341
- editLockTooltipText: editLockTooltipText
546
+ editLockTooltipText: editLockTooltipText,
547
+ checkoutUserId: checkoutUserId,
548
+ checkoutDate: checkoutDate,
549
+ fileExt: fileExt,
550
+ isMetadata: isMetadata
342
551
  };
343
552
  }
344
553
  // ========================================================================
345
554
  // RESTITUZIONE RISULTATO FINALE
346
555
  // ========================================================================
347
556
  return {
348
- // CICO è abilitato se configurato nel DTD e l'utente ha i permessi
349
- cicoEnabled: cicoInfo.CICO === 1 && cicoInfo.CanCICO === AccessLevels.Yes && fileExt !== null && fileExt !== '',
557
+ // CICO è abilitato se configurato nel DTD, l'utente ha i permessi e il documento non è di soli metadati
558
+ cicoEnabled: cicoInfo.CICO === 1 && cicoInfo.CanCICO === AccessLevels.Yes && fileExt !== null && fileExt !== '' && !isMetadata,
350
559
  checkoutStatus: checkoutStatus
351
560
  };
352
561
  };
@@ -18,7 +18,7 @@ export interface UseCheckInOutOperationsReturn {
18
18
  hideCommentFormCallback: () => void;
19
19
  copyCheckoutPathToClipboardCallback: (dcmt: DcmtInfo, filename: string) => void;
20
20
  handleCheckOutCallback: (dcmt: DcmtInfo, checkout: boolean, filename: string, downloadDcmtsAsync: (inputDcmts: Array<DcmtInfo> | undefined, downloadType?: DownloadTypes, downloadMode?: DownloadModes, onFileDownloaded?: (dcmtFile: File) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean) => Promise<void>, onRefreshAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>) => Promise<void>;
21
- handleCheckInCallback: (dcmt: DcmtInfo, onRefreshAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>) => Promise<void>;
21
+ handleCheckInCallback: (dcmt: DcmtInfo, checkoutDate?: string | null, onRefreshAsync?: (tid: number | undefined, did: number | undefined, refreshUI?: boolean, metadataResult?: SearchResultDescriptor | null) => Promise<void>) => Promise<void>;
22
22
  showCicoWaitPanel: boolean;
23
23
  cicoWaitPanelTitle: string;
24
24
  showCicoPrimaryProgress: boolean;
@@ -1,6 +1,6 @@
1
- import { useCallback, useState } from 'react';
1
+ import { useCallback, useMemo, useState } from 'react';
2
2
  import { cicoDownloadFilesCallback, dcmtsFileCachePreview, getCicoDownloadFileName, getExceptionMessage, removeDcmtsFileCache, renderCicoCheckInContent, SDKUI_Globals, SDKUI_Localizator, updateCicoCheckoutStorageItem, validateCicoFileName } from '../helper';
3
- import { ButtonNames, ShowAlert, TMMessageBoxManager, TMResultManager } from '../components';
3
+ import { ButtonNames, DeviceType, ShowAlert, TMMessageBoxManager, TMResultManager, useDeviceType } from '../components';
4
4
  import { ResultTypes, SDK_Globals } from '@topconsultnpm/sdk-ts';
5
5
  let abortController = new AbortController();
6
6
  export const useCheckInOutOperations = (props) => {
@@ -14,6 +14,10 @@ export const useCheckInOutOperations = (props) => {
14
14
  show: false,
15
15
  isRequired: false
16
16
  });
17
+ // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
18
+ const deviceType = useDeviceType();
19
+ // This avoids unnecessary re-renders by only recalculating when deviceType changes.
20
+ let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
17
21
  // State variable to control the visibility of the wait panel
18
22
  const [showCicoWaitPanel, setShowCicoWaitPanel] = useState(false);
19
23
  // State variable to store the title of the wait panel
@@ -127,7 +131,7 @@ export const useCheckInOutOperations = (props) => {
127
131
  });
128
132
  }
129
133
  };
130
- const handleCheckInCallback = async (dcmt, onRefreshAsync) => {
134
+ const handleCheckInCallback = async (dcmt, checkoutDate, onRefreshAsync) => {
131
135
  if (!dcmt)
132
136
  throw new Error("Document info is required");
133
137
  // Create a new file input element
@@ -144,12 +148,13 @@ export const useCheckInOutOperations = (props) => {
144
148
  if (!fileInput.files || fileInput.files.length === 0)
145
149
  return;
146
150
  const file = fileInput.files[0];
147
- const validateFileName = validateCicoFileName({ type: 'dcmtInfo', dcmtInfo: dcmt, originalFileName: dcmt.fileName ?? SDKUI_Localizator.SearchResult }, file.name);
151
+ const validateFileName = validateCicoFileName({ type: 'dcmtInfo', dcmtInfo: dcmt, originalFileName: dcmt.fileName ?? SDKUI_Localizator.SearchResult }, file.name, checkoutDate);
148
152
  TMMessageBoxManager.show({
149
153
  resizable: true,
150
154
  buttons: [ButtonNames.YES, ButtonNames.NO],
151
155
  message: renderCicoCheckInContent({ type: 'dcmtInfo', dcmtInfo: dcmt, originalFileName: dcmt.fileName ?? SDKUI_Localizator.SearchResult }, file, validateFileName.isValid, validateFileName.validationResults),
152
156
  title: "Check in",
157
+ initialWidth: !validateFileName.isValid && !isMobile ? '800px' : undefined,
153
158
  onButtonClick: async (e) => {
154
159
  if (e !== ButtonNames.YES)
155
160
  return;
@@ -21,5 +21,6 @@ export interface UseDcmtOperationsReturn {
21
21
  removeDcmtsFileCache: (key: string) => void;
22
22
  isDcmtFileInCache: (key: string) => boolean;
23
23
  runOperationAsync: (inputDcmts: DcmtInfo[] | undefined, dcmtOperationType: DcmtOperationTypes, actionAfterOperationAsync?: () => Promise<void>) => Promise<void>;
24
+ FileSourceDialog: () => JSX.Element;
24
25
  }
25
26
  export declare const useDcmtOperations: () => UseDcmtOperationsReturn;
@@ -4,9 +4,18 @@ import { SDK_Globals, RetrieveFileOptions, DcmtOpers, ResultTypes, RecentCategor
4
4
  import { ShowAlert, TMResultManager, FormulaHelper, TMExceptionBoxManager, TMSpinner } from '../components';
5
5
  import { Globalization, getExceptionMessage, dialogConfirmOperation, extensionHandler, downloadBase64File, SDKUI_Globals, dcmtsFileCacheDownload, CACHE_SIZE_LIMIT, clearDcmtsFileCache, dcmtsFileCachePreview, isDcmtFileInCache, removeDcmtsFileCache, SDKUI_Localizator } from '../helper';
6
6
  import { DcmtOperationTypes, DownloadTypes, FileExtensionHandler } from '../ts';
7
- import { useFileDialog } from './useInputDialog';
7
+ import { useFileDialog, useFileSourceDialog } from './useInputDialog';
8
8
  import { isXMLFileExt } from '../helper/dcmtsHelper';
9
9
  import { ShowConfirm } from '../components/base/TMConfirm';
10
+ const isScannerLicenseConfigured = () => {
11
+ try {
12
+ const scannerLicense = SDKUI_Globals.userSettings.advancedSettings.scannerLicense;
13
+ return scannerLicense && scannerLicense.trim() !== '';
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ };
10
19
  let abortController = new AbortController();
11
20
  const downloadCountMap = new Map();
12
21
  const getDownloadFileName = (fileName) => {
@@ -32,6 +41,7 @@ export const useDcmtOperations = () => {
32
41
  const [waitPanelValueSecondary, setWaitPanelValueSecondary] = useState(0);
33
42
  const [waitPanelMaxValueSecondary, setWaitPanelMaxValueSecondary] = useState(0);
34
43
  const { OpenFileDialog } = useFileDialog();
44
+ const [selectFileSource, FileSourceDialog] = useFileSourceDialog();
35
45
  const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false) => {
36
46
  if (inputDcmts === undefined)
37
47
  return;
@@ -210,7 +220,61 @@ export const useDcmtOperations = () => {
210
220
  return;
211
221
  if (inputDcmts.length <= 0)
212
222
  return;
213
- let file = inputDcmts[0].FILE ?? await OpenFileDialog();
223
+ let file = inputDcmts[0].FILE;
224
+ if (!file) {
225
+ if (isScannerLicenseConfigured()) {
226
+ const hasExistingFile = !!inputDcmts[0].FILEEXT;
227
+ const source = await selectFileSource(hasExistingFile);
228
+ if (!source)
229
+ return;
230
+ switch (source) {
231
+ case 'filesystem':
232
+ file = await OpenFileDialog();
233
+ break;
234
+ case 'scanner-new':
235
+ if (SDKUI_Globals.scanRequestHandler) {
236
+ file = await new Promise((resolve) => {
237
+ SDKUI_Globals.scanRequestHandler('new', (scannedFile) => resolve(scannedFile), () => resolve(undefined));
238
+ });
239
+ }
240
+ else {
241
+ ShowAlert({ message: SDKUI_Localizator.ScanFeatureUnavailableInThisContext, mode: 'info', duration: 3000, title: 'Scanner' });
242
+ return;
243
+ }
244
+ break;
245
+ case 'scanner-edit':
246
+ if (SDKUI_Globals.scanRequestHandler) {
247
+ // Download the existing file from the document
248
+ let existingFile;
249
+ try {
250
+ const rfo = new RetrieveFileOptions();
251
+ rfo.retrieveReason = DcmtOpers.None;
252
+ const retrievedFile = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(inputDcmts[0].TID, inputDcmts[0].DID, rfo);
253
+ existingFile = retrievedFile;
254
+ }
255
+ catch (ex) {
256
+ TMExceptionBoxManager.show({ exception: getExceptionMessage(ex) });
257
+ return;
258
+ }
259
+ if (!existingFile) {
260
+ ShowAlert({ message: 'Impossibile recuperare il file del documento.', mode: 'warning', duration: 3000, title: 'Scanner' });
261
+ return;
262
+ }
263
+ file = await new Promise((resolve) => {
264
+ SDKUI_Globals.scanRequestHandler('edit', (scannedFile) => resolve(scannedFile), () => resolve(undefined), existingFile);
265
+ });
266
+ }
267
+ else {
268
+ ShowAlert({ message: SDKUI_Localizator.ScanFeatureUnavailableInThisContext, mode: 'info', duration: 3000, title: 'Scanner' });
269
+ return;
270
+ }
271
+ break;
272
+ }
273
+ }
274
+ else {
275
+ file = await OpenFileDialog();
276
+ }
277
+ }
214
278
  if (!file)
215
279
  return;
216
280
  setShowWaitPanel(true);
@@ -489,10 +553,16 @@ export const useDcmtOperations = () => {
489
553
  actionAfterOperationAsync?.();
490
554
  TMResultManager.show(result, operationTitle, "TID", "DID");
491
555
  };
492
- dialogConfirmOperation(operationTitle, msg, doOperationAsync);
556
+ // Per SubstituteFile con beta features e scanner, non mostrare conferma
557
+ if (dcmtOperationType === DcmtOperationTypes.SubstituteFile && isScannerLicenseConfigured()) {
558
+ await doOperationAsync();
559
+ }
560
+ else {
561
+ dialogConfirmOperation(operationTitle, msg, doOperationAsync);
562
+ }
493
563
  };
494
564
  return {
495
565
  abortController, showWaitPanel, showPrimary, waitPanelTitle, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary,
496
- downloadDcmtsAsync, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache, runOperationAsync
566
+ downloadDcmtsAsync, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache, runOperationAsync, FileSourceDialog
497
567
  };
498
568
  };
@@ -105,10 +105,11 @@ export const useDocumentOperations = (props) => {
105
105
  }, [refreshOperationsTrigger]);
106
106
  // Context helpers
107
107
  const isDcmtFormContext = context === SearchResultContext.DCMT_FORM;
108
+ const isMasterDetailContext = context === SearchResultContext.MASTER_DETAIL;
108
109
  const { showHistory, showHistoryCallback, hideHistoryCallback, showCheckoutInformationForm, commentFormState, hideCommentFormCallback, showCheckoutInformationFormCallback, hideCheckoutInformationFormCallback, copyCheckoutPathToClipboardCallback, handleCheckOutCallback, handleCheckInCallback, showCicoWaitPanel, cicoWaitPanelTitle, showCicoPrimaryProgress, cicoPrimaryProgressText, cicoPrimaryProgressValue, cicoPrimaryProgressMax, } = useCheckInOutOperations({
109
110
  onRefreshPreview: onRefreshPreviewCallback
110
111
  });
111
- const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache } = useDcmtOperations();
112
+ const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync, runOperationAsync, getDcmtFileAsync, clearDcmtsFileCache, removeDcmtsFileCache, isDcmtFileInCache, FileSourceDialog } = useDcmtOperations();
112
113
  const {
113
114
  // Data
114
115
  relatedDcmts, pairedSearchResults, manyToManyRelations, selectedManyToManyRelation, manyToManyChooserDataSource, relatedDcmtsChooserDataSource,
@@ -616,12 +617,18 @@ export const useDocumentOperations = (props) => {
616
617
  const firstDoc = selectedDcmtInfos?.[0];
617
618
  if (!firstDoc)
618
619
  return;
620
+ // Take the first document (used for validation checks)
621
+ let dcmt = focusedItem;
622
+ if (isDcmtFormContext || isMasterDetailContext) {
623
+ dcmt = dcmtDataRowForCicoStatus;
624
+ }
625
+ const { checkoutStatus } = getDcmtCicoStatus(dcmt, allUsers, dtd);
619
626
  firstDoc.fileName = dtd?.name ?? SDKUI_Localizator.SearchResult;
620
627
  const onRefreshAsync = async () => {
621
628
  await updateCurrentDcmt?.();
622
629
  await refreshFocusedDataRowAsync?.(firstDoc.TID, firstDoc.DID, true);
623
630
  };
624
- await handleCheckInCallback(firstDoc, onRefreshAsync);
631
+ await handleCheckInCallback(firstDoc, checkoutStatus.checkoutDate, onRefreshAsync);
625
632
  };
626
633
  const copyCheckoutPathToClipboardOperationCallback = () => {
627
634
  const firstDoc = selectedDcmtInfos?.[0];
@@ -632,7 +639,7 @@ export const useDocumentOperations = (props) => {
632
639
  const checkinMenuItem = () => {
633
640
  // Take the first document (used for validation checks)
634
641
  let dcmt = focusedItem;
635
- if (isDcmtFormContext) {
642
+ if (isDcmtFormContext || isMasterDetailContext) {
636
643
  dcmt = dcmtDataRowForCicoStatus;
637
644
  }
638
645
  const { cicoEnabled, checkoutStatus } = getDcmtCicoStatus(dcmt, allUsers, dtd);
@@ -1059,9 +1066,13 @@ export const useDocumentOperations = (props) => {
1059
1066
  disabled: isDisabledForSingleRow() && isDisabledForMultiRow(),
1060
1067
  submenu: [
1061
1068
  addToFavoriteOperation(),
1062
- openFormOperation(),
1069
+ addReplaceFileOperation(),
1070
+ fileCheckMenuItem(),
1071
+ fileConversionsMenuItem(),
1072
+ ...(SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ? [createContextualTaskMenuItem()] : []),
1063
1073
  downloadFileMenuItem(),
1064
1074
  downloadXMLAttachmentsMenuItem(),
1075
+ ...(selectedDcmtInfos.length > 0 && isPdfEditorAvailable(dtd, selectedDcmtInfos[0]?.FILEEXT) && onOpenPdfEditorRequest ? [pdfEditorMenuItem(onOpenPdfEditorRequest)] : []),
1065
1076
  ]
1066
1077
  },
1067
1078
  signatureMenuItem(),
@@ -1081,6 +1092,7 @@ export const useDocumentOperations = (props) => {
1081
1092
  ...(inputDcmtFormLayoutMode === LayoutModes.Update ? [addToFavoriteOperation()] : []),
1082
1093
  addReplaceFileOperation(),
1083
1094
  openFormOperation(),
1095
+ deletetionMenuItem(),
1084
1096
  fileCheckMenuItem(),
1085
1097
  fileConversionsMenuItem(),
1086
1098
  ...(SDK_Globals.tmSession?.SessionDescr?.appModuleID === AppModules.SURFER ? [createContextualTaskMenuItem()] : []),
@@ -1090,6 +1102,7 @@ export const useDocumentOperations = (props) => {
1090
1102
  ]
1091
1103
  },
1092
1104
  signatureMenuItem(),
1105
+ checkinMenuItem(),
1093
1106
  ...((inputDcmtFormLayoutMode === LayoutModes.Update) ? [fullTextSearchMenuItem()] : []),
1094
1107
  ];
1095
1108
  };
@@ -1115,7 +1128,7 @@ export const useDocumentOperations = (props) => {
1115
1128
  };
1116
1129
  const renderFloatingBar = (floatingBarContainerRef && floatingBarContainerRef.current && allowFloatingBar && showFloatingBar && deviceType !== DeviceType.MOBILE) ? (_jsx(TMFloatingMenuBar, { containerRef: floatingBarContainerRef, contextMenuItems: operationItems(), isConstrained: true, defaultPosition: { x: 1, y: 88 }, defaultPinnedItems: ['rel-det', 'rel-mst', 'dl'], defaultOrientation: 'horizontal', hasContextMenu: false, pinnedItemIds: pinnedItemIds, onPinChange: setPinnedItemIds })) : null;
1117
1130
  const renderDcmtOperations = (_jsxs(_Fragment, { children: [(showExportForm && searchResult && dataColumns && dataSource && selectedRowKeys) && (_jsx(TMDataGridExportForm, { dataColumns: dataColumns, dataSource: dataSource, selectedRowKeys: selectedRowKeys, onCloseExportForm: () => setShowExportForm(false), searchResult: searchResult })), _jsx(StyledMultiViewPanel, { "$isVisible": isOpenDcmtForm, children: ((isOpenDcmtForm && focusedItem?.TID !== undefined && focusedItem?.DID !== undefined) &&
1118
- _jsx(TMDcmtForm, { isModal: openDcmtFormAsModal || (dcmtFormLayoutMode === LayoutModes.Ark && focusedItem?.DID !== undefined), titleModal: dtd?.name ?? '', TID: focusedItem.TID, DID: focusedItem.DID, allowButtonsRefs: true, layoutMode: dcmtFormLayoutMode, count: visibleItems?.length, itemIndex: visibleItems ? visibleItems.findIndex(o => o.rowIndex === focusedItem?.rowIndex) + 1 : undefined, canNext: canNavigateHandler ? canNavigateHandler('next') : false, canPrev: canNavigateHandler ? canNavigateHandler('prev') : false, onNext: () => onNavigateHandler && onNavigateHandler('next'), onPrev: () => onNavigateHandler && onNavigateHandler('prev'), onClose: () => { (false); onDcmtFormOpenChange(false, LayoutModes.Update); }, onWFOperationCompleted: onWFOperationCompleted, onTaskCreateRequest: onTaskCreateRequest, onSavedAsyncCallback: onSavedAsyncCallback, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, onReferenceClick: onReferenceClick, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.TID, focusedItem?.DID), showDcmtFormSidebar: showDcmtFormSidebar, datagridUtility: {
1131
+ _jsx(TMDcmtForm, { isModal: openDcmtFormAsModal || (dcmtFormLayoutMode === LayoutModes.Ark && focusedItem?.DID !== undefined), titleModal: dtd?.name ?? '', TID: focusedItem.TID, DID: focusedItem.DID, allowButtonsRefs: true, layoutMode: dcmtFormLayoutMode, count: visibleItems?.length, itemIndex: visibleItems ? visibleItems.findIndex(o => o.rowIndex === focusedItem?.rowIndex) + 1 : undefined, canNext: canNavigateHandler ? canNavigateHandler('next') : false, canPrev: canNavigateHandler ? canNavigateHandler('prev') : false, onNext: () => onNavigateHandler && onNavigateHandler('next'), onPrev: () => onNavigateHandler && onNavigateHandler('prev'), onClose: () => { (false); onDcmtFormOpenChange(false, LayoutModes.Update); }, onWFOperationCompleted: onWFOperationCompleted, onTaskCreateRequest: onTaskCreateRequest, onSavedAsyncCallback: onSavedAsyncCallback, openS4TViewer: openS4TViewer, onOpenS4TViewerRequest: onOpenS4TViewerRequest, onOpenPdfEditorRequest: onOpenPdfEditorRequest, openFileUploaderPdfEditor: openFileUploaderPdfEditor, onReferenceClick: onReferenceClick, allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, moreInfoTasks: getMoreInfoTasksForDocument(allTasks, focusedItem?.TID, focusedItem?.DID), showDcmtFormSidebar: showDcmtFormSidebar, datagridUtility: {
1119
1132
  onRefreshSearchAsyncDatagrid,
1120
1133
  onRefreshDataRowsAsync,
1121
1134
  refreshFocusedDataRowAsync,
@@ -1181,7 +1194,7 @@ export const useDocumentOperations = (props) => {
1181
1194
  updateBatchUpdateForm(false);
1182
1195
  setIsModifiedBatchUpdate(false);
1183
1196
  await onRefreshDataRowsAsync?.();
1184
- }, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: selectedDcmtInfos, isReject: 0, onClose: () => updateShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: selectedDcmtInfos, isReject: 1, onClose: () => updateShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: selectedDcmtInfos, onClose: () => updateShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { fromDTD: dtd, TID: contextConfig.approvalTID, DID: focusedItem?.DID, deviceType: deviceType, onCompleted: handleWFOperationCompleted, onClose: () => updateShowMoreInfoPopup(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, triggerBlogRefresh: onRefreshBlogDatagrid }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {}), taskFormDialogComponent, s4TViewerDialogComponent, currentCustomButton && _jsx(TMCustomButton, { button: currentCustomButton, formData: currentMetadataValues, selectedItems: selectedItemsFull, onClose: () => setCurrentCustomButton(undefined) })] }));
1197
+ }, onStatusChanged: (isModified) => { setIsModifiedBatchUpdate(isModified); } }), showApprovePopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: selectedDcmtInfos, isReject: 0, onClose: () => updateShowApprovePopup(false) }), showRejectPopup && _jsx(WorkFlowApproveRejectPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: selectedDcmtInfos, isReject: 1, onClose: () => updateShowRejectPopup(false) }), showReAssignPopup && _jsx(WorkFlowReAssignPopUp, { deviceType: deviceType, onCompleted: handleWFOperationCompleted, selectedItems: selectedDcmtInfos, onClose: () => updateShowReAssignPopup(false) }), showMoreInfoPopup && _jsx(WorkFlowMoreInfoPopUp, { fromDTD: dtd, TID: contextConfig.approvalTID, DID: focusedItem?.DID, deviceType: deviceType, onCompleted: handleWFOperationCompleted, onClose: () => updateShowMoreInfoPopup(false), allTasks: allTasks, getAllTasks: getAllTasks, deleteTaskByIdsCallback: deleteTaskByIdsCallback, addTaskCallback: addTaskCallback, editTaskCallback: editTaskCallback, handleNavigateToWGs: handleNavigateToWGs, handleNavigateToDossiers: handleNavigateToDossiers, triggerBlogRefresh: onRefreshBlogDatagrid }), _jsx(ConfirmFormatDialog, {}), _jsx(ConfirmAttachmentsDialog, {}), _jsx(FileSourceDialog, {}), taskFormDialogComponent, s4TViewerDialogComponent, currentCustomButton && _jsx(TMCustomButton, { button: currentCustomButton, formData: currentMetadataValues, selectedItems: selectedItemsFull, onClose: () => setCurrentCustomButton(undefined) })] }));
1185
1198
  return {
1186
1199
  operationItems: operationItems(),
1187
1200
  renderFloatingBar,
@@ -1234,6 +1247,7 @@ export const useDocumentOperations = (props) => {
1234
1247
  removeDcmtsFileCache,
1235
1248
  isDcmtFileInCache,
1236
1249
  runOperationAsync,
1250
+ FileSourceDialog,
1237
1251
  },
1238
1252
  relatedDocumentsInfo: {
1239
1253
  // Data