mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-11-02 03:07:46 +00:00
Merge pull request #179 from stephb9959/main
[WIFI-12515] Using simulated value directly instead of certificate
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.10.0(20)",
|
"version": "2.10.0(21)",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.10.0(20)",
|
"version": "2.10.0(21)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/icons": "^2.0.18",
|
"@chakra-ui/icons": "^2.0.18",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.10.0(20)",
|
"version": "2.10.0(21)",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.tsx",
|
"main": "index.tsx",
|
||||||
|
|||||||
1
src/@tanstack.react-table.d.ts
vendored
1
src/@tanstack.react-table.d.ts
vendored
@@ -6,6 +6,7 @@ declare module '@tanstack/table-core' {
|
|||||||
interface ColumnMeta<TData extends RowData, TValue> {
|
interface ColumnMeta<TData extends RowData, TValue> {
|
||||||
stopPropagation?: boolean;
|
stopPropagation?: boolean;
|
||||||
alwaysShow?: boolean;
|
alwaysShow?: boolean;
|
||||||
|
anchored?: boolean;
|
||||||
hasPopover?: boolean;
|
hasPopover?: boolean;
|
||||||
customMaxWidth?: string;
|
customMaxWidth?: string;
|
||||||
customMinWidth?: string;
|
customMinWidth?: string;
|
||||||
|
|||||||
34
src/components/Containers/ResponsiveTag/index.tsx
Normal file
34
src/components/Containers/ResponsiveTag/index.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { As, Icon, Tag, TagLabel, TagLeftIcon, TagProps, Tooltip, useBreakpoint } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
export interface ResponsiveTagProps extends TagProps {
|
||||||
|
label: string;
|
||||||
|
icon: As<any>;
|
||||||
|
tooltip?: string;
|
||||||
|
isCompact?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ResponsiveTag = React.memo(({ label, icon, tooltip, isCompact, ...props }: ResponsiveTagProps) => {
|
||||||
|
const breakpoint = useBreakpoint();
|
||||||
|
|
||||||
|
const isCompactVersion = isCompact || breakpoint === 'base' || breakpoint === 'sm';
|
||||||
|
|
||||||
|
if (isCompactVersion) {
|
||||||
|
return (
|
||||||
|
<Tooltip label={tooltip ?? label}>
|
||||||
|
<Tag size="lg" colorScheme="blue" {...props}>
|
||||||
|
<Icon as={icon} boxSize="18px" />
|
||||||
|
</Tag>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip label={tooltip ?? label}>
|
||||||
|
<Tag size="lg" colorScheme="blue" {...props}>
|
||||||
|
<TagLeftIcon boxSize="18px" as={icon} />
|
||||||
|
<TagLabel>{label}</TagLabel>
|
||||||
|
</Tag>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -58,6 +58,7 @@ export type DeviceWithStatus = {
|
|||||||
lastConfigurationDownload: number;
|
lastConfigurationDownload: number;
|
||||||
lastContact: number | string;
|
lastContact: number | string;
|
||||||
lastFWUpdate: number;
|
lastFWUpdate: number;
|
||||||
|
lastRecordedContact: number;
|
||||||
load: number;
|
load: number;
|
||||||
locale: string;
|
locale: string;
|
||||||
location: string;
|
location: string;
|
||||||
@@ -73,6 +74,7 @@ export type DeviceWithStatus = {
|
|||||||
restrictedDevice: boolean;
|
restrictedDevice: boolean;
|
||||||
rxBytes: number;
|
rxBytes: number;
|
||||||
serialNumber: string;
|
serialNumber: string;
|
||||||
|
simulated: boolean;
|
||||||
subscriber: string;
|
subscriber: string;
|
||||||
temperature: number;
|
temperature: number;
|
||||||
txBytes: number;
|
txBytes: number;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export interface GatewayDevice {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
serialNumber: string;
|
serialNumber: string;
|
||||||
|
simulated: boolean;
|
||||||
subscriber: string;
|
subscriber: string;
|
||||||
venue: string;
|
venue: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,17 +12,13 @@ import {
|
|||||||
HStack,
|
HStack,
|
||||||
Portal,
|
Portal,
|
||||||
Spacer,
|
Spacer,
|
||||||
Tag,
|
|
||||||
TagLabel,
|
|
||||||
TagLeftIcon,
|
|
||||||
Tooltip,
|
|
||||||
useBreakpoint,
|
useBreakpoint,
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
useToast,
|
useToast,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
import { Circuitry, Heart, HeartBreak, LockSimple, LockSimpleOpen, WifiHigh, WifiSlash } from '@phosphor-icons/react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Heart, HeartBreak, LockSimple, LockSimpleOpen, WifiHigh, WifiSlash } from '@phosphor-icons/react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import Masonry from 'react-masonry-css';
|
import Masonry from 'react-masonry-css';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
@@ -39,8 +35,8 @@ import DeviceActionDropdown from 'components/Buttons/DeviceActionDropdown';
|
|||||||
import { RefreshButton } from 'components/Buttons/RefreshButton';
|
import { RefreshButton } from 'components/Buttons/RefreshButton';
|
||||||
import { Card } from 'components/Containers/Card';
|
import { Card } from 'components/Containers/Card';
|
||||||
import { CardHeader } from 'components/Containers/Card/CardHeader';
|
import { CardHeader } from 'components/Containers/Card/CardHeader';
|
||||||
|
import { ResponsiveTag } from 'components/Containers/ResponsiveTag';
|
||||||
import GlobalSearchBar from 'components/GlobalSearchBar';
|
import GlobalSearchBar from 'components/GlobalSearchBar';
|
||||||
import FormattedDate from 'components/InformationDisplays/FormattedDate';
|
|
||||||
import { ConfigureModal } from 'components/Modals/ConfigureModal';
|
import { ConfigureModal } from 'components/Modals/ConfigureModal';
|
||||||
import { EventQueueModal } from 'components/Modals/EventQueueModal';
|
import { EventQueueModal } from 'components/Modals/EventQueueModal';
|
||||||
import FactoryResetModal from 'components/Modals/FactoryResetModal';
|
import FactoryResetModal from 'components/Modals/FactoryResetModal';
|
||||||
@@ -114,10 +110,11 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
if (!getStatus.data) return null;
|
if (!getStatus.data) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tag size="lg" colorScheme={getStatus?.data?.connected ? 'green' : 'red'}>
|
<ResponsiveTag
|
||||||
<TagLeftIcon boxSize="18px" as={getStatus.data.connected ? WifiHigh : WifiSlash} />
|
label={getStatus?.data?.connected ? t('common.connected') : t('common.disconnected')}
|
||||||
<TagLabel>{getStatus?.data?.connected ? t('common.connected') : t('common.disconnected')}</TagLabel>
|
colorScheme={getStatus?.data?.connected ? 'green' : 'red'}
|
||||||
</Tag>
|
icon={getStatus.data.connected ? WifiHigh : WifiSlash}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}, [getStatus.data]);
|
}, [getStatus.data]);
|
||||||
|
|
||||||
@@ -133,23 +130,12 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
if (sanityValue === 100) color = 'green';
|
if (sanityValue === 100) color = 'green';
|
||||||
else if (sanityValue > 80) color = 'yellow';
|
else if (sanityValue > 80) color = 'yellow';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<ResponsiveTag
|
||||||
hasArrow
|
label={sanity ? `${sanity}%` : t('common.unknown')}
|
||||||
label={
|
colorScheme={color}
|
||||||
getHealth.data?.values?.[0]?.recorded !== undefined ? (
|
icon={color === 'green' ? Heart : HeartBreak}
|
||||||
<FormattedDate date={getHealth.data?.values?.[0]?.recorded} />
|
/>
|
||||||
) : (
|
|
||||||
''
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Tag size="lg" colorScheme={color}>
|
|
||||||
<TagLeftIcon boxSize="18px" as={color === 'green' ? Heart : HeartBreak} />
|
|
||||||
<TagLabel>{sanity ? `${sanity}%` : t('common.unknown')}</TagLabel>
|
|
||||||
</Tag>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
);
|
||||||
}, [getStatus.data, getHealth.data]);
|
}, [getStatus.data, getHealth.data]);
|
||||||
|
|
||||||
@@ -158,21 +144,21 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
|
|
||||||
if (getDevice.data.restrictionDetails?.developer)
|
if (getDevice.data.restrictionDetails?.developer)
|
||||||
return (
|
return (
|
||||||
<Tooltip label={t('devices.restricted_overriden')} hasArrow>
|
<ResponsiveTag
|
||||||
<Tag size="lg" colorScheme="green">
|
label={`${t('devices.restricted')} ${isCompact ? '' : '(Dev Mode)'}`}
|
||||||
<TagLeftIcon boxSize="18px" as={LockSimpleOpen} />
|
tooltip={t('devices.restricted_overriden')}
|
||||||
<TagLabel>
|
colorScheme="green"
|
||||||
{t('devices.restricted')} {isCompact ? '' : '(Dev Mode)'}
|
icon={LockSimpleOpen}
|
||||||
</TagLabel>
|
/>
|
||||||
</Tag>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tag size="lg" colorScheme="red">
|
<ResponsiveTag
|
||||||
<TagLeftIcon boxSize="18px" as={LockSimple} />
|
label={t('devices.restricted')}
|
||||||
<TagLabel>{t('devices.restricted')}</TagLabel>
|
tooltip={t('devices.restricted')}
|
||||||
</Tag>
|
colorScheme="red"
|
||||||
|
icon={LockSimple}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}, [getDevice.data, isCompact]);
|
}, [getDevice.data, isCompact]);
|
||||||
|
|
||||||
@@ -189,6 +175,9 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<Heading size="md">{serialNumber}</Heading>
|
<Heading size="md">{serialNumber}</Heading>
|
||||||
|
{getDevice.data?.simulated ? (
|
||||||
|
<ResponsiveTag label={t('simulation.simulated')} colorScheme="purple" icon={Circuitry} />
|
||||||
|
) : null}
|
||||||
{connectedTag}
|
{connectedTag}
|
||||||
{healthTag}
|
{healthTag}
|
||||||
{restrictedTag}
|
{restrictedTag}
|
||||||
@@ -239,6 +228,9 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
<CardHeader>
|
<CardHeader>
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<Heading size="md">{serialNumber}</Heading>
|
<Heading size="md">{serialNumber}</Heading>
|
||||||
|
{getDevice.data?.simulated ? (
|
||||||
|
<ResponsiveTag label={t('simulation.simulated')} colorScheme="purple" icon={Circuitry} />
|
||||||
|
) : null}
|
||||||
{connectedTag}
|
{connectedTag}
|
||||||
{healthTag}
|
{healthTag}
|
||||||
{restrictedTag}
|
{restrictedTag}
|
||||||
|
|||||||
@@ -81,7 +81,9 @@ const DeviceListCard = () => {
|
|||||||
const configureModalProps = useDisclosure();
|
const configureModalProps = useDisclosure();
|
||||||
const rebootModalProps = useDisclosure();
|
const rebootModalProps = useDisclosure();
|
||||||
const scriptModal = useScriptModal();
|
const scriptModal = useScriptModal();
|
||||||
const tableController = useDataGrid({ tableSettingsId: 'gateway.devices.table' });
|
const tableController = useDataGrid({
|
||||||
|
tableSettingsId: 'gateway.devices.table',
|
||||||
|
});
|
||||||
const getCount = useGetDeviceCount({ enabled: true });
|
const getCount = useGetDeviceCount({ enabled: true });
|
||||||
const getDevices = useGetDevices({
|
const getDevices = useGetDevices({
|
||||||
pageInfo: {
|
pageInfo: {
|
||||||
@@ -133,14 +135,14 @@ const DeviceListCard = () => {
|
|||||||
h="35px"
|
h="35px"
|
||||||
w="35px"
|
w="35px"
|
||||||
borderRadius="50em"
|
borderRadius="50em"
|
||||||
bgColor={BADGE_COLORS[device.verifiedCertificate] ?? 'red'}
|
bgColor={BADGE_COLORS[device.simulated ? 'SIMULATED' : device.verifiedCertificate] ?? 'red'}
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
display="inline-flex"
|
display="inline-flex"
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
position="relative"
|
position="relative"
|
||||||
>
|
>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label={`${device.verifiedCertificate} - ${
|
label={`${device.simulated ? 'SIMULATED' : device.verifiedCertificate} - ${
|
||||||
device.connected ? t('common.connected') : t('common.disconnected')
|
device.connected ? t('common.connected') : t('common.disconnected')
|
||||||
} ${device.restrictedDevice ? `- ${t('devices.restricted')}` : ''}`}
|
} ${device.restrictedDevice ? `- ${t('devices.restricted')}` : ''}`}
|
||||||
>
|
>
|
||||||
@@ -325,14 +327,15 @@ const DeviceListCard = () => {
|
|||||||
const temperatureCell = React.useCallback((device: DeviceWithStatus) => {
|
const temperatureCell = React.useCallback((device: DeviceWithStatus) => {
|
||||||
if (!device.connected || device.temperature === 0) return <Center>-</Center>;
|
if (!device.connected || device.temperature === 0) return <Center>-</Center>;
|
||||||
|
|
||||||
|
const temperature = device.temperature > 1000 ? device.temperature / 1000 : device.temperature;
|
||||||
let colorScheme = 'red';
|
let colorScheme = 'red';
|
||||||
if (device.temperature <= 85) colorScheme = 'yellow';
|
if (temperature <= 85) colorScheme = 'yellow';
|
||||||
if (device.temperature <= 75) colorScheme = 'green';
|
if (temperature <= 75) colorScheme = 'green';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Center>
|
<Center>
|
||||||
<Tag borderRadius="full" variant="subtle" colorScheme={colorScheme}>
|
<Tag borderRadius="full" variant="subtle" colorScheme={colorScheme}>
|
||||||
<TagLabel>{fourDigitNumber(device.temperature)}°C</TagLabel>
|
<TagLabel>{fourDigitNumber(temperature)}°C</TagLabel>
|
||||||
<TagRightIcon marginStart="0.1rem" as={colorScheme === 'green' ? ThermometerCold : ThermometerHot} />
|
<TagRightIcon marginStart="0.1rem" as={colorScheme === 'green' ? ThermometerCold : ThermometerHot} />
|
||||||
</Tag>
|
</Tag>
|
||||||
</Center>
|
</Center>
|
||||||
@@ -349,6 +352,10 @@ const DeviceListCard = () => {
|
|||||||
cell: (v) => badgeCell(v.cell.row.original),
|
cell: (v) => badgeCell(v.cell.row.original),
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
meta: {
|
meta: {
|
||||||
|
columnSelectorOptions: {
|
||||||
|
label: 'Connection Badge',
|
||||||
|
},
|
||||||
|
anchored: true,
|
||||||
customWidth: '35px',
|
customWidth: '35px',
|
||||||
alwaysShow: true,
|
alwaysShow: true,
|
||||||
},
|
},
|
||||||
@@ -361,6 +368,7 @@ const DeviceListCard = () => {
|
|||||||
cell: (v) => serialCell(v.cell.row.original),
|
cell: (v) => serialCell(v.cell.row.original),
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
meta: {
|
meta: {
|
||||||
|
anchored: true,
|
||||||
alwaysShow: true,
|
alwaysShow: true,
|
||||||
customMaxWidth: '200px',
|
customMaxWidth: '200px',
|
||||||
customWidth: '130px',
|
customWidth: '130px',
|
||||||
@@ -508,6 +516,24 @@ const DeviceListCard = () => {
|
|||||||
cell: (v) => uptimeCell(v.cell.row.original),
|
cell: (v) => uptimeCell(v.cell.row.original),
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'lastRecordedContact',
|
||||||
|
header: t('analytics.last_connected'),
|
||||||
|
footer: '',
|
||||||
|
accessorKey: 'lastRecordedContact',
|
||||||
|
cell: (v) =>
|
||||||
|
dateCell(
|
||||||
|
v.cell.row.original.lastContact !== 0
|
||||||
|
? v.cell.row.original.lastContact
|
||||||
|
: v.cell.row.original.lastRecordedContact,
|
||||||
|
),
|
||||||
|
enableSorting: false,
|
||||||
|
meta: {
|
||||||
|
headerOptions: {
|
||||||
|
tooltip: t('analytics.last_connected_tooltip'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'lastContact',
|
id: 'lastContact',
|
||||||
header: t('analytics.last_contact'),
|
header: t('analytics.last_contact'),
|
||||||
|
|||||||
Reference in New Issue
Block a user