Merge pull request #195 from stephb9959/main

[WIFI-12948] Fixed view configuration modal cache
This commit is contained in:
Charles Bourque
2023-09-20 14:17:14 +01:00
committed by GitHub
6 changed files with 52 additions and 35 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "ucentral-client", "name": "ucentral-client",
"version": "2.11.0(7)", "version": "2.11.0(11)",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ucentral-client", "name": "ucentral-client",
"version": "2.11.0(7)", "version": "2.11.0(11)",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@chakra-ui/anatomy": "^2.1.1", "@chakra-ui/anatomy": "^2.1.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "ucentral-client", "name": "ucentral-client",
"version": "2.11.0(7)", "version": "2.11.0(11)",
"description": "", "description": "",
"private": true, "private": true,
"main": "index.tsx", "main": "index.tsx",

View File

@@ -30,7 +30,7 @@ export type ConfigureModalProps = {
}; };
}; };
export const ConfigureModal = ({ serialNumber, modalProps }: ConfigureModalProps) => { const _ConfigureModal = ({ serialNumber, modalProps }: ConfigureModalProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const toast = useToast(); const toast = useToast();
const configure = useConfigureDevice({ serialNumber }); const configure = useConfigureDevice({ serialNumber });
@@ -45,6 +45,7 @@ export const ConfigureModal = ({ serialNumber, modalProps }: ConfigureModalProps
const onImportConfiguration = () => { const onImportConfiguration = () => {
setNewConfig(getDevice.data?.configuration ? JSON.stringify(getDevice.data.configuration, null, 4) : ''); setNewConfig(getDevice.data?.configuration ? JSON.stringify(getDevice.data.configuration, null, 4) : '');
}; };
const isValid = React.useMemo(() => { const isValid = React.useMemo(() => {
try { try {
JSON.parse(newConfig); JSON.parse(newConfig);
@@ -71,9 +72,19 @@ export const ConfigureModal = ({ serialNumber, modalProps }: ConfigureModalProps
modalProps.onClose(); modalProps.onClose();
}, },
}); });
} catch (e) {} } catch (e) {
// do nothing
}
}; };
React.useEffect(() => {
if (modalProps.isOpen) {
getDevice.refetch();
} else {
setNewConfig('');
}
}, [modalProps.isOpen]);
return ( return (
<Modal <Modal
{...modalProps} {...modalProps}
@@ -124,3 +135,5 @@ export const ConfigureModal = ({ serialNumber, modalProps }: ConfigureModalProps
</Modal> </Modal>
); );
}; };
export const ConfigureModal = React.memo(_ConfigureModal);

View File

@@ -187,6 +187,8 @@ export const useConfigureDevice = ({ serialNumber }: { serialNumber: string }) =
return useMutation(configureDevice(serialNumber), { return useMutation(configureDevice(serialNumber), {
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries(['commands', serialNumber]); queryClient.invalidateQueries(['commands', serialNumber]);
queryClient.invalidateQueries(['device', serialNumber]);
queryClient.invalidateQueries(['devices']);
}, },
}); });
}; };
@@ -248,27 +250,14 @@ const startScript = (data: { serialNumber: string; timeout?: number; [k: string]
}) })
.then((response: { data: DeviceCommandHistory }) => response.data); .then((response: { data: DeviceCommandHistory }) => response.data);
export const useDeviceScript = ({ serialNumber }: { serialNumber: string }) => { export const useDeviceScript = ({ serialNumber }: { serialNumber: string }) => {
const { t } = useTranslation();
const toast = useToast();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation(startScript, { return useMutation(startScript, {
onSuccess: () => { onSuccess: () => {
queryClient.invalidateQueries(['commands', serialNumber]); queryClient.invalidateQueries(['commands', serialNumber]);
}, },
onError: (e) => { onError: () => {
queryClient.invalidateQueries(['commands', serialNumber]); queryClient.invalidateQueries(['commands', serialNumber]);
if (axios.isAxiosError(e)) {
toast({
id: 'script-error',
title: t('common.error'),
description: e?.response?.data?.ErrorDescription,
status: 'error',
duration: 5000,
isClosable: true,
position: 'top-right',
});
}
}, },
}); });
}; };

View File

@@ -11,7 +11,6 @@ import { compactDate } from 'helpers/dateFormatting';
import { useGetDevice } from 'hooks/Network/Devices'; import { useGetDevice } from 'hooks/Network/Devices';
import { useGetProvUi } from 'hooks/Network/Endpoints'; import { useGetProvUi } from 'hooks/Network/Endpoints';
import { useGetTag } from 'hooks/Network/Inventory'; import { useGetTag } from 'hooks/Network/Inventory';
import { DeviceConfiguration } from 'models/Device';
type Props = { type Props = {
serialNumber: string; serialNumber: string;
@@ -60,7 +59,7 @@ const DeviceDetails = ({ serialNumber }: Props) => {
<Heading size="md">{t('common.details')}</Heading> <Heading size="md">{t('common.details')}</Heading>
<Spacer /> <Spacer />
<ViewCapabilitiesModal serialNumber={serialNumber} /> <ViewCapabilitiesModal serialNumber={serialNumber} />
<ViewConfigurationModal configuration={getDevice.data?.configuration as DeviceConfiguration} /> <ViewConfigurationModal serialNumber={serialNumber} />
</CardHeader> </CardHeader>
<CardBody display="block"> <CardBody display="block">
<Grid templateColumns="repeat(2, 1fr)" gap={0} w="100%"> <Grid templateColumns="repeat(2, 1fr)" gap={0} w="100%">

View File

@@ -7,7 +7,9 @@ import {
AccordionPanel, AccordionPanel,
Box, Box,
Button, Button,
Center,
IconButton, IconButton,
Spinner,
Tooltip, Tooltip,
useClipboard, useClipboard,
useColorMode, useColorMode,
@@ -17,19 +19,26 @@ import { JsonViewer } from '@textea/json-viewer';
import { Barcode } from '@phosphor-icons/react'; import { Barcode } from '@phosphor-icons/react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Modal } from 'components/Modals/Modal'; import { Modal } from 'components/Modals/Modal';
import { DeviceConfiguration } from 'models/Device'; import { useGetDevice } from 'hooks/Network/Devices';
import { RefreshButton } from 'components/Buttons/RefreshButton';
const ViewConfigurationModal = ({ configuration }: { configuration?: DeviceConfiguration }) => { const ViewConfigurationModal = ({ serialNumber }: { serialNumber: string }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const getDevice = useGetDevice({ serialNumber });
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const { hasCopied, onCopy, setValue } = useClipboard(JSON.stringify(configuration ?? {}, null, 2)); const { hasCopied, onCopy, setValue } = useClipboard(JSON.stringify(getDevice.data?.configuration ?? {}, null, 2));
const { colorMode } = useColorMode(); const { colorMode } = useColorMode();
React.useEffect(() => { React.useEffect(() => {
if (configuration) { if (getDevice.data) {
setValue(JSON.stringify(configuration, null, 2)); setValue(JSON.stringify(getDevice.data.configuration, null, 2));
} }
}, [configuration]); }, [getDevice.data?.configuration]);
const handleOpenClick = () => {
getDevice.refetch();
onOpen();
};
return ( return (
<> <>
@@ -37,7 +46,7 @@ const ViewConfigurationModal = ({ configuration }: { configuration?: DeviceConfi
<IconButton <IconButton
aria-label={t('configurations.one')} aria-label={t('configurations.one')}
icon={<Barcode size={20} />} icon={<Barcode size={20} />}
onClick={onOpen} onClick={handleOpenClick}
colorScheme="purple" colorScheme="purple"
/> />
</Tooltip> </Tooltip>
@@ -45,14 +54,17 @@ const ViewConfigurationModal = ({ configuration }: { configuration?: DeviceConfi
isOpen={isOpen} isOpen={isOpen}
title={t('configurations.one')} title={t('configurations.one')}
topRightButtons={ topRightButtons={
<Button onClick={onCopy} size="md" colorScheme="teal"> <>
{hasCopied ? `${t('common.copied')}!` : t('common.copy')} <Button onClick={onCopy} size="md" colorScheme="teal">
</Button> {hasCopied ? `${t('common.copied')}!` : t('common.copy')}
</Button>
<RefreshButton onClick={getDevice.refetch} isFetching={getDevice.isFetching} />
</>
} }
onClose={onClose} onClose={onClose}
> >
<Box display="inline-block" w="100%"> <Box display="inline-block" w="100%">
{configuration && ( {getDevice.data && !getDevice.isFetching ? (
<Box maxH="calc(100vh - 250px)" minH="300px" overflowY="auto"> <Box maxH="calc(100vh - 250px)" minH="300px" overflowY="auto">
<Accordion defaultIndex={0} allowToggle> <Accordion defaultIndex={0} allowToggle>
<AccordionItem> <AccordionItem>
@@ -71,7 +83,7 @@ const ViewConfigurationModal = ({ configuration }: { configuration?: DeviceConfi
enableClipboard={false} enableClipboard={false}
theme={colorMode === 'light' ? undefined : 'dark'} theme={colorMode === 'light' ? undefined : 'dark'}
defaultInspectDepth={1} defaultInspectDepth={1}
value={configuration as object} value={getDevice.data.configuration as object}
style={{ background: 'unset', display: 'unset' }} style={{ background: 'unset', display: 'unset' }}
/> />
</AccordionPanel> </AccordionPanel>
@@ -86,11 +98,15 @@ const ViewConfigurationModal = ({ configuration }: { configuration?: DeviceConfi
</AccordionButton> </AccordionButton>
</h2> </h2>
<AccordionPanel pb={4} overflowX="auto"> <AccordionPanel pb={4} overflowX="auto">
<pre>{JSON.stringify(configuration, null, 2)}</pre> <pre>{JSON.stringify(getDevice.data.configuration, null, 2)}</pre>
</AccordionPanel> </AccordionPanel>
</AccordionItem> </AccordionItem>
</Accordion> </Accordion>
</Box> </Box>
) : (
<Center my={12}>
<Spinner size="xl" />
</Center>
)} )}
</Box> </Box>
</Modal> </Modal>
@@ -98,4 +114,4 @@ const ViewConfigurationModal = ({ configuration }: { configuration?: DeviceConfi
); );
}; };
export default ViewConfigurationModal; export default React.memo(ViewConfigurationModal);