Merge branch 'staging_environment' into gate_page_fixes
This commit is contained in:
commit
62cc0a2e97
21 changed files with 2716 additions and 29 deletions
|
|
@ -22,6 +22,15 @@ import { or } from "utils";
|
|||
import ComponentDiagnostics from "component/ComponentDiagnostics";
|
||||
import DeviceWizard from "device/DeviceWizard";
|
||||
|
||||
export interface DevicePageData {
|
||||
device: Device;
|
||||
components: Component[];
|
||||
interactions: Interaction[];
|
||||
permissions: pond.Permission[];
|
||||
preferences: pond.DevicePreferences;
|
||||
// componentPreferences: Map<string, pond.DeviceComponentPreferences>
|
||||
}
|
||||
|
||||
export default function DevicePage() {
|
||||
const deviceAPI = useDeviceAPI()
|
||||
const snackbar = useSnackbar()
|
||||
|
|
@ -30,6 +39,7 @@ export default function DevicePage() {
|
|||
const groupID = useParams<{ groupID: string }>()?.groupID ?? "";
|
||||
const { state } = useLocation();
|
||||
const [{ as, team, user }] = useGlobalState()
|
||||
// console.log(state)
|
||||
const [device, setDevice] = useState<Device>(state?.device ? Device.create(state.device) : Device.create())
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [permissions, setPermissions] = useState<pond.Permission[]>([])
|
||||
|
|
@ -51,11 +61,21 @@ export default function DevicePage() {
|
|||
|
||||
const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false)
|
||||
|
||||
// const [devicePageData, setDevicePageData] = useState(pond.GetDevicePageDataResponse.create())
|
||||
|
||||
const loadDevice = () => {
|
||||
// console.log("load device page data")
|
||||
if (loading) return
|
||||
if (state?.devicePageData) {
|
||||
setDevice(Device.create(state.devicePageData.device))
|
||||
setComponents(state.devicePageData.components.map((comp: pond.Component) => Component.create(comp)))
|
||||
setInteractions(state.devicePageData.interactions.map((inter: pond.Interaction) => Interaction.create(inter)))
|
||||
setPreferences(state.devicePageData.preferences)
|
||||
setPermissions(state.devicePageData.permissions)
|
||||
return
|
||||
}
|
||||
setLoading(true)
|
||||
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes(), as).then(resp => {
|
||||
// setDevicePageData(resp.data)
|
||||
let device = Device.any(resp.data.device)
|
||||
// console.log(resp.data.device)
|
||||
setDevice(device)
|
||||
|
|
@ -418,19 +438,9 @@ export default function DevicePage() {
|
|||
<PageContainer padding={isMobile ? 0 : 2}>
|
||||
<Grid container justifyContent={"space-between"}>
|
||||
<Grid>
|
||||
<SmartBreadcrumb />
|
||||
<SmartBreadcrumb deviceName={device.name()} />
|
||||
</Grid>
|
||||
<Grid>
|
||||
<AddComponentManualDialog
|
||||
device={device.id()}
|
||||
open={addComponentManualDialogOpen}
|
||||
onClose={() => setAddComponentManualDialogOpen(false)}
|
||||
/>
|
||||
{user.hasFeature("developer") === true &&
|
||||
<Button onClick={() => setAddComponentManualDialogOpen(true)}>
|
||||
Manual Comp
|
||||
</Button>
|
||||
}
|
||||
<DeviceActions
|
||||
device={device}
|
||||
isPaused={false}
|
||||
|
|
@ -449,8 +459,6 @@ export default function DevicePage() {
|
|||
<DeviceOverview
|
||||
device={device}
|
||||
components={[...components.values()]}
|
||||
// components={[]}
|
||||
// components={components}
|
||||
usage={getUsage()}
|
||||
loading={loading}
|
||||
groupID={parseInt(groupID)}
|
||||
|
|
|
|||
393
src/pages/DeviceSupport.tsx
Normal file
393
src/pages/DeviceSupport.tsx
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
import { Box, Button, FormControl, Grid2 as Grid, MenuItem, Select, Tab, Tabs, TextField, Typography, useTheme } from "@mui/material";
|
||||
import PageContainer from "./PageContainer";
|
||||
import { pond } from "protobuf-ts/pond";
|
||||
import LogsDisplay from "common/LogsDisplay";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDeviceAPI, useSnackbar } from "hooks";
|
||||
import { useLocation, useParams } from "react-router-dom";
|
||||
import { Component, Device, Interaction } from "models";
|
||||
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||
import SmartBreadcrumb from "common/SmartBreadcrumb";
|
||||
import { DevicePageData } from "./Device";
|
||||
import AddComponentManualDialog from "component/AddComponentManualDialog";
|
||||
import { useGlobalState } from "providers";
|
||||
import DeviceActions from "device/DeviceActions";
|
||||
import { cloneDeep } from "lodash";
|
||||
import { FindAvailablePositions } from "pbHelpers/DeviceAvailability";
|
||||
import LoadingScreen from "app/LoadingScreen";
|
||||
import DeviceOverview from "device/DeviceOverview";
|
||||
|
||||
interface TabPanelProps {
|
||||
children?: React.ReactNode;
|
||||
index: any;
|
||||
value: any;
|
||||
}
|
||||
|
||||
function TabPanelMine(props: TabPanelProps) {
|
||||
const { children, value, index, ...other } = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
role="tabpanel"
|
||||
hidden={value !== index}
|
||||
aria-labelledby={`simple-tab-${index}`}
|
||||
{...other}>
|
||||
{value === index && <>{children}</>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function DeviceSupport() {
|
||||
const deviceID = +(useParams<{ deviceID: string }>()?.deviceID ?? "0");
|
||||
|
||||
const deviceAPI = useDeviceAPI()
|
||||
const snackbar = useSnackbar()
|
||||
const theme = useTheme()
|
||||
|
||||
const { state } = useLocation();
|
||||
const [{ user, as }] = useGlobalState()
|
||||
const [device, setDevice] = useState<Device>(Device.create())
|
||||
const [devicePageData, setDevicePageData] = useState<DevicePageData>(state?.devicePageData ? state.devicePageData : undefined)
|
||||
const [tabNumber, setTabNumber] = useState(0)
|
||||
const [newCap, setNewCap] = useState(0);
|
||||
const [datacap, setDatacap] = useState<number>();
|
||||
const [isOver, setIsOver] = useState(undefined);
|
||||
const [pauseCheck, setPauseCheck] = useState(undefined);
|
||||
const [inputFirmware, setInputFirmware] = useState<string>("");
|
||||
const [platform, setPlatform] = useState<pond.DevicePlatform>(
|
||||
pond.DevicePlatform.DEVICE_PLATFORM_INVALID
|
||||
);
|
||||
const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false)
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
// useEffect(() => {
|
||||
// if (state?.device) return
|
||||
// deviceAPI.get(deviceID, undefined, getContextKeys(), getContextTypes()).then(resp => {
|
||||
// setDevice(Device.create(resp.data))
|
||||
// })
|
||||
// }, [deviceID, state?.device])
|
||||
|
||||
useEffect(() => {
|
||||
if (state?.devicePageData) {
|
||||
setDevice(Device.create(state?.devicePageData.device))
|
||||
return
|
||||
}
|
||||
setLoading(true)
|
||||
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes()).then(resp => {
|
||||
setDevice(resp.data?.device ? Device.create(resp.data?.device) : Device.create())
|
||||
setDevicePageData({
|
||||
device: resp.data.device ? Device.create(resp.data.device) : Device.create(),
|
||||
components: resp.data.components.map(comp => Component.create(comp)),
|
||||
interactions: resp.data.interactions.map(interaction => Interaction.create(interaction)),
|
||||
permissions: resp.data.permissions,
|
||||
preferences: resp.data.user?.preferences as pond.DevicePreferences
|
||||
})
|
||||
}).finally(() => {
|
||||
setLoading(false)
|
||||
})
|
||||
}, [deviceID, state?.devicePageData])
|
||||
|
||||
const handleChange = (_event: React.ChangeEvent<{}>, newValue: number) => {
|
||||
setTabNumber(newValue);
|
||||
};
|
||||
|
||||
const resetQuackCount = () => {
|
||||
deviceAPI.resetQuackCount(device.id()).then(resp => console.log(resp));
|
||||
};
|
||||
|
||||
const resetQuackCountTx = () => {
|
||||
deviceAPI.resetQuackCountTx(device.id()).then(resp => console.log(resp));
|
||||
};
|
||||
|
||||
const resetQuackCountTx1000 = () => {
|
||||
deviceAPI.resetQuackCountTx1000(device.id()).then(resp => console.log(resp));
|
||||
};
|
||||
|
||||
const clearPending = () => {
|
||||
deviceAPI.clearPending(device.id()).then(resp => {
|
||||
console.log(resp);
|
||||
});
|
||||
};
|
||||
|
||||
const setFirmwareVersion = (firmwareVersion: string) => {
|
||||
let status = device.status;
|
||||
status.firmwareVersion = firmwareVersion;
|
||||
deviceAPI.updateStatus(device.id(), status).then(() => {
|
||||
snackbar.info("Firmware version set to " + firmwareVersion);
|
||||
});
|
||||
};
|
||||
|
||||
const updateDevicePlatform = (firmwareVersion: pond.DevicePlatform) => {
|
||||
let settings = device.settings;
|
||||
settings.platform = firmwareVersion;
|
||||
deviceAPI.update(device.id(), settings).then(() => {
|
||||
snackbar.info("Platform set to " + firmwareVersion.toString());
|
||||
});
|
||||
};
|
||||
|
||||
const getDatacap = () => {
|
||||
deviceAPI.getDatacap(device.id()).then(resp => {
|
||||
//console.log(resp);
|
||||
setDatacap(resp.data.overlimit);
|
||||
});
|
||||
};
|
||||
|
||||
const updateDatacap = () => {
|
||||
deviceAPI.setDatacap(device.id(), newCap).then(resp => {
|
||||
console.log(resp);
|
||||
});
|
||||
};
|
||||
|
||||
const checkLimit = () => {
|
||||
deviceAPI.isOverLimit(device.id()).then(resp => {
|
||||
//console.log(resp);
|
||||
setIsOver(resp.data);
|
||||
});
|
||||
};
|
||||
|
||||
const checkIfPaused = () => {
|
||||
deviceAPI.isPaused(device.id()).then(resp => {
|
||||
//console.log(resp);
|
||||
setPauseCheck(resp.data);
|
||||
});
|
||||
};
|
||||
|
||||
const pauseDevice = () => {
|
||||
deviceAPI.pause(device.id()).then(resp => {
|
||||
console.log(resp);
|
||||
});
|
||||
};
|
||||
|
||||
const resumeDevice = () => {
|
||||
deviceAPI.resume(device.id()).then(resp => {
|
||||
console.log(resp);
|
||||
});
|
||||
};
|
||||
|
||||
const toggleNotificationPreference = () => {
|
||||
let updatedPreferences = cloneDeep(devicePageData.preferences);
|
||||
updatedPreferences.notify = !devicePageData.preferences.notify;
|
||||
let updatedDevicePageData = cloneDeep(devicePageData)
|
||||
updatedDevicePageData.preferences = updatedPreferences
|
||||
deviceAPI
|
||||
.updatePreferences(deviceID, updatedPreferences, getContextKeys(), getContextTypes(), as)
|
||||
.then(() => setDevicePageData(updatedDevicePageData))
|
||||
.catch(() => {
|
||||
snackbar.error(
|
||||
"Error occured while " +
|
||||
(devicePageData.preferences.notify ? "enabling" : "disabling") +
|
||||
" notifications"
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
if (!devicePageData) {
|
||||
return (
|
||||
<LoadingScreen message="Getting device data"/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<Grid container justifyContent={"space-between"}>
|
||||
<Grid>
|
||||
<SmartBreadcrumb deviceName={device.name()} state={{devicePageData: devicePageData}} />
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DeviceActions
|
||||
device={device}
|
||||
isPaused={false}
|
||||
isLoading={loading}
|
||||
permissions={devicePageData.permissions}
|
||||
preferences={devicePageData.preferences}
|
||||
toggleNotificationPreference={toggleNotificationPreference}
|
||||
refreshCallback={() => {}}
|
||||
availablePositions={FindAvailablePositions(devicePageData.components, device.settings.product).availability}
|
||||
availableOffsets={new Map()}
|
||||
components={[...devicePageData.components.map(comp => Component.any(comp))]}
|
||||
interactions={devicePageData.interactions.map(inter => Interaction.any(inter))}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{/* <SmartBreadcrumb deviceName={device.name()} state={{devicePageData: devicePageData}} /> */}
|
||||
<DeviceOverview device={device} components={devicePageData.components}/>
|
||||
<br/>
|
||||
<Tabs
|
||||
style={{ position: "sticky" }}
|
||||
value={tabNumber}
|
||||
onChange={handleChange}
|
||||
centered
|
||||
TabIndicatorProps={{ style: { background: "rgba(255,255,0,255)" } }}>
|
||||
<Tab label="Control Center" />
|
||||
<Tab label="Hologram" />
|
||||
<Tab label="DataDog" />
|
||||
<Tab label="DuckData" />
|
||||
</Tabs>
|
||||
<TabPanelMine value={tabNumber} index={0}>
|
||||
<Box>
|
||||
<Typography gutterBottom variant="h5">
|
||||
General Options:
|
||||
</Typography>
|
||||
<Grid container direction="row">
|
||||
<Grid>
|
||||
<Button color="primary" onClick={resetQuackCount}>
|
||||
Reset Count Rx (safe, use when quack count errors)
|
||||
</Button>
|
||||
<Button color="primary" onClick={resetQuackCountTx}>
|
||||
Reset Count Tx, Are you sure (ONLY use when device not responding)
|
||||
</Button>
|
||||
<Button color="primary" onClick={resetQuackCountTx1000}>
|
||||
Reset Count Tx - 1000, Are you sure (ONLY use when device not responding)
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Button color="primary" onClick={clearPending}>
|
||||
Clear Pending
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<AddComponentManualDialog
|
||||
device={device.id()}
|
||||
open={addComponentManualDialogOpen}
|
||||
onClose={() => setAddComponentManualDialogOpen(false)}
|
||||
/>
|
||||
{user.hasFeature("developer") === true &&
|
||||
<Button onClick={() => setAddComponentManualDialogOpen(true)}>
|
||||
Manual Comp
|
||||
</Button>
|
||||
}
|
||||
</Grid>
|
||||
<Grid container direction="row">
|
||||
<Grid>
|
||||
<TextField
|
||||
value={inputFirmware}
|
||||
onChange={e => setInputFirmware(e.currentTarget.value)}
|
||||
/>
|
||||
<Button color="primary" onClick={() => setFirmwareVersion(inputFirmware)}>
|
||||
Set Firmware
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container direction="row">
|
||||
<Grid>
|
||||
<FormControl>
|
||||
<Select
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={platform}
|
||||
label="Platform"
|
||||
onChange={(event: any) => setPlatform(event.target.value)}>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_PHOTON}>Photon</MenuItem>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_ELECTRON}>
|
||||
Electron
|
||||
</MenuItem>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_V2_CELLULAR}>
|
||||
V2 Cellular
|
||||
</MenuItem>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_V2_WIFI_S3}>
|
||||
V2 Wifi S3
|
||||
</MenuItem>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_V2_CELLULAR_BLACK}>
|
||||
V2 Cellular Black
|
||||
</MenuItem>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_V2_CELLULAR_GREEN}>
|
||||
V2 Cellular Green
|
||||
</MenuItem>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_V2_WIFI_BLUE}>
|
||||
V2 Wifi Blue
|
||||
</MenuItem>
|
||||
<MenuItem value={pond.DevicePlatform.DEVICE_PLATFORM_V2_CELLULAR_BLUE}>
|
||||
V2 Cellular Blue
|
||||
</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<Button color="primary" onClick={() => updateDevicePlatform(platform)}>
|
||||
Set Platform
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
<Box marginTop={theme.spacing(0.5)}>
|
||||
<Typography gutterBottom variant="h5">
|
||||
OPI Cable Functions:
|
||||
</Typography>
|
||||
<Grid container direction="row">
|
||||
<Grid>
|
||||
<Button color="primary">Cable Reprogrammer</Button>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Button color="primary">Cable Diagnostic</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</TabPanelMine>
|
||||
<TabPanelMine value={tabNumber} index={1}>
|
||||
<Grid container direction="column">
|
||||
<Grid container direction="row">
|
||||
<Grid>
|
||||
<TextField
|
||||
type="number"
|
||||
value={newCap}
|
||||
onChange={e => setNewCap(+e.target.value)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Button onClick={updateDatacap} color="primary">
|
||||
Set New Datacap
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container direction="row" alignItems="center">
|
||||
<Grid>
|
||||
<Button onClick={getDatacap} color="primary">
|
||||
DataCap
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Box margin={3}>{datacap && datacap / 1000 / 1000}Mb</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container direction="row" alignItems="center">
|
||||
<Grid>
|
||||
<Button onClick={checkLimit} color="primary">
|
||||
OverLimit
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Box margin={3}>
|
||||
{isOver === undefined ? "Click to Check" : isOver ? "Over Limit" : "Under Limit"}
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container direction="row" alignItems="center">
|
||||
<Grid>
|
||||
<Button onClick={checkIfPaused} color="primary">
|
||||
Am I Paused
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Box margin={3}>
|
||||
{pauseCheck === undefined ? "Click to Check" : pauseCheck ? "Paused" : "Running"}
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Button onClick={pauseDevice} color="primary">
|
||||
Pause Me
|
||||
</Button>
|
||||
<Button onClick={resumeDevice} color="primary">
|
||||
Get Me Goin
|
||||
</Button>
|
||||
</TabPanelMine>
|
||||
<TabPanelMine value={tabNumber} index={2}>
|
||||
<LogsDisplay deviceID={deviceID} />
|
||||
</TabPanelMine>
|
||||
<TabPanelMine value={tabNumber} index={3}>
|
||||
History Not imported yet
|
||||
{/* <CompleteHistory device={device} /> */}
|
||||
</TabPanelMine>
|
||||
</PageContainer>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue