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

This commit is contained in:
csawatzky 2026-04-14 15:29:59 -06:00
parent da5ef99a3e
commit 0556fe2d8b
5 changed files with 121 additions and 17 deletions

View file

@ -57,6 +57,8 @@ interface Props {
components?: Map<string, Component>;
setComponents?: React.Dispatch<React.SetStateAction<Map<string, Component>>>;
updateBinStatus?: (componentKeys: string[], removed?: boolean) => void;
componentDevices?: Map<string, number>
setComponentDevices?: React.Dispatch<React.SetStateAction<Map<string, number>>>;
}
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 | HTMLElement>(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) {

View file

@ -71,7 +71,9 @@ const useStyles = makeStyles((theme: Theme) => {
interface Props {
components?: Map<string, Component>;
componentDevices?: Map<string, number>;
setComponents?: React.Dispatch<React.SetStateAction<Map<string, Component>>>;
setComponentDevices?: React.Dispatch<React.SetStateAction<Map<string, number>>>;
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 (
<ResponsiveDialog
fullScreen={false}
@ -229,19 +265,37 @@ export default function BinComponents(props: Props) {
onClose={() => setComponentToRemove(undefined)}>
<DialogTitle>Remove {componentToRemove?.name()}?</DialogTitle>
<DialogContent>
<DialogContentText>
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.
</DialogContentText>
{lastComponent ?
<DialogContentText>
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.
</DialogContentText>
:
<DialogContentText>
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.
</DialogContentText>
}
</DialogContent>
<DialogActions>
<Button onClick={() => setComponentToRemove(undefined)} color="primary">
Cancel
</Button>
{lastComponent
?
<React.Fragment>
<Button onClick={() => removeComponent(componentToRemove!.key())} color="primary">
Remove Component
</Button>
<Button onClick={() => removeComponent(componentToRemove!.key(), devId)} color="primary">
Remove Component And Device
</Button>
</React.Fragment> :
<Button onClick={() => removeComponent(componentToRemove!.key())} color="primary">
Remove
</Button>
}
</DialogActions>
</ResponsiveDialog>
);
@ -256,7 +310,7 @@ export default function BinComponents(props: Props) {
<DialogTitle>Remove All Components?</DialogTitle>
<DialogContent>
<DialogContentText>
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.
</DialogContentText>
@ -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) {
</ListItemAvatar>
<ListItemText inset={cIcon === undefined}>{component.name()}</ListItemText>
<ListItemSecondaryAction>
<IconButton onClick={() => setComponentToRemove(component)}>
<IconButton onClick={() => {
setComponentToRemove(component)
}}>
<Remove />
</IconButton>
</ListItemSecondaryAction>

View file

@ -30,7 +30,9 @@ interface Props {
coords?: { longitude: number; latitude: number };
binYards?: pond.BinYardSettings[];
components?: Map<string, Component>;
componentDevices?: Map<string, number>
setComponents?: React.Dispatch<React.SetStateAction<Map<string, Component>>>;
setComponentDevices?: React.Dispatch<React.SetStateAction<Map<string, number>>>;
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) {
<Box padding={1}>
<BinComponents
components={components ? components : undefined}
componentDevices={componentDevices}
setComponents={setComponents}
setComponentDevices={setComponentDevices}
bin={bin.key()}
binGrain={bin.grain()}
updateBinStatus={updateBinStatus}