Merge branch 'staging_environment' into gate_page_fixes
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/x-icon" id="favicon-link" />
|
<link rel="icon" type="image/x-icon" id="favicon-link" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Adaptive Dashboard</title>
|
<title id="title-id">Adaptive Dashboard</title>
|
||||||
<link rel="manifest" id="manifest-link" />
|
<link rel="manifest" id="manifest-link" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"start": "VITE_AUTH0_CLIENT_ID=5pUCkl2SfogkWmM244UDcLEUOp8EFdHd VITE_AUTH0_AUDIENCE=api.brandxtech.ca VITE_APP_API_URL=https://api.brandxtech.ca/v1 VITE_APP_WS_URL=ws://api.brandxtech.ca/v1/live vite",
|
"start": "VITE_AUTH0_CLIENT_ID=5pUCkl2SfogkWmM244UDcLEUOp8EFdHd VITE_AUTH0_AUDIENCE=api.brandxtech.ca VITE_APP_API_URL=https://api.brandxtech.ca/v1 VITE_APP_WS_URL=ws://api.brandxtech.ca/v1/live vite",
|
||||||
"start-local": "VITE_AUTH0_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_AUTH0_AUDIENCE=bxt-dev.api.adaptiveagriculture.ca VITE_APP_API_URL=http://localhost:50052/v1 VITE_APP_WS_URL=ws://localhost:50052/v1/live VITE_APP_BILLING_URL=http://localhost:50053/v1 VITE_APP_RECLUSE_URL=http://localhost:50054/v1 VITE_APP_GITLAB_URL=http://localhost:50055/v1 vite",
|
"start-local": "VITE_AUTH0_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_AUTH0_AUDIENCE=bxt-dev.api.adaptiveagriculture.ca VITE_APP_API_URL=http://localhost:50052/v1 VITE_APP_WS_URL=ws://localhost:50052/v1/live VITE_APP_BILLING_URL=http://localhost:50053/v1 VITE_APP_RECLUSE_URL=http://localhost:50054/v1 VITE_APP_GITLAB_URL=http://localhost:50055/v1 vite",
|
||||||
"start-dev": "VITE_AUTH0_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_APP_API_URL=https://bxt-dev.api.adaptiveagriculture.ca/v1 VITE_AUTH0_CLIENT_DOMAIN=brandxtech.auth0.com VITE_AUTH0_AUDIENCE=bxt-dev.api.adaptiveagriculture.ca VITE_AUTH0_DEV_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 vite",
|
"start-dev": "VITE_AUTH0_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 VITE_APP_API_URL=https://bxt-dev.api.adaptiveagriculture.ca/v1 VITE_AUTH0_CLIENT_DOMAIN=brandxtech.auth0.com VITE_AUTH0_AUDIENCE=bxt-dev.api.adaptiveagriculture.ca VITE_AUTH0_DEV_CLIENT_ID=dzJTpqIeMA4Rwk4xujtwPbAO3TY32bM1 vite",
|
||||||
"start-staging": "VITE_AUTH0_CLIENT_ID=3ib460VvLwdeyse5iUSQfxkVdQaUmphP VITE_AUTH0_AUDIENCE=stagingapi.brandxtech.ca VITE_AUTH0_CLIENT_DOMAIN=adaptivestaging.us.auth0.com VITE_APP_API_URL=https://stagingapi.brandxtech.ca/v1 VITE_APP_WS_URL=ws://stagingapi.brandxtech.ca/v1/live VITE_APP_AUTH0_CLIENT_DOMAIN=adaptivestaging.us.auth0.com VITE_APP_AUTH0_AUDIENCE=stagingapi.brandxtech.ca vite",
|
"start-staging": "VITE_LOCAL_STAGING=true VITE_AUTH0_CLIENT_ID=3ib460VvLwdeyse5iUSQfxkVdQaUmphP VITE_AUTH0_AUDIENCE=stagingapi.brandxtech.ca VITE_AUTH0_CLIENT_DOMAIN=adaptivestaging.us.auth0.com VITE_APP_API_URL=https://stagingapi.brandxtech.ca/v1 VITE_APP_WS_URL=ws://stagingapi.brandxtech.ca/v1/live VITE_APP_AUTH0_CLIENT_DOMAIN=adaptivestaging.us.auth0.com VITE_APP_AUTH0_AUDIENCE=stagingapi.brandxtech.ca vite",
|
||||||
"build": "tsc -b && vite build",
|
"build": "tsc -b && vite build",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
|
|
|
||||||
BIN
public/Staging/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
public/Staging/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/Staging/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
9
public/Staging/browserconfig.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/mstile-150x150.png"/>
|
||||||
|
<TileColor>#ffffff</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
||||||
BIN
public/Staging/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/Staging/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
public/Staging/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
26
public/Staging/manifest.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "Brand X Technologies",
|
||||||
|
"short_name": "BXT",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "favicon.ico",
|
||||||
|
"sizes": "48x48",
|
||||||
|
"type": "image/x-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "/",
|
||||||
|
"theme_color": "#272727",
|
||||||
|
"background_color": "#424242",
|
||||||
|
"display": "standalone",
|
||||||
|
"orientation": "any"
|
||||||
|
}
|
||||||
BIN
public/Staging/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
2198
public/Staging/safari-pinned-tab.svg
Normal file
|
After Width: | Height: | Size: 144 KiB |
|
|
@ -37,6 +37,11 @@ function App() {
|
||||||
faviconDocument.href = "BrandXTechnologies/favicon.ico"
|
faviconDocument.href = "BrandXTechnologies/favicon.ico"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Set title
|
||||||
|
const titleElement = document.getElementById("title-id") as HTMLElement;
|
||||||
|
if (titleElement) titleElement.textContent = whiteLabel.name;
|
||||||
|
|
||||||
|
|
||||||
let domain: string | undefined = import.meta.env.VITE_AUTH0_CLIENT_DOMAIN;
|
let domain: string | undefined = import.meta.env.VITE_AUTH0_CLIENT_DOMAIN;
|
||||||
let audience: string | undefined = import.meta.env.VITE_AUTH0_AUDIENCE;
|
let audience: string | undefined = import.meta.env.VITE_AUTH0_AUDIENCE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,14 +72,14 @@ const useStyles = makeStyles((theme: Theme) => {
|
||||||
marginLeft: theme.spacing(0.05),
|
marginLeft: theme.spacing(0.05),
|
||||||
marginRight: theme.spacing(0.05),
|
marginRight: theme.spacing(0.05),
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
backgroundColor: getSecondaryColour(), //use the colour of the whitelabel
|
//backgroundColor: getSecondaryColour(), //use the colour of the whitelabel
|
||||||
//backgroundColor: "gold",
|
backgroundColor: "gold", //for now Dustin just wants it to be gold
|
||||||
color: "black",
|
color: "black",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
buttonToggled: {
|
buttonToggled: {
|
||||||
backgroundColor: getSecondaryColour(), //use the colour of the whitelabel
|
//backgroundColor: getSecondaryColour(), //use the colour of the whitelabel
|
||||||
//backgroundColor: "gold",
|
backgroundColor: "gold", //for now Dustin just wants it to be gold
|
||||||
color: "black",
|
color: "black",
|
||||||
borderRadius: 24,
|
borderRadius: 24,
|
||||||
fontWeight: "bold"
|
fontWeight: "bold"
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,12 @@ import {
|
||||||
LinkProps,
|
LinkProps,
|
||||||
Skeleton,
|
Skeleton,
|
||||||
Theme,
|
Theme,
|
||||||
|
Typography,
|
||||||
useTheme
|
useTheme
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Replay } from "@mui/icons-material";
|
import { Replay } from "@mui/icons-material";
|
||||||
import { useMobile } from "hooks";
|
import { useMobile } from "hooks";
|
||||||
import { ReactNode, useEffect, useRef } from "react";
|
import { ReactNode } from "react";
|
||||||
import { useLocation } from "react-router";
|
import { useLocation } from "react-router";
|
||||||
import { Link as RouterLink } from "react-router-dom";
|
import { Link as RouterLink } from "react-router-dom";
|
||||||
import { or } from "utils/types";
|
import { or } from "utils/types";
|
||||||
|
|
@ -57,11 +58,13 @@ interface Props {
|
||||||
paddingTop?: number;
|
paddingTop?: number;
|
||||||
paddingBottom?: number;
|
paddingBottom?: number;
|
||||||
prependPaths?: string[];
|
prependPaths?: string[];
|
||||||
|
state?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LinkRouterProps extends LinkProps {
|
interface LinkRouterProps extends LinkProps {
|
||||||
to: string;
|
to: string;
|
||||||
replace?: boolean;
|
replace?: boolean;
|
||||||
|
state?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LinkRouter = (props: LinkRouterProps) => <Link {...props} component={RouterLink as any} />;
|
const LinkRouter = (props: LinkRouterProps) => <Link {...props} component={RouterLink as any} />;
|
||||||
|
|
@ -72,7 +75,7 @@ export default function SmartBreadcrumb(props: Props) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isMobile = useMobile();
|
const isMobile = useMobile();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { loading, reload } = props;
|
const { loading, reload, state } = props;
|
||||||
|
|
||||||
const groupID = (): string => {
|
const groupID = (): string => {
|
||||||
let index = prependPaths?.indexOf("groups")
|
let index = prependPaths?.indexOf("groups")
|
||||||
|
|
@ -289,7 +292,7 @@ export default function SmartBreadcrumb(props: Props) {
|
||||||
|
|
||||||
if (prependPaths) pathnames.splice(pathnames.length - 1, 0, ...prependPaths);
|
if (prependPaths) pathnames.splice(pathnames.length - 1, 0, ...prependPaths);
|
||||||
|
|
||||||
pathnames.forEach((_value: any, index: any) => {
|
pathnames.forEach((value: any, index: any) => {
|
||||||
|
|
||||||
const lastPath = index === pathnames.length - 1;
|
const lastPath = index === pathnames.length - 1;
|
||||||
const to = `/${pathnames.slice(0, index + 1).join("/")}`;
|
const to = `/${pathnames.slice(0, index + 1).join("/")}`;
|
||||||
|
|
@ -310,6 +313,21 @@ export default function SmartBreadcrumb(props: Props) {
|
||||||
links.push(linkComponent(to, label, lastPath));
|
links.push(linkComponent(to, label, lastPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value === "support") {
|
||||||
|
links.push(
|
||||||
|
<Chip
|
||||||
|
key={"support-chip"}
|
||||||
|
variant={"filled"}
|
||||||
|
label={
|
||||||
|
<Typography variant="subtitle1" color="textPrimary">
|
||||||
|
Support
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
className={classes.chip}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return links;
|
return links;
|
||||||
};
|
};
|
||||||
|
|
@ -324,6 +342,7 @@ export default function SmartBreadcrumb(props: Props) {
|
||||||
color={lastPath ? "textPrimary" : "textSecondary"}
|
color={lastPath ? "textPrimary" : "textSecondary"}
|
||||||
variant="subtitle1"
|
variant="subtitle1"
|
||||||
to={to}
|
to={to}
|
||||||
|
state={state}
|
||||||
sx={{ '&:hover': { color: getThemeType() === "dark" ? 'white' : "black" }}}
|
sx={{ '&:hover': { color: getThemeType() === "dark" ? 'white' : "black" }}}
|
||||||
className={classes.textOverflow}>
|
className={classes.textOverflow}>
|
||||||
{label}
|
{label}
|
||||||
|
|
|
||||||
|
|
@ -176,12 +176,12 @@ export default function StatusPlenum(props: Props) {
|
||||||
>
|
>
|
||||||
<Grid2>
|
<Grid2>
|
||||||
<Typography variant="body2" style={{ color: blue[300]}}>
|
<Typography variant="body2" style={{ color: blue[300]}}>
|
||||||
{device.status.sen5x?.voc.toFixed(1)}%
|
V: {device.status.sen5x?.voc.toFixed(1)}%
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
<Grid2>
|
<Grid2>
|
||||||
<Typography variant="body2" style={{ color: blue[400]}}>
|
<Typography variant="body2" style={{ color: blue[400]}}>
|
||||||
{device.status.sen5x?.nox.toFixed(1)}%
|
N: {device.status.sen5x?.nox.toFixed(1)}%
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ import {
|
||||||
AccountCircle as ObjectUsersIcon,
|
AccountCircle as ObjectUsersIcon,
|
||||||
SupervisedUserCircle as ObjectTeamsIcon,
|
SupervisedUserCircle as ObjectTeamsIcon,
|
||||||
Sync as SyncDeviceIcon,
|
Sync as SyncDeviceIcon,
|
||||||
Wifi as WifiIcon
|
Wifi as WifiIcon,
|
||||||
|
Visibility
|
||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
import { Skeleton } from "@mui/material";
|
import { Skeleton } from "@mui/material";
|
||||||
// import Datadog from "assets/external/datadog.png";
|
// import Datadog from "assets/external/datadog.png";
|
||||||
|
|
@ -47,7 +48,7 @@ import { Component, Device, deviceScope, Interaction } from "models";
|
||||||
// import { isShareableLink } from "pbHelpers/Device";
|
// import { isShareableLink } from "pbHelpers/Device";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
import { useGlobalState } from "providers";
|
import { useGlobalState } from "providers";
|
||||||
import React, { useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
// import { useHistory, useRouteMatch } from "react-router";
|
// import { useHistory, useRouteMatch } from "react-router";
|
||||||
import { isOffline } from "utils/environment";
|
import { isOffline } from "utils/environment";
|
||||||
import { or } from "utils/types";
|
import { or } from "utils/types";
|
||||||
|
|
@ -71,6 +72,7 @@ import Connection from "./Connection";
|
||||||
import ComponentOrder from "component/ComponentOrder";
|
import ComponentOrder from "component/ComponentOrder";
|
||||||
import ArcGISDeviceData from "./ArcGISDeviceData";
|
import ArcGISDeviceData from "./ArcGISDeviceData";
|
||||||
import UpgradeDevice from "./UpgradeDevice";
|
import UpgradeDevice from "./UpgradeDevice";
|
||||||
|
import { DevicePageData } from "pages/Device";
|
||||||
|
|
||||||
const useStyles = makeStyles((_theme: Theme) => {
|
const useStyles = makeStyles((_theme: Theme) => {
|
||||||
// const isMobile = useMobile()
|
// const isMobile = useMobile()
|
||||||
|
|
@ -169,6 +171,19 @@ export default function DeviceActions(props: Props) {
|
||||||
isJsonDataDialogOpen: false
|
isJsonDataDialogOpen: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [devicePageData, setDevicePageData] = useState<DevicePageData | undefined>(undefined);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let newPageData: DevicePageData = {
|
||||||
|
device: device,
|
||||||
|
components: components,
|
||||||
|
interactions: interactions,
|
||||||
|
preferences: preferences,
|
||||||
|
permissions: permissions,
|
||||||
|
}
|
||||||
|
setDevicePageData(newPageData)
|
||||||
|
}, [device, components, interactions, preferences, permissions])
|
||||||
|
|
||||||
const openDialog = (target: keyof DialogState) => {
|
const openDialog = (target: keyof DialogState) => {
|
||||||
let updatedDialogState = cloneDeep(dialogState);
|
let updatedDialogState = cloneDeep(dialogState);
|
||||||
updatedDialogState[target] = true;
|
updatedDialogState[target] = true;
|
||||||
|
|
@ -495,9 +510,18 @@ export default function DeviceActions(props: Props) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showSupport = () => {
|
||||||
|
return user.allowedTo("provision") && !location.pathname.includes("support")
|
||||||
|
}
|
||||||
|
|
||||||
const buttons = () => {
|
const buttons = () => {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
{showSupport() && <Tooltip title="Support">
|
||||||
|
<IconButton onClick={() => navigate("support", { state: {device: device, devicePageData: devicePageData }})}>
|
||||||
|
<Visibility />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>}
|
||||||
{canWrite && user.allowedTo("provision") && <UpgradeDevice device={device} />}
|
{canWrite && user.allowedTo("provision") && <UpgradeDevice device={device} />}
|
||||||
{/* {!isShareableLink(match.params.deviceID) && ( */}
|
{/* {!isShareableLink(match.params.deviceID) && ( */}
|
||||||
<NotificationButton
|
<NotificationButton
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { ErrorBoundary } from "react-error-boundary";
|
||||||
import { getWhitelabel } from "services/whiteLabel";
|
import { getWhitelabel } from "services/whiteLabel";
|
||||||
import Ventilation from "pages/VentEditor";
|
import Ventilation from "pages/VentEditor";
|
||||||
import { useGlobalState } from "providers";
|
import { useGlobalState } from "providers";
|
||||||
|
import DeviceSupport from "pages/DeviceSupport";
|
||||||
|
|
||||||
const DeviceHistory = lazy(() => import("pages/DeviceHistory"));
|
const DeviceHistory = lazy(() => import("pages/DeviceHistory"));
|
||||||
const DevicePage = lazy(() => import("pages/Device"));
|
const DevicePage = lazy(() => import("pages/Device"));
|
||||||
|
|
@ -103,6 +104,10 @@ export default function Router() {
|
||||||
path="/:deviceID" // "/settings/basic"
|
path="/:deviceID" // "/settings/basic"
|
||||||
element={<DevicePage />}
|
element={<DevicePage />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/:deviceID/support" // "/settings/basic"
|
||||||
|
element={<DeviceSupport />}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/:deviceID/components/:componentID" // "/settings/basic"
|
path="/:deviceID/components/:componentID" // "/settings/basic"
|
||||||
element={<DeviceComponent />}
|
element={<DeviceComponent />}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,15 @@ import { or } from "utils";
|
||||||
import ComponentDiagnostics from "component/ComponentDiagnostics";
|
import ComponentDiagnostics from "component/ComponentDiagnostics";
|
||||||
import DeviceWizard from "device/DeviceWizard";
|
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() {
|
export default function DevicePage() {
|
||||||
const deviceAPI = useDeviceAPI()
|
const deviceAPI = useDeviceAPI()
|
||||||
const snackbar = useSnackbar()
|
const snackbar = useSnackbar()
|
||||||
|
|
@ -30,6 +39,7 @@ export default function DevicePage() {
|
||||||
const groupID = useParams<{ groupID: string }>()?.groupID ?? "";
|
const groupID = useParams<{ groupID: string }>()?.groupID ?? "";
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
const [{ as, team, user }] = useGlobalState()
|
const [{ as, team, user }] = useGlobalState()
|
||||||
|
// console.log(state)
|
||||||
const [device, setDevice] = useState<Device>(state?.device ? Device.create(state.device) : Device.create())
|
const [device, setDevice] = useState<Device>(state?.device ? Device.create(state.device) : Device.create())
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [permissions, setPermissions] = useState<pond.Permission[]>([])
|
const [permissions, setPermissions] = useState<pond.Permission[]>([])
|
||||||
|
|
@ -51,11 +61,21 @@ export default function DevicePage() {
|
||||||
|
|
||||||
const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false)
|
const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false)
|
||||||
|
|
||||||
|
// const [devicePageData, setDevicePageData] = useState(pond.GetDevicePageDataResponse.create())
|
||||||
|
|
||||||
const loadDevice = () => {
|
const loadDevice = () => {
|
||||||
// console.log("load device page data")
|
|
||||||
if (loading) return
|
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)
|
setLoading(true)
|
||||||
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes(), as).then(resp => {
|
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes(), as).then(resp => {
|
||||||
|
// setDevicePageData(resp.data)
|
||||||
let device = Device.any(resp.data.device)
|
let device = Device.any(resp.data.device)
|
||||||
// console.log(resp.data.device)
|
// console.log(resp.data.device)
|
||||||
setDevice(device)
|
setDevice(device)
|
||||||
|
|
@ -418,19 +438,9 @@ export default function DevicePage() {
|
||||||
<PageContainer padding={isMobile ? 0 : 2}>
|
<PageContainer padding={isMobile ? 0 : 2}>
|
||||||
<Grid container justifyContent={"space-between"}>
|
<Grid container justifyContent={"space-between"}>
|
||||||
<Grid>
|
<Grid>
|
||||||
<SmartBreadcrumb />
|
<SmartBreadcrumb deviceName={device.name()} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid>
|
<Grid>
|
||||||
<AddComponentManualDialog
|
|
||||||
device={device.id()}
|
|
||||||
open={addComponentManualDialogOpen}
|
|
||||||
onClose={() => setAddComponentManualDialogOpen(false)}
|
|
||||||
/>
|
|
||||||
{user.hasFeature("developer") === true &&
|
|
||||||
<Button onClick={() => setAddComponentManualDialogOpen(true)}>
|
|
||||||
Manual Comp
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
<DeviceActions
|
<DeviceActions
|
||||||
device={device}
|
device={device}
|
||||||
isPaused={false}
|
isPaused={false}
|
||||||
|
|
@ -449,8 +459,6 @@ export default function DevicePage() {
|
||||||
<DeviceOverview
|
<DeviceOverview
|
||||||
device={device}
|
device={device}
|
||||||
components={[...components.values()]}
|
components={[...components.values()]}
|
||||||
// components={[]}
|
|
||||||
// components={components}
|
|
||||||
usage={getUsage()}
|
usage={getUsage()}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
groupID={parseInt(groupID)}
|
groupID={parseInt(groupID)}
|
||||||
|
|
|
||||||
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -70,7 +70,7 @@ interface WhiteLabel {
|
||||||
// };
|
// };
|
||||||
|
|
||||||
const STAGING_WHITELABEL: WhiteLabel = {
|
const STAGING_WHITELABEL: WhiteLabel = {
|
||||||
name: import.meta.env.VITE_APP_WEBSITE_TITLE,
|
name: "Staging",
|
||||||
primaryColour: import.meta.env.VITE_APP_PRIMARY_COLOUR,
|
primaryColour: import.meta.env.VITE_APP_PRIMARY_COLOUR,
|
||||||
secondaryColour: import.meta.env.VITE_APP_SECONDARY_COLOUR,
|
secondaryColour: import.meta.env.VITE_APP_SECONDARY_COLOUR,
|
||||||
signatureColour: import.meta.env.VITE_APP_SIGNATURE_COLOUR,
|
signatureColour: import.meta.env.VITE_APP_SIGNATURE_COLOUR,
|
||||||
|
|
@ -276,7 +276,7 @@ export function getWhitelabel(): WhiteLabel {
|
||||||
if (window.location.origin.includes("bxt-dev")) {
|
if (window.location.origin.includes("bxt-dev")) {
|
||||||
return BXT_WHITE_LABEL;
|
return BXT_WHITE_LABEL;
|
||||||
}
|
}
|
||||||
if (window.location.origin.includes("staging")) {
|
if (window.location.origin.includes("staging") || import.meta.env.VITE_LOCAL_STAGING=='true') {
|
||||||
return STAGING_WHITELABEL;
|
return STAGING_WHITELABEL;
|
||||||
}
|
}
|
||||||
const whiteLabelKeys = Array.from(whitelabels.keys());
|
const whiteLabelKeys = Array.from(whitelabels.keys());
|
||||||
|
|
|
||||||