@iotready/nextjs-components-library 1.0.0-preview4 → 1.0.0-preview40
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/assets/translations/en.json +92 -0
- package/assets/translations/index.js +4 -0
- package/assets/translations/it.json +92 -0
- package/assets/translations/scripts/export.js +74 -0
- package/assets/translations/scripts/import.js +66 -0
- package/components/accounts/AccountMenu.d.ts +2 -1
- package/components/accounts/AccountMenu.js +2 -2
- package/components/accounts/AccountProfile.d.ts +2 -1
- package/components/accounts/AccountProfile.js +15 -15
- package/components/charts/TrendChart.d.ts +28 -6
- package/components/charts/TrendChart.js +555 -149
- package/components/groups/GroupUpdate.d.ts +9 -10
- package/components/groups/GroupUpdate.js +21 -38
- package/components/groups/GroupsDevices.d.ts +22 -17
- package/components/groups/GroupsDevices.js +165 -110
- package/components/groups/Map.d.ts +5 -9
- package/components/groups/Map.js +2 -2
- package/components/settings/DynamicMenu.d.ts +1 -0
- package/components/settings/DynamicMenu.js +2 -1
- package/components/users/UserUpdate.d.ts +2 -1
- package/components/users/UserUpdate.js +2 -2
- package/components/users/UsersDataGrid.d.ts +11 -3
- package/components/users/UsersDataGrid.js +49 -32
- package/package.json +8 -4
- package/server-actions/annotations.d.ts +4 -0
- package/server-actions/annotations.js +12 -0
- package/server-actions/groups.d.ts +16 -16
- package/server-actions/groups.js +157 -72
- package/server-actions/index.d.ts +1 -0
- package/server-actions/index.js +1 -0
- package/server-actions/influx.d.ts +17 -13
- package/server-actions/influx.js +207 -98
- package/server-actions/trackle.d.ts +10 -4
- package/server-actions/trackle.js +59 -38
- package/server-actions/types.d.ts +16 -0
- package/server-actions/types.js +6 -0
- package/types/device.d.ts +19 -0
- package/types/device.js +1 -0
- package/types/index.d.ts +1 -0
- package/types/index.js +1 -0
- package/types/user.d.ts +2 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"library": {
|
|
3
|
+
"groupsDevices": {
|
|
4
|
+
"noDevices": "No devices",
|
|
5
|
+
"noDevicesInGroup": "No devices in {{entity}}",
|
|
6
|
+
"addDevices": "Add devices",
|
|
7
|
+
"filterReturnsNoResult": "Filter returns no result",
|
|
8
|
+
"list": "List",
|
|
9
|
+
"map": "Map",
|
|
10
|
+
"allDevices": "All devices",
|
|
11
|
+
"group": "Group",
|
|
12
|
+
"organization": "Organization",
|
|
13
|
+
"createGroup": "Create {{entity}}",
|
|
14
|
+
"backToGroup": "Back to {{entity}}",
|
|
15
|
+
"addToGroup": "Add to group",
|
|
16
|
+
"manageGroup": "Manage {{entity}}",
|
|
17
|
+
"removeFromGroup": "Remove from {{entity}}",
|
|
18
|
+
"closeEdit": "Close edit",
|
|
19
|
+
"editGroup": "Edit {{entity}}",
|
|
20
|
+
"newGroup": "New {{entity}}",
|
|
21
|
+
"groupName": "{{entity}} Name",
|
|
22
|
+
"description": "Description",
|
|
23
|
+
"cancel": "Cancel",
|
|
24
|
+
"create": "Create"
|
|
25
|
+
},
|
|
26
|
+
"groupUpdate": {
|
|
27
|
+
"name": "Name",
|
|
28
|
+
"description": "Description",
|
|
29
|
+
"update": "Update",
|
|
30
|
+
"addMembers": "Add members",
|
|
31
|
+
"noMembersFound": "No members found",
|
|
32
|
+
"selectUser": "Select user",
|
|
33
|
+
"add": "Add",
|
|
34
|
+
"deleteGroup": "Delete {{entity}}",
|
|
35
|
+
"actionCannotBeUndone": "This action cannot be undone",
|
|
36
|
+
"mustRemoveDevicesAndMembers": "You must manually remove devices and members from {{entity}} before deletion",
|
|
37
|
+
"mustRemoveDevicesMembersAndGroups": "You must manually remove devices, members and groups from {{entity}} before deletion",
|
|
38
|
+
"confirmDeleteGroup": "Are you sure you want to delete the {{entity}}?",
|
|
39
|
+
"yesRemoveIt": "Yes, remove it"
|
|
40
|
+
},
|
|
41
|
+
"usersDataGrid": {
|
|
42
|
+
"filterBy": "Filter by",
|
|
43
|
+
"search": "Search...",
|
|
44
|
+
"emailAddress": "Email Address",
|
|
45
|
+
"fullName": "Full name",
|
|
46
|
+
"role": "Role"
|
|
47
|
+
},
|
|
48
|
+
"accountMenu": {
|
|
49
|
+
"manageAccount": "Manage account",
|
|
50
|
+
"signOut": "Sign Out",
|
|
51
|
+
"openMenu": "Open menu"
|
|
52
|
+
},
|
|
53
|
+
"accountProfile": {
|
|
54
|
+
"completeInfo": "Please complete the informations below",
|
|
55
|
+
"profileName": "Profile name",
|
|
56
|
+
"firstName": "First name",
|
|
57
|
+
"enterFirstName": "Enter your first name",
|
|
58
|
+
"lastName": "Last name",
|
|
59
|
+
"enterLastName": "Enter your last name",
|
|
60
|
+
"update": "Update",
|
|
61
|
+
"security": "Security",
|
|
62
|
+
"setOrEditPassword": "Set or edit your password",
|
|
63
|
+
"newPassword": "New Password",
|
|
64
|
+
"confirmPassword": "Confirm Password",
|
|
65
|
+
"cancel": "Cancel",
|
|
66
|
+
"save": "Save",
|
|
67
|
+
"deleteAccount": "Delete account",
|
|
68
|
+
"actionCannotBeUndone": "This action cannot be undone",
|
|
69
|
+
"confirmDeleteAccount": "Are you sure you want to delete the account?",
|
|
70
|
+
"yesRemove": "Yes, remove",
|
|
71
|
+
"passwordRequired": "Password is required",
|
|
72
|
+
"confirmPasswordRequired": "Confirm password is required",
|
|
73
|
+
"passwordsMustMatch": "Password and Confirmation password must be the same",
|
|
74
|
+
"passwordUpdated": "Password updated",
|
|
75
|
+
"userUpdated": "User updated",
|
|
76
|
+
"passwordRequirements": "Password must be longer than 8 characters and must contain 1 uppercase letter (A-Z), 1 lowercase letter (a-z), 1 digit (0-9) e 1 special symbol (!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~ )."
|
|
77
|
+
},
|
|
78
|
+
"userUpdate": {
|
|
79
|
+
"role": "Role",
|
|
80
|
+
"update": "Update"
|
|
81
|
+
},
|
|
82
|
+
"trendChart": {
|
|
83
|
+
"export": "Export",
|
|
84
|
+
"noDataMeasure": "No data measure",
|
|
85
|
+
"connectPointValues": "Connect point values",
|
|
86
|
+
"showAnnotations": "Show annotations"
|
|
87
|
+
},
|
|
88
|
+
"map": {
|
|
89
|
+
"noPositionsForDevices": "No positions for devices"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"library": {
|
|
3
|
+
"groupsDevices": {
|
|
4
|
+
"noDevices": "Nessun dispositivo",
|
|
5
|
+
"noDevicesInGroup": "Nessun dispositivo nel {{entity}}",
|
|
6
|
+
"addDevices": "Aggiungi dispositivi",
|
|
7
|
+
"filterReturnsNoResult": "Il filtro non restituisce risultati",
|
|
8
|
+
"list": "Lista",
|
|
9
|
+
"map": "Mappa",
|
|
10
|
+
"allDevices": "Tutti i dispositivi",
|
|
11
|
+
"group": "Gruppo",
|
|
12
|
+
"organization": "Organizzazione",
|
|
13
|
+
"createGroup": "Crea {{entity}}",
|
|
14
|
+
"backToGroup": "Torna al {{entity}}",
|
|
15
|
+
"addToGroup": "Aggiungi al gruppo",
|
|
16
|
+
"manageGroup": "Gestisci {{entity}}",
|
|
17
|
+
"removeFromGroup": "Rimuovi dal {{entity}}",
|
|
18
|
+
"closeEdit": "Chiudi modifica",
|
|
19
|
+
"editGroup": "Modifica {{entity}}",
|
|
20
|
+
"newGroup": "Nuovo {{entity}}",
|
|
21
|
+
"groupName": "Nome {{entity}}",
|
|
22
|
+
"description": "Descrizione",
|
|
23
|
+
"cancel": "Annulla",
|
|
24
|
+
"create": "Crea"
|
|
25
|
+
},
|
|
26
|
+
"groupUpdate": {
|
|
27
|
+
"name": "Nome",
|
|
28
|
+
"description": "Descrizione",
|
|
29
|
+
"update": "Aggiorna",
|
|
30
|
+
"addMembers": "Aggiungi membri",
|
|
31
|
+
"noMembersFound": "Nessun membro trovato",
|
|
32
|
+
"selectUser": "Seleziona utente",
|
|
33
|
+
"add": "Aggiungi",
|
|
34
|
+
"deleteGroup": "Elimina {{entity}}",
|
|
35
|
+
"actionCannotBeUndone": "Questa azione non può essere annullata",
|
|
36
|
+
"mustRemoveDevicesAndMembers": "Devi rimuovere manualmente i dispositivi e i membri dal {{entity}} prima dell'eliminazione",
|
|
37
|
+
"mustRemoveDevicesMembersAndGroups": "Devi rimuovere manualmente i dispositivi, i membri e i gruppi dal {{entity}} prima dell'eliminazione",
|
|
38
|
+
"confirmDeleteGroup": "Sei sicuro di voler eliminare il {{entity}}?",
|
|
39
|
+
"yesRemoveIt": "Sì, rimuovi"
|
|
40
|
+
},
|
|
41
|
+
"usersDataGrid": {
|
|
42
|
+
"filterBy": "Filtra per",
|
|
43
|
+
"search": "Cerca...",
|
|
44
|
+
"emailAddress": "Indirizzo email",
|
|
45
|
+
"fullName": "Nome completo",
|
|
46
|
+
"role": "Ruolo"
|
|
47
|
+
},
|
|
48
|
+
"accountMenu": {
|
|
49
|
+
"manageAccount": "Gestisci account",
|
|
50
|
+
"signOut": "Esci",
|
|
51
|
+
"openMenu": "Apri menu"
|
|
52
|
+
},
|
|
53
|
+
"accountProfile": {
|
|
54
|
+
"completeInfo": "Completa le informazioni qui sotto",
|
|
55
|
+
"profileName": "Nome profilo",
|
|
56
|
+
"firstName": "Nome",
|
|
57
|
+
"enterFirstName": "Inserisci il tuo nome",
|
|
58
|
+
"lastName": "Cognome",
|
|
59
|
+
"enterLastName": "Inserisci il tuo cognome",
|
|
60
|
+
"update": "Aggiorna",
|
|
61
|
+
"security": "Sicurezza",
|
|
62
|
+
"setOrEditPassword": "Imposta o modifica la tua password",
|
|
63
|
+
"newPassword": "Nuova Password",
|
|
64
|
+
"confirmPassword": "Conferma Password",
|
|
65
|
+
"cancel": "Annulla",
|
|
66
|
+
"save": "Salva",
|
|
67
|
+
"deleteAccount": "Elimina account",
|
|
68
|
+
"actionCannotBeUndone": "Questa azione non può essere annullata",
|
|
69
|
+
"confirmDeleteAccount": "Sei sicuro di voler eliminare l'account?",
|
|
70
|
+
"yesRemove": "Sì, rimuovi",
|
|
71
|
+
"passwordRequired": "La password è obbligatoria",
|
|
72
|
+
"confirmPasswordRequired": "La conferma della password è obbligatoria",
|
|
73
|
+
"passwordsMustMatch": "La password e la conferma della password devono essere uguali",
|
|
74
|
+
"passwordUpdated": "Password aggiornata",
|
|
75
|
+
"userUpdated": "Utente aggiornato",
|
|
76
|
+
"passwordRequirements": "La password deve essere più lunga di 8 caratteri e deve contenere 1 lettera maiuscola (A-Z), 1 lettera minuscola (a-z), 1 cifra (0-9) e 1 simbolo speciale (!\"#$%&'()*+,-./:;<=>?@[\\]^_{|}~ )."
|
|
77
|
+
},
|
|
78
|
+
"userUpdate": {
|
|
79
|
+
"role": "Ruolo",
|
|
80
|
+
"update": "Aggiorna"
|
|
81
|
+
},
|
|
82
|
+
"trendChart": {
|
|
83
|
+
"export": "Esporta",
|
|
84
|
+
"noDataMeasure": "Nessuna misurazione dati",
|
|
85
|
+
"connectPointValues": "Collega i valori dei punti",
|
|
86
|
+
"showAnnotations": "Mostra annotazioni"
|
|
87
|
+
},
|
|
88
|
+
"map": {
|
|
89
|
+
"noPositionsForDevices": "Nessuna posizione per i dispositivi"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// script.js
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const ExcelJS = require('exceljs');
|
|
5
|
+
console.log(__dirname);
|
|
6
|
+
const LOCALES_DIR = path.resolve(__dirname, '../../translations');
|
|
7
|
+
const OUTPUT_FILE = path.resolve(__dirname, 'translations.xlsx');
|
|
8
|
+
|
|
9
|
+
// 1) Legge tutti i file *.json nella cartella locales
|
|
10
|
+
const files = fs.readdirSync(LOCALES_DIR).filter(f => f.endsWith('.json'));
|
|
11
|
+
|
|
12
|
+
// 2) Funzione ricorsiva per appiattire l'oggetto
|
|
13
|
+
function flatten(obj, prefix = '', res = {}) {
|
|
14
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
15
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
16
|
+
if (val && typeof val === 'object' && !Array.isArray(val)) {
|
|
17
|
+
flatten(val, fullKey, res);
|
|
18
|
+
} else {
|
|
19
|
+
res[fullKey] = val;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return res;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function buildWorkbook() {
|
|
26
|
+
// Carica ciascun file e appiattisci
|
|
27
|
+
const translations = {}; // { en: { key: val, ... }, it: { ... }, ... }
|
|
28
|
+
const allKeys = new Set();
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
const lang = path.basename(file, '.json');
|
|
31
|
+
const content = JSON.parse(
|
|
32
|
+
fs.readFileSync(path.join(LOCALES_DIR, file), 'utf8'),
|
|
33
|
+
);
|
|
34
|
+
const flat = flatten(content);
|
|
35
|
+
translations[lang] = flat;
|
|
36
|
+
Object.keys(flat).forEach(k => allKeys.add(k));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Prepara il workbook
|
|
40
|
+
const workbook = new ExcelJS.Workbook();
|
|
41
|
+
const sheet = workbook.addWorksheet('Translations');
|
|
42
|
+
|
|
43
|
+
// Intestazioni: Key + lingue in ordine alfabetico
|
|
44
|
+
const langs = Object.keys(translations).sort();
|
|
45
|
+
sheet.columns = [
|
|
46
|
+
{header: 'key', key: 'key', width: 50},
|
|
47
|
+
...langs.map(l => ({header: l, key: l, width: 40})),
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// 3) Aggiungi le righe e verifica mancanze
|
|
51
|
+
allKeys.forEach(key => {
|
|
52
|
+
const row = {key};
|
|
53
|
+
langs.forEach(l => {
|
|
54
|
+
row[l] = translations[l][key] || '';
|
|
55
|
+
if (!translations[l][key]) {
|
|
56
|
+
// Log di warning per chiave mancante
|
|
57
|
+
console.warn(`⚠️ [${l}] mancante: ${key}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
sheet.addRow(row);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Formatta header in grassetto
|
|
64
|
+
sheet.getRow(1).font = {bold: true};
|
|
65
|
+
|
|
66
|
+
// 4) Salva
|
|
67
|
+
await workbook.xlsx.writeFile(OUTPUT_FILE);
|
|
68
|
+
console.log(`✅ File generato: ${OUTPUT_FILE}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
buildWorkbook().catch(err => {
|
|
72
|
+
console.error(err);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// import-from-xlsx.js
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const ExcelJS = require('exceljs');
|
|
5
|
+
|
|
6
|
+
const INPUT_XLSX = path.resolve(__dirname, './translations.xlsx');
|
|
7
|
+
const OUTPUT_DIR = path.resolve(__dirname, './generated'); // dove salvare i file JSON
|
|
8
|
+
|
|
9
|
+
// Crea output dir se non esiste
|
|
10
|
+
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
11
|
+
fs.mkdirSync(OUTPUT_DIR);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Espande le chiavi a punti in oggetti annidati
|
|
15
|
+
function expandKey(obj, key, value) {
|
|
16
|
+
const parts = key.split('.');
|
|
17
|
+
let current = obj;
|
|
18
|
+
parts.forEach((part, i) => {
|
|
19
|
+
if (i === parts.length - 1) {
|
|
20
|
+
current[part] = value;
|
|
21
|
+
} else {
|
|
22
|
+
current[part] = current[part] || {};
|
|
23
|
+
current = current[part];
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function processExcel() {
|
|
29
|
+
const workbook = new ExcelJS.Workbook();
|
|
30
|
+
await workbook.xlsx.readFile(INPUT_XLSX);
|
|
31
|
+
|
|
32
|
+
const sheet = workbook.getWorksheet(1); // primo foglio
|
|
33
|
+
const headerRow = sheet.getRow(1).values;
|
|
34
|
+
|
|
35
|
+
const langs = headerRow.slice(2); // Salta "key" che è in colonna 1
|
|
36
|
+
|
|
37
|
+
const data = {}; // { en: { ... }, it: { ... } }
|
|
38
|
+
|
|
39
|
+
langs.forEach(lang => {
|
|
40
|
+
if (lang) data[lang] = {};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
sheet.eachRow((row, rowNumber) => {
|
|
44
|
+
if (rowNumber === 1) return; // salta header
|
|
45
|
+
|
|
46
|
+
const key = row.getCell(1).value;
|
|
47
|
+
langs.forEach((lang, index) => {
|
|
48
|
+
const value = row.getCell(index + 2).value;
|
|
49
|
+
if (key && value != null) {
|
|
50
|
+
expandKey(data[lang], key, value);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Scrivi i file JSON
|
|
56
|
+
for (const [lang, content] of Object.entries(data)) {
|
|
57
|
+
const outPath = path.join(OUTPUT_DIR, `${lang}.json`);
|
|
58
|
+
fs.writeFileSync(outPath, JSON.stringify(content, null, 2), 'utf8');
|
|
59
|
+
console.log(`✅ Creato: ${outPath}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
processExcel().catch(err => {
|
|
64
|
+
console.error(err);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { UserType } from '../../types/user';
|
|
2
2
|
import { Theme } from "@emotion/react";
|
|
3
|
-
export default function UserMenuAccount({ userInfo, handleClick, handleSignOut, accountRoute, theme }: {
|
|
3
|
+
export default function UserMenuAccount({ userInfo, handleClick, handleSignOut, accountRoute, theme, t }: {
|
|
4
4
|
userInfo: UserType;
|
|
5
5
|
handleClick: () => void;
|
|
6
6
|
handleSignOut: () => Promise<void>;
|
|
7
7
|
accountRoute?: string;
|
|
8
8
|
theme: Theme;
|
|
9
|
+
t: (key: string, params?: any) => string;
|
|
9
10
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,7 +5,7 @@ import { Box, Typography, IconButton, Menu, MenuItem, Tooltip, Avatar, ListItem,
|
|
|
5
5
|
import { Logout, Person } from "@mui/icons-material";
|
|
6
6
|
import { useRouter } from 'next/navigation';
|
|
7
7
|
import { ThemeProvider } from '@mui/material/styles';
|
|
8
|
-
export default function UserMenuAccount({ userInfo, handleClick, handleSignOut, accountRoute = '/account', theme }) {
|
|
8
|
+
export default function UserMenuAccount({ userInfo, handleClick, handleSignOut, accountRoute = '/account', theme, t }) {
|
|
9
9
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
10
10
|
const router = useRouter();
|
|
11
11
|
const handleAccountClick = (event) => {
|
|
@@ -33,5 +33,5 @@ export default function UserMenuAccount({ userInfo, handleClick, handleSignOut,
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
}
|
|
36
|
-
}, children: [_jsxs(ListItem, { sx: { display: 'flex', alignItems: 'center' }, children: [_jsx(ListItemIcon, { sx: { minWidth: 46 }, children: _jsx(Avatar, {}) }), _jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle2", children: userInfo.name?.replace('/', ' ') }), _jsx(Typography, { variant: "subtitle2", sx: { fontWeight: 'normal' }, children: userInfo.email })] })] }), _jsxs(MenuItem, { onClick: () => { router.push(accountRoute); handleClick(); handleClose(); }, sx: { py: 1 }, children: [_jsx(ListItemIcon, { sx: { mr: 1 }, children: _jsx(Person, { fontSize: "small" }) }), "
|
|
36
|
+
}, children: [_jsxs(ListItem, { sx: { display: 'flex', alignItems: 'center' }, children: [_jsx(ListItemIcon, { sx: { minWidth: 46 }, children: _jsx(Avatar, {}) }), _jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle2", children: userInfo.name?.replace('/', ' ') }), _jsx(Typography, { variant: "subtitle2", sx: { fontWeight: 'normal' }, children: userInfo.email })] })] }), _jsxs(MenuItem, { onClick: () => { router.push(accountRoute); handleClick(); handleClose(); }, sx: { py: 1 }, children: [_jsx(ListItemIcon, { sx: { mr: 1 }, children: _jsx(Person, { fontSize: "small" }) }), " ", t('library.accountMenu.manageAccount')] }), _jsxs(MenuItem, { onClick: async () => await handleSignOut(), sx: { py: 1 }, children: [_jsx(ListItemIcon, { sx: { mr: 1 }, children: _jsx(Logout, { fontSize: "small" }) }), " ", t('library.accountMenu.signOut')] })] }), _jsx(Tooltip, { title: t('library.accountMenu.openMenu'), children: _jsx(IconButton, { onClick: handleAccountClick, children: _jsx(Avatar, { sx: { bgcolor: 'secondary.main', color: 'secondary.contrastText' }, alt: userInfo.name !== " " ? userInfo.name : userInfo.email, src: userInfo.picture, children: userInfo.picture ? '' : userInfo.name !== " " ? userInfo.name?.charAt(0).toUpperCase() : userInfo.email?.charAt(0).toUpperCase() }) }) })] }) }));
|
|
37
37
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UserType } from '../../types/user';
|
|
2
2
|
import { Theme } from "@emotion/react";
|
|
3
|
-
declare const AccountProfile: ({ userAccount, handleSignOut, handleUpdateUser, handleUpdatePassword, handleDeleteUser, container, containerProps, theme, afterUpdateCallback, confirmMui }: {
|
|
3
|
+
declare const AccountProfile: ({ userAccount, handleSignOut, handleUpdateUser, handleUpdatePassword, handleDeleteUser, container, containerProps, theme, afterUpdateCallback, confirmMui, t }: {
|
|
4
4
|
userAccount: UserType;
|
|
5
5
|
handleSignOut: () => Promise<void>;
|
|
6
6
|
handleUpdateUser: (id: string, user: Partial<UserType>) => Promise<void>;
|
|
@@ -11,5 +11,6 @@ declare const AccountProfile: ({ userAccount, handleSignOut, handleUpdateUser, h
|
|
|
11
11
|
theme: Theme;
|
|
12
12
|
afterUpdateCallback: (user: Partial<UserType>) => void;
|
|
13
13
|
confirmMui?: (options?: any) => Promise<void>;
|
|
14
|
+
t: (key: string, params?: any) => string;
|
|
14
15
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
15
16
|
export default AccountProfile;
|
|
@@ -6,7 +6,7 @@ import { LoadingButton } from '@mui/lab';
|
|
|
6
6
|
import { VisibilityOff, Visibility, Delete } from '@mui/icons-material';
|
|
7
7
|
import Grid from '@mui/material/Grid2';
|
|
8
8
|
import { ThemeProvider } from '@mui/material/styles';
|
|
9
|
-
const AccountProfile = ({ userAccount, handleSignOut, handleUpdateUser, handleUpdatePassword, handleDeleteUser, container = 'Box', containerProps = {}, theme, afterUpdateCallback = () => { }, confirmMui }) => {
|
|
9
|
+
const AccountProfile = ({ userAccount, handleSignOut, handleUpdateUser, handleUpdatePassword, handleDeleteUser, container = 'Box', containerProps = {}, theme, afterUpdateCallback = () => { }, confirmMui, t }) => {
|
|
10
10
|
const [userInfo, setUserInfo] = useState(userAccount);
|
|
11
11
|
const [loadingUdateButton, setLoadingUpdateButton] = useState(false);
|
|
12
12
|
const [loadingSaveButton, setLoadingSaveButton] = useState(false);
|
|
@@ -39,20 +39,20 @@ const AccountProfile = ({ userAccount, handleSignOut, handleUpdateUser, handleUp
|
|
|
39
39
|
};
|
|
40
40
|
const savePassword = async () => {
|
|
41
41
|
if (password === "") {
|
|
42
|
-
setError('
|
|
42
|
+
setError(t('library.accountProfile.passwordRequired'));
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
if (confirmPassword === "") {
|
|
46
|
-
setError('
|
|
46
|
+
setError(t('library.accountProfile.confirmPasswordRequired'));
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
if (password !== confirmPassword) {
|
|
50
|
-
setError('
|
|
50
|
+
setError(t('library.accountProfile.passwordsMustMatch'));
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
const passwordRegex = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ]).{8,}$/;
|
|
54
54
|
if (!passwordRegex.test(password)) {
|
|
55
|
-
setError(
|
|
55
|
+
setError(t('library.accountProfile.passwordRequirements'));
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
setLoadingSaveButton(true);
|
|
@@ -61,7 +61,7 @@ const AccountProfile = ({ userAccount, handleSignOut, handleUpdateUser, handleUp
|
|
|
61
61
|
await handleUpdatePassword(userInfo.id, password);
|
|
62
62
|
setError("");
|
|
63
63
|
setShowEditPassword(false);
|
|
64
|
-
alert('
|
|
64
|
+
alert(t('library.accountProfile.passwordUpdated'));
|
|
65
65
|
}
|
|
66
66
|
catch (err) {
|
|
67
67
|
console.log(err);
|
|
@@ -74,11 +74,11 @@ const AccountProfile = ({ userAccount, handleSignOut, handleUpdateUser, handleUp
|
|
|
74
74
|
setLoadingUpdateButton(true);
|
|
75
75
|
if (userInfo) {
|
|
76
76
|
try {
|
|
77
|
-
await handleUpdateUser(userInfo.id, {
|
|
77
|
+
await handleUpdateUser(userInfo.id, { firstname: userInfo.firstname, lastname: userInfo.lastname });
|
|
78
78
|
if (afterUpdateCallback) {
|
|
79
79
|
afterUpdateCallback(userInfo);
|
|
80
80
|
}
|
|
81
|
-
alert('
|
|
81
|
+
alert(t('library.accountProfile.userUpdated'));
|
|
82
82
|
}
|
|
83
83
|
catch (err) {
|
|
84
84
|
console.log(err);
|
|
@@ -90,10 +90,10 @@ const AccountProfile = ({ userAccount, handleSignOut, handleUpdateUser, handleUp
|
|
|
90
90
|
if (userInfo) {
|
|
91
91
|
try {
|
|
92
92
|
if (confirmMui) {
|
|
93
|
-
await confirmMui({ description:
|
|
93
|
+
await confirmMui({ description: t('library.accountProfile.confirmDeleteAccount'), confirmationText: t('library.accountProfile.yesRemove'), confirmationButtonProps: { variant: 'contained', color: 'error' } });
|
|
94
94
|
}
|
|
95
95
|
else {
|
|
96
|
-
confirm(
|
|
96
|
+
confirm(t('library.accountProfile.confirmDeleteAccount'));
|
|
97
97
|
}
|
|
98
98
|
setLoadingDeleteButton(true);
|
|
99
99
|
await handleDeleteUser(userInfo.id);
|
|
@@ -137,17 +137,17 @@ const AccountProfile = ({ userAccount, handleSignOut, handleUpdateUser, handleUp
|
|
|
137
137
|
}
|
|
138
138
|
}*/
|
|
139
139
|
const renderAccountProfile = (_jsxs(Box, { component: "div", children: [!userInfo.name ?
|
|
140
|
-
_jsx(Alert, { severity: "warning", sx: { mb: 2 }, children:
|
|
141
|
-
: '', _jsx(Grid, { container: true, spacing: 2, children: _jsxs(Grid, { size: { xs: 12, md: 9, lg: 6 }, children: [_jsxs(Box, { component: "div", children: [_jsx(Typography, { variant: "h6", children:
|
|
142
|
-
_jsxs(Box, { component: "div", sx: { mt: 2, mb: 0 }, children: [_jsx(TextField, { required: true, fullWidth: true, name: "password", label:
|
|
140
|
+
_jsx(Alert, { severity: "warning", sx: { mb: 2 }, children: t('library.accountProfile.completeInfo') })
|
|
141
|
+
: '', _jsx(Grid, { container: true, spacing: 2, children: _jsxs(Grid, { size: { xs: 12, md: 9, lg: 6 }, children: [_jsxs(Box, { component: "div", children: [_jsx(Typography, { variant: "h6", children: t('library.accountProfile.profileName') }), _jsx(Box, { component: "div", sx: { mt: 2, mb: 0 }, children: _jsx(TextField, { fullWidth: true, label: t('library.accountProfile.firstName'), name: "firstname", value: userInfo.firstname, onChange: handleChange, error: !userInfo.firstname || userInfo.firstname === "" ? true : false, helperText: !userInfo.firstname || userInfo.firstname === "" ? t('library.accountProfile.enterFirstName') : '', size: "small" }) }), _jsx(Box, { component: "div", sx: { mt: 2, mb: 0 }, children: _jsx(TextField, { fullWidth: true, label: t('library.accountProfile.lastName'), name: "lastname", value: userInfo.lastname, onChange: handleChange, error: !userInfo.lastname || userInfo.lastname === "" ? true : false, helperText: !userInfo.lastname || userInfo.lastname === "" ? t('library.accountProfile.enterLastName') : '', size: "small" }) }), _jsx(Box, { component: "div", sx: { mt: 2, mb: 0 }, children: _jsx(LoadingButton, { variant: "contained", color: "primary", loading: loadingUdateButton, onClick: () => handleUpdate(), disabled: !userInfo.firstname || userInfo.firstname === "" || !userInfo.lastname || userInfo.lastname === "", children: t('library.accountProfile.update') }) })] }), _jsxs(Box, { component: "div", sx: { mt: 4 }, children: [_jsx(Typography, { variant: "h6", children: t('library.accountProfile.security') }), !showEditPassword ? _jsx(Box, { component: "div", sx: { mt: 2, mb: 0 }, children: _jsx(Button, { variant: 'outlined', onClick: () => setShowEditPassword(!showEditPassword), children: t('library.accountProfile.setOrEditPassword') }) }) : '', showEditPassword ?
|
|
142
|
+
_jsxs(Box, { component: "div", sx: { mt: 2, mb: 0 }, children: [_jsx(TextField, { required: true, fullWidth: true, name: "password", label: t('library.accountProfile.newPassword'), type: showNewPassword ? 'text' : 'password', id: "password", size: 'small', autoComplete: "current-password", onChange: (e) => setPassword(e.target.value), value: password, slotProps: {
|
|
143
143
|
input: {
|
|
144
144
|
endAdornment: _jsx(InputAdornment, { position: "end", children: _jsx(IconButton, { "aria-label": "toggle password visibility", onClick: handleClickShowPassword, onMouseDown: handleMouseDownPassword, edge: "end", children: showNewPassword ? _jsx(VisibilityOff, {}) : _jsx(Visibility, {}) }) }),
|
|
145
145
|
}
|
|
146
|
-
} }), _jsx(TextField, { sx: { mt: 2 }, required: true, fullWidth: true, label:
|
|
146
|
+
} }), _jsx(TextField, { sx: { mt: 2 }, required: true, fullWidth: true, label: t('library.accountProfile.confirmPassword'), type: showConfirmPassword ? 'text' : 'password', id: "confirm-password", size: 'small', autoComplete: "confirm-password", onChange: (e) => setConfirmPassword(e.target.value), value: confirmPassword, slotProps: {
|
|
147
147
|
input: {
|
|
148
148
|
endAdornment: _jsx(InputAdornment, { position: "end", children: _jsx(IconButton, { "aria-label": "toggle password visibility", onClick: handleClickShowConfirmPassword, onMouseDown: handleMouseDownConfirmPassword, edge: "end", children: showConfirmPassword ? _jsx(VisibilityOff, {}) : _jsx(Visibility, {}) }) }),
|
|
149
149
|
}
|
|
150
|
-
} }), error !== '' ? _jsx(Box, { component: 'div', sx: { mt: 1 }, children: _jsx(Typography, { variant: 'subtitle2', color: 'error', children: error }) }) : '', _jsxs(Box, { component: "div", sx: { mt: 3 }, children: [_jsx(Button, { variant: "contained", color: "inherit", onClick: () => setShowEditPassword(false), sx: { mr: 2 }, children:
|
|
150
|
+
} }), error !== '' ? _jsx(Box, { component: 'div', sx: { mt: 1 }, children: _jsx(Typography, { variant: 'subtitle2', color: 'error', children: error }) }) : '', _jsxs(Box, { component: "div", sx: { mt: 3 }, children: [_jsx(Button, { variant: "contained", color: "inherit", onClick: () => setShowEditPassword(false), sx: { mr: 2 }, children: t('library.accountProfile.cancel') }), _jsx(LoadingButton, { loading: loadingSaveButton, type: "submit", variant: "contained", color: "primary", onClick: () => savePassword(), children: t('library.accountProfile.save') })] })] }) : ''] }), _jsxs(Box, { component: "div", sx: { mt: 4 }, children: [_jsx(Typography, { variant: 'h6', children: t('library.accountProfile.deleteAccount') }), _jsx(Box, { component: "div", sx: { mt: 2, mb: 0 }, children: _jsx(Alert, { severity: "error", sx: { mt: 2 }, action: _jsxs(LoadingButton, { variant: "contained", color: "error", loading: loadingDeleteButton, onClick: () => handleDelete(), size: 'small', children: [_jsx(Delete, { fontSize: "small", sx: { mr: 1 } }), " ", t('library.accountProfile.deleteAccount')] }), children: t('library.accountProfile.actionCannotBeUndone') }) })] })] }, 3) })] }));
|
|
151
151
|
return _jsx(ThemeProvider, { theme: theme, children: container === "Card" ? (_jsx(Card, { ...containerProps, children: _jsx(CardContent, { children: renderAccountProfile }) })) : (_jsx(Box, { ...containerProps, children: renderAccountProfile })) });
|
|
152
152
|
};
|
|
153
153
|
export default AccountProfile;
|
|
@@ -1,17 +1,39 @@
|
|
|
1
1
|
import 'chartjs-adapter-moment';
|
|
2
2
|
import 'moment/locale/it';
|
|
3
3
|
import { Theme } from "@emotion/react";
|
|
4
|
+
import { FilterTagMode, InfluxFillType } from '../../server-actions/types';
|
|
4
5
|
type Measure = {
|
|
5
6
|
name: string;
|
|
7
|
+
description: string;
|
|
6
8
|
polltime: number;
|
|
9
|
+
dwPolltime?: number;
|
|
7
10
|
unit: string;
|
|
11
|
+
stepped: boolean;
|
|
8
12
|
};
|
|
9
|
-
declare const TrendChart: ({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
declare const TrendChart: ({ filter, measures1, annotationsDataFn, measures2, enableDatePicker, handleGetInfluxData, handleGetDwSlotsCB, handleExportDataCB, theme, initialTimeStart, initialTimeEnd, t }: {
|
|
14
|
+
filter: {
|
|
15
|
+
field: string;
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
annotationsDataFn?: () => Promise<any>;
|
|
19
|
+
measures1?: Array<Measure>;
|
|
20
|
+
measures2?: Array<Measure>;
|
|
13
21
|
enableDatePicker: boolean;
|
|
14
|
-
handleGetInfluxData: (measure: string, timeStart: number, timeEnd: number,
|
|
22
|
+
handleGetInfluxData: (measure: string, timeStart: number, timeEnd: number, filter: {
|
|
23
|
+
field: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}, timeGroup: string, raw: boolean, fill?: InfluxFillType, filterTag?: number, includeTag?: FilterTagMode) => Promise<any>;
|
|
26
|
+
handleGetDwSlotsCB?: (timeStart: number, timeEnd: number, filter: {
|
|
27
|
+
field: string;
|
|
28
|
+
value: string;
|
|
29
|
+
}) => Promise<any>;
|
|
30
|
+
handleExportDataCB?: (measure: string, timeStart: number, timeEnd: number, filter: {
|
|
31
|
+
field: string;
|
|
32
|
+
value: string;
|
|
33
|
+
}) => Promise<any>;
|
|
15
34
|
theme: Theme;
|
|
16
|
-
|
|
35
|
+
initialTimeStart?: number;
|
|
36
|
+
initialTimeEnd?: number;
|
|
37
|
+
t: (key: string, params?: any) => string;
|
|
38
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
17
39
|
export default TrendChart;
|