@topconsultnpm/sdkui-react 6.22.0-dev1.9 → 6.22.0-dev2.2
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/TMDataGridExportForm.js +39 -30
- package/lib/components/base/TMModal.js +1 -1
- package/lib/components/choosers/TMDynDataListItemChooser.d.ts +2 -0
- package/lib/components/choosers/TMDynDataListItemChooser.js +4 -6
- package/lib/components/editors/TMDateBox.d.ts +16 -1
- package/lib/components/editors/TMDateBox.js +90 -22
- package/lib/components/editors/TMMetadataEditor.js +19 -20
- package/lib/components/editors/TMTextArea.d.ts +1 -0
- package/lib/components/editors/TMTextArea.js +23 -15
- package/lib/components/editors/TMTextBox.d.ts +2 -0
- package/lib/components/editors/TMTextBox.js +38 -22
- package/lib/components/features/documents/TMDcmtForm.d.ts +2 -1
- package/lib/components/features/documents/TMDcmtForm.js +107 -8
- package/lib/components/features/documents/TMRelationViewer.js +13 -32
- package/lib/components/features/search/TMSearch.d.ts +2 -1
- package/lib/components/features/search/TMSearch.js +2 -2
- package/lib/components/features/search/TMSearchResult.d.ts +2 -1
- package/lib/components/features/search/TMSearchResult.js +13 -40
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +4 -2
- package/lib/components/features/search/TMSignatureInfoContent.js +373 -79
- package/lib/components/forms/Login/TMLoginForm.d.ts +2 -0
- package/lib/components/forms/Login/TMLoginForm.js +17 -3
- package/lib/components/forms/Login/TextBox.d.ts +3 -0
- package/lib/components/forms/Login/TextBox.js +2 -2
- package/lib/components/pages/TMPage.js +3 -1
- package/lib/components/query/TMQueryEditor.js +1 -1
- package/lib/components/viewers/TMMidViewer.js +1 -1
- package/lib/helper/Globalization.d.ts +1 -1
- package/lib/helper/SDKUI_Globals.js +22 -2
- package/lib/helper/SDKUI_Localizator.d.ts +9 -0
- package/lib/helper/SDKUI_Localizator.js +90 -0
- package/lib/helper/TMUtils.d.ts +29 -1
- package/lib/helper/TMUtils.js +249 -10
- package/lib/helper/grafometricSignaturesCache.d.ts +45 -0
- package/lib/helper/grafometricSignaturesCache.js +56 -0
- package/lib/helper/index.d.ts +1 -0
- package/lib/helper/index.js +1 -0
- package/lib/hooks/useDocumentOperations.d.ts +2 -1
- package/lib/hooks/useDocumentOperations.js +15 -15
- package/lib/hooks/usePreventFileDrop.js +14 -3
- package/lib/ts/graphometricTypes.d.ts +62 -0
- package/lib/ts/graphometricTypes.js +1 -0
- package/lib/ts/index.d.ts +1 -0
- package/lib/ts/index.js +1 -0
- package/package.json +66 -61
|
@@ -1,43 +1,174 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
-
import { SDK_Globals } from "@topconsultnpm/sdk-ts";
|
|
4
|
-
import { IconCopy, getExceptionMessage, SDKUI_Localizator } from "../../../helper";
|
|
3
|
+
import { SDK_Globals, RetrieveFileOptions, DcmtOpers, GeneralRetrieveFormats } from "@topconsultnpm/sdk-ts";
|
|
4
|
+
import { IconCopy, IconDownload, IconWarning, IconCheck, getExceptionMessage, SDKUI_Localizator, IconCircleInfo, IconRefresh } from "../../../helper";
|
|
5
|
+
import { getGrafometricSignatures, putGrafometricSignatures, removeGrafometricSignatures } from "../../../helper/grafometricSignaturesCache";
|
|
6
|
+
import TMTooltip from "../../base/TMTooltip";
|
|
5
7
|
import TMSpinner from "../../base/TMSpinner";
|
|
8
|
+
import TMModal from "../../base/TMModal";
|
|
9
|
+
import { DeviceType, useDeviceType } from "../../base/TMDeviceProvider";
|
|
10
|
+
import { LoadIndicator } from "devextreme-react";
|
|
11
|
+
import { TMColors } from "../../../utils/theme";
|
|
12
|
+
import ShowAlert from "../../base/TMAlert";
|
|
6
13
|
const TMSignatureInfoContent = (props) => {
|
|
7
|
-
const { inputDcmt } = props;
|
|
14
|
+
const { inputDcmt, graphometricManager, onClose } = props;
|
|
15
|
+
/** Abilita la cache delle firme grafometriche */
|
|
16
|
+
const useGrafometricCache = false;
|
|
17
|
+
/** Abilita la visualizzazione della sezione firme grafometriche */
|
|
18
|
+
const showGrafometricSection = false;
|
|
19
|
+
const deviceType = useDeviceType();
|
|
20
|
+
const isMobile = deviceType === DeviceType.MOBILE;
|
|
8
21
|
const [selectedHash, setSelectedHash] = useState('sha256');
|
|
9
22
|
const [signerInfo, setSignerInfo] = useState(undefined);
|
|
10
23
|
const [error, setError] = useState(undefined);
|
|
11
24
|
const [copiedHash, setCopiedHash] = useState(false);
|
|
25
|
+
// Stati per firma grafometrica (firme con dati biometrici estratti dal PDF)
|
|
26
|
+
const [grafometricSignatures, setGrafometricSignatures] = useState([]);
|
|
27
|
+
const [grafometricError, setGrafometricError] = useState(undefined);
|
|
28
|
+
const [isDataReady, setIsDataReady] = useState(false);
|
|
29
|
+
// Stati per gestire il caricamento on-demand delle firme grafometriche
|
|
30
|
+
const [isGrafometricRequested, setIsGrafometricRequested] = useState(false);
|
|
31
|
+
const [isGrafometricLoading, setIsGrafometricLoading] = useState(false);
|
|
32
|
+
// Caricamento iniziale: recupera solo signerInfo
|
|
33
|
+
// Le firme grafometriche vengono caricate on-demand tramite pulsante (o dalla cache se disponibili)
|
|
12
34
|
useEffect(() => {
|
|
13
35
|
const fetchSignerInfo = async () => {
|
|
36
|
+
const ue = SDK_Globals.tmSession?.NewUpdateEngineByID();
|
|
37
|
+
if (!ue) {
|
|
38
|
+
setError("Sessione non disponibile");
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
ue.TID = inputDcmt.TID;
|
|
42
|
+
ue.DID = inputDcmt.DID;
|
|
43
|
+
const signerInfoDescriptor = await ue.GetSignersAsync();
|
|
44
|
+
if (!signerInfoDescriptor) {
|
|
45
|
+
setError("Informazioni di firma non disponibili");
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
return signerInfoDescriptor;
|
|
49
|
+
};
|
|
50
|
+
const loadSignerInfo = async () => {
|
|
14
51
|
TMSpinner.show();
|
|
52
|
+
setIsDataReady(false);
|
|
53
|
+
setError(undefined);
|
|
54
|
+
// Reset stati grafometrici quando cambia il documento
|
|
55
|
+
setGrafometricError(undefined);
|
|
56
|
+
setGrafometricSignatures([]);
|
|
57
|
+
setIsGrafometricRequested(false);
|
|
15
58
|
try {
|
|
16
|
-
const
|
|
17
|
-
if (!ue) {
|
|
18
|
-
setError("Sessione non disponibile");
|
|
19
|
-
TMSpinner.hide();
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
ue.TID = inputDcmt.TID;
|
|
23
|
-
ue.DID = inputDcmt.DID;
|
|
24
|
-
const signerInfoDescriptor = await ue.GetSignersAsync();
|
|
25
|
-
if (!signerInfoDescriptor) {
|
|
26
|
-
setError("Informazioni di firma non disponibili");
|
|
27
|
-
TMSpinner.hide();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
59
|
+
const signerInfoDescriptor = await fetchSignerInfo();
|
|
30
60
|
setSignerInfo(signerInfoDescriptor);
|
|
31
|
-
|
|
32
|
-
|
|
61
|
+
// Controlla se ci sono firme grafometriche in cache per questo documento
|
|
62
|
+
if (useGrafometricCache && graphometricManager && inputDcmt.FILEEXT?.toLowerCase() === "pdf") {
|
|
63
|
+
const cachedSignatures = getGrafometricSignatures(inputDcmt.TID, inputDcmt.DID);
|
|
64
|
+
if (cachedSignatures !== undefined) {
|
|
65
|
+
setGrafometricSignatures(cachedSignatures);
|
|
66
|
+
setIsGrafometricRequested(true);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
33
69
|
}
|
|
34
70
|
catch (err) {
|
|
35
71
|
setError(getExceptionMessage(err));
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
setIsDataReady(true);
|
|
36
75
|
TMSpinner.hide();
|
|
37
76
|
}
|
|
38
77
|
};
|
|
39
|
-
|
|
40
|
-
}, [inputDcmt]);
|
|
78
|
+
loadSignerInfo();
|
|
79
|
+
}, [inputDcmt, graphometricManager]);
|
|
80
|
+
// Funzione per estrarre le firme grafometriche (chiamata on-demand)
|
|
81
|
+
const extractGraphometricSignaturesFromPdf = async (forceRefresh = false) => {
|
|
82
|
+
// Verifica che graphometricManager sia definito e che il file sia un PDF
|
|
83
|
+
if (!graphometricManager) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Controlla se i dati sono già in cache (a meno che non sia richiesto un refresh forzato)
|
|
87
|
+
if (useGrafometricCache) {
|
|
88
|
+
if (!forceRefresh) {
|
|
89
|
+
const cachedSignatures = getGrafometricSignatures(inputDcmt.TID, inputDcmt.DID);
|
|
90
|
+
if (cachedSignatures !== undefined) {
|
|
91
|
+
setGrafometricSignatures(cachedSignatures);
|
|
92
|
+
setIsGrafometricRequested(true);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Rimuovi dalla cache se è richiesto un refresh forzato
|
|
98
|
+
removeGrafometricSignatures(inputDcmt.TID, inputDcmt.DID);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
setIsGrafometricLoading(true);
|
|
102
|
+
setGrafometricError(undefined);
|
|
103
|
+
setGrafometricSignatures([]);
|
|
104
|
+
try {
|
|
105
|
+
if (inputDcmt.FILEEXT?.toLowerCase() !== "pdf") {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// Configura opzioni per il download del file
|
|
109
|
+
const rfo = new RetrieveFileOptions();
|
|
110
|
+
rfo.retrieveReason = DcmtOpers.ShowFile;
|
|
111
|
+
rfo.generalRetrieveFormat = GeneralRetrieveFormats.OriginalUnsigned;
|
|
112
|
+
// Scarica il PDF dal server
|
|
113
|
+
const file = await SDK_Globals.tmSession?.NewSearchEngine().RetrieveFileAsync(inputDcmt.TID, inputDcmt.DID, rfo);
|
|
114
|
+
if (!file) {
|
|
115
|
+
console.warn('Impossibile scaricare il file PDF per l\'estrazione delle firme grafometriche');
|
|
116
|
+
setGrafometricError("Non è stato possibile verificare la presenza di firme grafometriche. Riprovare più tardi.");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (file.type !== "application/pdf") {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const graphometricAttachments = await graphometricManager.extractGraphometricAttachments(file);
|
|
123
|
+
// Processa tutti gli attachment grafometrici con graphometricManager
|
|
124
|
+
const extractedSignatures = [];
|
|
125
|
+
// Filtra gli attachment con dataBase64 valido
|
|
126
|
+
const validAttachments = graphometricAttachments.filter(att => att.dataBase64 !== undefined);
|
|
127
|
+
// Estrai tutti i dataUrl degli attachment
|
|
128
|
+
const dataUrls = validAttachments.map(att => att.dataBase64).filter((data) => data !== undefined);
|
|
129
|
+
// Usa graphometricManager per estrarre i dati biometrici da tutte le immagini
|
|
130
|
+
const results = await graphometricManager.extractBiometricData(dataUrls);
|
|
131
|
+
// Processa i risultati (verifica che sia un array)
|
|
132
|
+
const errors = [];
|
|
133
|
+
if (Array.isArray(results)) {
|
|
134
|
+
results.forEach((result, index) => {
|
|
135
|
+
if (result.success && result.data) {
|
|
136
|
+
const originalAttachment = validAttachments[index];
|
|
137
|
+
extractedSignatures.push({
|
|
138
|
+
biometricData: result.data,
|
|
139
|
+
originalDataBase64: originalAttachment?.dataBase64,
|
|
140
|
+
originalFileName: originalAttachment?.fileName
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else if (!result.success && result.error) {
|
|
144
|
+
errors.push(result.error);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// Se ci sono errori e nessuna firma estratta, mostra gli errori
|
|
149
|
+
if (errors.length > 0 && extractedSignatures.length === 0) {
|
|
150
|
+
setGrafometricError(errors.join('; '));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
// Salva in cache (se abilitata)
|
|
154
|
+
if (useGrafometricCache) {
|
|
155
|
+
putGrafometricSignatures(inputDcmt.TID, inputDcmt.DID, extractedSignatures);
|
|
156
|
+
}
|
|
157
|
+
setGrafometricSignatures(extractedSignatures);
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error('Errore estrazione firme grafometriche dal PDF:', err);
|
|
161
|
+
setGrafometricError("Non è stato possibile verificare la presenza di firme grafometriche. Riprovare più tardi.");
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
setIsGrafometricLoading(false);
|
|
165
|
+
setIsGrafometricRequested(true);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
// Funzione per forzare il refresh delle firme grafometriche
|
|
169
|
+
const refreshGrafometricSignatures = () => {
|
|
170
|
+
extractGraphometricSignaturesFromPdf(true);
|
|
171
|
+
};
|
|
41
172
|
const hashButtonStyle = (isActive) => ({
|
|
42
173
|
padding: '8px 16px',
|
|
43
174
|
margin: '0 2px',
|
|
@@ -81,64 +212,227 @@ const TMSignatureInfoContent = (props) => {
|
|
|
81
212
|
}
|
|
82
213
|
};
|
|
83
214
|
if (error) {
|
|
84
|
-
return (_jsx("div", { style: {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
215
|
+
return (_jsx(TMModal, { title: SDKUI_Localizator.SignatureInformation, expandable: true, onClose: onClose, width: isMobile ? '95%' : '700px', height: isMobile ? '90%' : 'auto', children: _jsx("div", { style: { padding: '20px', minHeight: '200px', display: 'flex', alignItems: 'center', justifyContent: 'center' }, children: _jsx("div", { style: {
|
|
216
|
+
padding: '20px',
|
|
217
|
+
textAlign: 'center',
|
|
218
|
+
color: '#d32f2f',
|
|
219
|
+
background: '#ffebee',
|
|
220
|
+
borderRadius: '8px',
|
|
221
|
+
width: '100%'
|
|
222
|
+
}, children: error }) }) }));
|
|
91
223
|
}
|
|
92
|
-
|
|
93
|
-
|
|
224
|
+
// Mostra il contenuto solo quando entrambi i caricamenti (signerInfo e firme grafometriche) sono completati
|
|
225
|
+
if (!isDataReady || !signerInfo) {
|
|
226
|
+
return (_jsx(TMModal, { title: SDKUI_Localizator.SignatureInformation, expandable: true, onClose: onClose, width: isMobile ? '95%' : '700px', height: isMobile ? '90%' : 'auto', children: _jsxs("div", { style: {
|
|
227
|
+
padding: '20px',
|
|
228
|
+
minHeight: '200px',
|
|
229
|
+
display: 'flex',
|
|
230
|
+
flexDirection: 'column',
|
|
231
|
+
alignItems: 'center',
|
|
232
|
+
justifyContent: 'center',
|
|
233
|
+
gap: '16px'
|
|
234
|
+
}, children: [_jsx(LoadIndicator, {}), _jsxs("span", { style: { color: '#666', fontSize: '14px' }, children: [SDKUI_Localizator.Loading, "..."] })] }) }));
|
|
94
235
|
}
|
|
95
|
-
return (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
236
|
+
return (_jsx(TMModal, { title: SDKUI_Localizator.SignatureInformation, expandable: true, onClose: onClose, width: isMobile ? '95%' : '700px', height: isMobile ? '90%' : 'auto', children: _jsx("div", { style: { padding: '16px', minHeight: '200px', overflow: 'auto' }, children: _jsxs("div", { style: { lineHeight: "1.5em", boxSizing: "border-box", userSelect: 'text' }, children: [_jsxs("div", { children: [_jsxs("h4", { style: { margin: '0 0 12px 0', color: '#0078d4', fontSize: '16px' }, children: ["Firme digitali (", signerInfo.signers?.length ?? 0, ")"] }), signerInfo.signers && signerInfo.signers.length > 0 ? (signerInfo.signers.map((signer, idx) => (_jsxs("div", { style: {
|
|
237
|
+
border: "1px solid #d0d0d0",
|
|
238
|
+
borderRadius: "8px",
|
|
239
|
+
padding: "16px",
|
|
240
|
+
marginBottom: "12px",
|
|
241
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
|
|
242
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
|
|
243
|
+
userSelect: 'text',
|
|
244
|
+
}, children: [_jsxs("h3", { style: { margin: "0 0 12px", color: "#0078d4", fontSize: '15px', fontWeight: '600' }, children: ["Firma ", signer.levelAndIndex] }), _jsxs("div", { style: {
|
|
245
|
+
display: 'grid',
|
|
246
|
+
gap: '10px',
|
|
247
|
+
fontSize: '13px'
|
|
248
|
+
}, children: [_jsxs("div", { children: [_jsx("strong", { style: { color: '#555' }, children: "Intestatario:" }), _jsx("div", { style: { marginTop: '4px', color: '#333' }, children: signer.info1 ?? '-' })] }), _jsxs("div", { children: [_jsx("strong", { style: { color: '#555' }, children: "Riferimento temporale:" }), _jsx("div", { style: { marginTop: '4px', color: '#333' }, children: signer.info2 ?? '-' })] }), _jsxs("div", { children: [_jsx("strong", { style: { color: '#555' }, children: "Dettagli:" }), _jsx("div", { style: { marginTop: '4px', color: '#333' }, children: signer.info3 ?? '-' })] })] })] }, idx)))) : (_jsx("div", { style: {
|
|
249
|
+
border: "1px solid #d0d0d0",
|
|
250
|
+
borderRadius: "8px",
|
|
251
|
+
padding: "16px",
|
|
252
|
+
marginBottom: "12px",
|
|
253
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
|
|
254
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
|
|
255
|
+
userSelect: 'text',
|
|
256
|
+
textAlign: 'center',
|
|
257
|
+
color: '#666'
|
|
258
|
+
}, children: SDKUI_Localizator.NoSignatureFound }))] }), showGrafometricSection && graphometricManager && inputDcmt.FILEEXT?.toLowerCase() === "pdf" && (_jsxs("div", { style: { marginTop: '16px' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px' }, children: [_jsxs("h4", { style: { margin: 0, color: '#0078d4', fontSize: '16px' }, children: ["Firme Grafometriche ", isGrafometricRequested && !isGrafometricLoading && !grafometricError && `(${grafometricSignatures.length})`] }), isGrafometricRequested && !isGrafometricLoading && (_jsx(TMTooltip, { content: "Aggiorna", children: _jsx("button", { onClick: refreshGrafometricSignatures, style: {
|
|
259
|
+
background: 'transparent',
|
|
260
|
+
border: 'none',
|
|
261
|
+
cursor: 'pointer',
|
|
262
|
+
padding: '4px',
|
|
263
|
+
borderRadius: '4px',
|
|
264
|
+
display: 'flex',
|
|
265
|
+
alignItems: 'center',
|
|
266
|
+
color: '#0078d4',
|
|
267
|
+
transition: 'all 0.2s ease'
|
|
268
|
+
}, onMouseEnter: (e) => {
|
|
269
|
+
e.currentTarget.style.background = '#e6f2ff';
|
|
270
|
+
}, onMouseLeave: (e) => {
|
|
271
|
+
e.currentTarget.style.background = 'transparent';
|
|
272
|
+
}, children: _jsx(IconRefresh, { width: 18, height: 18 }) }) }))] }), !isGrafometricRequested && !isGrafometricLoading && (_jsx("div", { style: {
|
|
273
|
+
border: "1px solid #d0d0d0",
|
|
274
|
+
borderRadius: "8px",
|
|
275
|
+
padding: "20px",
|
|
276
|
+
marginBottom: "12px",
|
|
277
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
|
|
278
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
|
|
279
|
+
display: 'flex',
|
|
280
|
+
flexDirection: 'column',
|
|
281
|
+
alignItems: 'center',
|
|
282
|
+
gap: '12px'
|
|
283
|
+
}, children: _jsx("button", { onClick: () => extractGraphometricSignaturesFromPdf(), style: {
|
|
284
|
+
display: 'flex',
|
|
285
|
+
alignItems: 'center',
|
|
286
|
+
gap: '8px',
|
|
287
|
+
padding: '10px 20px',
|
|
288
|
+
border: '2px solid #0078d4',
|
|
289
|
+
borderRadius: '8px',
|
|
290
|
+
background: 'linear-gradient(135deg, #0078d4 0%, #005a9e 100%)',
|
|
291
|
+
color: '#fff',
|
|
292
|
+
cursor: 'pointer',
|
|
293
|
+
fontSize: '14px',
|
|
294
|
+
fontWeight: '600',
|
|
295
|
+
transition: 'all 0.2s ease',
|
|
296
|
+
boxShadow: '0 2px 6px rgba(0,120,212,0.3)',
|
|
297
|
+
}, onMouseEnter: (e) => {
|
|
298
|
+
e.currentTarget.style.background = 'linear-gradient(135deg, #005a9e 0%, #004578 100%)';
|
|
299
|
+
e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,120,212,0.4)';
|
|
300
|
+
e.currentTarget.style.transform = 'translateY(-1px)';
|
|
301
|
+
}, onMouseLeave: (e) => {
|
|
302
|
+
e.currentTarget.style.background = 'linear-gradient(135deg, #0078d4 0%, #005a9e 100%)';
|
|
303
|
+
e.currentTarget.style.boxShadow = '0 2px 6px rgba(0,120,212,0.3)';
|
|
304
|
+
e.currentTarget.style.transform = 'translateY(0)';
|
|
305
|
+
}, children: "Scarica firme grafometriche" }) })), isGrafometricLoading && (_jsxs("div", { style: {
|
|
306
|
+
border: "1px solid #d0d0d0",
|
|
307
|
+
borderRadius: "8px",
|
|
308
|
+
padding: "24px",
|
|
309
|
+
marginBottom: "12px",
|
|
310
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
|
|
311
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
|
|
312
|
+
display: 'flex',
|
|
313
|
+
flexDirection: 'column',
|
|
314
|
+
alignItems: 'center',
|
|
315
|
+
gap: '12px'
|
|
316
|
+
}, children: [_jsx(LoadIndicator, {}), _jsx("span", { style: { color: '#666', fontSize: '13px' }, children: "Analisi delle firme grafometriche in corso..." })] })), grafometricError && isGrafometricRequested && (_jsx("div", { style: {
|
|
317
|
+
border: "1px solid #d0d0d0",
|
|
318
|
+
borderRadius: "8px",
|
|
319
|
+
padding: "16px",
|
|
320
|
+
marginBottom: "12px",
|
|
321
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
|
|
322
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
|
|
323
|
+
}, children: _jsxs("div", { style: {
|
|
324
|
+
color: '#d32f2f',
|
|
325
|
+
fontSize: '13px',
|
|
326
|
+
display: 'flex',
|
|
327
|
+
alignItems: 'center',
|
|
328
|
+
gap: '8px'
|
|
329
|
+
}, children: [_jsx(IconWarning, { width: 16, height: 16 }), grafometricError] }) })), isGrafometricRequested && !isGrafometricLoading && !grafometricError && grafometricSignatures.length === 0 && (_jsx("div", { style: {
|
|
330
|
+
border: "1px solid #d0d0d0",
|
|
331
|
+
borderRadius: "8px",
|
|
332
|
+
padding: "16px",
|
|
333
|
+
marginBottom: "12px",
|
|
334
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
|
|
335
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
|
|
336
|
+
textAlign: 'center',
|
|
337
|
+
color: '#666'
|
|
338
|
+
}, children: _jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px' }, children: [_jsx(IconCircleInfo, { width: 16, height: 16, style: { color: TMColors.iconLight } }), "Nessuna firma grafometrica trovata nel documento."] }) })), isGrafometricRequested && !isGrafometricLoading && grafometricSignatures.length > 0 && (_jsx(_Fragment, { children: grafometricSignatures.map((signature, idx) => {
|
|
339
|
+
const data = signature.biometricData;
|
|
340
|
+
const isIntegrityOk = data.integrityStatus === 'OK';
|
|
341
|
+
const integrityColor = isIntegrityOk ? '#28a745' : (data.integrityStatus === 'FAIL' ? '#dc3545' : '#ffc107');
|
|
342
|
+
const isDataStatusOk = data.dataStatus === 'GOOD';
|
|
343
|
+
const dataStatusColor = isDataStatusOk ? '#28a745' : (data.dataStatus === 'ERROR' ? '#dc3545' : '#ffc107');
|
|
344
|
+
const downloadBiometricData = () => {
|
|
345
|
+
if (!graphometricManager || !signature.originalDataBase64) {
|
|
346
|
+
ShowAlert({
|
|
347
|
+
mode: 'warning',
|
|
348
|
+
message: "I dati biometrici non sono disponibili per questa firma.",
|
|
349
|
+
duration: 3000,
|
|
350
|
+
title: SDKUI_Localizator.Warning,
|
|
351
|
+
});
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
graphometricManager.downloadDecryptedPngWithBiometricData({
|
|
355
|
+
fileName: signature.originalFileName,
|
|
356
|
+
dataBase64: signature.originalDataBase64
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
return (_jsxs("div", { style: {
|
|
360
|
+
border: "1px solid #d0d0d0",
|
|
361
|
+
borderRadius: "8px",
|
|
362
|
+
padding: "16px",
|
|
363
|
+
marginBottom: "12px",
|
|
364
|
+
background: "linear-gradient(135deg, #ffffff 0%, #f9f9f9 100%)",
|
|
365
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.08)",
|
|
366
|
+
userSelect: 'text',
|
|
367
|
+
}, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '12px' }, children: [_jsxs("h3", { style: { margin: 0, color: "#0078d4", fontSize: '15px', fontWeight: '600' }, children: ["Firma #", idx + 1] }), _jsx("div", { style: { display: 'flex', gap: '8px' }, children: signature.originalDataBase64 && (_jsxs("button", { onClick: downloadBiometricData, style: {
|
|
368
|
+
display: 'flex',
|
|
369
|
+
alignItems: 'center',
|
|
370
|
+
gap: '6px',
|
|
371
|
+
padding: '6px 12px',
|
|
372
|
+
border: '1px solid #28a745',
|
|
373
|
+
borderRadius: '6px',
|
|
374
|
+
background: '#fff',
|
|
375
|
+
color: '#28a745',
|
|
376
|
+
cursor: 'pointer',
|
|
377
|
+
fontSize: '12px',
|
|
378
|
+
fontWeight: '500',
|
|
379
|
+
transition: 'all 0.2s ease',
|
|
380
|
+
}, onMouseEnter: (e) => {
|
|
381
|
+
e.currentTarget.style.background = '#28a745';
|
|
382
|
+
e.currentTarget.style.color = '#fff';
|
|
383
|
+
}, onMouseLeave: (e) => {
|
|
384
|
+
e.currentTarget.style.background = '#fff';
|
|
385
|
+
e.currentTarget.style.color = '#28a745';
|
|
386
|
+
}, children: [_jsx(IconDownload, { width: 14, height: 14 }), "Download"] })) })] }), _jsx("div", { style: {
|
|
387
|
+
background: '#fafafa',
|
|
388
|
+
borderRadius: '6px',
|
|
389
|
+
padding: '16px',
|
|
390
|
+
marginBottom: '16px',
|
|
391
|
+
textAlign: 'center',
|
|
392
|
+
border: '1px solid #e8e8e8'
|
|
393
|
+
}, children: _jsx("img", { src: `${data.signatureImage}`, draggable: false, alt: `Firma di ${data.signatureName || 'Firmatario'}`, style: {
|
|
394
|
+
maxWidth: '100%',
|
|
395
|
+
maxHeight: '100px',
|
|
396
|
+
objectFit: 'contain'
|
|
397
|
+
} }) }), _jsxs("div", { style: {
|
|
398
|
+
display: 'grid',
|
|
399
|
+
gap: '8px',
|
|
400
|
+
fontSize: '13px'
|
|
401
|
+
}, children: [data.signatureName && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Firmatario:" }), _jsx("span", { style: { color: '#333' }, children: data.signatureName })] })), data.reasonForSigning && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Motivo firma:" }), _jsx("span", { style: { color: '#333' }, children: data.reasonForSigning })] })), data.dateTimeFormatted && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Data e ora:" }), _jsx("span", { style: { color: '#333' }, children: data.dateTimeFormatted })] })), data.digitizerType && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Dispositivo:" }), _jsx("span", { style: { color: '#333' }, children: data.digitizerType })] })), data.digitizerDriver && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Driver:" }), _jsx("span", { style: { color: '#333', wordBreak: 'break-all' }, children: data.digitizerDriver })] })), data.operatingSystem && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Sistema operativo:" }), _jsx("span", { style: { color: '#333', wordBreak: 'break-all' }, children: data.operatingSystem })] })), data.networkInterfaceCard && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Scheda di rete:" }), _jsx("span", { style: { color: '#333', wordBreak: 'break-all' }, children: data.networkInterfaceCard })] })), (() => {
|
|
402
|
+
const extraData = data.extraData ?? {};
|
|
403
|
+
return Object.keys(extraData).length > 0 && (_jsxs("div", { style: { display: 'flex', borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsx("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0 }, children: "Extra Data:" }), _jsx("div", { style: { color: '#333', wordBreak: 'break-all' }, children: Object.entries(extraData).map(([key, value]) => (_jsxs("div", { children: [key, ": ", value] }, key))) })] }));
|
|
404
|
+
})(), _jsxs("div", { style: { borderBottom: '1px solid #eee', paddingBottom: '8px' }, children: [_jsxs("div", { style: { display: 'flex' }, children: [_jsxs("strong", { style: { color: '#555', minWidth: '160px', flexShrink: 0, display: 'flex', alignItems: 'center', gap: '4px' }, children: ["Integrit\u00E0 firma:", _jsx(TMTooltip, { content: "Verifica se la firma biometrica \u00E8 stata alterata", children: _jsx(IconCircleInfo, { width: 14, height: 14, style: { color: TMColors.iconLight } }) })] }), _jsx("span", { style: {
|
|
405
|
+
color: integrityColor,
|
|
406
|
+
fontWeight: '600',
|
|
407
|
+
display: 'flex',
|
|
408
|
+
alignItems: 'center',
|
|
409
|
+
gap: '6px'
|
|
410
|
+
}, children: isIntegrityOk ? _jsxs(_Fragment, { children: [_jsx(IconCheck, { width: 14, height: 14 }), " Verificata"] }) : _jsxs(_Fragment, { children: [_jsx(IconWarning, { width: 14, height: 14 }), " ", data.integrityStatus] }) })] }), data.integrityWarning && (_jsx("div", { style: { marginLeft: '160px', marginTop: '4px', fontSize: '12px', color: '#856404', fontStyle: 'italic' }, children: data.integrityWarning }))] })] })] }, idx));
|
|
411
|
+
}) }))] })), signerInfo.shA256 && (_jsxs("div", { style: {
|
|
412
|
+
marginBottom: '12px',
|
|
413
|
+
padding: '16px',
|
|
414
|
+
background: '#f5f5f5',
|
|
415
|
+
borderRadius: '8px',
|
|
416
|
+
border: '1px solid #e0e0e0'
|
|
417
|
+
}, children: [_jsxs("div", { style: { marginBottom: '12px', display: 'flex', gap: '4px', flexWrap: 'wrap' }, children: [signerInfo.shA256 && (_jsx("button", { onClick: () => setSelectedHash('sha256'), style: hashButtonStyle(selectedHash === 'sha256'), children: "SHA-256" })), signerInfo.shA1 && (_jsx("button", { onClick: () => setSelectedHash('sha1'), style: hashButtonStyle(selectedHash === 'sha1'), children: "SHA-1" })), signerInfo.shA256Base64 && (_jsx("button", { onClick: () => setSelectedHash('sha256base64'), style: hashButtonStyle(selectedHash === 'sha256base64'), children: "Base64" }))] }), _jsxs("div", { style: {
|
|
418
|
+
background: '#fff',
|
|
419
|
+
padding: '12px',
|
|
420
|
+
borderRadius: '6px',
|
|
421
|
+
wordBreak: 'break-all',
|
|
422
|
+
fontSize: '12px',
|
|
423
|
+
border: '1px solid #d0d0d0',
|
|
424
|
+
userSelect: 'text',
|
|
425
|
+
}, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '6px' }, children: [_jsxs("strong", { style: { color: '#0078d4', fontSize: '14px' }, children: [getHashLabel(), ":"] }), _jsxs("button", { onClick: copyToClipboard, style: {
|
|
426
|
+
background: copiedHash ? '#d4edda' : 'transparent',
|
|
427
|
+
border: 'none',
|
|
428
|
+
cursor: 'pointer',
|
|
429
|
+
padding: '4px 8px',
|
|
430
|
+
borderRadius: '4px',
|
|
431
|
+
display: 'flex',
|
|
432
|
+
alignItems: 'center',
|
|
433
|
+
gap: '4px',
|
|
434
|
+
transition: 'all 0.2s ease',
|
|
435
|
+
color: copiedHash ? '#155724' : '#666'
|
|
436
|
+
}, title: "Copia", children: [_jsx(IconCopy, { width: 16, height: 16 }), copiedHash && _jsx("span", { style: { fontSize: '11px' }, children: "Copiato" })] })] }), _jsx("div", { style: { color: '#333' }, children: getHashValue() })] })] }))] }) }) }));
|
|
143
437
|
};
|
|
144
438
|
export default TMSignatureInfoContent;
|
|
@@ -38,6 +38,7 @@ export interface ITMLoginDefaultValues {
|
|
|
38
38
|
username?: string;
|
|
39
39
|
behalfUsername?: string;
|
|
40
40
|
domain?: string;
|
|
41
|
+
cultureID?: CultureIDs;
|
|
41
42
|
}
|
|
42
43
|
interface ITMLoginFormProps {
|
|
43
44
|
isConnector?: boolean;
|
|
@@ -48,6 +49,7 @@ interface ITMLoginFormProps {
|
|
|
48
49
|
onChangeLanguage?: (e: CultureIDs) => void;
|
|
49
50
|
cultureID?: CultureIDs;
|
|
50
51
|
defaultLoginValues?: ITMLoginDefaultValues;
|
|
52
|
+
onEndpointChange?: (endpoint: TMEndpointsType | undefined) => void;
|
|
51
53
|
}
|
|
52
54
|
declare const TMLoginForm: React.FunctionComponent<ITMLoginFormProps>;
|
|
53
55
|
export default TMLoginForm;
|
|
@@ -107,6 +107,8 @@ const TMLoginForm = (props) => {
|
|
|
107
107
|
const usernameOnBehalfOfRef = useRef(null);
|
|
108
108
|
const passwordOnBehalfOfRRef = useRef(null);
|
|
109
109
|
const defaultLoginAppliedRef = useRef(false);
|
|
110
|
+
const onEndpointChangeRef = useRef(props.onEndpointChange);
|
|
111
|
+
onEndpointChangeRef.current = props.onEndpointChange;
|
|
110
112
|
const [loginStep, setLoginStep] = useState(1);
|
|
111
113
|
const [tmServer, setTmServer] = useState();
|
|
112
114
|
const [tmSession, setTmSession] = useState();
|
|
@@ -225,6 +227,8 @@ const TMLoginForm = (props) => {
|
|
|
225
227
|
setAuthDomain(props.defaultLoginValues.domain);
|
|
226
228
|
if (props.defaultLoginValues.behalfUsername)
|
|
227
229
|
setUsernameOnBehalf(props.defaultLoginValues.behalfUsername);
|
|
230
|
+
if (props.defaultLoginValues.cultureID)
|
|
231
|
+
props.onChangeLanguage?.(props.defaultLoginValues.cultureID);
|
|
228
232
|
}, [props.defaultLoginValues, props.endpoints]);
|
|
229
233
|
useEffect(() => {
|
|
230
234
|
if (!hasSingleOption)
|
|
@@ -260,6 +264,9 @@ const TMLoginForm = (props) => {
|
|
|
260
264
|
useEffect(() => {
|
|
261
265
|
setTmServer(new TopMediaServer(endpoint?.URL));
|
|
262
266
|
}, [endpoint]);
|
|
267
|
+
useEffect(() => {
|
|
268
|
+
onEndpointChangeRef.current?.(endpoint);
|
|
269
|
+
}, [endpoint]);
|
|
263
270
|
useEffect(() => {
|
|
264
271
|
if (!tmServer)
|
|
265
272
|
return;
|
|
@@ -336,6 +343,12 @@ const TMLoginForm = (props) => {
|
|
|
336
343
|
const disablePasswordOperations = useMemo(() => {
|
|
337
344
|
return (username.length === 0 || !dcmtArchive || !endpoint);
|
|
338
345
|
}, [username, dcmtArchive, endpoint]);
|
|
346
|
+
const loginKey = useMemo(() => {
|
|
347
|
+
const archivePart = dcmtArchive
|
|
348
|
+
? (dcmtArchive.description?.replace(/ /g, '_') || dcmtArchive.id || '')
|
|
349
|
+
: (manualArchiveID ?? '');
|
|
350
|
+
return `${archivePart}:${username}`;
|
|
351
|
+
}, [dcmtArchive, manualArchiveID, username]);
|
|
339
352
|
const showLoginBtn = useMemo(() => {
|
|
340
353
|
if (loginStep === 1)
|
|
341
354
|
return false;
|
|
@@ -714,7 +727,8 @@ const TMLoginForm = (props) => {
|
|
|
714
727
|
marginBottom: windowHeight === WindowHeight.SMALL ? '30px' : '25px',
|
|
715
728
|
width: '100%',
|
|
716
729
|
minHeight: '15px'
|
|
717
|
-
}, children: [_jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Endpoint, children: _jsx(IconAccessPoint, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: endpoint?.Description ?? '', children: _jsx("p", { children: endpoint?.Description && endpoint.Description.length > 20 ? endpoint.Description.substring(0, 20) + '...' : endpoint?.Description }) })] }), _jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.ArchiveID, children: _jsx(IconArchiveDoc, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID, children: _jsx(StyledArchiveText, { children: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID }) })] })] }), _jsxs(StyledStepContainer, { "$windowHeight": windowHeight, "$deviceType": deviceType, children: [_jsx(SelectBox, { value: authMode, options: authModeOptions, onValueChanged: (value) => setAuthMode(value), validationItems: fieldValidations('authenticationMode'), icon: _jsx(IconLogin, {}), label: SDKUI_Localizator.AuthMode }), _jsxs(StyledCredentialWrapper, { children: [authMode === AuthenticationModes.WindowsThroughTopMedia && _jsx(TextBox, { ref: authDomainRef, value: authDomain, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain
|
|
730
|
+
}, children: [_jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.Endpoint, children: _jsx(IconAccessPoint, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: endpoint?.Description ?? '', children: _jsx("p", { children: endpoint?.Description && endpoint.Description.length > 20 ? endpoint.Description.substring(0, 20) + '...' : endpoint?.Description }) })] }), _jsxs(StyledDescription, { children: [_jsx(TMTooltip, { content: SDKUI_Localizator.ArchiveID, children: _jsx(IconArchiveDoc, { color: TMColors.primary, fontSize: 16 }) }), _jsx(TMTooltip, { content: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID, children: _jsx(StyledArchiveText, { children: dcmtArchive ? (dcmtArchive.description ?? '') : manualArchiveID }) })] })] }), _jsxs(StyledStepContainer, { "$windowHeight": windowHeight, "$deviceType": deviceType, children: [_jsx(SelectBox, { value: authMode, options: authModeOptions, onValueChanged: (value) => setAuthMode(value), validationItems: fieldValidations('authenticationMode'), icon: _jsx(IconLogin, {}), label: SDKUI_Localizator.AuthMode }), _jsxs(StyledCredentialWrapper, { children: [authMode === AuthenticationModes.WindowsThroughTopMedia && _jsx(TextBox, { ref: authDomainRef, value: authDomain, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain, autoComplete: "off" }), authMode !== AuthenticationModes.MSAzure &&
|
|
731
|
+
_jsxs("form", { onSubmit: (e) => e.preventDefault(), style: { width: '100%' }, children: [_jsx("input", { name: "login_key", autoComplete: "username", readOnly: true, tabIndex: -1, value: loginKey, style: { position: 'absolute', width: 1, height: 1, opacity: 0, overflow: 'hidden', border: 0, padding: 0 } }, loginKey), _jsx(CeredentialContainer, { isMobile: isMobile, ref: usernameRef, secondaryRef: passwordRef, usernameValidator: fieldValidations('username'), passwordValidator: fieldValidations('password'), authMode: authMode, username: username, password: password, onUsernameChanged: (un) => setUsername(un), onPasswordChanged: (ps) => setPassword(ps), usernameAutoComplete: "off", passwordAutoComplete: "current-password" })] }), authMode === AuthenticationModes.TopMediaOnBehalfOf &&
|
|
718
732
|
_jsxs(StyledCredentialWrapper, { children: [_jsx(TextBox, { value: authDomain, ref: authDomainRef, onValueChanged: (e) => setAuthDomain(e), validationItems: fieldValidations('authDomain'), type: "text", icon: _jsx(IconWeb, {}), label: SDKUI_Localizator.Domain }), _jsx(CeredentialContainer, { isMobile: isMobile, ref: usernameOnBehalfOfRef, secondaryRef: passwordOnBehalfOfRRef, usernameValidator: fieldValidations('usernameOnBehalfOf'), passwordValidator: fieldValidations('passwordOnBehalfOf'), authMode: AuthenticationModes.TopMediaOnBehalfOf, username: usernameOnBehalf, password: passwordOnBehalf, onUsernameChanged: (un) => setUsernameOnBehalf(un), onPasswordChanged: (ps) => setPasswordOnBehalf(ps) })] })] }), authMode !== AuthenticationModes.TopMediaWithMFA &&
|
|
719
733
|
_jsx(RapidAccessContainer, { isSaveEnable: saveLoginEnable, name: saveLoginName, nameValidationItems: fieldValidations('rapidAccessName'), onEnableSaveChange: () => setSaveLoginEnable(!saveLoginEnable), onNameChange: (name) => setSaveLoginName(name) })] })] }), loginStep === 3 &&
|
|
720
734
|
_jsxs(StyledStepThreeContainer, { "$isMobile": isMobile, children: [_jsx(OTPReader, { isMobile: isMobile, digits: otpCode, onChange: handleDigitChange, onFullChange: handleFullChange, text: _jsxs("div", { children: [" ", LOGINLocalizator.EnterOtpInstructions, " "] }), header: '', additionalButtons: [
|
|
@@ -723,7 +737,7 @@ const TMLoginForm = (props) => {
|
|
|
723
737
|
] }), _jsx(StyledRapidAccessWrapper, { "$isMobile": isMobile, children: _jsx(RapidAccessContainer, { isSaveEnable: saveLoginEnable, name: saveLoginName, nameValidationItems: fieldValidations('rapidAccessName'), onEnableSaveChange: () => setSaveLoginEnable(!saveLoginEnable), onNameChange: (name) => setSaveLoginName(name) }) })] }), _jsxs(StyledButtonContainer, { "$windowHeight": windowHeight, children: [showContinueBtn && _jsx(TMButton, { fontSize: "1.2rem", onClick: nextStepHandler, showTooltip: false, caption: LOGINLocalizator.Continue, disabled: disableContinueBtn }), showLoginBtn && _jsx(TMButton, { fontSize: "1.2rem", showTooltip: false, onClick: loginHandler, caption: saveLoginEnable ? SDKUI_Localizator.SaveAndLogin : SDKUI_Localizator.Login, disabled: disableLoginBtn })] })] }), showPasswordOperations && _jsx(StyledForgetPassword, { "$isMobile": isMobile, children: _jsx(TMButton, { disabled: disablePasswordOperations, btnStyle: "text", caption: SDKUI_Localizator.ForgetPassword, showTooltip: false, onClick: () => setShowForgetPassword(true) }) }), showBackBtn && _jsx(StyledBackButton, { children: _jsx(TMButton, { onClick: previousStepHandler, btnStyle: "icon", icon: _jsx(IconArrowLeft, { fontSize: 20 }), caption: SDKUI_Localizator.Back }) }), showCultureIDs && _jsx(Menu, { onClose: () => setShowCultureIDs(false), x: 'calc(100% - 250px)', y: 50, visible: showCultureIDs, children: _jsxs(StyledMenuItemContainer, { children: [_jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.It_IT), title: cultureIDsDataSource[0].display, src: it, alt: "it", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.En_US), title: cultureIDsDataSource[3].display, src: en, alt: "en", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.Fr_FR), title: cultureIDsDataSource[1].display, src: fr, alt: "fr", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.Es_ES), title: cultureIDsDataSource[4].display, src: es, alt: "es", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.Pt_PT), title: cultureIDsDataSource[2].display, src: pt, alt: "pt", width: BANNER_DIMENSION, height: BANNER_DIMENSION }), _jsx(StyledLangChooser, { onClick: () => cultureIDHandler(CultureIDs.De_DE), title: cultureIDsDataSource[5].display, src: de, alt: "de", width: BANNER_DIMENSION, height: BANNER_DIMENSION })] }) }), showChangePassword && _jsx(ChangePassword, { tmSession: changePswTmSession, onClose: () => setShowChangePassword(false) }), showForgetPassword && _jsx(RecoverPasswordFlow, { isMobile: isMobile, tmSession: changePswTmSession, onClose: () => setShowForgetPassword(false), windowHeight: windowHeight }), showRapidAccess && _jsx(RapidAccessLogin, { isMobile: isMobile, onClose: () => setShowRapidAccess(false), onSelect: handleRapidAccessSelection })] })] })] }));
|
|
724
738
|
};
|
|
725
739
|
export default TMLoginForm;
|
|
726
|
-
const CeredentialContainer = forwardRef(({ isMobile = false, authMode = AuthenticationModes.TopMedia, password = '', username = '', onPasswordChanged, onUsernameChanged, passwordValidator = [], usernameValidator = [], secondaryRef }, ref) => {
|
|
740
|
+
const CeredentialContainer = forwardRef(({ isMobile = false, authMode = AuthenticationModes.TopMedia, password = '', username = '', onPasswordChanged, onUsernameChanged, passwordValidator = [], usernameValidator = [], secondaryRef, usernameAutoComplete = 'off', passwordAutoComplete = 'off' }, ref) => {
|
|
727
741
|
const passwordRef = useRef(null);
|
|
728
742
|
useImperativeHandle(ref, () => {
|
|
729
743
|
return usernameRef.current;
|
|
@@ -749,7 +763,7 @@ const CeredentialContainer = forwardRef(({ isMobile = false, authMode = Authenti
|
|
|
749
763
|
secondaryRef.current = passwordRef.current;
|
|
750
764
|
}
|
|
751
765
|
}, [secondaryRef]);
|
|
752
|
-
return (_jsxs(StyledCredentialContainer, { "$isMobile": isMobile, "$authMode": authMode, children: [_jsx(TextBox, { ref: usernameRef, value: username, onValueChanged: (e) => onUsernameChanged(e), validationItems: usernameValidator, type: "text", icon: _jsx(IconUser, {}), label: SDKUI_Localizator.UserName }), _jsx(TextBox, { ref: passwordRef, value: password, onValueChanged: (e) => onPasswordChanged(e), validationItems: passwordValidator, type: "password", icon: authMode !== AuthenticationModes.TopMediaOnBehalfOf ? _jsx(IconPassword, {}) : undefined, label: SDKUI_Localizator.Password })] }));
|
|
766
|
+
return (_jsxs(StyledCredentialContainer, { "$isMobile": isMobile, "$authMode": authMode, children: [_jsx(TextBox, { ref: usernameRef, value: username, onValueChanged: (e) => onUsernameChanged(e), validationItems: usernameValidator, type: "text", icon: _jsx(IconUser, {}), label: SDKUI_Localizator.UserName, autoComplete: usernameAutoComplete }), _jsx(TextBox, { ref: passwordRef, value: password, onValueChanged: (e) => onPasswordChanged(e), validationItems: passwordValidator, type: "password", icon: authMode !== AuthenticationModes.TopMediaOnBehalfOf ? _jsx(IconPassword, {}) : undefined, label: SDKUI_Localizator.Password, autoComplete: passwordAutoComplete })] }));
|
|
753
767
|
});
|
|
754
768
|
const RapidAccessContainer = ({ isSaveEnable, name, nameValidationItems, onEnableSaveChange, onNameChange }) => {
|
|
755
769
|
return (_jsxs(StyledRapidLoginSave, { children: [_jsx(TMCheckBox, { label: LOGINLocalizator.CreateNewQuickAccess, onValueChanged: () => onEnableSaveChange(), value: isSaveEnable, labelColor: "#313131" }), isSaveEnable && _jsx(TextBox, { validationItems: nameValidationItems, disabled: !isSaveEnable, type: "text", value: name, onValueChanged: (value) => onNameChange(value), placeHolder: "Es: Admin risorse umane" })] }));
|
|
@@ -19,6 +19,9 @@ interface TextBoxProps {
|
|
|
19
19
|
readOnly?: boolean;
|
|
20
20
|
cursor?: 'default' | 'pointer' | 'text';
|
|
21
21
|
showSuccess?: boolean;
|
|
22
|
+
name?: string;
|
|
23
|
+
id?: string;
|
|
24
|
+
autoComplete?: string;
|
|
22
25
|
onClick?: () => void;
|
|
23
26
|
onValueChanged?: (value: string) => void;
|
|
24
27
|
onKeyDown?: (event: React.KeyboardEvent) => void;
|