update to the group setting for adding/removing devices
This commit is contained in:
parent
68ec1217c6
commit
acbd49b907
2 changed files with 118 additions and 28 deletions
|
|
@ -7,6 +7,7 @@ import {
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Divider,
|
Divider,
|
||||||
Grid2,
|
Grid2,
|
||||||
|
IconButton,
|
||||||
lighten,
|
lighten,
|
||||||
List,
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
|
|
@ -36,12 +37,23 @@ import { useGlobalState } from "providers";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import RemoveGroup from "./RemoveGroup";
|
import RemoveGroup from "./RemoveGroup";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
import { Add, Remove } from "@mui/icons-material";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => {
|
const useStyles = makeStyles((theme: Theme) => {
|
||||||
return ({
|
return ({
|
||||||
deviceListContainer: {
|
deviceListContainer: {
|
||||||
marginBottom: theme.spacing(1)
|
marginBottom: theme.spacing(1)
|
||||||
},
|
},
|
||||||
|
listTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 650
|
||||||
|
},
|
||||||
|
listButton: {
|
||||||
|
cursor: "pointer",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: lighten(theme.palette.background.default, 0.25)
|
||||||
|
}
|
||||||
|
},
|
||||||
devicesList: {
|
devicesList: {
|
||||||
overflow: "auto",
|
overflow: "auto",
|
||||||
minHeight: "25vh",
|
minHeight: "25vh",
|
||||||
|
|
@ -87,6 +99,7 @@ export default function GroupSettings(props: Props) {
|
||||||
const deviceAPI = useDeviceAPI();
|
const deviceAPI = useDeviceAPI();
|
||||||
const snackbar = useSnackbar()
|
const snackbar = useSnackbar()
|
||||||
const [devices, setDevices] = useState<Device[]>([]);
|
const [devices, setDevices] = useState<Device[]>([]);
|
||||||
|
const [nonGroupDevices, setNonGroupDevices] = useState<Device[]>([]);
|
||||||
const [group, setGroup] = useState<Group>(initialGroup ? Group.clone(initialGroup) : new Group());
|
const [group, setGroup] = useState<Group>(initialGroup ? Group.clone(initialGroup) : new Group());
|
||||||
const [isRemoveGroupOpen, setIsRemoveGroupOpen] = useState<boolean>(
|
const [isRemoveGroupOpen, setIsRemoveGroupOpen] = useState<boolean>(
|
||||||
mode === "remove" ? true : false
|
mode === "remove" ? true : false
|
||||||
|
|
@ -109,13 +122,14 @@ export default function GroupSettings(props: Props) {
|
||||||
|
|
||||||
const loadDevices = useCallback(() => {
|
const loadDevices = useCallback(() => {
|
||||||
setLoadingDevices(true);
|
setLoadingDevices(true);
|
||||||
|
//this lists the devices for the user/team viewing
|
||||||
deviceAPI
|
deviceAPI
|
||||||
.list(1000000, 0, "asc")
|
.list(1000000, 0, "asc")
|
||||||
.then((response: any) => {
|
.then((response: any) => {
|
||||||
let rDevices: Device[] = response.data.devices
|
let rDevices: Device[] = response.data.devices
|
||||||
? response.data.devices.map((device: any) => Device.any(device))
|
? response.data.devices.map((device: any) => Device.any(device))
|
||||||
: [];
|
: [];
|
||||||
|
//remove duplicates from the options
|
||||||
setDevices(rDevices);
|
setDevices(rDevices);
|
||||||
})
|
})
|
||||||
.catch((_error: any) => {
|
.catch((_error: any) => {
|
||||||
|
|
@ -124,6 +138,16 @@ export default function GroupSettings(props: Props) {
|
||||||
.finally(() => setLoadingDevices(false));
|
.finally(() => setLoadingDevices(false));
|
||||||
}, [deviceAPI, as]);
|
}, [deviceAPI, as]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
let ungrouped: Device[] = []
|
||||||
|
devices.forEach(device => {
|
||||||
|
if(!groupDeviceNumbers.includes(device.id())){
|
||||||
|
ungrouped.push(device)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setNonGroupDevices(ungrouped)
|
||||||
|
},[groupDeviceNumbers, devices])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (prevInitialGroup !== initialGroup) {
|
if (prevInitialGroup !== initialGroup) {
|
||||||
setGroup(initialGroup ? Group.clone(initialGroup) : new Group());
|
setGroup(initialGroup ? Group.clone(initialGroup) : new Group());
|
||||||
|
|
@ -317,27 +341,58 @@ export default function GroupSettings(props: Props) {
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
) : (
|
) : (
|
||||||
<List dense className={classes.devicesList}>
|
<React.Fragment>
|
||||||
{filterDevices(deviceSearch, devices, [])
|
{groupDevices &&
|
||||||
.sort((a, b: Device) => a.name().localeCompare(b.name()))
|
<List dense className={classes.devicesList}>
|
||||||
.map(device => {
|
{filterDevices(deviceSearch, groupDevices, [])
|
||||||
const label = `checkbox-list-secondary-label-${device.id()}`;
|
.sort((a, b: Device) => a.name().localeCompare(b.name()))
|
||||||
return (
|
.map(device => {
|
||||||
<ListItem key={device.id()} onClick={() => changeDevices(device.id())}>
|
const label = `checkbox-list-secondary-label-${device.id()}`;
|
||||||
<ListItemText id={label} primary={device.name()} />
|
return (
|
||||||
<ListItemSecondaryAction>
|
<ListItem className={classes.listButton} key={device.id()} onClick={() => {
|
||||||
<Checkbox
|
removeDevice(device.id())
|
||||||
edge="end"
|
}}>
|
||||||
onChange={() => changeDevices(device.id())}
|
<ListItemText id={label} primary={device.name()} />
|
||||||
checked={group.settings.devices.includes(device.id())}
|
<ListItemSecondaryAction>
|
||||||
inputProps={{ "aria-labelledby": label }}
|
{/* <Checkbox
|
||||||
disabled={!canEdit}
|
edge="end"
|
||||||
/>
|
onChange={() => changeDevices(device.id())}
|
||||||
</ListItemSecondaryAction>
|
checked={group.settings.devices.includes(device.id())}
|
||||||
</ListItem>
|
inputProps={{ "aria-labelledby": label }}
|
||||||
);
|
disabled={!canEdit}
|
||||||
})}
|
/> */}
|
||||||
</List>
|
-
|
||||||
|
</ListItemSecondaryAction>
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
}
|
||||||
|
<List dense className={classes.devicesList}>
|
||||||
|
{filterDevices(deviceSearch, nonGroupDevices, [])
|
||||||
|
.sort((a, b: Device) => a.name().localeCompare(b.name()))
|
||||||
|
.map(device => {
|
||||||
|
const label = `checkbox-list-secondary-label-${device.id()}`;
|
||||||
|
return (
|
||||||
|
<ListItem className={classes.listButton} key={device.id()} onClick={() => {
|
||||||
|
addDevice(device.id())
|
||||||
|
}}>
|
||||||
|
<ListItemText id={label} primary={device.name()} />
|
||||||
|
<ListItemSecondaryAction>
|
||||||
|
{/* <Checkbox
|
||||||
|
edge="end"
|
||||||
|
onChange={() => changeDevices(device.id())}
|
||||||
|
checked={group.settings.devices.includes(device.id())}
|
||||||
|
inputProps={{ "aria-labelledby": label }}
|
||||||
|
disabled={!canEdit}
|
||||||
|
/> */}
|
||||||
|
+
|
||||||
|
</ListItemSecondaryAction>
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
|
|
@ -383,16 +438,49 @@ export default function GroupSettings(props: Props) {
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
) : (
|
) : (
|
||||||
|
<React.Fragment>
|
||||||
|
{groupDevices &&
|
||||||
|
<React.Fragment>
|
||||||
|
<Typography className={classes.listTitle}>Grouped Devices</Typography>
|
||||||
|
<List dense className={classes.devicesList}>
|
||||||
|
{filterDevices(deviceSearch, groupDevices, [])
|
||||||
|
.sort((a, b: Device) => a.name().localeCompare(b.name()))
|
||||||
|
.map(device => {
|
||||||
|
const label = `checkbox-list-secondary-label-${device.id()}`;
|
||||||
|
return (
|
||||||
|
<ListItem className={classes.listButton} key={device.id()} onClick={() => {
|
||||||
|
removeDevice(device.id())
|
||||||
|
}}>
|
||||||
|
<ListItemText id={label} primary={device.name()} />
|
||||||
|
<ListItemSecondaryAction>
|
||||||
|
{/* <Checkbox
|
||||||
|
edge="end"
|
||||||
|
onChange={() => changeDevices(device.id())}
|
||||||
|
checked={group.settings.devices.includes(device.id())}
|
||||||
|
inputProps={{ "aria-labelledby": label }}
|
||||||
|
disabled={!canEdit}
|
||||||
|
/> */}
|
||||||
|
<Remove />
|
||||||
|
</ListItemSecondaryAction>
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
<Typography className={classes.listTitle}>Devices You Can Add</Typography>
|
||||||
<List dense className={classes.devicesList}>
|
<List dense className={classes.devicesList}>
|
||||||
{filterDevices(deviceSearch, devices, [])
|
{filterDevices(deviceSearch, nonGroupDevices, [])
|
||||||
.sort((a, b: Device) => a.name().localeCompare(b.name()))
|
.sort((a, b: Device) => a.name().localeCompare(b.name()))
|
||||||
.map(device => {
|
.map(device => {
|
||||||
const label = `checkbox-list-secondary-label-${device.id()}`;
|
const label = `checkbox-list-secondary-label-${device.id()}`;
|
||||||
return (
|
return (
|
||||||
<ListItem key={device.id()} onClick={() => changeDevices(device.id())}>
|
<ListItem className={classes.listButton} key={device.id()} onClick={() => {
|
||||||
|
addDevice(device.id())
|
||||||
|
}}>
|
||||||
<ListItemText id={label} primary={device.name()} />
|
<ListItemText id={label} primary={device.name()} />
|
||||||
<ListItemSecondaryAction>
|
<ListItemSecondaryAction>
|
||||||
<Checkbox
|
{/* <Checkbox
|
||||||
edge="end"
|
edge="end"
|
||||||
onChange={(_, checked) => {
|
onChange={(_, checked) => {
|
||||||
if (checked) addDevice(device.id());
|
if (checked) addDevice(device.id());
|
||||||
|
|
@ -402,12 +490,14 @@ export default function GroupSettings(props: Props) {
|
||||||
checked={groupDeviceNumbers.includes(device.id())}
|
checked={groupDeviceNumbers.includes(device.id())}
|
||||||
inputProps={{ "aria-labelledby": label }}
|
inputProps={{ "aria-labelledby": label }}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
/>
|
/> */}
|
||||||
|
<Add />
|
||||||
</ListItemSecondaryAction>
|
</ListItemSecondaryAction>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</List>
|
</List>
|
||||||
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export default function GroupProvider(props: PropsWithChildren<Props>) {
|
||||||
|
|
||||||
const addDevice = (group: number, device: number) => {
|
const addDevice = (group: number, device: number) => {
|
||||||
let url = "/groups/" + group + "/devices/" + device + "/add";
|
let url = "/groups/" + group + "/devices/" + device + "/add";
|
||||||
if (as) url = pondURL(url + as)
|
if (as) url = url + "?as=" + as
|
||||||
return new Promise<AxiosResponse>((resolve, reject) => {
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
||||||
post(pondURL(url), group).then(resp => {
|
post(pondURL(url), group).then(resp => {
|
||||||
return resolve(resp)
|
return resolve(resp)
|
||||||
|
|
@ -100,7 +100,7 @@ export default function GroupProvider(props: PropsWithChildren<Props>) {
|
||||||
|
|
||||||
const removeDevice = (group: number, device: number) => {
|
const removeDevice = (group: number, device: number) => {
|
||||||
let url = "/groups/" + group + "/devices/" + device + "/remove";
|
let url = "/groups/" + group + "/devices/" + device + "/remove";
|
||||||
if (as) url = pondURL(url + as)
|
if (as) url = url + "?as=" + as
|
||||||
return new Promise<AxiosResponse>((resolve, reject) => {
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
||||||
post(pondURL(url), group).then(resp => {
|
post(pondURL(url), group).then(resp => {
|
||||||
return resolve(resp)
|
return resolve(resp)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue