tags owned by device are loaded with device page data, adding tag is object agnostic
This commit is contained in:
parent
4e7c68401b
commit
0076f2d208
8 changed files with 93 additions and 34 deletions
3
package-lock.json
generated
3
package-lock.json
generated
|
|
@ -4247,8 +4247,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/protobuf-ts": {
|
"node_modules/protobuf-ts": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#e3d1689e1bf3842b0601cf166be9aff78ef093ff",
|
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#91931b1936a92bb0bc24700664adf72eb8a912dd",
|
||||||
"integrity": "sha512-hlkiHxih/Z+kBGMoyWI2Y/vn6afNqRElGuZ/LLGPaLZe2BLXRLKAQOHzR3a7SLfz6p2TkZISNdpmeveK7xgKSg==",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"protobufjs": "^6.8.8"
|
"protobufjs": "^6.8.8"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { User } from '../models/user'
|
||||||
import { Team } from '../models/team'
|
import { Team } from '../models/team'
|
||||||
import { makeStyles } from '@mui/styles'
|
import { makeStyles } from '@mui/styles'
|
||||||
import { Theme } from '@mui/material'
|
import { Theme } from '@mui/material'
|
||||||
import FirmwareLoader from './FirmwareLoader'
|
// import FirmwareLoader from './FirmwareLoader'
|
||||||
|
|
||||||
const reducer = (state: GlobalState, action: GlobalStateAction): GlobalState => {
|
const reducer = (state: GlobalState, action: GlobalStateAction): GlobalState => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -99,11 +99,11 @@ export default function UserWrapper(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StateProvider state={global} reducer={reducer}>
|
<StateProvider state={global} reducer={reducer}>
|
||||||
<FirmwareLoader>
|
{/* <FirmwareLoader> */}
|
||||||
<main className={classes.appContent}>
|
<main className={classes.appContent}>
|
||||||
<NavigationContainer toggleTheme={toggleTheme} />
|
<NavigationContainer toggleTheme={toggleTheme} />
|
||||||
</main>
|
</main>
|
||||||
</FirmwareLoader>
|
{/* </FirmwareLoader> */}
|
||||||
</StateProvider>
|
</StateProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -27,8 +27,8 @@ import {
|
||||||
Wifi as WifiIcon
|
Wifi as WifiIcon
|
||||||
} 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";
|
||||||
import { ImgIcon } from "common/ImgIcon";
|
// import { ImgIcon } from "common/ImgIcon";
|
||||||
import NotificationButton from "common/NotificationButton";
|
import NotificationButton from "common/NotificationButton";
|
||||||
// import ComponentOrder from "component/ComponentOrder";
|
// import ComponentOrder from "component/ComponentOrder";
|
||||||
// import ComponentSettings from "component/ComponentSettings";
|
// import ComponentSettings from "component/ComponentSettings";
|
||||||
|
|
@ -44,7 +44,7 @@ import { cloneDeep } from "lodash";
|
||||||
// import { Component, Device, deviceScope, Interaction } from "models";
|
// import { Component, Device, deviceScope, Interaction } from "models";
|
||||||
import { Device, deviceScope } from "models";
|
import { Device, deviceScope } from "models";
|
||||||
// import { MatchParams } from "navigation/Routes";
|
// import { MatchParams } from "navigation/Routes";
|
||||||
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, { useState } from "react";
|
||||||
|
|
@ -64,7 +64,7 @@ import { useNavigate } from "react-router-dom";
|
||||||
import DeviceSettings from "device/DeviceSettings";
|
import DeviceSettings from "device/DeviceSettings";
|
||||||
import ObjectTeams from "teams/ObjectTeams";
|
import ObjectTeams from "teams/ObjectTeams";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => {
|
const useStyles = makeStyles((_theme: Theme) => {
|
||||||
// const isMobile = useMobile()
|
// const isMobile = useMobile()
|
||||||
return ({
|
return ({
|
||||||
greenIcon: {
|
greenIcon: {
|
||||||
|
|
@ -373,7 +373,6 @@ export default function DeviceActions(props: Props) {
|
||||||
isJsonDataDialogOpen
|
isJsonDataDialogOpen
|
||||||
} = dialogState;
|
} = dialogState;
|
||||||
|
|
||||||
console.log(canWrite)
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<DeviceSettings
|
<DeviceSettings
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,12 @@ interface Props {
|
||||||
usage?: Usage;
|
usage?: Usage;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
disableAddTag?: boolean;
|
disableAddTag?: boolean;
|
||||||
|
tags: pond.Tag[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DeviceOverview(props: Props) {
|
export default function DeviceOverview(props: Props) {
|
||||||
const [{ user, firmware }] = useGlobalState();
|
const [{ user, firmware }] = useGlobalState();
|
||||||
const { device, components, usage, loading, disableAddTag } = props;
|
const { device, components, usage, loading, disableAddTag, tags } = props;
|
||||||
const prevComponents = usePrevious(components);
|
const prevComponents = usePrevious(components);
|
||||||
const { info } = useSnackbar();
|
const { info } = useSnackbar();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
@ -224,7 +225,7 @@ export default function DeviceOverview(props: Props) {
|
||||||
<StatusChip status="pending" />
|
<StatusChip status="pending" />
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
{user.allowedTo("provision") && <DeviceTags device={device} disableAdd={disableAddTag} />}
|
{user.allowedTo("provision") && <DeviceTags tags={tags} device={device} disableAdd={disableAddTag} />}
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import { filterByTag } from "pbHelpers/Tag";
|
||||||
import { useDeviceAPI, useSnackbar, useTagAPI } from "providers";
|
import { useDeviceAPI, useSnackbar, useTagAPI } from "providers";
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||||
|
|
||||||
const useStyles = makeStyles((_theme: Theme) => {
|
const useStyles = makeStyles((_theme: Theme) => {
|
||||||
return ({
|
return ({
|
||||||
|
|
@ -128,6 +129,7 @@ function DeviceTag(props: DeviceTagProps) {
|
||||||
interface DeviceTagsProps {
|
interface DeviceTagsProps {
|
||||||
device: Device;
|
device: Device;
|
||||||
disableAdd?: boolean;
|
disableAdd?: boolean;
|
||||||
|
tags: pond.Tag[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DeviceTags(props: DeviceTagsProps) {
|
export default function DeviceTags(props: DeviceTagsProps) {
|
||||||
|
|
@ -155,19 +157,45 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(tags)
|
console.log(props.tags)
|
||||||
}, [tags])
|
let newTags: string[] = []
|
||||||
|
props.tags.forEach(tag => {
|
||||||
|
if (tag.settings) newTags.push(tag.settings?.key)
|
||||||
|
})
|
||||||
|
setDeviceTags(newTags)
|
||||||
|
}, [props.tags])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadTags()
|
loadTags()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
if (previousDeviceRef.current !== device) {
|
// // if (previousDeviceRef.current !== device) {
|
||||||
setDeviceTags(device.status.tagKeys);
|
// let keys = getContextKeys()
|
||||||
previousDeviceRef.current = device;
|
// keys.push(device.id().toString())
|
||||||
}
|
// let types = getContextTypes()
|
||||||
}, [device]);
|
// types.push("device")
|
||||||
|
// setDeviceTags(device.status.tagKeys);
|
||||||
|
// previousDeviceRef.current = device;
|
||||||
|
// tagAPI.listTags(
|
||||||
|
// undefined,
|
||||||
|
// undefined,
|
||||||
|
// undefined,
|
||||||
|
// undefined,
|
||||||
|
// undefined,
|
||||||
|
// undefined,
|
||||||
|
// keys,
|
||||||
|
// types,
|
||||||
|
// ).then(resp => {
|
||||||
|
// // console.log(resp.data)
|
||||||
|
// let newTagKeys: string[] = []
|
||||||
|
// resp.data.tags.forEach((tag: any) => {
|
||||||
|
// newTagKeys.push(tag.settings.key)
|
||||||
|
// })
|
||||||
|
// setDeviceTags(newTagKeys)
|
||||||
|
// })
|
||||||
|
// // }
|
||||||
|
// }, [device]);
|
||||||
|
|
||||||
const addTag = (tag: Tag) => {
|
const addTag = (tag: Tag) => {
|
||||||
if (!deviceTags.some(dt => dt === tag.key())) {
|
if (!deviceTags.some(dt => dt === tag.key())) {
|
||||||
|
|
@ -195,12 +223,6 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<CircularProgress />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{deviceTags.map(key => {
|
{deviceTags.map(key => {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ export default function DevicePage() {
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [permissions, setPermissions] = useState<pond.Permission[]>([])
|
const [permissions, setPermissions] = useState<pond.Permission[]>([])
|
||||||
const [preferences, setPreferences] = useState<pond.DevicePreferences>(pond.DevicePreferences.create())
|
const [preferences, setPreferences] = useState<pond.DevicePreferences>(pond.DevicePreferences.create())
|
||||||
|
const [tags, setTags] = useState<pond.Tag[]>([]);
|
||||||
|
|
||||||
const [cellularUsage, _setCellularUsage] = useState<number>(0);
|
const [cellularUsage, _setCellularUsage] = useState<number>(0);
|
||||||
const [cellularStatus, _setCellularStatus] = useState<string>("");
|
const [cellularStatus, _setCellularStatus] = useState<string>("");
|
||||||
|
|
@ -55,6 +56,7 @@ export default function DevicePage() {
|
||||||
setPermissions(newPermissions)
|
setPermissions(newPermissions)
|
||||||
let u = User.any(resp.data.user);
|
let u = User.any(resp.data.user);
|
||||||
setPreferences(u.preferences)
|
setPreferences(u.preferences)
|
||||||
|
setTags(resp.data.tags)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
setDevice(Device.create());
|
setDevice(Device.create());
|
||||||
// setComponents(new Map());
|
// setComponents(new Map());
|
||||||
|
|
@ -79,10 +81,6 @@ export default function DevicePage() {
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(permissions)
|
|
||||||
}, [permissions])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadDevice()
|
loadDevice()
|
||||||
}, [deviceID])
|
}, [deviceID])
|
||||||
|
|
@ -138,6 +136,7 @@ export default function DevicePage() {
|
||||||
components={[]}
|
components={[]}
|
||||||
usage={getUsage()}
|
usage={getUsage()}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
|
tags={tags}
|
||||||
/>
|
/>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,6 @@ export default function Devices() {
|
||||||
|
|
||||||
const loadDevices = () => {
|
const loadDevices = () => {
|
||||||
setDevicesLoading(true)
|
setDevicesLoading(true)
|
||||||
console.log(getKeys())
|
|
||||||
deviceAPI.list(
|
deviceAPI.list(
|
||||||
limit,
|
limit,
|
||||||
page*limit,
|
page*limit,
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,23 @@ import { useHTTP } from "hooks";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
import { createContext, PropsWithChildren, useContext } from "react";
|
import { createContext, PropsWithChildren, useContext } from "react";
|
||||||
import { pondURL } from "./pond";
|
import { pondURL } from "./pond";
|
||||||
|
import { useGlobalState } from "providers/StateContainer";
|
||||||
|
|
||||||
export interface ITagAPIContext {
|
export interface ITagAPIContext {
|
||||||
addTag: (tag: pond.TagSettings) => Promise<any>;
|
addTag: (tag: pond.TagSettings) => Promise<any>;
|
||||||
updateTag: (tagID: string, tag: pond.TagSettings) => Promise<any>;
|
updateTag: (tagID: string, tag: pond.TagSettings) => Promise<any>;
|
||||||
removeTag: (tagID: string) => Promise<any>;
|
removeTag: (tagID: string) => Promise<any>;
|
||||||
getTag: (tagID: string) => Promise<any>;
|
getTag: (tagID: string) => Promise<any>;
|
||||||
listTags: () => Promise<any>;
|
listTags: (
|
||||||
|
limit?: number,
|
||||||
|
offset?: number,
|
||||||
|
order?: "asc" | "desc",
|
||||||
|
orderBy?: string,
|
||||||
|
search?: string,
|
||||||
|
asRoot?: boolean,
|
||||||
|
keys?: string[],
|
||||||
|
types?: string[]
|
||||||
|
) => Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TagAPIContext = createContext<ITagAPIContext>({} as ITagAPIContext);
|
export const TagAPIContext = createContext<ITagAPIContext>({} as ITagAPIContext);
|
||||||
|
|
@ -18,6 +28,7 @@ interface Props {}
|
||||||
export default function TagProvider(props: PropsWithChildren<Props>) {
|
export default function TagProvider(props: PropsWithChildren<Props>) {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const { get, del, put, post } = useHTTP();
|
const { get, del, put, post } = useHTTP();
|
||||||
|
const [{ as }] = useGlobalState()
|
||||||
|
|
||||||
const addTag = (tag: pond.TagSettings) => {
|
const addTag = (tag: pond.TagSettings) => {
|
||||||
return post(pondURL("/tags"), tag);
|
return post(pondURL("/tags"), tag);
|
||||||
|
|
@ -35,8 +46,37 @@ export default function TagProvider(props: PropsWithChildren<Props>) {
|
||||||
return get(pondURL("/tags/" + tagID));
|
return get(pondURL("/tags/" + tagID));
|
||||||
};
|
};
|
||||||
|
|
||||||
const listTags = () => {
|
// const listTags = () => {
|
||||||
return get(pondURL("/tags"));
|
|
||||||
|
// return get(pondURL("/tags"));
|
||||||
|
// };
|
||||||
|
|
||||||
|
const listTags = (
|
||||||
|
limit?: number,
|
||||||
|
offset?: number,
|
||||||
|
order?: "asc" | "desc",
|
||||||
|
orderBy?: string,
|
||||||
|
search?: string,
|
||||||
|
asRoot?: boolean,
|
||||||
|
keys?: string[],
|
||||||
|
types?: string[]
|
||||||
|
) => {
|
||||||
|
limit = limit ? limit : 100
|
||||||
|
const url = pondURL(
|
||||||
|
"/tags" +
|
||||||
|
"?limit=" +
|
||||||
|
limit +
|
||||||
|
"&offset=" +
|
||||||
|
offset +
|
||||||
|
("&order=" + (order ? order : "asc")) +
|
||||||
|
("&by=" + (orderBy ? orderBy : "deviceId")) +
|
||||||
|
(search ? "&search=" + search : "") +
|
||||||
|
(asRoot ? "&asRoot=" + asRoot.toString() : "") +
|
||||||
|
(as && !(types && types.length > 0 && types[0] === "team") ? "&as=" + as : "") +
|
||||||
|
(keys ? "&keys=" + keys.toString() : "") +
|
||||||
|
(types ? "&types=" + types.toString() : "")
|
||||||
|
);
|
||||||
|
return get<pond.ListDevicesResponse>(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue