mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui.git
synced 2025-10-29 09:52:31 +00:00
Add device re-enrollment with confirmation modal
- Add ReEnrollModal component for user confirmation before re-enrollment - Update DeviceActionDropdown to open modal instead of direct action - Add modal state management in Device Wrapper component - Add translation keys for re-enrollment UI with certificate renewal messaging - Remove direct useReEnroll hook usage in favor of modal pattern Signed-off-by: Sebastian Rubina <sebastian.rubina@icloud.com>
This commit is contained in:
@@ -516,6 +516,8 @@
|
|||||||
"trace_description": "Launch a remote trace of this device for either a specific duration or a number of packets",
|
"trace_description": "Launch a remote trace of this device for either a specific duration or a number of packets",
|
||||||
"re_enroll": "Re-enroll",
|
"re_enroll": "Re-enroll",
|
||||||
"re_enroll_initiated": "Re-enrollment initiated for device {{serialNumber}}",
|
"re_enroll_initiated": "Re-enrollment initiated for device {{serialNumber}}",
|
||||||
|
"re_enroll_warning": "This will renew the operational certificate for device {{serialNumber}}. The device will obtain a new certificate from the controller.",
|
||||||
|
"confirm_re_enroll": "Renew Certificate for {{serialNumber}}",
|
||||||
"update_success": "Device updated!",
|
"update_success": "Device updated!",
|
||||||
"updated_blacklist": "Updated Blacklist!"
|
"updated_blacklist": "Updated Blacklist!"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ interface Props {
|
|||||||
onOpenTelemetryModal: (serialNumber: string) => void;
|
onOpenTelemetryModal: (serialNumber: string) => void;
|
||||||
onOpenScriptModal: (device: GatewayDevice) => void;
|
onOpenScriptModal: (device: GatewayDevice) => void;
|
||||||
onOpenRebootModal: (serialNumber: string) => void;
|
onOpenRebootModal: (serialNumber: string) => void;
|
||||||
onReEnroll?: () => void;
|
onOpenReEnrollModal?: (serialNumber: string) => void;
|
||||||
size?: 'sm' | 'md' | 'lg';
|
size?: 'sm' | 'md' | 'lg';
|
||||||
isCompact?: boolean;
|
isCompact?: boolean;
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ const DeviceActionDropdown = ({
|
|||||||
onOpenConfigureModal,
|
onOpenConfigureModal,
|
||||||
onOpenScriptModal,
|
onOpenScriptModal,
|
||||||
onOpenRebootModal,
|
onOpenRebootModal,
|
||||||
onReEnroll,
|
onOpenReEnrollModal,
|
||||||
size,
|
size,
|
||||||
isCompact,
|
isCompact,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
@@ -236,7 +236,11 @@ const DeviceActionDropdown = ({
|
|||||||
<MenuItem onClick={handleRebootClick} hidden={!isCompact}>
|
<MenuItem onClick={handleRebootClick} hidden={!isCompact}>
|
||||||
{t('commands.reboot')}
|
{t('commands.reboot')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{onReEnroll && <MenuItem onClick={onReEnroll}>{t('controller.devices.re_enroll')}</MenuItem>}
|
{onOpenReEnrollModal && (
|
||||||
|
<MenuItem onClick={() => onOpenReEnrollModal(device.serialNumber)}>
|
||||||
|
{t('controller.devices.re_enroll')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
<MenuItem onClick={handleOpenTelemetry}>{t('controller.telemetry.title')}</MenuItem>
|
<MenuItem onClick={handleOpenTelemetry}>{t('controller.telemetry.title')}</MenuItem>
|
||||||
<MenuItem onClick={handleOpenScript}>{t('script.one')}</MenuItem>
|
<MenuItem onClick={handleOpenScript}>{t('script.one')}</MenuItem>
|
||||||
<MenuItem onClick={handleOpenTrace}>{t('controller.devices.trace')}</MenuItem>
|
<MenuItem onClick={handleOpenTrace}>{t('controller.devices.trace')}</MenuItem>
|
||||||
|
|||||||
50
src/components/Modals/ReEnrollModal/index.tsx
Normal file
50
src/components/Modals/ReEnrollModal/index.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Center, Spinner, Alert, Button } from '@chakra-ui/react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Modal } from '../Modal';
|
||||||
|
import { useReEnroll } from 'hooks/Network/ReEnroll';
|
||||||
|
import { ModalProps } from 'models/Modal';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
modalProps: ModalProps;
|
||||||
|
serialNumber: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReEnrollModal = ({ modalProps: { isOpen, onClose }, serialNumber }: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { mutate: reEnroll, isLoading } = useReEnroll({ serialNumber });
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
reEnroll(
|
||||||
|
{ serialNumber, when: 0 },
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
onClose();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose} title={t('controller.devices.re_enroll')}>
|
||||||
|
{isLoading ? (
|
||||||
|
<Center>
|
||||||
|
<Spinner size="lg" />
|
||||||
|
</Center>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Alert colorScheme="blue" mb={6}>
|
||||||
|
{t('controller.devices.re_enroll_warning', { serialNumber })}
|
||||||
|
</Alert>
|
||||||
|
<Center mb={6}>
|
||||||
|
<Button size="lg" colorScheme="blue" onClick={submit} fontWeight="bold">
|
||||||
|
{t('controller.devices.confirm_re_enroll', { serialNumber })}
|
||||||
|
</Button>
|
||||||
|
</Center>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReEnrollModal;
|
||||||
@@ -41,6 +41,7 @@ import { EventQueueModal } from 'components/Modals/EventQueueModal';
|
|||||||
import FactoryResetModal from 'components/Modals/FactoryResetModal';
|
import FactoryResetModal from 'components/Modals/FactoryResetModal';
|
||||||
import { FirmwareUpgradeModal } from 'components/Modals/FirmwareUpgradeModal';
|
import { FirmwareUpgradeModal } from 'components/Modals/FirmwareUpgradeModal';
|
||||||
import { RebootModal } from 'components/Modals/RebootModal';
|
import { RebootModal } from 'components/Modals/RebootModal';
|
||||||
|
import ReEnrollModal from 'components/Modals/ReEnrollModal';
|
||||||
import { useScriptModal } from 'components/Modals/ScriptModal/useScriptModal';
|
import { useScriptModal } from 'components/Modals/ScriptModal/useScriptModal';
|
||||||
import ethernetConnected from './ethernetIconConnected.svg?react';
|
import ethernetConnected from './ethernetIconConnected.svg?react';
|
||||||
import ethernetDisconnected from './ethernetIconDisconnected.svg?react';
|
import ethernetDisconnected from './ethernetIconDisconnected.svg?react';
|
||||||
@@ -48,7 +49,6 @@ import { TelemetryModal } from 'components/Modals/TelemetryModal';
|
|||||||
import { TraceModal } from 'components/Modals/TraceModal';
|
import { TraceModal } from 'components/Modals/TraceModal';
|
||||||
import { WifiScanModal } from 'components/Modals/WifiScanModal';
|
import { WifiScanModal } from 'components/Modals/WifiScanModal';
|
||||||
import { useDeleteDevice, useGetDevice, useGetDeviceHealthChecks, useGetDeviceStatus } from 'hooks/Network/Devices';
|
import { useDeleteDevice, useGetDevice, useGetDeviceHealthChecks, useGetDeviceStatus } from 'hooks/Network/Devices';
|
||||||
import { useReEnroll } from 'hooks/Network/ReEnroll';
|
|
||||||
import SwitchPortExamination from './SwitchPortExamination';
|
import SwitchPortExamination from './SwitchPortExamination';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -77,8 +77,8 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
const telemetryModalProps = useDisclosure();
|
const telemetryModalProps = useDisclosure();
|
||||||
const traceModalProps = useDisclosure();
|
const traceModalProps = useDisclosure();
|
||||||
const rebootModalProps = useDisclosure();
|
const rebootModalProps = useDisclosure();
|
||||||
|
const reEnrollModalProps = useDisclosure();
|
||||||
const scriptModal = useScriptModal();
|
const scriptModal = useScriptModal();
|
||||||
const reEnroll = useReEnroll({ serialNumber });
|
|
||||||
// Sticky-top styles
|
// Sticky-top styles
|
||||||
const isCompact = breakpoint === 'base' || breakpoint === 'sm' || breakpoint === 'md';
|
const isCompact = breakpoint === 'base' || breakpoint === 'sm' || breakpoint === 'md';
|
||||||
const boxShadow = useColorModeValue('0px 7px 23px rgba(0, 0, 0, 0.05)', 'none');
|
const boxShadow = useColorModeValue('0px 7px 23px rgba(0, 0, 0, 0.05)', 'none');
|
||||||
@@ -218,7 +218,7 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
onOpenTelemetryModal={telemetryModalProps.onOpen}
|
onOpenTelemetryModal={telemetryModalProps.onOpen}
|
||||||
onOpenScriptModal={scriptModal.openModal}
|
onOpenScriptModal={scriptModal.openModal}
|
||||||
onOpenRebootModal={rebootModalProps.onOpen}
|
onOpenRebootModal={rebootModalProps.onOpen}
|
||||||
onReEnroll={() => reEnroll.mutate({ serialNumber, when: 0 })}
|
onOpenReEnrollModal={reEnrollModalProps.onOpen}
|
||||||
size="md"
|
size="md"
|
||||||
isCompact
|
isCompact
|
||||||
/>
|
/>
|
||||||
@@ -271,7 +271,7 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
onOpenTelemetryModal={telemetryModalProps.onOpen}
|
onOpenTelemetryModal={telemetryModalProps.onOpen}
|
||||||
onOpenRebootModal={rebootModalProps.onOpen}
|
onOpenRebootModal={rebootModalProps.onOpen}
|
||||||
onOpenScriptModal={scriptModal.openModal}
|
onOpenScriptModal={scriptModal.openModal}
|
||||||
onReEnroll={() => reEnroll.mutate({ serialNumber, when: 0 })}
|
onOpenReEnrollModal={reEnrollModalProps.onOpen}
|
||||||
size="md"
|
size="md"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -315,6 +315,7 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
<ConfigureModal serialNumber={serialNumber} modalProps={configureModalProps} />
|
<ConfigureModal serialNumber={serialNumber} modalProps={configureModalProps} />
|
||||||
<TelemetryModal serialNumber={serialNumber} modalProps={telemetryModalProps} />
|
<TelemetryModal serialNumber={serialNumber} modalProps={telemetryModalProps} />
|
||||||
<RebootModal serialNumber={serialNumber} modalProps={rebootModalProps} />
|
<RebootModal serialNumber={serialNumber} modalProps={rebootModalProps} />
|
||||||
|
<ReEnrollModal serialNumber={serialNumber} modalProps={reEnrollModalProps} />
|
||||||
{scriptModal.modal}
|
{scriptModal.modal}
|
||||||
<Box mt={isCompact ? '0px' : '68px'}>
|
<Box mt={isCompact ? '0px' : '68px'}>
|
||||||
<Masonry
|
<Masonry
|
||||||
|
|||||||
Reference in New Issue
Block a user