mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-10-30 01:42:19 +00:00
Version 2.5.10
This commit is contained in:
20
package-lock.json
generated
20
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ucentral-client",
|
||||
"version": "2.5.9",
|
||||
"version": "2.5.10",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ucentral-client",
|
||||
"version": "2.5.9",
|
||||
"version": "2.5.10",
|
||||
"dependencies": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
@@ -32,7 +32,7 @@
|
||||
"react-tooltip": "^4.2.21",
|
||||
"react-widgets": "^5.1.1",
|
||||
"sass": "^1.35.1",
|
||||
"ucentral-libs": "^1.0.45",
|
||||
"ucentral-libs": "^1.0.51",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -15046,9 +15046,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ucentral-libs": {
|
||||
"version": "1.0.45",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.45.tgz",
|
||||
"integrity": "sha512-CLLU0u9pKe9PsbkFIRx0VXmOqERhcI3EUUSQhGgdLefu6VyPbkt2jgwjL4ou/KBx+LcW7EixSq3CLmj3WlPlLQ==",
|
||||
"version": "1.0.51",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.51.tgz",
|
||||
"integrity": "sha512-VcWWThbkM0wx5MJ9zlQIohQVnwFHzTy5hvcGnY8J9uIqR3EScA2S6JHnUyPWwQ1qo6G0svgmmDUKeFLW06fZcw==",
|
||||
"dependencies": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
@@ -15058,6 +15058,7 @@
|
||||
"libphonenumber-js": "^1.9.37",
|
||||
"lodash": "^4.17.21",
|
||||
"react-flow-renderer": "^9.6.6",
|
||||
"react-i18next": "^11.11.0",
|
||||
"react-paginate": "^7.1.3",
|
||||
"react-phone-input-2": "^2.14.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
@@ -28137,9 +28138,9 @@
|
||||
}
|
||||
},
|
||||
"ucentral-libs": {
|
||||
"version": "1.0.45",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.45.tgz",
|
||||
"integrity": "sha512-CLLU0u9pKe9PsbkFIRx0VXmOqERhcI3EUUSQhGgdLefu6VyPbkt2jgwjL4ou/KBx+LcW7EixSq3CLmj3WlPlLQ==",
|
||||
"version": "1.0.51",
|
||||
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.51.tgz",
|
||||
"integrity": "sha512-VcWWThbkM0wx5MJ9zlQIohQVnwFHzTy5hvcGnY8J9uIqR3EScA2S6JHnUyPWwQ1qo6G0svgmmDUKeFLW06fZcw==",
|
||||
"requires": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
@@ -28149,6 +28150,7 @@
|
||||
"libphonenumber-js": "^1.9.37",
|
||||
"lodash": "^4.17.21",
|
||||
"react-flow-renderer": "^9.6.6",
|
||||
"react-i18next": "^11.11.0",
|
||||
"react-paginate": "^7.1.3",
|
||||
"react-phone-input-2": "^2.14.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ucentral-client",
|
||||
"version": "2.5.9",
|
||||
"version": "2.5.10",
|
||||
"dependencies": {
|
||||
"@coreui/coreui": "^3.4.0",
|
||||
"@coreui/icons": "^2.0.1",
|
||||
@@ -26,7 +26,7 @@
|
||||
"react-tooltip": "^4.2.21",
|
||||
"react-widgets": "^5.1.1",
|
||||
"sass": "^1.35.1",
|
||||
"ucentral-libs": "^1.0.45",
|
||||
"ucentral-libs": "^1.0.51",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"main": "index.js",
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
"contact": {
|
||||
"access_pin": "Zugangs-PIN",
|
||||
"add_contact": "Kontakt hinzufügen",
|
||||
"contact": "Kontakt",
|
||||
"create_contact": "Kontakt erstellen",
|
||||
"currently_selected_contact": "Aktuell ausgewählter Kontakt: {{contact}}",
|
||||
"delete": "Kontakt löschen?",
|
||||
@@ -347,7 +348,9 @@
|
||||
"currently_selected_venue": "Aktuell ausgewählter Veranstaltungsort: {{config}}",
|
||||
"delete_success": "Entität erfolgreich gelöscht",
|
||||
"delete_warning": "Achtung: Dieser Vorgang kann nicht rückgängig gemacht werden",
|
||||
"duplicate_from_node": "Mit einem bestimmten Root-Knoten duplizieren",
|
||||
"duplicate_map": "Karte duplizieren",
|
||||
"duplicate_with_node": "Dupliziere {{mapName}} mit {{rootName}} als Root-Knoten",
|
||||
"edit_failure": "Aktualisierung fehlgeschlagen : {{error}}",
|
||||
"enter_here": "Geben Sie hier die IP(s) ein, die Sie hinzufügen möchten",
|
||||
"entire_tree": "Netzwerkkarte",
|
||||
@@ -664,6 +667,19 @@
|
||||
"uptime": "Betriebszeit",
|
||||
"used_total_memory": "{{used}} verwendet / {{total}} insgesamt"
|
||||
},
|
||||
"subscriber": {
|
||||
"create": "Abonnenten erstellen",
|
||||
"edit": "Abonnent bearbeiten",
|
||||
"error_create": "Fehler beim Erstellen des Abonnenten: {{error}}",
|
||||
"error_delete": "Fehler beim Löschen des Abonnenten: {{error}}",
|
||||
"error_fetching": "Fehler beim Abrufen von Abonnenten: {{error}}",
|
||||
"error_fetching_single": "Fehler beim Abrufen des Abonnenten: {{error}}",
|
||||
"error_update": "Fehler beim Aktualisieren des Abonnenten: {{error}}",
|
||||
"subscribers": "Abonnenten",
|
||||
"success_create": "Abonnent erfolgreich erstellt!",
|
||||
"success_delete": "Abonnent erfolgreich gelöscht!",
|
||||
"success_update": "Abonnent erfolgreich aktualisiert!"
|
||||
},
|
||||
"system": {
|
||||
"error_fetching": "Fehler beim Abrufen von Systeminformationen",
|
||||
"error_reloading": "Fehler beim Neuladen: {{error}}",
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
"contact": {
|
||||
"access_pin": "Access PIN",
|
||||
"add_contact": "Add Contact",
|
||||
"contact": "Contact",
|
||||
"create_contact": "Create Contact",
|
||||
"currently_selected_contact": "Currently Selected Contact: {{contact}}",
|
||||
"delete": "Delete Contact?",
|
||||
@@ -347,7 +348,9 @@
|
||||
"currently_selected_venue": "Currently Selected Venue: {{config}}",
|
||||
"delete_success": "Entity Successfully Deleted",
|
||||
"delete_warning": "Warning: this operation cannot be reverted",
|
||||
"duplicate_from_node": "Duplicate with specific Root Node",
|
||||
"duplicate_map": "Duplicate Map",
|
||||
"duplicate_with_node": "Duplicate {{mapName}} with {{rootName}} as root node",
|
||||
"edit_failure": "Update unsuccessful : {{error}}",
|
||||
"enter_here": "Enter the IP(s) you'd like to add here",
|
||||
"entire_tree": "Network Map",
|
||||
@@ -664,6 +667,19 @@
|
||||
"uptime": "Uptime",
|
||||
"used_total_memory": "{{used}} used / {{total}} total "
|
||||
},
|
||||
"subscriber": {
|
||||
"create": "Create Subscriber",
|
||||
"edit": "Edit Subscriber",
|
||||
"error_create": "Error creating subscriber: {{error}}",
|
||||
"error_delete": "Error deleting subscriber: {{error}}",
|
||||
"error_fetching": "Error fetching subscribers: {{error}}",
|
||||
"error_fetching_single": "Error fetching subscriber: {{error}}",
|
||||
"error_update": "Error updating subscriber: {{error}}",
|
||||
"subscribers": "Subscribers",
|
||||
"success_create": "Subscriber successfully created!",
|
||||
"success_delete": "Subscriber successfully deleted!",
|
||||
"success_update": "Successfully updated subscriber!"
|
||||
},
|
||||
"system": {
|
||||
"error_fetching": "Error while fetching system information",
|
||||
"error_reloading": "Error while reloading: {{error}}",
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
"contact": {
|
||||
"access_pin": "PIN de acceso",
|
||||
"add_contact": "Agregar contacto",
|
||||
"contact": "Contacto",
|
||||
"create_contact": "Crear contacto",
|
||||
"currently_selected_contact": "Contacto seleccionado actualmente: {{contact}}",
|
||||
"delete": "¿Borrar contacto?",
|
||||
@@ -347,7 +348,9 @@
|
||||
"currently_selected_venue": "Lugar seleccionado actualmente: {{config}}",
|
||||
"delete_success": "Entidad eliminada correctamente",
|
||||
"delete_warning": "Advertencia: esta operación no se puede revertir",
|
||||
"duplicate_from_node": "Duplicar con un nodo raíz específico",
|
||||
"duplicate_map": "Mapa duplicado",
|
||||
"duplicate_with_node": "Duplicar {{mapName}} con {{rootName}} como nodo raíz",
|
||||
"edit_failure": "Actualización fallida: {{error}}",
|
||||
"enter_here": "Ingrese las IP que desea agregar aquí",
|
||||
"entire_tree": "Mapa de red",
|
||||
@@ -664,6 +667,19 @@
|
||||
"uptime": "Tiempo de actividad",
|
||||
"used_total_memory": "{{used}} usado / {{total}} total"
|
||||
},
|
||||
"subscriber": {
|
||||
"create": "Crear suscriptor",
|
||||
"edit": "Editar suscriptor",
|
||||
"error_create": "Error al crear el suscriptor: {{error}}",
|
||||
"error_delete": "Error al eliminar el suscriptor: {{error}}",
|
||||
"error_fetching": "Error al obtener suscriptores: {{error}}",
|
||||
"error_fetching_single": "Error al obtener el suscriptor: {{error}}",
|
||||
"error_update": "Error al actualizar el suscriptor: {{error}}",
|
||||
"subscribers": "Suscriptores",
|
||||
"success_create": "¡Suscriptor creado correctamente!",
|
||||
"success_delete": "¡Suscriptor eliminado correctamente!",
|
||||
"success_update": "Suscriptor actualizado con éxito!"
|
||||
},
|
||||
"system": {
|
||||
"error_fetching": "Error al obtener información del sistema",
|
||||
"error_reloading": "Error al recargar: {{error}}",
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
"contact": {
|
||||
"access_pin": "NIP d'accès",
|
||||
"add_contact": "Ajouter le contact",
|
||||
"contact": "Contact",
|
||||
"create_contact": "Créer un contact",
|
||||
"currently_selected_contact": "Contact actuellement sélectionné : {{contact}}",
|
||||
"delete": "Effacer le contact?",
|
||||
@@ -347,7 +348,9 @@
|
||||
"currently_selected_venue": "Lieu actuellement sélectionné : {{config}}",
|
||||
"delete_success": "Entité supprimée avec succès",
|
||||
"delete_warning": "Attention : cette opération ne peut pas être annulée",
|
||||
"duplicate_from_node": "Dupliquer avec un nœud racine spécifique",
|
||||
"duplicate_map": "Carte en double",
|
||||
"duplicate_with_node": "Dupliquer {{mapName}} avec {{rootName}} comme nœud racine",
|
||||
"edit_failure": "Échec de la mise à jour : {{error}}",
|
||||
"enter_here": "Entrez les IP que vous souhaitez ajouter ici",
|
||||
"entire_tree": "Carte du réseau",
|
||||
@@ -664,6 +667,19 @@
|
||||
"uptime": "La disponibilité",
|
||||
"used_total_memory": "{{used}} utilisé / {{total}} total"
|
||||
},
|
||||
"subscriber": {
|
||||
"create": "Créer un abonné",
|
||||
"edit": "Modifier l'abonné",
|
||||
"error_create": "Erreur lors de la création de l'abonné : {{error}}",
|
||||
"error_delete": "Erreur lors de la suppression de l'abonné : {{error}}",
|
||||
"error_fetching": "Erreur lors de la récupération des abonnés : {{error}}",
|
||||
"error_fetching_single": "Erreur lors de la récupération de l'abonné : {{error}}",
|
||||
"error_update": "Erreur lors de la mise à jour de l'abonné : {{error}}",
|
||||
"subscribers": "Les abonnés",
|
||||
"success_create": "Abonné créé avec succès !",
|
||||
"success_delete": "Abonné supprimé avec succès !",
|
||||
"success_update": "Abonné mis à jour avec succès !"
|
||||
},
|
||||
"system": {
|
||||
"error_fetching": "Erreur lors de la récupération des informations système",
|
||||
"error_reloading": "Erreur lors du rechargement : {{error}}",
|
||||
|
||||
@@ -272,6 +272,7 @@
|
||||
"contact": {
|
||||
"access_pin": "PIN de acesso",
|
||||
"add_contact": "Adicionar contato",
|
||||
"contact": "Contato",
|
||||
"create_contact": "Criar Contato",
|
||||
"currently_selected_contact": "Contato atualmente selecionado: {{contact}}",
|
||||
"delete": "Excluir contato?",
|
||||
@@ -347,7 +348,9 @@
|
||||
"currently_selected_venue": "Local selecionado atualmente: {{config}}",
|
||||
"delete_success": "Entidade excluída com sucesso",
|
||||
"delete_warning": "Aviso: esta operação não pode ser revertida",
|
||||
"duplicate_from_node": "Duplicar com nó raiz específico",
|
||||
"duplicate_map": "Mapa duplicado",
|
||||
"duplicate_with_node": "Duplicar {{mapName}} com {{rootName}} como nó raiz",
|
||||
"edit_failure": "Atualização malsucedida: {{error}}",
|
||||
"enter_here": "Digite o (s) IP (s) que deseja adicionar aqui",
|
||||
"entire_tree": "Mapa de Rede",
|
||||
@@ -664,6 +667,19 @@
|
||||
"uptime": "Tempo de atividade",
|
||||
"used_total_memory": "{{used}} usado / {{total}} total"
|
||||
},
|
||||
"subscriber": {
|
||||
"create": "Criar assinante",
|
||||
"edit": "Editar Assinante",
|
||||
"error_create": "Erro ao criar assinante: {{error}}",
|
||||
"error_delete": "Erro ao excluir assinante: {{error}}",
|
||||
"error_fetching": "Erro ao buscar assinantes: {{error}}",
|
||||
"error_fetching_single": "Erro ao buscar assinante: {{error}}",
|
||||
"error_update": "Erro ao atualizar assinante: {{error}}",
|
||||
"subscribers": "Inscritos",
|
||||
"success_create": "Assinante criado com sucesso!",
|
||||
"success_delete": "Assinante excluído com sucesso!",
|
||||
"success_update": "Assinante atualizado com sucesso!"
|
||||
},
|
||||
"system": {
|
||||
"error_fetching": "Erro ao buscar informações do sistema",
|
||||
"error_reloading": "Erro ao recarregar: {{error}}",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import routes from 'routes';
|
||||
import { CSidebarNavItem } from '@coreui/react';
|
||||
import { cilBarcode, cilRouter, cilSave, cilSettings, cilPeople } from '@coreui/icons';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import { Header, Sidebar, Footer, PageContainer, ToastProvider, useAuth } from 'ucentral-libs';
|
||||
|
||||
const TheLayout = () => {
|
||||
@@ -8,46 +11,52 @@ const TheLayout = () => {
|
||||
const { endpoints, currentToken, user, avatar, logout } = useAuth();
|
||||
const { t, i18n } = useTranslation();
|
||||
|
||||
const navigation = [
|
||||
{
|
||||
_tag: 'CSidebarNavItem',
|
||||
name: t('common.devices'),
|
||||
icon: 'cilRouter',
|
||||
to: '/devices',
|
||||
},
|
||||
{
|
||||
_tag: 'CSidebarNavItem',
|
||||
name: t('firmware.title'),
|
||||
icon: 'cilSave',
|
||||
to: '/firmware',
|
||||
},
|
||||
{
|
||||
_tag: 'CSidebarNavItem',
|
||||
name: t('configuration.default_configs'),
|
||||
icon: 'cilBarcode',
|
||||
to: '/defaultconfigurations',
|
||||
},
|
||||
{
|
||||
_tag: 'CSidebarNavItem',
|
||||
name: t('user.users'),
|
||||
to: '/users',
|
||||
icon: 'cilPeople',
|
||||
},
|
||||
{
|
||||
_tag: 'CSidebarNavItem',
|
||||
name: t('common.system'),
|
||||
to: '/system',
|
||||
icon: 'cilSettings',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="c-app c-default-layout">
|
||||
<Sidebar
|
||||
showSidebar={showSidebar}
|
||||
setShowSidebar={setShowSidebar}
|
||||
logo="assets/OpenWiFi_LogoLockup_WhiteColour.svg"
|
||||
options={navigation}
|
||||
options={
|
||||
<>
|
||||
<CSidebarNavItem
|
||||
className="font-weight-bold"
|
||||
name={t('common.devices')}
|
||||
to="/devices"
|
||||
icon={<CIcon content={cilRouter} size="xl" className="mr-3" />}
|
||||
/>
|
||||
<CSidebarNavItem
|
||||
className="font-weight-bold"
|
||||
name={t('firmware.title')}
|
||||
to="/firmware"
|
||||
icon={<CIcon content={cilSave} size="xl" className="mr-3" />}
|
||||
/>
|
||||
<CSidebarNavItem
|
||||
className="font-weight-bold"
|
||||
name={t('configuration.default_configs')}
|
||||
to="/defaultconfigurations"
|
||||
icon={<CIcon content={cilBarcode} size="xl" className="mr-3" />}
|
||||
/>
|
||||
<CSidebarNavItem
|
||||
className="font-weight-bold"
|
||||
name="Configurations"
|
||||
to="/configuration"
|
||||
icon={<CIcon content={cilBarcode} size="xl" className="mr-3" />}
|
||||
/>
|
||||
<CSidebarNavItem
|
||||
className="font-weight-bold"
|
||||
name={t('user.users')}
|
||||
to="/users"
|
||||
icon={<CIcon content={cilPeople} size="xl" className="mr-3" />}
|
||||
/>
|
||||
<CSidebarNavItem
|
||||
className="font-weight-bold"
|
||||
name={t('common.system')}
|
||||
to="/system"
|
||||
icon={<CIcon content={cilSettings} size="xl" className="mr-3" />}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
redirectTo="/devices"
|
||||
/>
|
||||
<div className="c-wrapper">
|
||||
|
||||
@@ -1,392 +1,11 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CCard, CCardBody, CCardHeader, CButton, CPopover, CButtonToolbar } from '@coreui/react';
|
||||
import { cilPencil, cilSave, cilSync, cilX } from '@coreui/icons';
|
||||
import CIcon from '@coreui/icons-react';
|
||||
import axiosInstance from 'utils/axiosInstance';
|
||||
import { testRegex } from 'utils/helper';
|
||||
import { useUser, EditMyProfile, useAuth, useToast } from 'ucentral-libs';
|
||||
|
||||
const initialState = {
|
||||
Id: {
|
||||
value: '',
|
||||
error: false,
|
||||
editable: false,
|
||||
},
|
||||
newPassword: {
|
||||
value: '',
|
||||
error: false,
|
||||
editable: true,
|
||||
ignore: true,
|
||||
},
|
||||
confirmNewPassword: {
|
||||
value: '',
|
||||
error: false,
|
||||
editable: true,
|
||||
ignore: true,
|
||||
},
|
||||
email: {
|
||||
value: '',
|
||||
error: false,
|
||||
editable: false,
|
||||
},
|
||||
description: {
|
||||
value: '',
|
||||
error: false,
|
||||
editable: true,
|
||||
},
|
||||
name: {
|
||||
value: '',
|
||||
error: false,
|
||||
editable: true,
|
||||
},
|
||||
notes: {
|
||||
value: [],
|
||||
editable: false,
|
||||
},
|
||||
userTypeProprietaryInfo: {
|
||||
value: {},
|
||||
error: false,
|
||||
},
|
||||
mfaMethod: {
|
||||
value: '',
|
||||
error: false,
|
||||
},
|
||||
};
|
||||
import { ProfilePage as Page } from 'ucentral-libs';
|
||||
|
||||
const ProfilePage = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentToken, endpoints, user, getAvatar, avatar } = useAuth();
|
||||
const { addToast } = useToast();
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [userForm, updateWithId, updateWithKey, setUser] = useUser(initialState);
|
||||
const [newAvatar, setNewAvatar] = useState('');
|
||||
const [newAvatarFile, setNewAvatarFile] = useState(null);
|
||||
const [avatarDeleted, setAvatarDeleted] = useState(false);
|
||||
const [fileInputKey, setFileInputKey] = useState(0);
|
||||
const [policies, setPolicies] = useState({
|
||||
passwordPolicy: '',
|
||||
passwordPattern: '',
|
||||
accessPolicy: '',
|
||||
});
|
||||
|
||||
const getPasswordPolicy = () => {
|
||||
axiosInstance
|
||||
.post(`${endpoints.owsec}/api/v1/oauth2?requirements=true`, {})
|
||||
.then((response) => {
|
||||
const newPolicies = response.data;
|
||||
newPolicies.accessPolicy = `${endpoints.owsec}${newPolicies.accessPolicy}`;
|
||||
newPolicies.passwordPolicy = `${endpoints.owsec}${newPolicies.passwordPolicy}`;
|
||||
setPolicies(response.data);
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
const getUser = () => {
|
||||
const options = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${currentToken}`,
|
||||
},
|
||||
};
|
||||
|
||||
axiosInstance
|
||||
.get(`${endpoints.owsec}/api/v1/user/${user.Id}`, options)
|
||||
.then((response) => {
|
||||
const newUser = {};
|
||||
|
||||
for (const key of Object.keys(response.data)) {
|
||||
if (key in initialState && key !== 'currentPassword') {
|
||||
newUser[key] = {
|
||||
...initialState[key],
|
||||
value: response.data[key],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
newUser.mfaMethod = {
|
||||
value: response.data.userTypeProprietaryInfo.mfa.enabled
|
||||
? response.data.userTypeProprietaryInfo.mfa.method
|
||||
: '',
|
||||
error: false,
|
||||
};
|
||||
|
||||
setUser({ ...initialState, ...newUser });
|
||||
})
|
||||
.catch((e) => {
|
||||
addToast({
|
||||
title: t('common.error'),
|
||||
body: t('user.error_fetching_users', { error: e }),
|
||||
color: 'danger',
|
||||
autohide: true,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const uploadAvatar = () => {
|
||||
const options = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${currentToken}`,
|
||||
},
|
||||
};
|
||||
|
||||
const data = new FormData();
|
||||
data.append('file', newAvatarFile);
|
||||
|
||||
axiosInstance
|
||||
.post(`${endpoints.owsec}/api/v1/avatar/${user.Id}`, data, options)
|
||||
.then(() => {
|
||||
addToast({
|
||||
title: t('user.update_success_title'),
|
||||
body: t('user.update_success'),
|
||||
color: 'success',
|
||||
autohide: true,
|
||||
});
|
||||
getAvatar();
|
||||
setNewAvatar('');
|
||||
setNewAvatarFile(null);
|
||||
setFileInputKey(fileInputKey + 1);
|
||||
})
|
||||
.catch(() => {
|
||||
addToast({
|
||||
title: t('user.update_failure_title'),
|
||||
body: t('user.update_failure'),
|
||||
color: 'danger',
|
||||
autohide: true,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const updateUser = () => {
|
||||
setLoading(true);
|
||||
|
||||
if (newAvatar !== '' && newAvatarFile !== null) {
|
||||
uploadAvatar();
|
||||
} else if (avatarDeleted) {
|
||||
const options = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${currentToken}`,
|
||||
},
|
||||
};
|
||||
|
||||
axiosInstance
|
||||
.delete(`${endpoints.owsec}/api/v1/avatar/${user.Id}`, options)
|
||||
.then(() => {
|
||||
getAvatar();
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
if (
|
||||
userForm.newPassword.value !== '' &&
|
||||
(!testRegex(userForm.newPassword.value, policies.passwordPattern) ||
|
||||
userForm.newPassword.value !== userForm.confirmNewPassword.value)
|
||||
) {
|
||||
updateWithKey('newPassword', {
|
||||
error: true,
|
||||
});
|
||||
setLoading(false);
|
||||
} else {
|
||||
const newNotes = [];
|
||||
|
||||
for (let i = 0; i < userForm.notes.value.length; i += 1) {
|
||||
if (userForm.notes.value[i].new) newNotes.push({ note: userForm.notes.value[i].note });
|
||||
}
|
||||
|
||||
const propInfo = { ...userForm.userTypeProprietaryInfo.value };
|
||||
propInfo.mfa.method = userForm.mfaMethod.value === '' ? undefined : userForm.mfaMethod.value;
|
||||
propInfo.mfa.enabled = userForm.mfaMethod.value !== '';
|
||||
|
||||
const parameters = {
|
||||
id: user.Id,
|
||||
description: userForm.description.value,
|
||||
name: userForm.name.value,
|
||||
notes: newNotes,
|
||||
userTypeProprietaryInfo: propInfo,
|
||||
currentPassword: userForm.newPassword.value !== '' ? userForm.newPassword.value : undefined,
|
||||
};
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${currentToken}`,
|
||||
},
|
||||
};
|
||||
|
||||
axiosInstance
|
||||
.put(`${endpoints.owsec}/api/v1/user/${user.Id}`, parameters, options)
|
||||
.then(() => {
|
||||
addToast({
|
||||
title: t('user.update_success_title'),
|
||||
body: t('user.update_success'),
|
||||
color: 'success',
|
||||
autohide: true,
|
||||
});
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
toggleEditing();
|
||||
})
|
||||
.catch((e) => {
|
||||
addToast({
|
||||
title: t('user.update_failure_title'),
|
||||
body: t('user.update_failure', { error: e.response?.data?.ErrorDescription }),
|
||||
color: 'danger',
|
||||
autohide: true,
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
getUser();
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const addNote = (currentNote) => {
|
||||
const newNotes = [...userForm.notes.value];
|
||||
newNotes.unshift({
|
||||
note: currentNote,
|
||||
new: true,
|
||||
created: new Date().getTime() / 1000,
|
||||
createdBy: '',
|
||||
});
|
||||
updateWithKey('notes', { value: newNotes });
|
||||
};
|
||||
|
||||
const showPreview = (e) => {
|
||||
setAvatarDeleted(false);
|
||||
const imageFile = e.target.files[0];
|
||||
setNewAvatar(URL.createObjectURL(imageFile));
|
||||
setNewAvatarFile(imageFile);
|
||||
};
|
||||
|
||||
const deleteAvatar = () => {
|
||||
setNewAvatar('');
|
||||
setAvatarDeleted(true);
|
||||
};
|
||||
|
||||
const sendPhoneNumberTest = async (phoneNumber) => {
|
||||
const options = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${currentToken}`,
|
||||
},
|
||||
};
|
||||
|
||||
return axiosInstance
|
||||
.post(`${endpoints.owsec}/api/v1/sms?validateNumber=true`, { to: phoneNumber }, options)
|
||||
.then(() => true)
|
||||
.catch(() => {
|
||||
addToast({
|
||||
title: t('common.error'),
|
||||
body: t('user.error_sending_code'),
|
||||
color: 'danger',
|
||||
autohide: true,
|
||||
});
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
const testVerificationCode = async (phoneNumber, code) => {
|
||||
const options = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${currentToken}`,
|
||||
},
|
||||
};
|
||||
|
||||
return axiosInstance
|
||||
.post(
|
||||
`${endpoints.owsec}/api/v1/sms?completeValidation=true&validationCode=${code}`,
|
||||
{ to: phoneNumber },
|
||||
options,
|
||||
)
|
||||
.then(() => true)
|
||||
.catch(() => {
|
||||
addToast({
|
||||
title: t('common.error'),
|
||||
body: t('user.wrong_validation_code'),
|
||||
color: 'danger',
|
||||
autohide: true,
|
||||
});
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
const toggleEditing = () => {
|
||||
if (editing) {
|
||||
setAvatarDeleted(false);
|
||||
setNewAvatar('');
|
||||
getUser();
|
||||
getAvatar();
|
||||
}
|
||||
setEditing(!editing);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (user.Id) {
|
||||
getAvatar();
|
||||
getUser();
|
||||
}
|
||||
if (policies.passwordPattern.length === 0) {
|
||||
getPasswordPolicy();
|
||||
}
|
||||
}, [user.Id]);
|
||||
|
||||
return (
|
||||
<CCard className="my-0 py-0">
|
||||
<CCardHeader className="dark-header">
|
||||
<div style={{ fontWeight: '600' }} className=" text-value-lg float-left">
|
||||
{t('user.my_profile')}
|
||||
</div>
|
||||
<div className="text-right float-right">
|
||||
<CButtonToolbar role="group" className="justify-content-end">
|
||||
<CPopover content={t('common.save')}>
|
||||
<CButton disabled={!editing} color="info" onClick={updateUser} className="mx-1">
|
||||
<CIcon name="cil-save" content={cilSave} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
<CPopover content={t('common.edit')}>
|
||||
<CButton disabled={editing} color="dark" onClick={toggleEditing} className="mx-1">
|
||||
<CIcon name="cil-pencil" content={cilPencil} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
<CPopover content={t('common.stop_editing')}>
|
||||
<CButton disabled={!editing} color="dark" onClick={toggleEditing} className="mx-1">
|
||||
<CIcon name="cil-x" content={cilX} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
<CPopover content={t('common.refresh')}>
|
||||
<CButton disabled={editing} color="info" onClick={getUser} className="mx-1">
|
||||
<CIcon content={cilSync} />
|
||||
</CButton>
|
||||
</CPopover>
|
||||
</CButtonToolbar>
|
||||
</div>
|
||||
</CCardHeader>
|
||||
<CCardBody>
|
||||
<EditMyProfile
|
||||
t={t}
|
||||
user={userForm}
|
||||
updateUserWithId={updateWithId}
|
||||
updateWithKey={updateWithKey}
|
||||
loading={loading}
|
||||
policies={policies}
|
||||
addNote={addNote}
|
||||
avatar={avatar}
|
||||
newAvatar={newAvatar}
|
||||
showPreview={showPreview}
|
||||
deleteAvatar={deleteAvatar}
|
||||
fileInputKey={fileInputKey}
|
||||
sendPhoneNumberTest={sendPhoneNumberTest}
|
||||
testVerificationCode={testVerificationCode}
|
||||
editing={editing}
|
||||
avatarDeleted={avatarDeleted}
|
||||
/>
|
||||
</CCardBody>
|
||||
</CCard>
|
||||
);
|
||||
return <Page t={t} axiosInstance={axiosInstance} />;
|
||||
};
|
||||
|
||||
export default ProfilePage;
|
||||
|
||||
Reference in New Issue
Block a user