mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-11-01 10:47:45 +00:00
Merge pull request #195 from stephb9959/main
[WIFI-12948] Fixed view configuration modal cache
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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%">
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user