mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov-ui.git
synced 2025-10-30 18:17:46 +00:00
[WIFI-12412] Fixing SSID.services configuration options
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "wlan-cloud-owprov-ui",
|
"name": "wlan-cloud-owprov-ui",
|
||||||
"version": "2.9.0(16)",
|
"version": "2.9.0(18)",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "wlan-cloud-owprov-ui",
|
"name": "wlan-cloud-owprov-ui",
|
||||||
"version": "2.9.0(16)",
|
"version": "2.9.0(18)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/icons": "^2.0.11",
|
"@chakra-ui/icons": "^2.0.11",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wlan-cloud-owprov-ui",
|
"name": "wlan-cloud-owprov-ui",
|
||||||
"version": "2.9.0(16)",
|
"version": "2.9.0(18)",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.tsx",
|
"main": "index.tsx",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -714,7 +714,7 @@
|
|||||||
"invalid_ipv6": "Ungültige IPv6-Adresse (Bsp.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Ungültige IPv6-Adresse (Bsp.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Ungültige JSON-Zeichenfolge",
|
"invalid_json": "Ungültige JSON-Zeichenfolge",
|
||||||
"invalid_lease_time": "Ungültiger Lease-Time-Wert! Sie müssen im digitUnit-Format vorliegen. Zum Beispiel: 6d2h5m, was 6 Tage, 2 Stunden und 5 Minuten bedeutet. Hier sind die akzeptierten Einheiten: m, h, d. Wenn Sie eine Einheit nicht verwenden möchten, lassen Sie sie vollständig weg. Anstatt also 0d2h0m zu sagen, verwenden Sie 2h",
|
"invalid_lease_time": "Ungültiger Lease-Time-Wert! Sie müssen im digitUnit-Format vorliegen. Zum Beispiel: 6d2h5m, was 6 Tage, 2 Stunden und 5 Minuten bedeutet. Hier sind die akzeptierten Einheiten: m, h, d. Wenn Sie eine Einheit nicht verwenden möchten, lassen Sie sie vollständig weg. Anstatt also 0d2h0m zu sagen, verwenden Sie 2h",
|
||||||
"invalid_mac_uc": "Ungültiger UC-MAC-Wert, zum Beispiel: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Ungültiger MAC-Wert, zum Beispiel: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Ungültiges Passwort, bitte sehen Sie sich die Passwortrichtlinie an",
|
"invalid_password": "Ungültiges Passwort, bitte sehen Sie sich die Passwortrichtlinie an",
|
||||||
"invalid_phone_number": "Ungültige Telefonnummer",
|
"invalid_phone_number": "Ungültige Telefonnummer",
|
||||||
"invalid_phone_numbers": "Mindestens eine der Telefonnummern ist ungültig. Bitte geben Sie sie ohne Symbole und Leerzeichen oder in diesem Format an: +1(123)123-1234",
|
"invalid_phone_numbers": "Mindestens eine der Telefonnummern ist ungültig. Bitte geben Sie sie ohne Symbole und Leerzeichen oder in diesem Format an: +1(123)123-1234",
|
||||||
|
|||||||
@@ -714,7 +714,7 @@
|
|||||||
"invalid_ipv6": "Invalid IPv6 address (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Invalid IPv6 address (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Invalid JSON string",
|
"invalid_json": "Invalid JSON string",
|
||||||
"invalid_lease_time": "Invalid lease time value! They need to be in the digitUnit format. For example: 6d2h5m, which means 6 days, 2 hours and 5 minutes. Here are the accepted units: m, h, d. If you do not want to use a unit, omit it completely. So instead of saying 0d2h0m, use 2h",
|
"invalid_lease_time": "Invalid lease time value! They need to be in the digitUnit format. For example: 6d2h5m, which means 6 days, 2 hours and 5 minutes. Here are the accepted units: m, h, d. If you do not want to use a unit, omit it completely. So instead of saying 0d2h0m, use 2h",
|
||||||
"invalid_mac_uc": "Invalid UC-MAC value, for example: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Invalid MAC value, for example: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Invalid password, please look at the password policy",
|
"invalid_password": "Invalid password, please look at the password policy",
|
||||||
"invalid_phone_number": "Invalid Phone Number",
|
"invalid_phone_number": "Invalid Phone Number",
|
||||||
"invalid_phone_numbers": "One or more of the phone numbers are invalid. Please provide them without symbols and spaces, or in this format: +1(123)123-1234",
|
"invalid_phone_numbers": "One or more of the phone numbers are invalid. Please provide them without symbols and spaces, or in this format: +1(123)123-1234",
|
||||||
@@ -755,8 +755,8 @@
|
|||||||
"success_remove_claim": "Successfully removed claim on: {{serial}}",
|
"success_remove_claim": "Successfully removed claim on: {{serial}}",
|
||||||
"successful_reboots": "Started Rebooting: {{count}}",
|
"successful_reboots": "Started Rebooting: {{count}}",
|
||||||
"successful_upgrades": "Successful upgrades: {{count}}",
|
"successful_upgrades": "Successful upgrades: {{count}}",
|
||||||
"tag_one": "Tag",
|
"tag_one": "Device",
|
||||||
"tags": "Inventory Tags",
|
"tags": "Inventory Devices",
|
||||||
"title": "Inventory",
|
"title": "Inventory",
|
||||||
"warning_reboots": "Not connected: {{count}}",
|
"warning_reboots": "Not connected: {{count}}",
|
||||||
"warning_upgrades": "Devices not connected: {{count}}"
|
"warning_upgrades": "Devices not connected: {{count}}"
|
||||||
|
|||||||
@@ -714,7 +714,7 @@
|
|||||||
"invalid_ipv6": "Dirección IPv6 no válida (ej.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Dirección IPv6 no válida (ej.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Cadena JSON no válida",
|
"invalid_json": "Cadena JSON no válida",
|
||||||
"invalid_lease_time": "¡Valor de tiempo de arrendamiento no válido! Deben estar en el formato digitUnit. Por ejemplo: 6d2h5m, lo que significa 6 días, 2 horas y 5 minutos. Estas son las unidades aceptadas: m, h, d. Si no desea utilizar una unidad, omítala por completo. Entonces, en lugar de decir 0d2h0m, usa 2h",
|
"invalid_lease_time": "¡Valor de tiempo de arrendamiento no válido! Deben estar en el formato digitUnit. Por ejemplo: 6d2h5m, lo que significa 6 días, 2 horas y 5 minutos. Estas son las unidades aceptadas: m, h, d. Si no desea utilizar una unidad, omítala por completo. Entonces, en lugar de decir 0d2h0m, usa 2h",
|
||||||
"invalid_mac_uc": "Valor de UC-MAC no válido, por ejemplo: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Valor de MAC no válido, por ejemplo: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Contraseña no válida, consulte la política de contraseñas",
|
"invalid_password": "Contraseña no válida, consulte la política de contraseñas",
|
||||||
"invalid_phone_number": "Numero de telefono invalido",
|
"invalid_phone_number": "Numero de telefono invalido",
|
||||||
"invalid_phone_numbers": "Uno o más de los números de teléfono no son válidos. Proporciónelos sin símbolos ni espacios, o en este formato: +1(123)123-1234",
|
"invalid_phone_numbers": "Uno o más de los números de teléfono no son válidos. Proporciónelos sin símbolos ni espacios, o en este formato: +1(123)123-1234",
|
||||||
|
|||||||
@@ -714,7 +714,7 @@
|
|||||||
"invalid_ipv6": "Adresse IPv6 invalide (ex. : 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Adresse IPv6 invalide (ex. : 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Chaîne JSON non valide",
|
"invalid_json": "Chaîne JSON non valide",
|
||||||
"invalid_lease_time": "Valeur de durée de bail non valide ! Ils doivent être au format digitUnit. Par exemple : 6d2h5m, ce qui signifie 6 jours, 2 heures et 5 minutes. Voici les unités acceptées : m, h, d. Si vous ne voulez pas utiliser une unité, omettez-la complètement. Donc au lieu de dire 0d2h0m, utilisez 2h",
|
"invalid_lease_time": "Valeur de durée de bail non valide ! Ils doivent être au format digitUnit. Par exemple : 6d2h5m, ce qui signifie 6 jours, 2 heures et 5 minutes. Voici les unités acceptées : m, h, d. Si vous ne voulez pas utiliser une unité, omettez-la complètement. Donc au lieu de dire 0d2h0m, utilisez 2h",
|
||||||
"invalid_mac_uc": "Valeur UC-MAC non valide, par exemple : 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Valeur MAC non valide, par exemple : 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Mot de passe invalide, veuillez consulter la politique de mot de passe",
|
"invalid_password": "Mot de passe invalide, veuillez consulter la politique de mot de passe",
|
||||||
"invalid_phone_number": "Numéro de téléphone invalide",
|
"invalid_phone_number": "Numéro de téléphone invalide",
|
||||||
"invalid_phone_numbers": "Un ou plusieurs des numéros de téléphone sont invalides. Veuillez les fournir sans symboles ni espaces, ou dans ce format : +1(123)123-1234",
|
"invalid_phone_numbers": "Un ou plusieurs des numéros de téléphone sont invalides. Veuillez les fournir sans symboles ni espaces, ou dans ce format : +1(123)123-1234",
|
||||||
|
|||||||
@@ -714,7 +714,7 @@
|
|||||||
"invalid_ipv6": "Endereço IPv6 inválido (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Endereço IPv6 inválido (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Sequência JSON inválida",
|
"invalid_json": "Sequência JSON inválida",
|
||||||
"invalid_lease_time": "Valor de tempo de locação inválido! Eles precisam estar no formato digitUnit. Por exemplo: 6d2h5m, que significa 6 dias, 2 horas e 5 minutos. Aqui estão as unidades aceitas: m, h, d. Se você não quiser usar uma unidade, omita-a completamente. Então, em vez de dizer 0d2h0m, use 2h",
|
"invalid_lease_time": "Valor de tempo de locação inválido! Eles precisam estar no formato digitUnit. Por exemplo: 6d2h5m, que significa 6 dias, 2 horas e 5 minutos. Aqui estão as unidades aceitas: m, h, d. Se você não quiser usar uma unidade, omita-a completamente. Então, em vez de dizer 0d2h0m, use 2h",
|
||||||
"invalid_mac_uc": "Valor UC-MAC inválido, por exemplo: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Valor MAC inválido, por exemplo: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Senha inválida, consulte a política de senha",
|
"invalid_password": "Senha inválida, consulte a política de senha",
|
||||||
"invalid_phone_number": "Número de telefone inválido",
|
"invalid_phone_number": "Número de telefone inválido",
|
||||||
"invalid_phone_numbers": "Um ou mais números de telefone são inválidos. Forneça-os sem símbolos e espaços ou neste formato: +1(123)123-1234",
|
"invalid_phone_numbers": "Um ou mais números de telefone são inválidos. Forneça-os sem símbolos e espaços ou neste formato: +1(123)123-1234",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface Props extends ThemeProps {
|
|||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
label: undefined,
|
label: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const defaultProps = {
|
|||||||
onClick: () => {},
|
onClick: () => {},
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
label: undefined,
|
label: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface Props {
|
|||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
label: undefined,
|
label: undefined,
|
||||||
ml: undefined,
|
ml: undefined,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const defaultProps = {
|
|||||||
label: 'Edit',
|
label: 'Edit',
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
ml: undefined,
|
ml: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ interface Props {
|
|||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
ml: undefined,
|
ml: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const ResponsiveButton = ({
|
|||||||
onClick,
|
onClick,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
isLoading,
|
isLoading,
|
||||||
isCompact,
|
isCompact = true,
|
||||||
color,
|
color,
|
||||||
label,
|
label,
|
||||||
icon,
|
icon,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const defaultProps = {
|
|||||||
onSave: undefined,
|
onSave: undefined,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
ml: undefined,
|
ml: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ interface Props {
|
|||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
ml: undefined,
|
ml: undefined,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface Props extends ThemeProps {
|
|||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isCompact: false,
|
isCompact: true,
|
||||||
label: undefined,
|
label: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const ColumnPicker = ({
|
|||||||
setHiddenColumns,
|
setHiddenColumns,
|
||||||
defaultHiddenColumns = [],
|
defaultHiddenColumns = [],
|
||||||
size,
|
size,
|
||||||
isCompact,
|
isCompact = true,
|
||||||
}: ColumnPickerProps) => {
|
}: ColumnPickerProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { getPref, setPref } = useAuth();
|
const { getPref, setPref } = useAuth();
|
||||||
|
|||||||
@@ -5,27 +5,29 @@ import useFastField from 'hooks/useFastField';
|
|||||||
import { FieldProps } from 'models/Form';
|
import { FieldProps } from 'models/Form';
|
||||||
|
|
||||||
interface Props extends FieldProps, LayoutProps {
|
interface Props extends FieldProps, LayoutProps {
|
||||||
|
formatValue?: (value: string) => string;
|
||||||
hideButton?: boolean;
|
hideButton?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StringField = ({
|
const StringField: React.FC<Props> = ({
|
||||||
name,
|
name,
|
||||||
isDisabled = false,
|
isDisabled = false,
|
||||||
label,
|
label,
|
||||||
hideButton = false,
|
hideButton = false,
|
||||||
isRequired = false,
|
isRequired = false,
|
||||||
element,
|
element,
|
||||||
|
formatValue,
|
||||||
isArea = false,
|
isArea = false,
|
||||||
emptyIsUndefined = false,
|
emptyIsUndefined = false,
|
||||||
definitionKey,
|
definitionKey,
|
||||||
...props
|
...props
|
||||||
}: Props) => {
|
}) => {
|
||||||
const { value, error, isError, onChange, onBlur } = useFastField<string | undefined>({ name });
|
const { value, error, isError, onChange, onBlur } = useFastField<string | undefined>({ name });
|
||||||
|
|
||||||
const onFieldChange = useCallback(
|
const onFieldChange = useCallback(
|
||||||
(e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
|
(e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
|
||||||
if (emptyIsUndefined && e.target.value.length === 0) onChange(undefined);
|
if (emptyIsUndefined && e.target.value.length === 0) onChange(undefined);
|
||||||
else onChange(e.target.value);
|
else onChange(formatValue ? formatValue(e.target.value) : e.target.value);
|
||||||
},
|
},
|
||||||
[onChange],
|
[onChange],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Button, Modal, ModalOverlay, ModalContent, ModalBody, useDisclosure, Flex } from '@chakra-ui/react';
|
import {
|
||||||
|
Modal,
|
||||||
|
ModalOverlay,
|
||||||
|
ModalContent,
|
||||||
|
ModalBody,
|
||||||
|
useDisclosure,
|
||||||
|
Flex,
|
||||||
|
Tooltip,
|
||||||
|
IconButton,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
import { MagnifyingGlass } from 'phosphor-react';
|
import { MagnifyingGlass } from 'phosphor-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import SubscriberSearchDisplayTable from './Table';
|
import SubscriberSearchDisplayTable from './Table';
|
||||||
@@ -19,9 +28,9 @@ const SubscriberSearchModal = ({ operatorId }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button alignItems="center" colorScheme="blue" rightIcon={<MagnifyingGlass />} onClick={onOpen} ml={2}>
|
<Tooltip label={t('common.search')} hasArrow>
|
||||||
{t('common.search')}
|
<IconButton aria-label={t('common.search')} icon={<MagnifyingGlass />} onClick={onOpen} colorScheme="teal" />
|
||||||
</Button>
|
</Tooltip>
|
||||||
<Modal onClose={onClose} isOpen={isOpen} size="xl">
|
<Modal onClose={onClose} isOpen={isOpen} size="xl">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { AddIcon } from '@chakra-ui/icons';
|
import { Modal, ModalOverlay, ModalContent, ModalBody, Center, Spinner } from '@chakra-ui/react';
|
||||||
import { Button, Modal, ModalOverlay, ModalContent, ModalBody, Center, Spinner } from '@chakra-ui/react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import CreateSubscriberDeviceStep0 from './MultiStepForm/Step0';
|
import CreateSubscriberDeviceStep0 from './MultiStepForm/Step0';
|
||||||
import CreateSubscriberDeviceStep1 from './MultiStepForm/Step1';
|
import CreateSubscriberDeviceStep1 from './MultiStepForm/Step1';
|
||||||
import CreateSubscriberDeviceStep2 from './MultiStepForm/Step2';
|
import CreateSubscriberDeviceStep2 from './MultiStepForm/Step2';
|
||||||
import CreateSubscriberDeviceStep3 from './MultiStepForm/Step3';
|
import CreateSubscriberDeviceStep3 from './MultiStepForm/Step3';
|
||||||
import CloseButton from 'components/Buttons/CloseButton';
|
import CloseButton from 'components/Buttons/CloseButton';
|
||||||
|
import CreateButton from 'components/Buttons/CreateButton';
|
||||||
import StepButton from 'components/Buttons/StepButton';
|
import StepButton from 'components/Buttons/StepButton';
|
||||||
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
||||||
import ModalHeader from 'components/Modals/ModalHeader';
|
import ModalHeader from 'components/Modals/ModalHeader';
|
||||||
@@ -141,16 +141,7 @@ const CreateSubscriberDeviceModal = ({ refresh, operatorId, subscriberId, device
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
{user?.userRole === 'CSR' ? null : <CreateButton onClick={onOpen} ml={2} />}
|
||||||
hidden={user?.userRole === 'CSR'}
|
|
||||||
alignItems="center"
|
|
||||||
colorScheme="blue"
|
|
||||||
rightIcon={<AddIcon />}
|
|
||||||
onClick={onOpen}
|
|
||||||
ml={2}
|
|
||||||
>
|
|
||||||
{t('crud.create')}
|
|
||||||
</Button>
|
|
||||||
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ const DeviceActionDropdown = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Tooltip label={t('commands.other')}>
|
<Tooltip label={t('common.actions')}>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
aria-label="Commands"
|
aria-label="Commands"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { AddIcon } from '@chakra-ui/icons';
|
import { useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
||||||
import { Button, useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import CreateConfigurationForm from './Form';
|
import CreateConfigurationForm from './Form';
|
||||||
import CloseButton from 'components/Buttons/CloseButton';
|
import CloseButton from 'components/Buttons/CloseButton';
|
||||||
|
import CreateButton from 'components/Buttons/CreateButton';
|
||||||
import SaveButton from 'components/Buttons/SaveButton';
|
import SaveButton from 'components/Buttons/SaveButton';
|
||||||
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
||||||
import ModalHeader from 'components/Modals/ModalHeader';
|
import ModalHeader from 'components/Modals/ModalHeader';
|
||||||
@@ -51,9 +51,7 @@ const CreateConfigurationModal = ({ refresh, entityId }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button alignItems="center" colorScheme="blue" rightIcon={<AddIcon />} onClick={openModal} ml={2}>
|
<CreateButton onClick={openModal} ml={2} />
|
||||||
{t('crud.create')}
|
|
||||||
</Button>
|
|
||||||
<Modal onClose={closeModal} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
<Modal onClose={closeModal} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AddIcon } from '@chakra-ui/icons';
|
import { useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
||||||
import { Button, useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import CreateContactForm from './Form';
|
import CreateContactForm from './Form';
|
||||||
import CloseButton from 'components/Buttons/CloseButton';
|
import CloseButton from 'components/Buttons/CloseButton';
|
||||||
|
import CreateButton from 'components/Buttons/CreateButton';
|
||||||
import SaveButton from 'components/Buttons/SaveButton';
|
import SaveButton from 'components/Buttons/SaveButton';
|
||||||
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
||||||
import ModalHeader from 'components/Modals/ModalHeader';
|
import ModalHeader from 'components/Modals/ModalHeader';
|
||||||
@@ -47,16 +47,7 @@ const CreateContactModal = ({ refresh, entityId, isVenue, onCreate }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
{user?.userRole === 'CSR' ? null : <CreateButton onClick={onOpen} ml={2} />}
|
||||||
hidden={user?.userRole === 'CSR'}
|
|
||||||
alignItems="center"
|
|
||||||
colorScheme="blue"
|
|
||||||
rightIcon={<AddIcon />}
|
|
||||||
onClick={onOpen}
|
|
||||||
ml={2}
|
|
||||||
>
|
|
||||||
{t('crud.create')}
|
|
||||||
</Button>
|
|
||||||
<Modal onClose={closeModal} isOpen={isOpen} size="xl" initialFocusRef={initialRef}>
|
<Modal onClose={closeModal} isOpen={isOpen} size="xl" initialFocusRef={initialRef}>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ const DeviceActionDropdown = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Tooltip label={t('commands.other')}>
|
<Tooltip label={t('common.actions')}>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
aria-label="Commands"
|
aria-label="Commands"
|
||||||
|
|||||||
@@ -149,12 +149,6 @@ const EditTagModal = ({
|
|||||||
title={t('crud.edit_obj', { obj: tag?.name ?? tag?.serialNumber })}
|
title={t('crud.edit_obj', { obj: tag?.name ?? tag?.serialNumber })}
|
||||||
right={
|
right={
|
||||||
<>
|
<>
|
||||||
<SaveButton
|
|
||||||
onClick={form.submitForm}
|
|
||||||
isLoading={form.isSubmitting}
|
|
||||||
isDisabled={!editing || !form.isValid || (configuration !== null && !configuration.__form.isValid)}
|
|
||||||
mr={2}
|
|
||||||
/>
|
|
||||||
<Popover isOpen={isDeleteOpen} onOpen={onDeleteOpen} onClose={onDeleteClose}>
|
<Popover isOpen={isDeleteOpen} onOpen={onDeleteOpen} onClose={onDeleteClose}>
|
||||||
<Tooltip hasArrow label={t('crud.delete')} placement="top" isDisabled={isDeleteOpen}>
|
<Tooltip hasArrow label={t('crud.delete')} placement="top" isDisabled={isDeleteOpen}>
|
||||||
<Box>
|
<Box>
|
||||||
@@ -208,6 +202,13 @@ const EditTagModal = ({
|
|||||||
onClick={handlePushConfig}
|
onClick={handlePushConfig}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<SaveButton
|
||||||
|
onClick={form.submitForm}
|
||||||
|
isLoading={form.isSubmitting}
|
||||||
|
isDisabled={!editing || !form.isValid || (configuration !== null && !configuration.__form.isValid)}
|
||||||
|
hidden={!editing}
|
||||||
|
ml={2}
|
||||||
|
/>
|
||||||
<EditButton ml={2} isDisabled={editing} onClick={setEditing.toggle} isCompact />
|
<EditButton ml={2} isDisabled={editing} onClick={setEditing.toggle} isCompact />
|
||||||
<CloseButton ml={2} onClick={closeModal} />
|
<CloseButton ml={2} onClick={closeModal} />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
import { useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody, Tooltip, IconButton } from '@chakra-ui/react';
|
||||||
useDisclosure,
|
|
||||||
Modal,
|
|
||||||
ModalOverlay,
|
|
||||||
ModalContent,
|
|
||||||
ModalBody,
|
|
||||||
useBreakpoint,
|
|
||||||
Button,
|
|
||||||
Tooltip,
|
|
||||||
IconButton,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { UploadSimple } from 'phosphor-react';
|
import { UploadSimple } from 'phosphor-react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -36,7 +26,6 @@ const defaultProps = {
|
|||||||
|
|
||||||
const ImportDeviceCsvModal = ({ refresh, deviceClass, parent }) => {
|
const ImportDeviceCsvModal = ({ refresh, deviceClass, parent }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const breakpoint = useBreakpoint();
|
|
||||||
const [refreshId, setRefreshId] = useState(uuid());
|
const [refreshId, setRefreshId] = useState(uuid());
|
||||||
// 0: explanation, file import and file analysis
|
// 0: explanation, file import and file analysis
|
||||||
// 1: testing the serial number list with the API
|
// 1: testing the serial number list with the API
|
||||||
@@ -91,22 +80,6 @@ const ImportDeviceCsvModal = ({ refresh, deviceClass, parent }) => {
|
|||||||
onOpen();
|
onOpen();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getButton = () => {
|
|
||||||
if (breakpoint !== 'base' && breakpoint !== 'sm') {
|
|
||||||
return (
|
|
||||||
<Button ml={2} colorScheme="blue" onClick={openModal} rightIcon={<UploadSimple size={20} />}>
|
|
||||||
{t('devices.import_batch_tags')}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tooltip label={t('devices.import_batch_tags')}>
|
|
||||||
<IconButton ml={2} colorScheme="blue" onClick={openModal} icon={<UploadSimple size={20} />} />
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeModal = () => (isCloseable ? onClose() : openConfirm());
|
const closeModal = () => (isCloseable ? onClose() : openConfirm());
|
||||||
|
|
||||||
const closeCancelAndForm = () => {
|
const closeCancelAndForm = () => {
|
||||||
@@ -116,7 +89,9 @@ const ImportDeviceCsvModal = ({ refresh, deviceClass, parent }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{getButton()}
|
<Tooltip label={t('devices.import_batch_tags')}>
|
||||||
|
<IconButton ml={2} colorScheme="teal" onClick={openModal} icon={<UploadSimple size={20} />} />
|
||||||
|
</Tooltip>
|
||||||
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AddIcon } from '@chakra-ui/icons';
|
import { useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
||||||
import { Button, useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import CreateLocationForm from './Form';
|
import CreateLocationForm from './Form';
|
||||||
import CloseButton from 'components/Buttons/CloseButton';
|
import CloseButton from 'components/Buttons/CloseButton';
|
||||||
|
import CreateButton from 'components/Buttons/CreateButton';
|
||||||
import SaveButton from 'components/Buttons/SaveButton';
|
import SaveButton from 'components/Buttons/SaveButton';
|
||||||
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
||||||
import ModalHeader from 'components/Modals/ModalHeader';
|
import ModalHeader from 'components/Modals/ModalHeader';
|
||||||
import { useAuth } from 'contexts/AuthProvider';
|
|
||||||
import useFormRef from 'hooks/useFormRef';
|
import useFormRef from 'hooks/useFormRef';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
@@ -22,7 +21,6 @@ const defaultProps = {
|
|||||||
|
|
||||||
const CreateLocationModal = ({ refresh, entityId }) => {
|
const CreateLocationModal = ({ refresh, entityId }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { user } = useAuth();
|
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const { isOpen: showConfirm, onOpen: openConfirm, onClose: closeConfirm } = useDisclosure();
|
const { isOpen: showConfirm, onOpen: openConfirm, onClose: closeConfirm } = useDisclosure();
|
||||||
const { form, formRef } = useFormRef();
|
const { form, formRef } = useFormRef();
|
||||||
@@ -36,16 +34,7 @@ const CreateLocationModal = ({ refresh, entityId }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<CreateButton onClick={onOpen} ml={2} />
|
||||||
hidden={user?.userRole === 'CSR'}
|
|
||||||
alignItems="center"
|
|
||||||
colorScheme="blue"
|
|
||||||
rightIcon={<AddIcon />}
|
|
||||||
onClick={onOpen}
|
|
||||||
ml={2}
|
|
||||||
>
|
|
||||||
{t('crud.create')}
|
|
||||||
</Button>
|
|
||||||
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AddIcon } from '@chakra-ui/icons';
|
import { Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
||||||
import { Button, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import CreateSubscriberForm from './Form';
|
import CreateSubscriberForm from './Form';
|
||||||
import CloseButton from 'components/Buttons/CloseButton';
|
import CloseButton from 'components/Buttons/CloseButton';
|
||||||
|
import CreateButton from 'components/Buttons/CreateButton';
|
||||||
import SaveButton from 'components/Buttons/SaveButton';
|
import SaveButton from 'components/Buttons/SaveButton';
|
||||||
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
||||||
import ModalHeader from 'components/Modals/ModalHeader';
|
import ModalHeader from 'components/Modals/ModalHeader';
|
||||||
import { useAuth } from 'contexts/AuthProvider';
|
|
||||||
import useFormModal from 'hooks/useFormModal';
|
import useFormModal from 'hooks/useFormModal';
|
||||||
import useFormRef from 'hooks/useFormRef';
|
import useFormRef from 'hooks/useFormRef';
|
||||||
|
|
||||||
@@ -18,7 +17,6 @@ const propTypes = {
|
|||||||
};
|
};
|
||||||
const CreateSubscriberModal = ({ refresh, operatorId }) => {
|
const CreateSubscriberModal = ({ refresh, operatorId }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { user } = useAuth();
|
|
||||||
const { form, formRef } = useFormRef();
|
const { form, formRef } = useFormRef();
|
||||||
const { isOpen, isConfirmOpen, onOpen, closeConfirm, closeModal, closeCancelAndForm } = useFormModal({
|
const { isOpen, isConfirmOpen, onOpen, closeConfirm, closeModal, closeCancelAndForm } = useFormModal({
|
||||||
isDirty: form?.dirty,
|
isDirty: form?.dirty,
|
||||||
@@ -26,16 +24,7 @@ const CreateSubscriberModal = ({ refresh, operatorId }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<CreateButton onClick={onOpen} ml={2} />
|
||||||
hidden={user?.userRole === 'CSR'}
|
|
||||||
alignItems="center"
|
|
||||||
colorScheme="blue"
|
|
||||||
rightIcon={<AddIcon />}
|
|
||||||
onClick={onOpen}
|
|
||||||
ml={2}
|
|
||||||
>
|
|
||||||
{t('crud.create')}
|
|
||||||
</Button>
|
|
||||||
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
<Modal onClose={closeModal} isOpen={isOpen} size="xl">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
||||||
|
|||||||
@@ -42,6 +42,18 @@ const DhcpIpV4 = ({ namePrefix, isDisabled }: Props) => {
|
|||||||
definitionKey="interface.ipv4.dhcp-lease.macaddr"
|
definitionKey="interface.ipv4.dhcp-lease.macaddr"
|
||||||
isRequired
|
isRequired
|
||||||
w="220px"
|
w="220px"
|
||||||
|
formatValue={(v) => {
|
||||||
|
const r = /([a-f0-9]{2})([a-f0-9]{2})/i;
|
||||||
|
let str = v.replace(/[^a-f0-9]/gi, '');
|
||||||
|
|
||||||
|
while (r.test(str)) {
|
||||||
|
str = str.replace(r, `$1:$2`);
|
||||||
|
}
|
||||||
|
|
||||||
|
str = str.slice(0, 17);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}}
|
||||||
mr={4}
|
mr={4}
|
||||||
/>
|
/>
|
||||||
<StaticLeaseOffsetField subnet={ipv4?.subnet} />
|
<StaticLeaseOffsetField subnet={ipv4?.subnet} />
|
||||||
@@ -122,7 +134,7 @@ const DhcpIpV4 = ({ namePrefix, isDisabled }: Props) => {
|
|||||||
isRequired
|
isRequired
|
||||||
options={{
|
options={{
|
||||||
modalTitle: 'Reserved Addresses',
|
modalTitle: 'Reserved Addresses',
|
||||||
buttonLabel: 'Reserved Addresses',
|
buttonLabel: 'Manage Reserved Addresses',
|
||||||
onFormSubmit: (v: {
|
onFormSubmit: (v: {
|
||||||
__temp_ip?: string;
|
__temp_ip?: string;
|
||||||
secondMacAddress: string;
|
secondMacAddress: string;
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ const AdvancedSettings: React.FC<{ editing: boolean; namePrefix: string }> = ({
|
|||||||
definitionKey="interface.ssid.services"
|
definitionKey="interface.ssid.services"
|
||||||
isDisabled={!editing}
|
isDisabled={!editing}
|
||||||
options={[
|
options={[
|
||||||
{ value: 'captive', label: 'captive' },
|
|
||||||
{ value: 'radius-gw-proxy', label: 'radius-gw-proxy' },
|
{ value: 'radius-gw-proxy', label: 'radius-gw-proxy' },
|
||||||
{ value: 'wifi-steering', label: 'wifi-steering' },
|
{ value: 'wifi-steering', label: 'wifi-steering' },
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { IconButton, Tooltip, useDisclosure, Modal, ModalBody, ModalContent, ModalOverlay } from '@chakra-ui/react';
|
||||||
Button,
|
|
||||||
IconButton,
|
|
||||||
Tooltip,
|
|
||||||
useBreakpoint,
|
|
||||||
useDisclosure,
|
|
||||||
Modal,
|
|
||||||
ModalBody,
|
|
||||||
ModalContent,
|
|
||||||
ModalOverlay,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { CheckCircle, WarningOctagon } from 'phosphor-react';
|
import { CheckCircle, WarningOctagon } from 'phosphor-react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import isEqual from 'react-fast-compare';
|
import isEqual from 'react-fast-compare';
|
||||||
@@ -30,7 +20,6 @@ const defaultProps = {
|
|||||||
const ViewConfigErrorsModal = ({ errors, activeConfigurations, isDisabled }) => {
|
const ViewConfigErrorsModal = ({ errors, activeConfigurations, isDisabled }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const breakpoint = useBreakpoint();
|
|
||||||
const errorAmount =
|
const errorAmount =
|
||||||
errors.globals.length +
|
errors.globals.length +
|
||||||
errors.unit.length +
|
errors.unit.length +
|
||||||
@@ -42,28 +31,20 @@ const ViewConfigErrorsModal = ({ errors, activeConfigurations, isDisabled }) =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{breakpoint !== 'base' && breakpoint !== 'sm' ? (
|
<Tooltip
|
||||||
<Button
|
label={`${errorAmount} ${errorAmount === 1 ? t('common.error') : t('common.errors')}`}
|
||||||
colorScheme={errorAmount === 0 ? 'green' : 'red'}
|
hasArrow
|
||||||
type="button"
|
shouldWrapChildren
|
||||||
onClick={onOpen}
|
|
||||||
ml={2}
|
|
||||||
rightIcon={errorAmount === 0 ? <CheckCircle size={20} /> : <WarningOctagon size={20} />}
|
|
||||||
isDisabled={isDisabled || errorAmount === 0}
|
|
||||||
>
|
>
|
||||||
{errorAmount} {errorAmount === 1 ? t('common.error') : t('common.errors')}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Tooltip label={`${errorAmount} ${errorAmount === 1 ? t('common.error') : t('common.errors')}`}>
|
|
||||||
<IconButton
|
<IconButton
|
||||||
colorScheme={errorAmount === 0 ? 'green' : 'red'}
|
colorScheme={errorAmount === 0 ? 'green' : 'red'}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onOpen}
|
onClick={onOpen}
|
||||||
|
ml={2}
|
||||||
icon={errorAmount === 0 ? <CheckCircle size={20} /> : <WarningOctagon size={20} />}
|
icon={errorAmount === 0 ? <CheckCircle size={20} /> : <WarningOctagon size={20} />}
|
||||||
isDisabled={isDisabled || errorAmount === 0}
|
isDisabled={isDisabled || errorAmount === 0}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
|
||||||
<Modal onClose={onClose} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
<Modal onClose={onClose} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { IconButton, Tooltip, useDisclosure, Modal, ModalBody, ModalContent, ModalOverlay } from '@chakra-ui/react';
|
||||||
Button,
|
|
||||||
IconButton,
|
|
||||||
Tooltip,
|
|
||||||
useBreakpoint,
|
|
||||||
useDisclosure,
|
|
||||||
Modal,
|
|
||||||
ModalBody,
|
|
||||||
ModalContent,
|
|
||||||
ModalOverlay,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { CheckCircle, WarningOctagon } from 'phosphor-react';
|
import { CheckCircle, WarningOctagon } from 'phosphor-react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import isEqual from 'react-fast-compare';
|
import isEqual from 'react-fast-compare';
|
||||||
@@ -30,7 +20,6 @@ const defaultProps = {
|
|||||||
const ViewConfigWarningsModal = ({ warnings, activeConfigurations, isDisabled }) => {
|
const ViewConfigWarningsModal = ({ warnings, activeConfigurations, isDisabled }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const breakpoint = useBreakpoint();
|
|
||||||
const warningsAmount =
|
const warningsAmount =
|
||||||
warnings.globals.length +
|
warnings.globals.length +
|
||||||
warnings.unit.length +
|
warnings.unit.length +
|
||||||
@@ -42,18 +31,11 @@ const ViewConfigWarningsModal = ({ warnings, activeConfigurations, isDisabled })
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{breakpoint !== 'base' && breakpoint !== 'sm' ? (
|
<Tooltip
|
||||||
<Button
|
label={`${warningsAmount} ${warningsAmount === 1 ? t('common.warning') : t('common.warnings')}`}
|
||||||
colorScheme={warningsAmount === 0 ? 'green' : 'yellow'}
|
hasArrow
|
||||||
type="button"
|
shouldWrapChildren
|
||||||
onClick={onOpen}
|
|
||||||
rightIcon={warningsAmount === 0 ? <CheckCircle size={20} /> : <WarningOctagon size={20} />}
|
|
||||||
isDisabled={isDisabled || warningsAmount === 0}
|
|
||||||
>
|
>
|
||||||
{warningsAmount} {warningsAmount === 1 ? t('common.warning') : t('common.warnings')}
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Tooltip label={`${warningsAmount} ${warningsAmount === 1 ? t('common.warning') : t('common.warnings')}`}>
|
|
||||||
<IconButton
|
<IconButton
|
||||||
colorScheme={warningsAmount === 0 ? 'green' : 'yellow'}
|
colorScheme={warningsAmount === 0 ? 'green' : 'yellow'}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -62,7 +44,6 @@ const ViewConfigWarningsModal = ({ warnings, activeConfigurations, isDisabled })
|
|||||||
isDisabled={isDisabled || warningsAmount === 0}
|
isDisabled={isDisabled || warningsAmount === 0}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
|
||||||
<Modal onClose={onClose} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
<Modal onClose={onClose} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ const ConfigurationCard = ({ id }) => {
|
|||||||
<SaveButton
|
<SaveButton
|
||||||
onClick={handleSubmitClick}
|
onClick={handleSubmitClick}
|
||||||
isLoading={updateEntity.isLoading}
|
isLoading={updateEntity.isLoading}
|
||||||
isCompact={false}
|
|
||||||
isDisabled={
|
isDisabled={
|
||||||
!editing || !form.isValid || sections.invalidValues.length > 0 || (!form.dirty && !sections.isDirty)
|
!editing || !form.isValid || sections.invalidValues.length > 0 || (!form.dirty && !sections.isDirty)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ const EntityCard = ({ id }) => {
|
|||||||
<SaveButton
|
<SaveButton
|
||||||
onClick={form.submitForm}
|
onClick={form.submitForm}
|
||||||
isLoading={form.isSubmitting}
|
isLoading={form.isSubmitting}
|
||||||
isCompact={false}
|
|
||||||
isDisabled={!editing || !form.isValid || !form.dirty}
|
isDisabled={!editing || !form.isValid || !form.dirty}
|
||||||
ml={2}
|
ml={2}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Badge, Box, Button, Flex, HStack, Select, Spacer, Table, Text, Th, Thead, Tr } from '@chakra-ui/react';
|
import {
|
||||||
|
Badge,
|
||||||
|
Box,
|
||||||
|
Flex,
|
||||||
|
HStack,
|
||||||
|
IconButton,
|
||||||
|
Select,
|
||||||
|
Spacer,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
Th,
|
||||||
|
Thead,
|
||||||
|
Tooltip,
|
||||||
|
Tr,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
import { Download } from 'phosphor-react';
|
import { Download } from 'phosphor-react';
|
||||||
import { CSVLink } from 'react-csv';
|
import { CSVLink } from 'react-csv';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -131,9 +145,9 @@ const FmsLogsCard = () => {
|
|||||||
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
||||||
data={downloadableLogs as object[]}
|
data={downloadableLogs as object[]}
|
||||||
>
|
>
|
||||||
<Button onClick={() => {}} colorScheme="blue" leftIcon={<Download />}>
|
<Tooltip label={t('logs.export')} hasArrow>
|
||||||
{t('logs.export')}
|
<IconButton aria-label={t('logs.export')} icon={<Download />} colorScheme="blue" />
|
||||||
</Button>
|
</Tooltip>
|
||||||
</CSVLink>
|
</CSVLink>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Badge, Box, Button, Flex, HStack, Select, Spacer, Table, Text, Th, Thead, Tr } from '@chakra-ui/react';
|
import {
|
||||||
|
Badge,
|
||||||
|
Box,
|
||||||
|
Flex,
|
||||||
|
HStack,
|
||||||
|
IconButton,
|
||||||
|
Select,
|
||||||
|
Spacer,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
Th,
|
||||||
|
Thead,
|
||||||
|
Tooltip,
|
||||||
|
Tr,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
import { Download } from 'phosphor-react';
|
import { Download } from 'phosphor-react';
|
||||||
import { CSVLink } from 'react-csv';
|
import { CSVLink } from 'react-csv';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -134,9 +148,9 @@ const GeneralLogsCard = () => {
|
|||||||
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
||||||
data={downloadableLogs as object[]}
|
data={downloadableLogs as object[]}
|
||||||
>
|
>
|
||||||
<Button onClick={() => {}} colorScheme="blue" leftIcon={<Download />}>
|
<Tooltip label={t('logs.export')} hasArrow>
|
||||||
{t('logs.export')}
|
<IconButton aria-label={t('logs.export')} icon={<Download />} colorScheme="blue" />
|
||||||
</Button>
|
</Tooltip>
|
||||||
</CSVLink>
|
</CSVLink>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Box, Button, Flex, HStack, Spacer, Table, Text, Th, Thead, Tr } from '@chakra-ui/react';
|
import { Box, Flex, HStack, IconButton, Spacer, Table, Text, Th, Thead, Tooltip, Tr } from '@chakra-ui/react';
|
||||||
import { Download } from 'phosphor-react';
|
import { Download } from 'phosphor-react';
|
||||||
import { CSVLink } from 'react-csv';
|
import { CSVLink } from 'react-csv';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -124,9 +124,9 @@ const NotificationsCard = () => {
|
|||||||
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
||||||
data={downloadableLogs as object[]}
|
data={downloadableLogs as object[]}
|
||||||
>
|
>
|
||||||
<Button onClick={() => {}} colorScheme="blue" leftIcon={<Download />}>
|
<Tooltip label={t('logs.export')} hasArrow>
|
||||||
{t('logs.export')}
|
<IconButton aria-label={t('logs.export')} icon={<Download />} colorScheme="blue" />
|
||||||
</Button>
|
</Tooltip>
|
||||||
</CSVLink>
|
</CSVLink>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Badge, Box, Button, Flex, HStack, Select, Spacer, Table, Text, Th, Thead, Tr } from '@chakra-ui/react';
|
import {
|
||||||
|
Badge,
|
||||||
|
Box,
|
||||||
|
Flex,
|
||||||
|
HStack,
|
||||||
|
IconButton,
|
||||||
|
Select,
|
||||||
|
Spacer,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
Th,
|
||||||
|
Thead,
|
||||||
|
Tooltip,
|
||||||
|
Tr,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
import { Download } from 'phosphor-react';
|
import { Download } from 'phosphor-react';
|
||||||
import { CSVLink } from 'react-csv';
|
import { CSVLink } from 'react-csv';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -131,9 +145,9 @@ const SecLogsCard = () => {
|
|||||||
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
filename={`logs_${dateForFilename(new Date().getTime() / 1000)}.csv`}
|
||||||
data={downloadableLogs as object[]}
|
data={downloadableLogs as object[]}
|
||||||
>
|
>
|
||||||
<Button onClick={() => {}} colorScheme="blue" leftIcon={<Download />}>
|
<Tooltip label={t('logs.export')} hasArrow>
|
||||||
{t('logs.export')}
|
<IconButton aria-label={t('logs.export')} icon={<Download />} colorScheme="blue" />
|
||||||
</Button>
|
</Tooltip>
|
||||||
</CSVLink>
|
</CSVLink>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -29,11 +29,12 @@ const OperatorDetailsCard = ({ id }) => {
|
|||||||
<Heading size="md">{operator?.name}</Heading>
|
<Heading size="md">{operator?.name}</Heading>
|
||||||
</Box>
|
</Box>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
|
<DeleteOperatorButton isDisabled={editing || isFetching} operator={operator} />
|
||||||
<SaveButton
|
<SaveButton
|
||||||
onClick={form.submitForm}
|
onClick={form.submitForm}
|
||||||
isLoading={form.isSubmitting}
|
isLoading={form.isSubmitting}
|
||||||
isCompact={false}
|
|
||||||
isDisabled={!editing || !form.isValid || !form.dirty}
|
isDisabled={!editing || !form.isValid || !form.dirty}
|
||||||
|
hidden={!editing}
|
||||||
ml={2}
|
ml={2}
|
||||||
/>
|
/>
|
||||||
<ToggleEditButton
|
<ToggleEditButton
|
||||||
@@ -43,7 +44,6 @@ const OperatorDetailsCard = ({ id }) => {
|
|||||||
isDirty={formRef.dirty}
|
isDirty={formRef.dirty}
|
||||||
ml={2}
|
ml={2}
|
||||||
/>
|
/>
|
||||||
<DeleteOperatorButton isDisabled={editing || isFetching} operator={operator} />
|
|
||||||
<RefreshButton onClick={refetch} isFetching={isFetching} isDisabled={editing} ml={2} />
|
<RefreshButton onClick={refetch} isFetching={isFetching} isDisabled={editing} ml={2} />
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
import ApiKeyTable from './Table';
|
import ApiKeyTable from './Table';
|
||||||
import Card from 'components/Card';
|
import Card from 'components/Card';
|
||||||
import CardBody from 'components/Card/CardBody';
|
import CardBody from 'components/Card/CardBody';
|
||||||
@@ -10,7 +11,9 @@ const ApiKeysCard = () => {
|
|||||||
return (
|
return (
|
||||||
<Card p={4}>
|
<Card p={4}>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
|
<Box w="100%">
|
||||||
<ApiKeyTable userId={user?.id ?? ''} />
|
<ApiKeyTable userId={user?.id ?? ''} />
|
||||||
|
</Box>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ChevronDownIcon } from '@chakra-ui/icons';
|
import { IconButton, Menu, MenuButton, MenuItem, MenuList, Tooltip } from '@chakra-ui/react';
|
||||||
import { Button, Menu, MenuButton, MenuItem, MenuList } from '@chakra-ui/react';
|
import { Wrench } from 'phosphor-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useSendEmailResetSubscriber, useSuspendSubscriber } from 'hooks/Network/Subscribers';
|
import { useSendEmailResetSubscriber, useSuspendSubscriber } from 'hooks/Network/Subscribers';
|
||||||
import useMutationResult from 'hooks/useMutationResult';
|
import useMutationResult from 'hooks/useMutationResult';
|
||||||
@@ -12,13 +12,7 @@ interface Props {
|
|||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SubscriberActions = (
|
const SubscriberActions: React.FC<Props> = ({ subscriber, refresh, isDisabled }) => {
|
||||||
{
|
|
||||||
subscriber,
|
|
||||||
refresh,
|
|
||||||
isDisabled
|
|
||||||
}: Props
|
|
||||||
) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { mutateAsync: suspend } = useSuspendSubscriber({ id: subscriber?.id ?? '' });
|
const { mutateAsync: suspend } = useSuspendSubscriber({ id: subscriber?.id ?? '' });
|
||||||
const { mutateAsync: resetPassword } = useSendEmailResetSubscriber({ id: subscriber?.id ?? '' });
|
const { mutateAsync: resetPassword } = useSendEmailResetSubscriber({ id: subscriber?.id ?? '' });
|
||||||
@@ -41,9 +35,9 @@ const SubscriberActions = (
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton as={Button} rightIcon={<ChevronDownIcon />} ml={2} isDisabled={isDisabled}>
|
<Tooltip label={t('common.actions')} aria-label={t('common.actions')} hasArrow>
|
||||||
{t('common.actions')}
|
<MenuButton as={IconButton} icon={<Wrench size={20} />} ml={2} isDisabled={isDisabled} />
|
||||||
</MenuButton>
|
</Tooltip>
|
||||||
<MenuList>
|
<MenuList>
|
||||||
<MenuItem onClick={handleSuspendClick}>
|
<MenuItem onClick={handleSuspendClick}>
|
||||||
{subscriber?.suspended ? t('users.stop_suspension') : t('users.suspend')}
|
{subscriber?.suspended ? t('users.stop_suspension') : t('users.suspend')}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ interface Props {
|
|||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SubscriberCard = ({ id }: Props) => {
|
const SubscriberCard: React.FC<Props> = ({ id }) => {
|
||||||
const [editing, setEditing] = useBoolean();
|
const [editing, setEditing] = useBoolean();
|
||||||
const { data: subscriber, refetch, isFetching } = useGetSubscriber({ id });
|
const { data: subscriber, refetch, isFetching } = useGetSubscriber({ id });
|
||||||
const { form, formRef } = useFormRef();
|
const { form, formRef } = useFormRef();
|
||||||
@@ -41,11 +41,12 @@ const SubscriberCard = ({ id }: Props) => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<Box>
|
<Box>
|
||||||
|
<DeleteVenuePopover isDisabled={editing || isFetching} subscriber={subscriber} />
|
||||||
<SaveButton
|
<SaveButton
|
||||||
onClick={form.submitForm}
|
onClick={form.submitForm}
|
||||||
isLoading={form.isSubmitting}
|
isLoading={form.isSubmitting}
|
||||||
isCompact={false}
|
|
||||||
isDisabled={!editing || !form.isValid || !form.dirty}
|
isDisabled={!editing || !form.isValid || !form.dirty}
|
||||||
|
hidden={!editing}
|
||||||
ml={2}
|
ml={2}
|
||||||
/>
|
/>
|
||||||
<ToggleEditButton
|
<ToggleEditButton
|
||||||
@@ -55,9 +56,8 @@ const SubscriberCard = ({ id }: Props) => {
|
|||||||
isDirty={form.dirty}
|
isDirty={form.dirty}
|
||||||
ml={2}
|
ml={2}
|
||||||
/>
|
/>
|
||||||
<DeleteVenuePopover isDisabled={editing || isFetching} subscriber={subscriber} />
|
|
||||||
<RefreshButton onClick={refetch} isFetching={isFetching} isDisabled={editing} ml={2} />
|
|
||||||
<Actions subscriber={subscriber} refresh={refetch} isDisabled={editing} />
|
<Actions subscriber={subscriber} refresh={refetch} isDisabled={editing} />
|
||||||
|
<RefreshButton onClick={refetch} isFetching={isFetching} isDisabled={editing} ml={2} />
|
||||||
</Box>
|
</Box>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Button, useDisclosure } from '@chakra-ui/react';
|
import { IconButton, Tooltip, useDisclosure } from '@chakra-ui/react';
|
||||||
|
import { Article } from 'phosphor-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import SystemLoggingModal from './Modal';
|
import SystemLoggingModal from './Modal';
|
||||||
import { EndpointApiResponse } from 'hooks/Network/Endpoints';
|
import { EndpointApiResponse } from 'hooks/Network/Endpoints';
|
||||||
@@ -15,9 +16,17 @@ const SystemLoggingButton = ({ endpoint, token }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button colorScheme="teal" onClick={modalProps.onOpen} mr={2} my="auto">
|
<Tooltip label={t('system.logging')} hasArrow>
|
||||||
{t('system.logging')}
|
<IconButton
|
||||||
</Button>
|
aria-label={t('system.logging')}
|
||||||
|
colorScheme="teal"
|
||||||
|
type="button"
|
||||||
|
my="auto"
|
||||||
|
onClick={modalProps.onOpen}
|
||||||
|
icon={<Article size={20} />}
|
||||||
|
mr={2}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
<SystemLoggingModal modalProps={modalProps} endpoint={endpoint.uri} token={token} />
|
<SystemLoggingModal modalProps={modalProps} endpoint={endpoint.uri} token={token} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { ArrowsClockwise } from 'phosphor-react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import SystemLoggingButton from './LoggingButton';
|
import SystemLoggingButton from './LoggingButton';
|
||||||
import SystemCertificatesTable from './SystemCertificatesTable';
|
import SystemCertificatesTable from './SystemCertificatesTable';
|
||||||
|
import RefreshButton from 'components/Buttons/RefreshButton';
|
||||||
import Card from 'components/Card';
|
import Card from 'components/Card';
|
||||||
import CardBody from 'components/Card/CardBody';
|
import CardBody from 'components/Card/CardBody';
|
||||||
import FormattedDate from 'components/FormattedDate';
|
import FormattedDate from 'components/FormattedDate';
|
||||||
@@ -70,16 +71,7 @@ const SystemTile = ({ endpoint, token }: Props) => {
|
|||||||
<Heading pt={0}>{endpoint.type}</Heading>
|
<Heading pt={0}>{endpoint.type}</Heading>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<SystemLoggingButton endpoint={endpoint} token={token} />
|
<SystemLoggingButton endpoint={endpoint} token={token} />
|
||||||
<Button
|
<RefreshButton onClick={refresh} isFetching={isFetchingSystem || isFetchingSubsystems} />
|
||||||
mt={1}
|
|
||||||
minWidth="112px"
|
|
||||||
colorScheme="blue"
|
|
||||||
rightIcon={<ArrowsClockwise />}
|
|
||||||
onClick={refresh}
|
|
||||||
isLoading={isFetchingSystem || isFetchingSubsystems}
|
|
||||||
>
|
|
||||||
{t('common.refresh')}
|
|
||||||
</Button>
|
|
||||||
</Box>
|
</Box>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<VStack w="100%">
|
<VStack w="100%">
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ const UserActions = ({ id, isSuspended, isWaitingForCheck, refresh, size = 'sm',
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Tooltip label={t('commands.other')}>
|
<Tooltip label={t('common.actions')}>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
aria-label="Commands"
|
aria-label="Commands"
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AddIcon } from '@chakra-ui/icons';
|
import { useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
||||||
import { Button, useDisclosure, Modal, ModalOverlay, ModalContent, ModalBody } from '@chakra-ui/react';
|
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import CreateUserForm from './Form';
|
import CreateUserForm from './Form';
|
||||||
import CloseButton from 'components/Buttons/CloseButton';
|
import CloseButton from 'components/Buttons/CloseButton';
|
||||||
|
import CreateButton from 'components/Buttons/CreateButton';
|
||||||
import SaveButton from 'components/Buttons/SaveButton';
|
import SaveButton from 'components/Buttons/SaveButton';
|
||||||
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
import ConfirmCloseAlert from 'components/Modals/Actions/ConfirmCloseAlert';
|
||||||
import ModalHeader from 'components/Modals/ModalHeader';
|
import ModalHeader from 'components/Modals/ModalHeader';
|
||||||
@@ -47,16 +47,7 @@ const CreateUserModal = ({ requirements, refreshUsers }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
{user?.userRole === 'CSR' ? null : <CreateButton onClick={onOpen} ml={2} />}
|
||||||
hidden={user?.userRole === 'CSR'}
|
|
||||||
alignItems="center"
|
|
||||||
colorScheme="blue"
|
|
||||||
rightIcon={<AddIcon />}
|
|
||||||
onClick={onOpen}
|
|
||||||
ml={2}
|
|
||||||
>
|
|
||||||
{t('crud.create')}
|
|
||||||
</Button>
|
|
||||||
<Modal onClose={closeModal} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
<Modal onClose={closeModal} isOpen={isOpen} size="xl" scrollBehavior="inside">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
<ModalContent maxWidth={{ sm: '600px', md: '700px', lg: '800px', xl: '50%' }}>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { v4 as uuid } from 'uuid';
|
|||||||
import CreateUserModal from './CreateUserModal';
|
import CreateUserModal from './CreateUserModal';
|
||||||
import EditUserModal from './EditUserModal';
|
import EditUserModal from './EditUserModal';
|
||||||
import UserActions from './UserActions';
|
import UserActions from './UserActions';
|
||||||
|
import RefreshButton from 'components/Buttons/RefreshButton';
|
||||||
import Card from 'components/Card';
|
import Card from 'components/Card';
|
||||||
import CardBody from 'components/Card/CardBody';
|
import CardBody from 'components/Card/CardBody';
|
||||||
import CardHeader from 'components/Card/CardHeader';
|
import CardHeader from 'components/Card/CardHeader';
|
||||||
@@ -145,15 +146,7 @@ const UserTable = ({ title }) => {
|
|||||||
preference="provisioning.userTable.hiddenColumns"
|
preference="provisioning.userTable.hiddenColumns"
|
||||||
/>
|
/>
|
||||||
<CreateUserModal requirements={requirements} refreshUsers={refreshUsers} />
|
<CreateUserModal requirements={requirements} refreshUsers={refreshUsers} />
|
||||||
<Button
|
<RefreshButton onClick={refreshUsers} isFetching={isFetching} ml={2} />
|
||||||
colorScheme="gray"
|
|
||||||
onClick={refreshUsers}
|
|
||||||
rightIcon={<ArrowsClockwise />}
|
|
||||||
ml={2}
|
|
||||||
isLoading={isFetching}
|
|
||||||
>
|
|
||||||
{t('common.refresh')}
|
|
||||||
</Button>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const DeleteVenuePopover = ({ venue, isDisabled }) => {
|
|||||||
<Popover isOpen={isOpen} onOpen={onOpen} onClose={onClose}>
|
<Popover isOpen={isOpen} onOpen={onOpen} onClose={onClose}>
|
||||||
<PopoverAnchor>
|
<PopoverAnchor>
|
||||||
<span>
|
<span>
|
||||||
<DeleteButton onClick={onOpen} isDisabled={isDisabled} ml={2} />
|
<DeleteButton onClick={onOpen} isDisabled={isDisabled} />
|
||||||
</span>
|
</span>
|
||||||
</PopoverAnchor>
|
</PopoverAnchor>
|
||||||
<PopoverContent>
|
<PopoverContent>
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ const VenueCard = ({ id }: { id: string }) => {
|
|||||||
<SaveButton
|
<SaveButton
|
||||||
onClick={form.submitForm}
|
onClick={form.submitForm}
|
||||||
isLoading={form.isSubmitting}
|
isLoading={form.isSubmitting}
|
||||||
isCompact={false}
|
|
||||||
isDisabled={!editing || !form.isValid || !form.dirty}
|
isDisabled={!editing || !form.isValid || !form.dirty}
|
||||||
ml={2}
|
ml={2}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { Button, Modal, ModalOverlay, ModalContent, ModalBody, useDisclosure } from '@chakra-ui/react';
|
import { Modal, ModalOverlay, ModalContent, ModalBody, useDisclosure, Tooltip, IconButton } from '@chakra-ui/react';
|
||||||
import { Plus } from 'phosphor-react';
|
import { Copy } from 'phosphor-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import Actions from './Actions';
|
import Actions from './Actions';
|
||||||
@@ -38,9 +38,14 @@ const UseExistingContactModal = ({ onAssignContact, venue }: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button type="button" colorScheme="blue" rightIcon={<Plus size={20} />} onClick={onOpen} ml={2}>
|
<Tooltip label={t('venues.use_existing')}>
|
||||||
{t('venues.use_existing')}
|
<IconButton
|
||||||
</Button>
|
aria-label={t('venues.use_existing')}
|
||||||
|
icon={<Copy size={20} />}
|
||||||
|
onClick={onOpen}
|
||||||
|
colorScheme="teal"
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
<Modal initialFocusRef={undefined} onClose={onClose} isOpen={isOpen} size="xl">
|
<Modal initialFocusRef={undefined} onClose={onClose} isOpen={isOpen} size="xl">
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
<ModalContent maxWidth={{ sm: '90%', md: '900px', lg: '1000px', xl: '80%' }}>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { extendTheme } from '@chakra-ui/react';
|
import { Tooltip, extendTheme } from '@chakra-ui/react';
|
||||||
import CardComponent from './additions/card/Card';
|
import CardComponent from './additions/card/Card';
|
||||||
import CardBodyComponent from './additions/card/CardBody';
|
import CardBodyComponent from './additions/card/CardBody';
|
||||||
import CardHeaderComponent from './additions/card/CardHeader';
|
import CardHeaderComponent from './additions/card/CardHeader';
|
||||||
@@ -13,19 +13,30 @@ import breakpoints from './foundations/breakpoints';
|
|||||||
import font from './foundations/fonts';
|
import font from './foundations/fonts';
|
||||||
import globalStyles from './styles';
|
import globalStyles from './styles';
|
||||||
|
|
||||||
// import { mode } from "@chakra-ui/theme-tools";
|
const config: ThemeConfig = {
|
||||||
export default extendTheme(
|
initialColorMode: 'light',
|
||||||
{ breakpoints }, // Breakpoints
|
useSystemColorMode: false,
|
||||||
globalStyles,
|
};
|
||||||
font, // Global styles
|
|
||||||
buttonStyles, // Button styles
|
const theme = extendTheme({
|
||||||
badgeStyles, // Badge styles
|
config,
|
||||||
drawerStyles, // Sidebar variant for Chakra's drawer
|
font,
|
||||||
alertStyles,
|
breakpoints,
|
||||||
CardComponent, // Card component
|
colors: globalStyles.colors,
|
||||||
CardBodyComponent, // Card Body component
|
styles: globalStyles.styles,
|
||||||
CardHeaderComponent, // Card Header component
|
components: {
|
||||||
MainPanelComponent, // Main Panel component
|
Alert: alertStyles.components.Alert,
|
||||||
PanelContentComponent, // Panel Content component
|
Badge: badgeStyles.components.Badge,
|
||||||
PanelContainerComponent, // Panel Container component
|
Button: buttonStyles.components.Button,
|
||||||
);
|
Drawer: drawerStyles.components.Drawer,
|
||||||
|
Card: CardComponent.components.Card,
|
||||||
|
CardBody: CardBodyComponent.components.CardBody,
|
||||||
|
CardHeader: CardHeaderComponent.components.CardHeader,
|
||||||
|
MainPanel: MainPanelComponent.components.MainPanel,
|
||||||
|
PanelContent: PanelContentComponent.components.PanelContent,
|
||||||
|
PanelContainer: PanelContainerComponent.components.PanelContainer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Tooltip.defaultProps = { ...Tooltip.defaultProps, hasArrow: true };
|
||||||
|
export default theme;
|
||||||
|
|||||||
@@ -1,49 +1,9 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [tsconfigPaths(), react()],
|
||||||
tsconfigPaths(),
|
|
||||||
react(),
|
|
||||||
VitePWA({
|
|
||||||
registerType: 'autoUpdate',
|
|
||||||
devOptions: {
|
|
||||||
enabled: true,
|
|
||||||
/* other options */
|
|
||||||
},
|
|
||||||
manifest: {
|
|
||||||
name: 'OpenWiFi Provisioning App',
|
|
||||||
short_name: 'OpenWiFiProvisioning',
|
|
||||||
description: 'OpenWiFi Provisioning App',
|
|
||||||
theme_color: '#000000',
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: 'android-chrome-192x192.png',
|
|
||||||
sizes: '192x192',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'android-chrome-384x384.png',
|
|
||||||
sizes: '384x384',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'android-chrome-512x512.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'android-chrome-512x512.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png',
|
|
||||||
purpose: 'any maskable',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
build: {
|
build: {
|
||||||
outDir: './build',
|
outDir: './build',
|
||||||
chunkSizeWarningLimit: 1000,
|
chunkSizeWarningLimit: 1000,
|
||||||
|
|||||||
Reference in New Issue
Block a user