From acbd49b9075b2505ad805150043d17b17c788e0a Mon Sep 17 00:00:00 2001 From: csawatzky Date: Tue, 29 Apr 2025 14:04:08 -0600 Subject: [PATCH] update to the group setting for adding/removing devices --- src/group/GroupSettings.tsx | 142 ++++++++++++++++++++++++++------ src/providers/pond/groupAPI.tsx | 4 +- 2 files changed, 118 insertions(+), 28 deletions(-) diff --git a/src/group/GroupSettings.tsx b/src/group/GroupSettings.tsx index 2f15ef5..7c34568 100644 --- a/src/group/GroupSettings.tsx +++ b/src/group/GroupSettings.tsx @@ -7,6 +7,7 @@ import { DialogTitle, Divider, Grid2, + IconButton, lighten, List, ListItem, @@ -36,12 +37,23 @@ import { useGlobalState } from "providers"; import React, { useCallback, useEffect, useState } from "react"; import RemoveGroup from "./RemoveGroup"; import { pond } from "protobuf-ts/pond"; +import { Add, Remove } from "@mui/icons-material"; const useStyles = makeStyles((theme: Theme) => { return ({ deviceListContainer: { marginBottom: theme.spacing(1) }, + listTitle: { + fontSize: 20, + fontWeight: 650 + }, + listButton: { + cursor: "pointer", + "&:hover": { + backgroundColor: lighten(theme.palette.background.default, 0.25) + } + }, devicesList: { overflow: "auto", minHeight: "25vh", @@ -87,6 +99,7 @@ export default function GroupSettings(props: Props) { const deviceAPI = useDeviceAPI(); const snackbar = useSnackbar() const [devices, setDevices] = useState([]); + const [nonGroupDevices, setNonGroupDevices] = useState([]); const [group, setGroup] = useState(initialGroup ? Group.clone(initialGroup) : new Group()); const [isRemoveGroupOpen, setIsRemoveGroupOpen] = useState( mode === "remove" ? true : false @@ -109,13 +122,14 @@ export default function GroupSettings(props: Props) { const loadDevices = useCallback(() => { setLoadingDevices(true); + //this lists the devices for the user/team viewing deviceAPI .list(1000000, 0, "asc") .then((response: any) => { let rDevices: Device[] = response.data.devices ? response.data.devices.map((device: any) => Device.any(device)) : []; - + //remove duplicates from the options setDevices(rDevices); }) .catch((_error: any) => { @@ -124,6 +138,16 @@ export default function GroupSettings(props: Props) { .finally(() => setLoadingDevices(false)); }, [deviceAPI, as]); + useEffect(()=>{ + let ungrouped: Device[] = [] + devices.forEach(device => { + if(!groupDeviceNumbers.includes(device.id())){ + ungrouped.push(device) + } + }) + setNonGroupDevices(ungrouped) + },[groupDeviceNumbers, devices]) + useEffect(() => { if (prevInitialGroup !== initialGroup) { setGroup(initialGroup ? Group.clone(initialGroup) : new Group()); @@ -317,27 +341,58 @@ export default function GroupSettings(props: Props) { ) : ( - - {filterDevices(deviceSearch, devices, []) - .sort((a, b: Device) => a.name().localeCompare(b.name())) - .map(device => { - const label = `checkbox-list-secondary-label-${device.id()}`; - return ( - changeDevices(device.id())}> - - - changeDevices(device.id())} - checked={group.settings.devices.includes(device.id())} - inputProps={{ "aria-labelledby": label }} - disabled={!canEdit} - /> - - - ); - })} - + + {groupDevices && + + {filterDevices(deviceSearch, groupDevices, []) + .sort((a, b: Device) => a.name().localeCompare(b.name())) + .map(device => { + const label = `checkbox-list-secondary-label-${device.id()}`; + return ( + { + removeDevice(device.id()) + }}> + + + {/* changeDevices(device.id())} + checked={group.settings.devices.includes(device.id())} + inputProps={{ "aria-labelledby": label }} + disabled={!canEdit} + /> */} + - + + + ); + })} + + } + + {filterDevices(deviceSearch, nonGroupDevices, []) + .sort((a, b: Device) => a.name().localeCompare(b.name())) + .map(device => { + const label = `checkbox-list-secondary-label-${device.id()}`; + return ( + { + addDevice(device.id()) + }}> + + + {/* changeDevices(device.id())} + checked={group.settings.devices.includes(device.id())} + inputProps={{ "aria-labelledby": label }} + disabled={!canEdit} + /> */} + + + + + ); + })} + + )} ); @@ -383,16 +438,49 @@ export default function GroupSettings(props: Props) { ) : ( + + {groupDevices && + + Grouped Devices + + {filterDevices(deviceSearch, groupDevices, []) + .sort((a, b: Device) => a.name().localeCompare(b.name())) + .map(device => { + const label = `checkbox-list-secondary-label-${device.id()}`; + return ( + { + removeDevice(device.id()) + }}> + + + {/* changeDevices(device.id())} + checked={group.settings.devices.includes(device.id())} + inputProps={{ "aria-labelledby": label }} + disabled={!canEdit} + /> */} + + + + ); + })} + + + } + Devices You Can Add - {filterDevices(deviceSearch, devices, []) + {filterDevices(deviceSearch, nonGroupDevices, []) .sort((a, b: Device) => a.name().localeCompare(b.name())) .map(device => { const label = `checkbox-list-secondary-label-${device.id()}`; return ( - changeDevices(device.id())}> + { + addDevice(device.id()) + }}> - { if (checked) addDevice(device.id()); @@ -402,12 +490,14 @@ export default function GroupSettings(props: Props) { checked={groupDeviceNumbers.includes(device.id())} inputProps={{ "aria-labelledby": label }} disabled={!canEdit} - /> + /> */} + ); })} + )} ); diff --git a/src/providers/pond/groupAPI.tsx b/src/providers/pond/groupAPI.tsx index ef0ba34..45d140c 100644 --- a/src/providers/pond/groupAPI.tsx +++ b/src/providers/pond/groupAPI.tsx @@ -88,7 +88,7 @@ export default function GroupProvider(props: PropsWithChildren) { const addDevice = (group: number, device: number) => { let url = "/groups/" + group + "/devices/" + device + "/add"; - if (as) url = pondURL(url + as) + if (as) url = url + "?as=" + as return new Promise((resolve, reject) => { post(pondURL(url), group).then(resp => { return resolve(resp) @@ -100,7 +100,7 @@ export default function GroupProvider(props: PropsWithChildren) { const removeDevice = (group: number, device: number) => { let url = "/groups/" + group + "/devices/" + device + "/remove"; - if (as) url = pondURL(url + as) + if (as) url = url + "?as=" + as return new Promise((resolve, reject) => { post(pondURL(url), group).then(resp => { return resolve(resp)