@topconsultnpm/sdkui-react 6.19.0-dev2.9 → 6.19.0-test2

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 (97) hide show
  1. package/lib/components/base/TMAccordionNew.d.ts +28 -0
  2. package/lib/components/base/TMAccordionNew.js +326 -0
  3. package/lib/components/base/TMButton.d.ts +1 -0
  4. package/lib/components/base/TMButton.js +6 -6
  5. package/lib/components/base/TMCustomButton.d.ts +1 -1
  6. package/lib/components/base/TMCustomButton.js +83 -28
  7. package/lib/components/base/TMDataGridExportForm.js +9 -3
  8. package/lib/components/base/TMFileManager.js +11 -2
  9. package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -0
  10. package/lib/components/base/TMFileManagerDataGridView.js +12 -3
  11. package/lib/components/base/TMFileManagerThumbnailItems.d.ts +2 -0
  12. package/lib/components/base/TMFileManagerThumbnailItems.js +12 -2
  13. package/lib/components/base/TMFileManagerThumbnailsView.d.ts +2 -0
  14. package/lib/components/base/TMFileManagerThumbnailsView.js +2 -2
  15. package/lib/components/base/TMModal.d.ts +2 -0
  16. package/lib/components/base/TMModal.js +48 -3
  17. package/lib/components/base/TMPopUp.js +74 -5
  18. package/lib/components/base/TMWaitPanel.js +8 -2
  19. package/lib/components/choosers/TMDataListItemChooser.js +1 -1
  20. package/lib/components/choosers/TMDcmtTypeChooser.js +2 -2
  21. package/lib/components/choosers/TMMetadataChooser.d.ts +4 -1
  22. package/lib/components/choosers/TMMetadataChooser.js +31 -8
  23. package/lib/components/choosers/TMUserChooser.d.ts +4 -0
  24. package/lib/components/choosers/TMUserChooser.js +21 -5
  25. package/lib/components/editors/TMMetadataValues.js +45 -4
  26. package/lib/components/editors/TMTextArea.d.ts +1 -0
  27. package/lib/components/editors/TMTextArea.js +44 -10
  28. package/lib/components/editors/TMTextBox.js +34 -4
  29. package/lib/components/editors/TMTextExpression.js +36 -28
  30. package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +30 -0
  31. package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +471 -0
  32. package/lib/components/features/assistant/ToppySpeechBubble.d.ts +9 -0
  33. package/lib/components/features/assistant/ToppySpeechBubble.js +117 -0
  34. package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -0
  35. package/lib/components/features/blog/TMBlogCommentForm.js +18 -6
  36. package/lib/components/features/documents/TMDcmtBlog.js +1 -1
  37. package/lib/components/features/documents/TMDcmtForm.js +290 -31
  38. package/lib/components/features/documents/TMDcmtIcon.js +9 -4
  39. package/lib/components/features/documents/TMDcmtPreview.js +45 -8
  40. package/lib/components/features/documents/TMRelationViewer.js +55 -22
  41. package/lib/components/features/search/TMSearch.js +2 -2
  42. package/lib/components/features/search/TMSearchQueryEditor.js +1 -1
  43. package/lib/components/features/search/TMSearchQueryPanel.js +10 -28
  44. package/lib/components/features/search/TMSearchResult.js +102 -33
  45. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -1
  46. package/lib/components/features/search/TMSearchResultsMenuItems.js +67 -28
  47. package/lib/components/features/search/TMSignSettingsForm.d.ts +9 -0
  48. package/lib/components/features/search/TMSignSettingsForm.js +621 -0
  49. package/lib/components/features/tasks/TMTaskForm.js +10 -4
  50. package/lib/components/features/tasks/TMTasksAgenda.js +1 -1
  51. package/lib/components/features/tasks/TMTasksCalendar.js +1 -1
  52. package/lib/components/features/tasks/TMTasksUtils.d.ts +1 -0
  53. package/lib/components/features/tasks/TMTasksUtils.js +17 -2
  54. package/lib/components/features/tasks/TMTasksUtilsView.js +26 -4
  55. package/lib/components/features/tasks/TMTasksView.js +11 -5
  56. package/lib/components/features/workflow/TMWorkflowPopup.js +3 -3
  57. package/lib/components/features/workflow/diagram/WFDiagram.js +19 -1
  58. package/lib/components/forms/TMSaveForm.js +3 -11
  59. package/lib/components/grids/TMBlogAttachments.d.ts +0 -14
  60. package/lib/components/grids/TMBlogAttachments.js +10 -5
  61. package/lib/components/grids/TMBlogsPost.d.ts +8 -3
  62. package/lib/components/grids/TMBlogsPost.js +100 -39
  63. package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
  64. package/lib/components/grids/TMBlogsPostUtils.js +27 -6
  65. package/lib/components/index.d.ts +2 -1
  66. package/lib/components/index.js +2 -1
  67. package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
  68. package/lib/components/layout/panelManager/TMPanelManagerContainer.js +2 -2
  69. package/lib/components/layout/panelManager/TMPanelManagerContext.js +0 -1
  70. package/lib/components/layout/panelManager/TMPanelManagerToolbar.js +2 -1
  71. package/lib/components/layout/panelManager/types.d.ts +1 -0
  72. package/lib/components/settings/SettingsAppearance.js +5 -5
  73. package/lib/helper/GlobalStyles.d.ts +2 -0
  74. package/lib/helper/GlobalStyles.js +10 -0
  75. package/lib/helper/Globalization.d.ts +1 -0
  76. package/lib/helper/Globalization.js +30 -0
  77. package/lib/helper/SDKUI_Localizator.d.ts +41 -1
  78. package/lib/helper/SDKUI_Localizator.js +410 -10
  79. package/lib/helper/TMIcons.d.ts +4 -1
  80. package/lib/helper/TMIcons.js +13 -1
  81. package/lib/helper/TMToppyMessage.d.ts +1 -0
  82. package/lib/helper/TMToppyMessage.js +4 -3
  83. package/lib/helper/TMUtils.d.ts +42 -4
  84. package/lib/helper/TMUtils.js +190 -23
  85. package/lib/helper/dcmtsHelper.d.ts +2 -1
  86. package/lib/helper/dcmtsHelper.js +56 -17
  87. package/lib/helper/helpers.d.ts +1 -1
  88. package/lib/helper/helpers.js +12 -17
  89. package/lib/helper/index.d.ts +1 -0
  90. package/lib/helper/index.js +1 -0
  91. package/lib/hooks/useDcmtOperations.d.ts +1 -1
  92. package/lib/hooks/useDcmtOperations.js +10 -6
  93. package/lib/hooks/useRelatedDocuments.js +35 -26
  94. package/lib/ts/types.d.ts +2 -0
  95. package/package.json +8 -8
  96. package/lib/components/features/assistant/ToppyHelpCenter.d.ts +0 -12
  97. package/lib/components/features/assistant/ToppyHelpCenter.js +0 -173
@@ -2,6 +2,7 @@ import { ReactNode } from 'react';
2
2
  interface TMToppyMessageProps {
3
3
  message: ReactNode;
4
4
  titleTooltip?: string;
5
+ maxWidth?: string;
5
6
  }
6
7
  declare const TMToppyMessage: (props: TMToppyMessageProps) => import("react/jsx-runtime").JSX.Element;
7
8
  export default TMToppyMessage;
@@ -5,7 +5,7 @@ import TMLayoutContainer from '../components/base/TMLayout';
5
5
  const StyledToppyTextContainer = styled.div `
6
6
  padding: 22px 8px;
7
7
  width: 100%;
8
- max-width: 300px;
8
+ max-width: ${props => props.$maxWidth || '300px'};
9
9
  border: 1px solid #2559A5;
10
10
  border-radius: 30px;
11
11
  display: flex;
@@ -34,9 +34,10 @@ const StyledToppyImage = styled.img `
34
34
  max-width: 120px;
35
35
  height: auto;
36
36
  display: block;
37
+ user-select: none;
37
38
  `;
38
39
  const TMToppyMessage = (props) => {
39
- const { message, titleTooltip } = props;
40
- return (_jsxs(TMLayoutContainer, { gap: 30, alignItems: "center", justifyContent: "center", onContextMenu: (e) => e.preventDefault(), children: [_jsx(StyledToppyTextContainer, { children: _jsx(StyledToppyText, { title: titleTooltip || undefined, children: message }) }), _jsx(StyledToppyImage, { src: Toppy, alt: "Toppy" })] }));
40
+ const { message, titleTooltip, maxWidth } = props;
41
+ return (_jsxs(TMLayoutContainer, { gap: 30, alignItems: "center", justifyContent: "center", onContextMenu: (e) => e.preventDefault(), children: [_jsx(StyledToppyTextContainer, { "$maxWidth": maxWidth, children: _jsx(StyledToppyText, { title: titleTooltip || undefined, children: message }) }), _jsx(StyledToppyImage, { src: Toppy, alt: "Toppy", draggable: false, onMouseDown: (e) => e.stopPropagation() })] }));
41
42
  };
42
43
  export default TMToppyMessage;
@@ -6,10 +6,7 @@ export interface RowData {
6
6
  [key: string]: string | number | null;
7
7
  }
8
8
  export declare const associateColumnsToRows: (columns: Array<DataColumnDescriptor> | undefined, rows: Array<Array<string>> | undefined) => Array<RowData>;
9
- export declare const buildValueToLabelMapFromDataColumns: (columns: Array<DataColumnDescriptor>) => Promise<{
10
- valueToNameMap: Map<string, string>;
11
- captions: Set<string>;
12
- }>;
9
+ export declare const buildValueToLabelMapFromDataColumns: (columns: Array<DataColumnDescriptor>) => Promise<Map<string, Map<string, string>>>;
13
10
  export declare const getAvatarColor: (name: string) => string;
14
11
  export declare const extractInitialsFromName: (name: string) => string;
15
12
  export declare const SIGN4_TOP_WIDGET_ID = "60003";
@@ -26,4 +23,45 @@ export declare const StyledTabItem: import("styled-components/dist/types").IStyl
26
23
  export declare const StyledTabIcon: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, TabItemProps>> & string;
27
24
  export declare const TMCountBadge: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
28
25
  export declare const getPdgsIconMap: (fontSize?: number) => Map<PdGs, JSX.Element>;
26
+ /**
27
+ * Analizza e configura i parametri delle informazioni di firma per un documento.
28
+ *
29
+ * @param did - ID del documento
30
+ * @param informationSign - Stringa di configurazione della firma
31
+ * @param firstName - Nome del firmatario
32
+ * @param lastName - Cognome del firmatario
33
+ * @param title - Titolo del documento (per messaggi di errore)
34
+ *
35
+ * @returns Oggetto contenente le configurazioni dei campi della firma
36
+ *
37
+ * @example
38
+ * // Formati supportati:
39
+ *
40
+ * // 1. Configurazione predefinita (vuoto o undefined): solo data attiva
41
+ * parseSignatureConfiguration(1, undefined, "Mario", "Rossi", "Doc1")
42
+ *
43
+ * // 2. "All" - Tutti i campi attivi con valori di default
44
+ * parseSignatureConfiguration(1, "All", "Mario", "Rossi", "Doc1")
45
+ *
46
+ * // 3. "None" - Nessun campo attivo
47
+ * parseSignatureConfiguration(1, "None", "Mario", "Rossi", "Doc1")
48
+ *
49
+ * // 4. Formato con valori espliciti: Key=Value
50
+ * parseSignatureConfiguration(1, "Date=Yes,SignerBy=Mario,Location=Milano,Copyright=TopConsult", ...)
51
+ *
52
+ * // 5. Formato chiavi semplici (attiva i default): key1,key2,key3
53
+ * parseSignatureConfiguration(1, "date,signerby,location", "Mario", "Rossi", "Doc1")
54
+ *
55
+ * // 6. Formato misto
56
+ * parseSignatureConfiguration(1, "date,SignerBy=Yes,Location=Roma", "Mario", "Rossi", "Doc1")
57
+ */
58
+ export declare const parseSignatureConfiguration: (did: number, informationSign: string | undefined | null, firstName: string | undefined | null, lastName: string | undefined | null, title: string | undefined | null) => {
59
+ allowDate: boolean;
60
+ allowSignerBy: boolean;
61
+ signerByValue: string;
62
+ allowLocation: boolean;
63
+ locationValue: string;
64
+ allowCopyright: boolean;
65
+ copyrightValue: string;
66
+ };
29
67
  export {};
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styled from "styled-components";
3
3
  import { TMTooltip } from '../components';
4
- import { IconKey } from './TMIcons';
4
+ import { IconCADossier, IconKey, IconMenuCAWorkingGroups } from './TMIcons';
5
5
  import { DataListCacheService, MetadataDataDomains, PdGs } from '@topconsultnpm/sdk-ts';
6
6
  import { SDKUI_Localizator } from './SDKUI_Localizator';
7
7
  const StyledIconFileContainer = styled.div `
@@ -119,23 +119,27 @@ export const associateColumnsToRows = (columns, rows) => {
119
119
  };
120
120
  export const buildValueToLabelMapFromDataColumns = async (columns) => {
121
121
  const valueToNameMap = new Map();
122
- const captions = new Set();
123
- for (const col of columns) {
124
- const dataDomain = MetadataDataDomains[(col.extendedProperties?.["DataDomain"] ?? "None")];
122
+ const dataListColumns = columns.filter(col => {
123
+ const dataDomainRaw = col.extendedProperties?.["DataDomain"];
124
+ const dataDomain = MetadataDataDomains[(dataDomainRaw ?? "None")];
125
+ return dataDomain === MetadataDataDomains.DataList;
126
+ });
127
+ for (const col of dataListColumns) {
128
+ const tid = Number(col.extendedProperties?.["TID"]);
129
+ const mid = Number(col.extendedProperties?.["MID"]);
125
130
  const dataListID = Number(col.extendedProperties?.["DataListID"]);
126
- if (dataDomain === MetadataDataDomains.DataList) {
127
- if (col.caption) {
128
- captions.add(col.caption);
129
- }
131
+ if (tid && mid && dataListID) {
132
+ const tid_mid = `${tid}_${mid}`;
133
+ valueToNameMap.set(tid_mid, new Map());
130
134
  const dl = await DataListCacheService.GetAsync(dataListID);
131
135
  dl?.items?.forEach((item) => {
132
136
  if (item?.name !== undefined && item?.value !== undefined) {
133
- valueToNameMap.set(item.value, item.name);
137
+ valueToNameMap.get(tid_mid)?.set(item.value, item.name);
134
138
  }
135
139
  });
136
140
  }
137
141
  }
138
- return { valueToNameMap, captions };
142
+ return valueToNameMap;
139
143
  };
140
144
  export const getAvatarColor = (name) => {
141
145
  const colors = [
@@ -197,21 +201,184 @@ export const StyledTabIcon = styled.i `
197
201
  transition: color 0.2s ease;
198
202
  `;
199
203
  export const TMCountBadge = styled.div ` background-color: #ff5252; color: white; border-radius: 999px; margin-left: 8px; font-size: 0.7rem; line-height: 1; min-height: 20px; min-width: 20px; display: flex ; align-items: center; justify-content: center; `;
200
- const taskPdgsIconClassMap = () => {
201
- return new Map([
202
- [PdGs.None, ""],
203
- [PdGs.CF, "dx-icon-folder"],
204
- [PdGs.DT, "dx-icon-file"],
205
- [PdGs.WF, "dx-icon-box"],
206
- [PdGs.WG, "dx-icon-group"],
207
- ]);
208
- };
209
204
  export const getPdgsIconMap = (fontSize = 20) => {
210
205
  return new Map([
211
206
  [PdGs.None, _jsx("span", {}, "PdGs-None")],
212
- [PdGs.CF, _jsx("i", { style: { fontSize }, className: taskPdgsIconClassMap().get(PdGs.CF) }, "PdGs-CF")],
213
- [PdGs.DT, _jsx("i", { style: { fontSize }, className: taskPdgsIconClassMap().get(PdGs.DT) }, "PdGs-DT")],
214
- [PdGs.WF, _jsx("i", { style: { fontSize }, className: taskPdgsIconClassMap().get(PdGs.WF) }, "PdGs-WF")],
215
- [PdGs.WG, _jsx("i", { style: { fontSize }, className: taskPdgsIconClassMap().get(PdGs.WG) }, "PdGs-WG")], // <IconUserGroup color="#009700"/>
207
+ [PdGs.CF, _jsx(IconCADossier, { color: "#e65b00", fontSize: 28 }, "PdGs-CF")],
208
+ [PdGs.DT, _jsx("i", { style: { fontSize, color: '#b38600' }, className: "dx-icon-file" }, "PdGs-DT")],
209
+ [PdGs.WF, _jsx("i", { style: { fontSize }, className: "dx-icon-box" }, "PdGs-WF")],
210
+ [PdGs.WG, _jsx(IconMenuCAWorkingGroups, { color: "#009700", fontSize: 28 }, "PdGs-WG")],
216
211
  ]);
217
212
  };
213
+ /**
214
+ * Analizza e configura i parametri delle informazioni di firma per un documento.
215
+ *
216
+ * @param did - ID del documento
217
+ * @param informationSign - Stringa di configurazione della firma
218
+ * @param firstName - Nome del firmatario
219
+ * @param lastName - Cognome del firmatario
220
+ * @param title - Titolo del documento (per messaggi di errore)
221
+ *
222
+ * @returns Oggetto contenente le configurazioni dei campi della firma
223
+ *
224
+ * @example
225
+ * // Formati supportati:
226
+ *
227
+ * // 1. Configurazione predefinita (vuoto o undefined): solo data attiva
228
+ * parseSignatureConfiguration(1, undefined, "Mario", "Rossi", "Doc1")
229
+ *
230
+ * // 2. "All" - Tutti i campi attivi con valori di default
231
+ * parseSignatureConfiguration(1, "All", "Mario", "Rossi", "Doc1")
232
+ *
233
+ * // 3. "None" - Nessun campo attivo
234
+ * parseSignatureConfiguration(1, "None", "Mario", "Rossi", "Doc1")
235
+ *
236
+ * // 4. Formato con valori espliciti: Key=Value
237
+ * parseSignatureConfiguration(1, "Date=Yes,SignerBy=Mario,Location=Milano,Copyright=TopConsult", ...)
238
+ *
239
+ * // 5. Formato chiavi semplici (attiva i default): key1,key2,key3
240
+ * parseSignatureConfiguration(1, "date,signerby,location", "Mario", "Rossi", "Doc1")
241
+ *
242
+ * // 6. Formato misto
243
+ * parseSignatureConfiguration(1, "date,SignerBy=Yes,Location=Roma", "Mario", "Rossi", "Doc1")
244
+ */
245
+ export const parseSignatureConfiguration = (did, informationSign, firstName, lastName, title) => {
246
+ try {
247
+ // Rimuove spazi dalla stringa di input mantenendo il case originale
248
+ const signatureSign = informationSign?.trim();
249
+ // Definisce i valori di default per ciascun campo
250
+ const defaultLocationValue = SDKUI_Localizator.Torino;
251
+ const defaultCopyrightValue = "Sign4Top";
252
+ const defaultSignerByValue = `${firstName ?? ''} ${lastName ?? ''}`.trim() || '';
253
+ // Configurazione di default: solo data attiva
254
+ const defaultInfo = {
255
+ allowDate: true,
256
+ allowSignerBy: false,
257
+ signerByValue: defaultSignerByValue,
258
+ allowLocation: false,
259
+ locationValue: defaultLocationValue,
260
+ allowCopyright: false,
261
+ copyrightValue: defaultCopyrightValue
262
+ };
263
+ // Se la stringa è vuota o non definita, ritorna la configurazione di default
264
+ if (!signatureSign || signatureSign.length === 0) {
265
+ return defaultInfo;
266
+ }
267
+ // Caso speciale: "all" attiva tutti i campi con valori di default
268
+ if (signatureSign.toLowerCase() === "all") {
269
+ return {
270
+ allowDate: true,
271
+ allowSignerBy: true,
272
+ signerByValue: defaultSignerByValue,
273
+ allowLocation: true,
274
+ locationValue: defaultLocationValue,
275
+ allowCopyright: true,
276
+ copyrightValue: defaultCopyrightValue
277
+ };
278
+ }
279
+ // Caso speciale: "none" disattiva tutti i campi
280
+ if (signatureSign.toLowerCase() === "none") {
281
+ return {
282
+ allowDate: false,
283
+ allowSignerBy: false,
284
+ signerByValue: defaultSignerByValue,
285
+ allowLocation: false,
286
+ locationValue: defaultLocationValue,
287
+ allowCopyright: false,
288
+ copyrightValue: defaultCopyrightValue
289
+ };
290
+ }
291
+ // Chiavi ammesse per la configurazione
292
+ const allowedKeys = ["date", "signerby", "location", "copyright"];
293
+ // Suddivisione della stringa in parti separate da virgola
294
+ const infoParts = signatureSign.split(',').map(part => part.trim()).filter(Boolean);
295
+ // Validazione preventiva di tutte le chiavi
296
+ const invalidKeys = [];
297
+ for (const part of infoParts) {
298
+ const [key] = part.split("=");
299
+ const currentKey = key.trim().toLowerCase();
300
+ if (!allowedKeys.includes(currentKey)) {
301
+ invalidKeys.push(key.trim());
302
+ }
303
+ }
304
+ // Se ci sono chiavi non valide, lancia un errore unico
305
+ if (invalidKeys.length > 0) {
306
+ throw new Error(`${invalidKeys.length > 1 ? 'I parametri' : 'Il parametro'} "${invalidKeys.join('", "')}" non ${invalidKeys.length > 1 ? 'sono riconosciuti' : 'è riconosciuto'} nel campo "informationSign" per il documento "${title || did}". ` +
307
+ `I parametri ammessi sono: ${allowedKeys.join(", ")}. ` +
308
+ `Il valore attuale del campo è "${informationSign}"`);
309
+ }
310
+ // Clone della configurazione di default per la modifica
311
+ const info = { ...defaultInfo };
312
+ // Itera su ogni parte della configurazione
313
+ for (const part of infoParts) {
314
+ const [key, ...valueParts] = part.split("=");
315
+ const currentKey = key.trim().toLowerCase();
316
+ // Ricostruisce il valore nel caso contenga "=" al suo interno
317
+ const rawValue = valueParts.join("=").trim();
318
+ // Rimuove le virgolette dall'inizio e dalla fine del valore
319
+ const currentValue = rawValue.replace(/^["']|["']$/g, "");
320
+ // Helper per gestire i valori booleani e custom
321
+ const parseBooleanOrValue = (value) => {
322
+ const valueLower = value.toLowerCase();
323
+ if (valueLower === "no" || valueLower === "false")
324
+ return { enabled: false };
325
+ if (valueLower === "yes" || valueLower === "true" || !value)
326
+ return { enabled: true };
327
+ return { enabled: true, customValue: value };
328
+ };
329
+ // Processa ciascuna chiave in base al tipo
330
+ if (part.includes("=")) {
331
+ // Formato: Key=Value
332
+ switch (currentKey) {
333
+ case "date":
334
+ // Data supporta solo Yes/No/True/False
335
+ const dateLower = currentValue.toLowerCase();
336
+ info.allowDate = dateLower === "yes" || dateLower === "true";
337
+ break;
338
+ case "signerby": {
339
+ const parsed = parseBooleanOrValue(currentValue);
340
+ info.allowSignerBy = parsed.enabled;
341
+ info.signerByValue = parsed.customValue || defaultSignerByValue;
342
+ break;
343
+ }
344
+ case "location": {
345
+ const parsed = parseBooleanOrValue(currentValue);
346
+ info.allowLocation = parsed.enabled;
347
+ info.locationValue = parsed.customValue || defaultLocationValue;
348
+ break;
349
+ }
350
+ case "copyright": {
351
+ const parsed = parseBooleanOrValue(currentValue);
352
+ info.allowCopyright = parsed.enabled;
353
+ info.copyrightValue = parsed.customValue || defaultCopyrightValue;
354
+ break;
355
+ }
356
+ }
357
+ }
358
+ else {
359
+ // Formato: Key (attiva il campo con valore di default)
360
+ switch (currentKey) {
361
+ case "date":
362
+ info.allowDate = true;
363
+ break;
364
+ case "signerby":
365
+ info.allowSignerBy = true;
366
+ info.signerByValue = defaultSignerByValue;
367
+ break;
368
+ case "location":
369
+ info.allowLocation = true;
370
+ info.locationValue = defaultLocationValue;
371
+ break;
372
+ case "copyright":
373
+ info.allowCopyright = true;
374
+ info.copyrightValue = defaultCopyrightValue;
375
+ break;
376
+ }
377
+ }
378
+ }
379
+ return info;
380
+ }
381
+ catch (error) {
382
+ throw error;
383
+ }
384
+ };
@@ -4,4 +4,5 @@ export declare const hasDetailRelations: (mTID: number | undefined) => Promise<b
4
4
  /** Check if dcmtType (mTID) has configured Master or Many-to-Many relations */
5
5
  export declare const hasMasterRelations: (mTID: number | undefined) => Promise<boolean>;
6
6
  export declare const isXMLFileExt: (fileExt: string | undefined) => boolean;
7
- export declare const processButtonAttributes: (args: string | undefined, formData: MetadataValueDescriptorEx[] | undefined) => Record<string, string | number> | undefined;
7
+ export declare const getButtonAttributes: (args: string | undefined, formData: MetadataValueDescriptorEx[] | undefined, selectedItems: Array<any> | undefined) => Record<string, any> | undefined;
8
+ export declare const getSelectedItem: (args: string | undefined, formData: MetadataValueDescriptorEx[] | undefined, item: any) => Record<string, any> | undefined;
@@ -1,4 +1,4 @@
1
- import { RelationCacheService, RelationTypes } from "@topconsultnpm/sdk-ts";
1
+ import { RelationCacheService, RelationTypes, SDK_Globals } from "@topconsultnpm/sdk-ts";
2
2
  /** Check if dcmtType (mTID) has configured Detail or Many-to-Many relations */
3
3
  export const hasDetailRelations = async (mTID) => {
4
4
  let allRelations = await RelationCacheService.GetAllAsync();
@@ -24,20 +24,59 @@ export const isXMLFileExt = (fileExt) => {
24
24
  }
25
25
  };
26
26
  /*utility functions for TMCustomButton*/
27
- export const processButtonAttributes = (args, formData) => args && formData ? splitArguments(replaceCustomButtonAttributes(args, formDataMap(formData))) : undefined;
28
- const replaceCustomButtonAttributes = (input, attributes) => {
29
- const matches = Array.from(input.matchAll(/@\w+/g));
30
- return matches
31
- .map(([match]) => `${match}=${attributes[match.slice(1)] ?? ''}`)
32
- .join(';') + ';';
27
+ export const getButtonAttributes = (args, formData, selectedItems) => args && formData ? formDataMap(formData, args, selectedItems) : undefined;
28
+ const getSelectedItems = (selectedItems) => selectedItems && selectedItems.map(item => item["DID"]) || [];
29
+ export const getSelectedItem = (args, formData, item) => {
30
+ //converto item in formData
31
+ const formDataConverted = [];
32
+ for (const key in item) {
33
+ const md = formData?.find(md => `${item["TID"]}_${md.mid}` === key);
34
+ if (md) { // aggiungo solo i metadati
35
+ const name = md.md?.name || "";
36
+ formDataConverted.push({ md: { name: name }, value: item[key] });
37
+ }
38
+ }
39
+ return args && formDataConverted ?
40
+ formDataMap(formDataConverted, args, []) : undefined;
41
+ };
42
+ const formDataMap = (data, args, selectedItems) => {
43
+ const session = SDK_Globals.tmSession;
44
+ const sessionDescr = session?.SessionDescr;
45
+ const result = {};
46
+ // Helper per estrarre il valore di un campo
47
+ const getParamValue = (fieldName) => {
48
+ const md = data.find(md => md.md?.name === fieldName);
49
+ switch (fieldName) {
50
+ case 'SelectedDIDs': return getSelectedItems(selectedItems);
51
+ case 'AuthenticationMode': return sessionDescr?.authenticationMode ?? null;
52
+ case 'ArchiveID': return sessionDescr?.archiveID ?? null;
53
+ case 'CultureID': return sessionDescr?.cultureID ?? null;
54
+ case 'Domain': return sessionDescr?.domain ?? null;
55
+ case 'UserID': return sessionDescr?.userID ?? null;
56
+ case 'UserName': return sessionDescr?.userName ?? null;
57
+ case 'Session': return session ?? null;
58
+ default: return md?.value;
59
+ }
60
+ };
61
+ // Regex per catturare: chiave=[...] o chiave={...} o {@campo}
62
+ const keyValueRegex = /(\w+)=\[([^\]]+)\]|(\w+)=\{@?([^}]+)\}|\{@([^}]+)\}/g;
63
+ for (const match of args.matchAll(keyValueRegex)) {
64
+ if (match[1]) {
65
+ // Formato: chiave=[{@campo} testo {@campo} ...]
66
+ const key = match[1];
67
+ const content = match[2].replace(/\{@([^}]+)\}/g, (_, fieldName) => data.find(md => md.md?.name === fieldName)?.value ?? '');
68
+ result[key] = content;
69
+ }
70
+ else if (match[3]) {
71
+ // Formato: chiave={@campo} o chiave={valore}
72
+ const key = match[3];
73
+ const value = match[4];
74
+ result[key] = value.startsWith('@') ? getParamValue(value.substring(1)) : value;
75
+ }
76
+ else if (match[5]) {
77
+ // Formato: {@campo}
78
+ result[match[5]] = getParamValue(match[5]);
79
+ }
80
+ }
81
+ return result;
33
82
  };
34
- const formDataMap = (data) => data.reduce((acc, md) => {
35
- const key = md.md?.name;
36
- if (key && md.value)
37
- acc[key] = md.value;
38
- return acc;
39
- }, {});
40
- const splitArguments = (input) => Object.fromEntries(Array.from(input.matchAll(/@?(\w+)=([^;]+)/g), ([, key, value]) => [
41
- key,
42
- isNaN(Number(value)) ? value : Number(value),
43
- ]));
@@ -6,7 +6,7 @@ declare const TABLET_WIDTH = 1024;
6
6
  declare const MOBILE_WIDTH = 640;
7
7
  declare const calcResponsiveDirection: (deviceType: DeviceType, desktopDir: "horizontal" | "vertical", tabletDir: "horizontal" | "vertical", mobileDir: "horizontal" | "vertical") => "horizontal" | "vertical";
8
8
  declare const openApps: (appModule: AppModules, tmSession: ITopMediaSession, appRoutes?: any[]) => Promise<void>;
9
- export declare const setSDK_GlobalsInfoAsync: (tms: ITopMediaSession | undefined) => Promise<ITopMediaSession>;
9
+ export declare const setSDK_GlobalsInfoAsync: (tms: ITopMediaSession | undefined) => Promise<ITopMediaSession | undefined>;
10
10
  declare const calcResponsiveSizes: (deviceType: DeviceType | undefined, desktopSize: string, tabletSize: string, mobileSize: string) => string;
11
11
  declare const getColor: (color: ColorsType) => string;
12
12
  /**
@@ -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, SystemMIDs, SystemMIDsAsNumber, TopMediaServer } from "@topconsultnpm/sdk-ts";
4
+ import { AccessLevels, MetadataDataDomains, MetadataDataTypes, MetadataDescriptor, MetadataFormatDescriptor, MetadataFormats, MetadataPermission, SDK_Globals, SetGlobalsInfoAsync, SystemMIDs, SystemMIDsAsNumber, TopMediaServer } 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";
@@ -37,22 +37,13 @@ const openApps = async (appModule, tmSession, appRoutes) => {
37
37
  }
38
38
  };
39
39
  export const setSDK_GlobalsInfoAsync = async (tms) => {
40
- const tmServer = new TopMediaServer(tms?.TopMediaServer?.BaseAddress);
41
- const tmSessionNew = tmServer?.NewSession();
42
- if (tmSessionNew) {
43
- tmSessionNew.SessionDescr = tms?.SessionDescr;
44
- }
45
- SDK_Globals.tmSession = tmSessionNew;
46
- SDK_Globals.tmSession.AutoRefresh = true;
47
- if (SDK_Globals.license == undefined) {
48
- try {
49
- SDK_Globals.license = await tmSessionNew.NewLicenseEngine().RetrieveAsync();
50
- }
51
- catch (e) {
52
- TMExceptionBoxManager.show({ title: 'Errore caricamento licenza', exception: e });
53
- }
40
+ try {
41
+ return await SetGlobalsInfoAsync(tms);
42
+ }
43
+ catch (e) {
44
+ TMExceptionBoxManager.show({ exception: e.message });
45
+ return undefined;
54
46
  }
55
- return tmSessionNew;
56
47
  };
57
48
  const calcResponsiveSizes = (deviceType, desktopSize, tabletSize, mobileSize) => {
58
49
  if (deviceType === DeviceType.DESKTOP)
@@ -480,6 +471,9 @@ export const extensionHandler = (fileExt) => {
480
471
  case 'xml.p7m.tsd': return FileExtensionHandler.READY_TO_SHOW;
481
472
  case 'pdf': return FileExtensionHandler.READY_TO_SHOW;
482
473
  case 'txt': return FileExtensionHandler.READY_TO_SHOW;
474
+ case 'config':
475
+ case 'cfg':
476
+ case 'json': return FileExtensionHandler.READY_TO_SHOW;
483
477
  default: return FileExtensionHandler.NONE;
484
478
  }
485
479
  };
@@ -633,7 +627,8 @@ export const highlightText = (text, searchValue) => {
633
627
  export const renderHighlightedText = (text, searchText, isSelected) => {
634
628
  if (!searchText)
635
629
  return text;
636
- const regex = new RegExp(`(${searchText})`, 'gi');
630
+ const escapedSearchText = searchText.trim().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
631
+ const regex = new RegExp(`(${escapedSearchText})`, 'gi');
637
632
  return text.split(regex).map((part, index) => regex.test(part) ? (_jsx("span", { style: { backgroundColor: isSelected ? '#6c9023' : 'yellow' }, children: part }, index)) : (part));
638
633
  };
639
634
  export function versionAndBuildtypeInfo(module) {
@@ -10,3 +10,4 @@ export * from './TMUtils';
10
10
  export * from './TMCommandsContextMenu';
11
11
  export * from './TMConditionalWrapper';
12
12
  export * from './TMToppyMessage';
13
+ export * from './GlobalStyles';
@@ -10,3 +10,4 @@ export * from './TMUtils';
10
10
  export * from './TMCommandsContextMenu';
11
11
  export * from './TMConditionalWrapper';
12
12
  export * from './TMToppyMessage';
13
+ export * from './GlobalStyles';
@@ -12,7 +12,7 @@ export declare function useDcmtOperations(): {
12
12
  waitPanelTextSecondary: string;
13
13
  waitPanelValueSecondary: number;
14
14
  waitPanelMaxValueSecondary: number;
15
- downloadDcmtsAsync: (inputDcmts: DcmtInfo[] | undefined, downloadType?: DownloadTypes, downloadMode?: DownloadModes, onFileDownloaded?: (dcmtFile: File) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>) => Promise<void>;
15
+ downloadDcmtsAsync: (inputDcmts: DcmtInfo[] | undefined, downloadType?: DownloadTypes, downloadMode?: DownloadModes, onFileDownloaded?: (dcmtFile: File) => void, confirmAttachments?: (list: FileDescriptor[]) => Promise<string[] | undefined>, skipConfirmation?: boolean) => Promise<void>;
16
16
  getDcmtFileAsync: (inputDcmt: DcmtInfo | undefined, rfo: RetrieveFileOptions, operationTitle: string, keepWaitPanelPrimary: boolean, bypassCache?: boolean) => Promise<{
17
17
  file: File | undefined;
18
18
  isFromCache: boolean;
@@ -20,12 +20,15 @@ export function useDcmtOperations() {
20
20
  const [waitPanelValueSecondary, setWaitPanelValueSecondary] = useState(0);
21
21
  const [waitPanelMaxValueSecondary, setWaitPanelMaxValueSecondary] = useState(0);
22
22
  const { OpenFileDialog } = useFileDialog();
23
- const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded) => {
23
+ const _downloadDcmtsAsync = async (inputDcmts, downloadMode = "download", onFileDownloaded, skipConfirmation = false) => {
24
24
  if (inputDcmts === undefined)
25
25
  return;
26
26
  if (inputDcmts.length <= 0)
27
27
  return;
28
- if (inputDcmts.length === 1 && downloadMode === "openInNewWindow") {
28
+ const fileExtLower = inputDcmts[0]?.FILEEXT?.toLowerCase();
29
+ const needsForceDownload = fileExtLower?.includes('p7m') || fileExtLower === 'msg';
30
+ const shouldShowConfirm = !skipConfirmation;
31
+ if (inputDcmts.length === 1 && shouldShowConfirm && (downloadMode === "openInNewWindow" || (downloadMode === "download" && needsForceDownload))) {
29
32
  if (!inputDcmts[0].FILEEXT)
30
33
  return;
31
34
  let readyToShow = extensionHandler(inputDcmts[0].FILEEXT) === FileExtensionHandler.READY_TO_SHOW;
@@ -93,7 +96,8 @@ export function useDcmtOperations() {
93
96
  else {
94
97
  const alink2 = document.createElement('a');
95
98
  alink2.href = fileURL;
96
- alink2.download = inputDcmts[i].fileName ?? file?.name;
99
+ const downloadFileName = inputDcmts[i].fileName ?? (inputDcmts[i].FILEEXT ? `${inputDcmts[i].DID}.${inputDcmts[i].FILEEXT}` : file?.name);
100
+ alink2.download = downloadFileName;
97
101
  alink2.target = "_blank";
98
102
  alink2.rel = "noreferrer";
99
103
  alink2.click();
@@ -182,11 +186,11 @@ export function useDcmtOperations() {
182
186
  TMExceptionBoxManager.show({ exception: err });
183
187
  }
184
188
  };
185
- const downloadDcmtsAsync = async (inputDcmts, downloadType = DownloadTypes.Attachment, downloadMode = "download", onFileDownloaded, confirmAttachments) => {
189
+ const downloadDcmtsAsync = async (inputDcmts, downloadType = DownloadTypes.Attachment, downloadMode = "download", onFileDownloaded, confirmAttachments, skipConfirmation = false) => {
186
190
  switch (downloadType) {
187
- case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded);
191
+ case DownloadTypes.Dcmt: return await _downloadDcmtsAsync(inputDcmts, downloadMode, onFileDownloaded, skipConfirmation);
188
192
  case DownloadTypes.Attachment: return await _downloadAttachmentsAsync(inputDcmts, confirmAttachments);
189
- default: return await _downloadDcmtsAsync(inputDcmts);
193
+ default: return await _downloadDcmtsAsync(inputDcmts, undefined, undefined, skipConfirmation);
190
194
  }
191
195
  };
192
196
  const uploadDcmtsAsync = async (inputDcmts, operationTitle, operType, actionAfterOperationAsync) => {