implemented new tag method
This commit is contained in:
parent
eb5fd127e3
commit
6439d217e9
6 changed files with 48 additions and 48 deletions
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -7256,7 +7256,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#86c8ea9c667b2d01c56e0af05f77c1326f8e08fa",
|
"resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#cf0774d8aab2663916bbb0b2c44f4bb3352487b5",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"protobufjs": "^6.8.8"
|
"protobufjs": "^6.8.8"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import { notNull, or } from "utils/types";
|
||||||
// import { MatchParams } from "navigation/Routes";
|
// import { MatchParams } from "navigation/Routes";
|
||||||
// import DeviceHologram from "./DeviceHologram";
|
// import DeviceHologram from "./DeviceHologram";
|
||||||
import { makeStyles } from "@mui/styles";
|
import { makeStyles } from "@mui/styles";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const useStyles = makeStyles((_theme: Theme) => {
|
const useStyles = makeStyles((_theme: Theme) => {
|
||||||
return ({
|
return ({
|
||||||
|
|
@ -39,13 +39,12 @@ interface Props {
|
||||||
usage?: Usage;
|
usage?: Usage;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
disableAddTag?: boolean;
|
disableAddTag?: boolean;
|
||||||
tags: pond.Tag[];
|
|
||||||
groupID?: number;
|
groupID?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DeviceOverview(props: Props) {
|
export default function DeviceOverview(props: Props) {
|
||||||
const [{ user, firmware }] = useGlobalState();
|
const [{ user, firmware }] = useGlobalState();
|
||||||
const { device, components, groupID, usage, loading, disableAddTag, tags } = props;
|
const { device, components, groupID, usage, loading, disableAddTag } = props;
|
||||||
const prevComponents = usePrevious(components);
|
const prevComponents = usePrevious(components);
|
||||||
const { info } = useSnackbar();
|
const { info } = useSnackbar();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
@ -156,8 +155,8 @@ export default function DeviceOverview(props: Props) {
|
||||||
variant={modemComponent ? "filled" : "outlined"}
|
variant={modemComponent ? "filled" : "outlined"}
|
||||||
clickable={modemComponent !== null}
|
clickable={modemComponent !== null}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
console.log(modemComponent)
|
// console.log(modemComponent)
|
||||||
console.log(modemComponent?.key())
|
// console.log(modemComponent?.key())
|
||||||
if (modemComponent && modemComponent.key()) {
|
if (modemComponent && modemComponent.key()) {
|
||||||
navigate(pathToDevice() + "/components/" + modemComponent.key());
|
navigate(pathToDevice() + "/components/" + modemComponent.key());
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +233,7 @@ export default function DeviceOverview(props: Props) {
|
||||||
<StatusChip status="pending" />
|
<StatusChip status="pending" />
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
{user.allowedTo("provision") && <DeviceTags tags={tags} device={device} disableAdd={disableAddTag} />}
|
{user.allowedTo("provision") && <DeviceTags device={device} disableAdd={disableAddTag} />}
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import {
|
||||||
Theme,
|
Theme,
|
||||||
Typography
|
Typography
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
// import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
|
||||||
import DeleteButton from "common/DeleteButton";
|
import DeleteButton from "common/DeleteButton";
|
||||||
import PeriodSelect from "common/time/PeriodSelect";
|
import PeriodSelect from "common/time/PeriodSelect";
|
||||||
import ResponsiveDialog from "common/ResponsiveDialog";
|
import ResponsiveDialog from "common/ResponsiveDialog";
|
||||||
|
|
@ -27,7 +26,6 @@ import { IsExtended, ListDeviceProductDescribers } from "products/DeviceProduct"
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
import { useGlobalState } from "providers";
|
import { useGlobalState } from "providers";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
// import { useHistory } from "react-router";
|
|
||||||
import { quack } from "protobuf-ts/quack";
|
import { quack } from "protobuf-ts/quack";
|
||||||
import LinearMutationBuilder from "common/LinearMutationBuilder";
|
import LinearMutationBuilder from "common/LinearMutationBuilder";
|
||||||
import { makeStyles } from "@mui/styles";
|
import { makeStyles } from "@mui/styles";
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import TagSettings from "common/TagSettings";
|
||||||
import { Device, Tag } from "models";
|
import { Device, Tag } from "models";
|
||||||
import { filterByTag } from "pbHelpers/Tag";
|
import { filterByTag } from "pbHelpers/Tag";
|
||||||
import { useDeviceAPI, useSnackbar, useTagAPI } from "providers";
|
import { useDeviceAPI, useSnackbar, useTagAPI } from "providers";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
|
||||||
const useStyles = makeStyles((_theme: Theme) => {
|
const useStyles = makeStyles((_theme: Theme) => {
|
||||||
|
|
@ -32,7 +32,7 @@ const useStyles = makeStyles((_theme: Theme) => {
|
||||||
|
|
||||||
interface AddDeviceTagProps {
|
interface AddDeviceTagProps {
|
||||||
device: Device;
|
device: Device;
|
||||||
deviceTags: string[];
|
deviceTags: pond.TagSettings[];
|
||||||
addTagToDevice: (tag: Tag) => void;
|
addTagToDevice: (tag: Tag) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ function AddDeviceTag(props: AddDeviceTagProps) {
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const tagItems = tags
|
const tagItems = tags
|
||||||
.filter(tag => !deviceTags.some(key => key === tag.settings.key))
|
.filter(tag => !deviceTags.some(tagSettings => tagSettings.key === tag.settings.key))
|
||||||
.filter(tag => filterByTag(searchValue, tag))
|
.filter(tag => filterByTag(searchValue, tag))
|
||||||
.sort((a, b) => (a.name().toLowerCase() > b.name().toLowerCase() ? 1 : -1))
|
.sort((a, b) => (a.name().toLowerCase() > b.name().toLowerCase() ? 1 : -1))
|
||||||
.map((tag, index, array) => (
|
.map((tag, index, array) => (
|
||||||
|
|
@ -102,7 +102,10 @@ function AddDeviceTag(props: AddDeviceTagProps) {
|
||||||
</List>
|
</List>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<TagSettings open={createNewOpen} mode="add" onClose={() => setCreateNewOpen(false)} />
|
<TagSettings open={createNewOpen} mode="add" onClose={() => {
|
||||||
|
setCreateNewOpen(false)
|
||||||
|
loadTags()
|
||||||
|
}} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +130,6 @@ 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) {
|
||||||
|
|
@ -138,8 +140,8 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
||||||
// const [loading, setLoading] = useState(false)
|
// const [loading, setLoading] = useState(false)
|
||||||
const deviceAPI = useDeviceAPI();
|
const deviceAPI = useDeviceAPI();
|
||||||
const { error } = useSnackbar();
|
const { error } = useSnackbar();
|
||||||
const [deviceTags, setDeviceTags] = useState<string[]>(device.status.tagKeys);
|
const [deviceTags, setDeviceTags] = useState<pond.TagSettings[]>(device.status.tags);
|
||||||
// const previousDeviceRef = useRef(device);
|
const previousDeviceRef = useRef(device);
|
||||||
|
|
||||||
const loadTags = () => {
|
const loadTags = () => {
|
||||||
// setLoading(true)
|
// setLoading(true)
|
||||||
|
|
@ -155,36 +157,35 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let newTags: string[] = []
|
if (previousDeviceRef.current !== device) {
|
||||||
props.tags.forEach(tag => {
|
setDeviceTags(device.status.tags);
|
||||||
if (tag.settings) newTags.push(tag.settings?.key)
|
previousDeviceRef.current = device;
|
||||||
})
|
}
|
||||||
setDeviceTags(newTags)
|
}, [device]);
|
||||||
}, [props.tags])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadTags()
|
loadTags()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const addTag = (tag: Tag) => {
|
const addTag = (tag: Tag) => {
|
||||||
if (!deviceTags.some(dt => dt === tag.key())) {
|
if (!deviceTags.some(dt => dt.key === tag.settings.key)) {
|
||||||
deviceAPI
|
deviceAPI
|
||||||
.tag(device.id(), tag.key())
|
.tag(device.id(), tag.settings.key)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setDeviceTags([...deviceTags, tag.key()]);
|
setDeviceTags([...deviceTags, tag.settings]);
|
||||||
})
|
})
|
||||||
.catch(() => error("Failed to tag device as " + tag.name()));
|
.catch(() => error("Failed to tag device as " + tag.name));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeTagFromDevice = (tag: Tag) => {
|
const removeTagFromDevice = (tag: Tag) => {
|
||||||
if (deviceTags.some(dt => dt === tag.key())) {
|
if (deviceTags.some(dt => dt.key === tag.settings.key)) {
|
||||||
deviceAPI
|
deviceAPI
|
||||||
.untag(device.id(), tag.key())
|
.untag(device.id(), tag.key())
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setDeviceTags(deviceTags.filter(t => tag.key() !== t));
|
setDeviceTags(deviceTags.filter(t => tag.key() !== t.key));
|
||||||
})
|
})
|
||||||
.catch(() => error("Failed to remove tag " + tag.name() + " from device"));
|
.catch(() => error("Failed to remove tag " + tag.name + " from device"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -194,14 +195,11 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{deviceTags.map(key => {
|
{deviceTags?.map(tagSettings => {
|
||||||
let tag = tags.find(t => t.settings.key === key);
|
let pondTag = pond.Tag.create({ settings: tagSettings })
|
||||||
if (!tag) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<Grid key={tag.settings.key}>
|
<Grid key={"device-tags-"+tagSettings.key}>
|
||||||
<DeviceTag tag={tag} removeTagFromDevice={removeTagFromDevice} />
|
<DeviceTag tag={Tag.create(pondTag)} removeTagFromDevice={removeTagFromDevice} />
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Button, Checkbox, Divider, FormControlLabel, List, ListItem, Typography } from "@mui/material";
|
import { Button, Divider, List, ListItem, Typography } from "@mui/material";
|
||||||
import Grid from '@mui/material/Grid2';
|
import Grid from '@mui/material/Grid2';
|
||||||
import { Component, Device, Interaction, User } from "models";
|
import { Component, Device, Interaction, User } from "models";
|
||||||
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||||
|
|
@ -33,7 +33,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 [tags, setTags] = useState<pond.Tag[]>([]);
|
||||||
const [interactions, setInteractions] = useState<Interaction[]>([]);
|
const [interactions, setInteractions] = useState<Interaction[]>([]);
|
||||||
const [prefsMap, setPrefsMap] = useState<Map<string, pond.DeviceComponentPreferences>>(new Map());
|
const [prefsMap, setPrefsMap] = useState<Map<string, pond.DeviceComponentPreferences>>(new Map());
|
||||||
|
|
||||||
|
|
@ -52,10 +52,10 @@ export default function DevicePage() {
|
||||||
|
|
||||||
const loadDevice = () => {
|
const loadDevice = () => {
|
||||||
if (loading) return
|
if (loading) return
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes()).then(resp => {
|
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes()).then(resp => {
|
||||||
let device = Device.any(resp.data.device)
|
let device = Device.any(resp.data.device)
|
||||||
|
// console.log(resp.data.device)
|
||||||
setDevice(device)
|
setDevice(device)
|
||||||
let newPermissions: pond.Permission[] = []
|
let newPermissions: pond.Permission[] = []
|
||||||
resp.data.permissions.forEach(perm => {
|
resp.data.permissions.forEach(perm => {
|
||||||
|
|
@ -69,7 +69,8 @@ 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)
|
// setTags(resp.data.tags)
|
||||||
|
resp.data.device?.status?.tagNames
|
||||||
let newComps: Component[] = []
|
let newComps: Component[] = []
|
||||||
resp.data.components.forEach(comp => {
|
resp.data.components.forEach(comp => {
|
||||||
newComps.push(Component.create(comp))
|
newComps.push(Component.create(comp))
|
||||||
|
|
@ -290,8 +291,8 @@ export default function DevicePage() {
|
||||||
<Divider component="li" />
|
<Divider component="li" />
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Grid width={"100%"} container justifyContent="flex-start" direction="row" spacing={2}>
|
<Grid width={"100%"} container justifyContent="flex-start" direction="row" spacing={2}>
|
||||||
{sensorComponents.map(card => (
|
{sensorComponents.map((card, index) => (
|
||||||
<Grid size={{
|
<Grid key={"sensor-components-"+index} size={{
|
||||||
xs: 12,
|
xs: 12,
|
||||||
sm: isMobile ? 12 : 6,
|
sm: isMobile ? 12 : 6,
|
||||||
md: isMobile ? 12 : 6,
|
md: isMobile ? 12 : 6,
|
||||||
|
|
@ -311,8 +312,8 @@ export default function DevicePage() {
|
||||||
<Divider component="li" />
|
<Divider component="li" />
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Grid width={"100%"} container justifyContent="flex-start" direction="row" spacing={2}>
|
<Grid width={"100%"} container justifyContent="flex-start" direction="row" spacing={2}>
|
||||||
{controllerComponents.map(card => (
|
{controllerComponents.map((card, index) => (
|
||||||
<Grid size={{
|
<Grid key={"sensor-components-"+index} size={{
|
||||||
xs: 12,
|
xs: 12,
|
||||||
sm: isMobile ? 12 : 6,
|
sm: isMobile ? 12 : 6,
|
||||||
md: isMobile ? 12 : 6,
|
md: isMobile ? 12 : 6,
|
||||||
|
|
@ -422,9 +423,11 @@ export default function DevicePage() {
|
||||||
open={addComponentManualDialogOpen}
|
open={addComponentManualDialogOpen}
|
||||||
onClose={() => setAddComponentManualDialogOpen(false)}
|
onClose={() => setAddComponentManualDialogOpen(false)}
|
||||||
/>
|
/>
|
||||||
<Button onClick={() => setAddComponentManualDialogOpen(true)}>
|
{user.hasFeature("developer") === true &&
|
||||||
Manual Comp
|
<Button onClick={() => setAddComponentManualDialogOpen(true)}>
|
||||||
</Button>
|
Manual Comp
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
<DeviceActions
|
<DeviceActions
|
||||||
device={device}
|
device={device}
|
||||||
isPaused={false}
|
isPaused={false}
|
||||||
|
|
@ -445,7 +448,6 @@ export default function DevicePage() {
|
||||||
// components={components}
|
// components={components}
|
||||||
usage={getUsage()}
|
usage={getUsage()}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
tags={tags}
|
|
||||||
groupID={parseInt(groupID)}
|
groupID={parseInt(groupID)}
|
||||||
/>
|
/>
|
||||||
{componentCards()}
|
{componentCards()}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { createContext, PropsWithChildren, useContext } from "react";
|
||||||
import { pondURL } from "./pond";
|
import { pondURL } from "./pond";
|
||||||
import { useGlobalState } from "providers/StateContainer";
|
import { useGlobalState } from "providers/StateContainer";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
|
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||||
|
|
||||||
export interface ITagAPIContext {
|
export interface ITagAPIContext {
|
||||||
addTag: (tag: pond.TagSettings) => Promise<any>;
|
addTag: (tag: pond.TagSettings) => Promise<any>;
|
||||||
|
|
@ -87,6 +88,8 @@ export default function TagProvider(props: PropsWithChildren<Props>) {
|
||||||
types?: string[]
|
types?: string[]
|
||||||
) => {
|
) => {
|
||||||
limit = limit ? limit : 100
|
limit = limit ? limit : 100
|
||||||
|
// if (!keys) keys = getContextKeys()
|
||||||
|
// if (!types) types = getContextTypes()
|
||||||
const url = pondURL(
|
const url = pondURL(
|
||||||
"/tags" +
|
"/tags" +
|
||||||
"?limit=" +
|
"?limit=" +
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue