@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.
- package/lib/components/base/TMAccordionNew.d.ts +28 -0
- package/lib/components/base/TMAccordionNew.js +326 -0
- package/lib/components/base/TMButton.d.ts +1 -0
- package/lib/components/base/TMButton.js +6 -6
- package/lib/components/base/TMCustomButton.d.ts +1 -1
- package/lib/components/base/TMCustomButton.js +83 -28
- package/lib/components/base/TMDataGridExportForm.js +9 -3
- package/lib/components/base/TMFileManager.js +11 -2
- package/lib/components/base/TMFileManagerDataGridView.d.ts +2 -0
- package/lib/components/base/TMFileManagerDataGridView.js +12 -3
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +2 -0
- package/lib/components/base/TMFileManagerThumbnailItems.js +12 -2
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +2 -0
- package/lib/components/base/TMFileManagerThumbnailsView.js +2 -2
- package/lib/components/base/TMModal.d.ts +2 -0
- package/lib/components/base/TMModal.js +48 -3
- package/lib/components/base/TMPopUp.js +74 -5
- package/lib/components/base/TMWaitPanel.js +8 -2
- package/lib/components/choosers/TMDataListItemChooser.js +1 -1
- package/lib/components/choosers/TMDcmtTypeChooser.js +2 -2
- package/lib/components/choosers/TMMetadataChooser.d.ts +4 -1
- package/lib/components/choosers/TMMetadataChooser.js +31 -8
- package/lib/components/choosers/TMUserChooser.d.ts +4 -0
- package/lib/components/choosers/TMUserChooser.js +21 -5
- package/lib/components/editors/TMMetadataValues.js +45 -4
- package/lib/components/editors/TMTextArea.d.ts +1 -0
- package/lib/components/editors/TMTextArea.js +44 -10
- package/lib/components/editors/TMTextBox.js +34 -4
- package/lib/components/editors/TMTextExpression.js +36 -28
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +30 -0
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +471 -0
- package/lib/components/features/assistant/ToppySpeechBubble.d.ts +9 -0
- package/lib/components/features/assistant/ToppySpeechBubble.js +117 -0
- package/lib/components/features/blog/TMBlogCommentForm.d.ts +2 -0
- package/lib/components/features/blog/TMBlogCommentForm.js +18 -6
- package/lib/components/features/documents/TMDcmtBlog.js +1 -1
- package/lib/components/features/documents/TMDcmtForm.js +290 -31
- package/lib/components/features/documents/TMDcmtIcon.js +9 -4
- package/lib/components/features/documents/TMDcmtPreview.js +45 -8
- package/lib/components/features/documents/TMRelationViewer.js +55 -22
- package/lib/components/features/search/TMSearch.js +2 -2
- package/lib/components/features/search/TMSearchQueryEditor.js +1 -1
- package/lib/components/features/search/TMSearchQueryPanel.js +10 -28
- package/lib/components/features/search/TMSearchResult.js +102 -33
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +2 -1
- package/lib/components/features/search/TMSearchResultsMenuItems.js +67 -28
- package/lib/components/features/search/TMSignSettingsForm.d.ts +9 -0
- package/lib/components/features/search/TMSignSettingsForm.js +621 -0
- package/lib/components/features/tasks/TMTaskForm.js +10 -4
- package/lib/components/features/tasks/TMTasksAgenda.js +1 -1
- package/lib/components/features/tasks/TMTasksCalendar.js +1 -1
- package/lib/components/features/tasks/TMTasksUtils.d.ts +1 -0
- package/lib/components/features/tasks/TMTasksUtils.js +17 -2
- package/lib/components/features/tasks/TMTasksUtilsView.js +26 -4
- package/lib/components/features/tasks/TMTasksView.js +11 -5
- package/lib/components/features/workflow/TMWorkflowPopup.js +3 -3
- package/lib/components/features/workflow/diagram/WFDiagram.js +19 -1
- package/lib/components/forms/TMSaveForm.js +3 -11
- package/lib/components/grids/TMBlogAttachments.d.ts +0 -14
- package/lib/components/grids/TMBlogAttachments.js +10 -5
- package/lib/components/grids/TMBlogsPost.d.ts +8 -3
- package/lib/components/grids/TMBlogsPost.js +100 -39
- package/lib/components/grids/TMBlogsPostUtils.d.ts +1 -0
- package/lib/components/grids/TMBlogsPostUtils.js +27 -6
- package/lib/components/index.d.ts +2 -1
- package/lib/components/index.js +2 -1
- package/lib/components/layout/panelManager/TMPanelManagerContainer.d.ts +1 -0
- package/lib/components/layout/panelManager/TMPanelManagerContainer.js +2 -2
- package/lib/components/layout/panelManager/TMPanelManagerContext.js +0 -1
- package/lib/components/layout/panelManager/TMPanelManagerToolbar.js +2 -1
- package/lib/components/layout/panelManager/types.d.ts +1 -0
- package/lib/components/settings/SettingsAppearance.js +5 -5
- package/lib/helper/GlobalStyles.d.ts +2 -0
- package/lib/helper/GlobalStyles.js +10 -0
- package/lib/helper/Globalization.d.ts +1 -0
- package/lib/helper/Globalization.js +30 -0
- package/lib/helper/SDKUI_Localizator.d.ts +41 -1
- package/lib/helper/SDKUI_Localizator.js +410 -10
- package/lib/helper/TMIcons.d.ts +4 -1
- package/lib/helper/TMIcons.js +13 -1
- package/lib/helper/TMToppyMessage.d.ts +1 -0
- package/lib/helper/TMToppyMessage.js +4 -3
- package/lib/helper/TMUtils.d.ts +42 -4
- package/lib/helper/TMUtils.js +190 -23
- package/lib/helper/dcmtsHelper.d.ts +2 -1
- package/lib/helper/dcmtsHelper.js +56 -17
- package/lib/helper/helpers.d.ts +1 -1
- package/lib/helper/helpers.js +12 -17
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/hooks/useDcmtOperations.d.ts +1 -1
- package/lib/hooks/useDcmtOperations.js +10 -6
- package/lib/hooks/useRelatedDocuments.js +35 -26
- package/lib/ts/types.d.ts +2 -0
- package/package.json +8 -8
- package/lib/components/features/assistant/ToppyHelpCenter.d.ts +0 -12
- 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;
|
package/lib/helper/TMUtils.d.ts
CHANGED
|
@@ -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 {};
|
package/lib/helper/TMUtils.js
CHANGED
|
@@ -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
|
|
123
|
-
|
|
124
|
-
const dataDomain = MetadataDataDomains[(
|
|
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 (
|
|
127
|
-
|
|
128
|
-
|
|
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
|
|
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(
|
|
213
|
-
[PdGs.DT, _jsx("i", { style: { fontSize }, className:
|
|
214
|
-
[PdGs.WF, _jsx("i", { style: { fontSize }, className:
|
|
215
|
-
[PdGs.WG, _jsx(
|
|
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
|
|
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
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
]));
|
package/lib/helper/helpers.d.ts
CHANGED
|
@@ -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
|
/**
|
package/lib/helper/helpers.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Colors } from "../utils/theme";
|
|
3
3
|
import { ButtonNames, DeviceType, TMExceptionBoxManager, TMMessageBoxManager, TMSpinner } from "../components";
|
|
4
|
-
import { AccessLevels, MetadataDataDomains, MetadataDataTypes, MetadataDescriptor, MetadataFormatDescriptor, MetadataFormats, MetadataPermission, SDK_Globals, 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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
|
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) {
|
package/lib/helper/index.d.ts
CHANGED
package/lib/helper/index.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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) => {
|