From 0556fe2d8b6ca25350948d1d4b93cb7460a0d983 Mon Sep 17 00:00:00 2001 From: csawatzky Date: Tue, 14 Apr 2026 15:29:59 -0600 Subject: [PATCH] made some changes in the bin sensors to open a new dialog when the component being removed is the last one for a device so users can remove the device from the bin along with the component --- src/bin/BinActions.tsx | 6 ++ src/bin/BinComponents.tsx | 116 ++++++++++++++++++++++++++++++---- src/bin/BinSensors.tsx | 6 ++ src/pages/Bin.tsx | 4 +- src/providers/pond/binAPI.tsx | 6 +- 5 files changed, 121 insertions(+), 17 deletions(-) diff --git a/src/bin/BinActions.tsx b/src/bin/BinActions.tsx index a425ea6..c9f7c8f 100644 --- a/src/bin/BinActions.tsx +++ b/src/bin/BinActions.tsx @@ -57,6 +57,8 @@ interface Props { components?: Map; setComponents?: React.Dispatch>>; updateBinStatus?: (componentKeys: string[], removed?: boolean) => void; + componentDevices?: Map + setComponentDevices?: React.Dispatch>>; } interface OpenState { @@ -77,7 +79,9 @@ export default function BinActions(props: Props) { refreshCallback, userID, components, + componentDevices, setComponents, + setComponentDevices, updateBinStatus } = props; const [anchorEl, setAnchorEl] = React.useState(null); @@ -245,7 +249,9 @@ export default function BinActions(props: Props) { open={openState.sensors} userID={userID} components={components} + componentDevices={componentDevices} setComponents={setComponents} + setComponentDevices={setComponentDevices} updateBinStatus={updateBinStatus} onClose={refresh => { if (refresh === true) { diff --git a/src/bin/BinComponents.tsx b/src/bin/BinComponents.tsx index 7864c46..0b81cba 100644 --- a/src/bin/BinComponents.tsx +++ b/src/bin/BinComponents.tsx @@ -71,7 +71,9 @@ const useStyles = makeStyles((theme: Theme) => { interface Props { components?: Map; + componentDevices?: Map; setComponents?: React.Dispatch>>; + setComponentDevices?: React.Dispatch>>; bin: string; binGrain: pond.Grain; updateBinStatus?: (componentKeys: string[], removed?: boolean) => void; @@ -84,7 +86,7 @@ interface Option { } export default function BinComponents(props: Props) { - const { components, bin, setComponents, updateBinStatus, binGrain } = props; + const { components, componentDevices, bin, setComponents, setComponentDevices, updateBinStatus, binGrain } = props; const [{as}] = useGlobalState(); const classes = useStyles(); const binAPI = useBinAPI(); @@ -208,20 +210,54 @@ export default function BinComponents(props: Props) { // } // }, [selectedDevice, componentAPI, deviceComponents, snackbar]); - const removeComponent = (component: string) => { - binAPI.removeComponent(bin, component, as).then(() => { + const removeComponent = (component: string, device?: number) => { + console.log(device) + binAPI.removeComponent(bin, component, device, as).then(() => { + if (components && setComponents) { if (components.delete(component)) { let newComponents = new Map(components); setComponents(newComponents); } } + if(componentDevices && setComponentDevices) { + if (componentDevices.delete(component)) { + let newComponentDevices = new Map(componentDevices); + setComponentDevices(newComponentDevices); + } + } snackbar.info("Component removed from bin"); }); setComponentToRemove(undefined); }; - const removeComponentConfirmation = () => { + const removeComponentConfirmation = (last?: boolean) => { + let lastComponent = false; + let devId: number | undefined; + if(last){ + lastComponent = last + }else{ + if (componentDevices && componentToRemove) { + const id = componentDevices.get(componentToRemove.key()); + + if (id !== undefined) { + devId = id + let count = 0; + + for (const val of componentDevices.values()) { + if (val === devId) { + count++; + + if (count > 1) { + break; // stop early once we know it's not the last + } + } + } + + lastComponent = count === 1; + } + } + } return ( setComponentToRemove(undefined)}> Remove {componentToRemove?.name()}? - - This will remove {componentToRemove?.name()} from this bin. If you don't have direct - access to this component or the device it is attached to, you will not be able to add it - back. - + {lastComponent ? + + This component {componentToRemove?.name()} is the last component from its device. You can choose to remove only the component itself or the device along with it. + Leaving the device may have unexpected results if the device will continue to be used and it is recommended to remove it if the device is being moved to a new bin. + + : + + This will remove {componentToRemove?.name()} from this bin. If you don't have direct + access to this component or the device it is attached to, you will not be able to add it + back. + + } + {lastComponent + ? + + + + : + } ); @@ -256,7 +310,7 @@ export default function BinComponents(props: Props) { Remove All Components? - This will remove All attached components from this bin. If you don't have direct access + This will remove All attached components and devices from this bin. If you don't have direct access to these components or the devices they are attached to, you will not be able to add them back. @@ -320,6 +374,12 @@ export default function BinComponents(props: Props) { setComponents(newComponents); } } + if(componentDevices && setComponentDevices) { + if (componentDevices.set(component.key(), device)) { + let newComponentDevices = new Map(componentDevices); + setComponentDevices(newComponentDevices); + } + } //if a grain cable was added to the bin update the components grain type to match the bin if (preferences.type === pond.BinComponent.BIN_COMPONENT_GRAIN_CABLE) { let settings = component.settings; @@ -338,15 +398,40 @@ export default function BinComponents(props: Props) { } }); } else { - binAPI.removeComponent(bin, component.key(), as).then(resp => { - if (components && setComponents) { + let lastComponent = false; + if (componentDevices) { + console.log(componentDevices) + let count = 0; + for (const val of componentDevices.values()) { + if (val === device) { + count++; + + if (count > 1) { + break; // stop early once we know it's not the last + } + } + } + lastComponent = count === 1; + } + if(lastComponent){ + setComponentToRemove(component) + }else{ + binAPI.removeComponent(bin, component.key(), undefined, as).then(resp => { + if (components && setComponents) { if (components.delete(component.key())) { let newComponents = new Map(components); setComponents(newComponents); } } + if(componentDevices && setComponentDevices) { + if (componentDevices.delete(component.key())) { + let newComponentDevices = new Map(componentDevices); + setComponentDevices(newComponentDevices); + } + } snackbar.info("Component removed from bin"); - }); + }); + } } }; @@ -567,7 +652,10 @@ export default function BinComponents(props: Props) { {component.name()} - setComponentToRemove(component)}> + { + setComponentToRemove(component) + + }}> diff --git a/src/bin/BinSensors.tsx b/src/bin/BinSensors.tsx index f1c81ac..492091e 100644 --- a/src/bin/BinSensors.tsx +++ b/src/bin/BinSensors.tsx @@ -30,7 +30,9 @@ interface Props { coords?: { longitude: number; latitude: number }; binYards?: pond.BinYardSettings[]; components?: Map; + componentDevices?: Map setComponents?: React.Dispatch>>; + setComponentDevices?: React.Dispatch>>; updateBinStatus?: (componentKeys: string[], removed?: boolean) => void; } @@ -43,7 +45,9 @@ export default function BinSensors(props: Props) { mode, openedBinYard, components, + componentDevices, setComponents, + setComponentDevices, updateBinStatus } = props; const [initialized, setInitialized] = useState(false); @@ -93,7 +97,9 @@ export default function BinSensors(props: Props) { { let device = Device.create(dev); if (attachedDevIds.includes(device.id())) { - devs.push(Device.create(dev)); + devs.push(device); } }); setDevices(devs); @@ -674,6 +674,8 @@ export default function Bin(props: Props) { userID={user.id()} components={components} setComponents={setComponents} + componentDevices={componentDevices} + setComponentDevices={setComponentDevices} updateBinStatus={updateStatus} /> diff --git a/src/providers/pond/binAPI.tsx b/src/providers/pond/binAPI.tsx index def6699..e0d46f9 100644 --- a/src/providers/pond/binAPI.tsx +++ b/src/providers/pond/binAPI.tsx @@ -30,6 +30,7 @@ export interface IBinAPIContext { removeComponent: ( bin: string, component: string, + device?: number, otherTeam?: string ) => Promise>; removeAllComponents: (bin: string, otherTeam?: string) => Promise>; @@ -254,10 +255,11 @@ export default function BinProvider(props: PropsWithChildren) { }) }; - const removeComponent = (bin: string, component: string, otherTeam?: string) => { + const removeComponent = (bin: string, component: string, device?: number, otherTeam?: string) => { const view = otherTeam ? otherTeam : as let url = "/bins/" + bin + "/removeComponent/" + component; - if (view) url = url + "?as=" + view; + if (device) url = url + "?deviceToRemove=" + device + if (view) url = url + (device ? "&as=" : "?as=") + view; return new Promise>((resolve, reject)=>{ post(pondURL(url)).then(resp => { resp.data = pond.RemoveBinComponentResponse.fromObject(resp.data)