Merge pull request #137 from stephb9959/main

[WIFI-11858] Sticky device page top bar
This commit is contained in:
Charles Bourque
2022-12-01 08:52:15 +00:00
committed by GitHub
5 changed files with 144 additions and 54 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "ucentral-client", "name": "ucentral-client",
"version": "2.8.0(27)", "version": "2.8.0(28)",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ucentral-client", "name": "ucentral-client",
"version": "2.8.0(27)", "version": "2.8.0(28)",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@chakra-ui/icons": "^2.0.11", "@chakra-ui/icons": "^2.0.11",

View File

@@ -1,6 +1,6 @@
{ {
"name": "ucentral-client", "name": "ucentral-client",
"version": "2.8.0(27)", "version": "2.8.0(30)",
"description": "", "description": "",
"private": true, "private": true,
"main": "index.tsx", "main": "index.tsx",

View File

@@ -1,7 +1,22 @@
import React from 'react'; import React from 'react';
import { BackgroundProps, Box, InteractivityProps, LayoutProps, SpaceProps, useStyleConfig } from '@chakra-ui/react'; import {
BackgroundProps,
Box,
EffectProps,
InteractivityProps,
LayoutProps,
PositionProps,
SpaceProps,
useStyleConfig,
} from '@chakra-ui/react';
export interface CardProps extends LayoutProps, SpaceProps, BackgroundProps, InteractivityProps { export interface CardProps
extends LayoutProps,
SpaceProps,
BackgroundProps,
InteractivityProps,
PositionProps,
EffectProps {
variant?: string; variant?: string;
onClick?: () => void; onClick?: () => void;
className?: string; className?: string;

View File

@@ -2,7 +2,7 @@
display: -webkit-box; display: -webkit-box;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
margin-left: -30px; margin-left: -20px;
width: auto; width: auto;
} }
.my-masonry-grid_column { .my-masonry-grid_column {

View File

@@ -1,5 +1,18 @@
import * as React from 'react'; import * as React from 'react';
import { Box, Heading, HStack, Spacer, Tag, TagLabel, TagLeftIcon, Tooltip, useDisclosure } from '@chakra-ui/react'; import {
Box,
Heading,
HStack,
Portal,
Spacer,
Tag,
TagLabel,
TagLeftIcon,
Tooltip,
useBreakpoint,
useColorModeValue,
useDisclosure,
} from '@chakra-ui/react';
import { Heart, HeartBreak, LockSimple, WifiHigh, WifiSlash } from 'phosphor-react'; import { Heart, HeartBreak, LockSimple, WifiHigh, WifiSlash } from 'phosphor-react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import Masonry from 'react-masonry-css'; import Masonry from 'react-masonry-css';
@@ -18,6 +31,7 @@ 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';
import { FirmwareUpgradeModal } from 'components/Modals/FirmwareUpgradeModal'; import { FirmwareUpgradeModal } from 'components/Modals/FirmwareUpgradeModal';
import { useScriptModal } from 'components/Modals/ScriptModal/useScriptModal';
import { TelemetryModal } from 'components/Modals/TelemetryModal'; 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';
@@ -29,6 +43,7 @@ type Props = {
const DevicePageWrapper = ({ serialNumber }: Props) => { const DevicePageWrapper = ({ serialNumber }: Props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const breakpoint = useBreakpoint();
const getDevice = useGetDevice({ serialNumber }); const getDevice = useGetDevice({ serialNumber });
const getStatus = useGetDeviceStatus({ serialNumber }); const getStatus = useGetDeviceStatus({ serialNumber });
const getHealth = useGetDeviceHealthChecks({ serialNumber, limit: 1 }); const getHealth = useGetDeviceHealthChecks({ serialNumber, limit: 1 });
@@ -39,7 +54,7 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
const upgradeModalProps = useDisclosure(); const upgradeModalProps = useDisclosure();
const telemetryModalProps = useDisclosure(); const telemetryModalProps = useDisclosure();
const traceModalProps = useDisclosure(); const traceModalProps = useDisclosure();
const scriptModal = useScriptModal();
const connectedTag = React.useMemo(() => { const connectedTag = React.useMemo(() => {
if (!getStatus.data) return null; if (!getStatus.data) return null;
@@ -83,6 +98,10 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
); );
}, [getStatus.data, getHealth.data]); }, [getStatus.data, getHealth.data]);
// Sticky-top styles
const isCompact = breakpoint === 'base' || breakpoint === 'sm' || breakpoint === 'md';
const boxShadow = useColorModeValue('0px 7px 23px rgba(0, 0, 0, 0.05)', 'none');
const refresh = () => { const refresh = () => {
getDevice.refetch(); getDevice.refetch();
getStatus.refetch(); getStatus.refetch();
@@ -91,54 +110,110 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
return ( return (
<> <>
<Card p={2} mb={4}> {isCompact ? (
<CardHeader> <Card p={2} mb={4}>
<HStack spacing={2}> <CardHeader>
<Heading size="md">{serialNumber}</Heading> <HStack spacing={2}>
{connectedTag} <Heading size="md">{serialNumber}</Heading>
{healthTag} {connectedTag}
{getDevice.data?.restrictedDevice && ( {healthTag}
<Tag size="lg" colorScheme="gray"> {getDevice.data?.restrictedDevice && (
<TagLeftIcon boxSize="18px" as={LockSimple} /> <Tag size="lg" colorScheme="gray">
<TagLabel>{t('devices.restricted')}</TagLabel> <TagLeftIcon boxSize="18px" as={LockSimple} />
</Tag> <TagLabel>{t('devices.restricted')}</TagLabel>
)} </Tag>
</HStack> )}
<Spacer /> </HStack>
<HStack spacing={2}> <Spacer />
{getDevice?.data && ( <HStack spacing={2}>
<DeviceActionDropdown {getDevice?.data && (
<DeviceActionDropdown
// @ts-ignore
device={getDevice?.data}
refresh={refresh}
onOpenScan={scanModalProps.onOpen}
onOpenFactoryReset={resetModalProps.onOpen}
onOpenUpgradeModal={upgradeModalProps.onOpen}
onOpenTrace={traceModalProps.onOpen}
onOpenEventQueue={eventQueueProps.onOpen}
onOpenConfigureModal={configureModalProps.onOpen}
onOpenTelemetryModal={telemetryModalProps.onOpen}
onOpenScriptModal={scriptModal.openModal}
size="md"
/>
)}
<RefreshButton
onClick={refresh}
isFetching={getDevice.isFetching || getHealth.isFetching || getStatus.isFetching}
isCompact
// @ts-ignore // @ts-ignore
device={getDevice?.data} colorScheme="blue"
refresh={refresh}
onOpenScan={scanModalProps.onOpen}
onOpenFactoryReset={resetModalProps.onOpen}
onOpenUpgradeModal={upgradeModalProps.onOpen}
onOpenTrace={traceModalProps.onOpen}
onOpenEventQueue={eventQueueProps.onOpen}
onOpenConfigureModal={configureModalProps.onOpen}
onOpenTelemetryModal={telemetryModalProps.onOpen}
size="md"
/> />
)} </HStack>
<RefreshButton </CardHeader>
onClick={refresh} </Card>
isFetching={getDevice.isFetching || getHealth.isFetching || getStatus.isFetching} ) : (
isCompact <Portal>
// @ts-ignore <Card
colorScheme="blue" p={2}
/> mb={4}
</HStack> top="100px"
</CardHeader> position="fixed"
<WifiScanModal modalProps={scanModalProps} serialNumber={serialNumber} /> w="calc(100vw - 271px)"
<FirmwareUpgradeModal modalProps={upgradeModalProps} serialNumber={serialNumber} /> right={{ base: '0px', sm: '0px', lg: '20px' }}
<FactoryResetModal modalProps={resetModalProps} serialNumber={serialNumber} /> boxShadow={boxShadow}
<TraceModal serialNumber={serialNumber} modalProps={traceModalProps} /> >
<EventQueueModal serialNumber={serialNumber} modalProps={eventQueueProps} /> <CardHeader>
<ConfigureModal serialNumber={serialNumber} modalProps={configureModalProps} /> <HStack spacing={2}>
<TelemetryModal serialNumber={serialNumber} modalProps={telemetryModalProps} /> <Heading size="md">{serialNumber}</Heading>
</Card> {connectedTag}
<Box marginLeft="10px"> {healthTag}
{getDevice.data?.restrictedDevice && (
<Tag size="lg" colorScheme="gray">
<TagLeftIcon boxSize="18px" as={LockSimple} />
<TagLabel>{t('devices.restricted')}</TagLabel>
</Tag>
)}
</HStack>
<Spacer />
<HStack spacing={2}>
{getDevice?.data && (
<DeviceActionDropdown
// @ts-ignore
device={getDevice?.data}
refresh={refresh}
onOpenScan={scanModalProps.onOpen}
onOpenFactoryReset={resetModalProps.onOpen}
onOpenUpgradeModal={upgradeModalProps.onOpen}
onOpenTrace={traceModalProps.onOpen}
onOpenEventQueue={eventQueueProps.onOpen}
onOpenConfigureModal={configureModalProps.onOpen}
onOpenTelemetryModal={telemetryModalProps.onOpen}
onOpenScriptModal={scriptModal.openModal}
size="md"
/>
)}
<RefreshButton
onClick={refresh}
isFetching={getDevice.isFetching || getHealth.isFetching || getStatus.isFetching}
isCompact
// @ts-ignore
colorScheme="blue"
/>
</HStack>
</CardHeader>
</Card>
</Portal>
)}
<WifiScanModal modalProps={scanModalProps} serialNumber={serialNumber} />
<FirmwareUpgradeModal modalProps={upgradeModalProps} serialNumber={serialNumber} />
<FactoryResetModal modalProps={resetModalProps} serialNumber={serialNumber} />
<TraceModal serialNumber={serialNumber} modalProps={traceModalProps} />
<EventQueueModal serialNumber={serialNumber} modalProps={eventQueueProps} />
<ConfigureModal serialNumber={serialNumber} modalProps={configureModalProps} />
<TelemetryModal serialNumber={serialNumber} modalProps={telemetryModalProps} />
{scriptModal.modal}
<Box mt={isCompact ? '0px' : '68px'}>
<Masonry <Masonry
breakpointCols={{ breakpointCols={{
default: 3, default: 3,