adding way of disabling the scan button

the button will be disabled once it has been clicked as well as on the device page if a scan is in progress (there are pending requests)
This commit is contained in:
csawatzky 2025-06-30 16:46:39 -06:00
parent 27228602e7
commit 5607672a4b
5 changed files with 39 additions and 6 deletions

2
package-lock.json generated
View file

@ -10889,7 +10889,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#091928b04970731f9b543fcecc313b6f4ea7d4e2", "resolved": "git+https://gitlab+deploy-token-50627:hv8mB4WkyvtjBpJKU1rN@gitlab.com/brandx/protobuf-ts.git#3c25c27d545a375db5705dd0450ea94d5a4a4dcb",
"dependencies": { "dependencies": {
"protobufjs": "^6.8.8" "protobufjs": "^6.8.8"
} }

View file

@ -37,6 +37,7 @@ interface Props {
//permissions: pond.Permission[]; //permissions: pond.Permission[];
components: Component[]; components: Component[];
refreshCallback: () => void; refreshCallback: () => void;
scanInProgress?: boolean
} }
const useStyles = makeStyles((theme: Theme) => { const useStyles = makeStyles((theme: Theme) => {
@ -69,7 +70,7 @@ const useStyles = makeStyles((theme: Theme) => {
}); });
export default function DeviceWizard(props: Props) { export default function DeviceWizard(props: Props) {
const { device, components, refreshCallback } = props; const { device, components, refreshCallback, scanInProgress } = props;
const [{as}] = useGlobalState(); const [{as}] = useGlobalState();
const [componentDialogOpen, setComponentDialogOpen] = useState(false); const [componentDialogOpen, setComponentDialogOpen] = useState(false);
const [availableOffsets, setAvailableOffsets] = useState<OffsetAvailabilityMap>(new Map()); const [availableOffsets, setAvailableOffsets] = useState<OffsetAvailabilityMap>(new Map());
@ -86,6 +87,7 @@ export default function DeviceWizard(props: Props) {
const [selectedPort, setSelectedPort] = useState<PortInformation>(); const [selectedPort, setSelectedPort] = useState<PortInformation>();
const deviceAPI = useDeviceAPI() const deviceAPI = useDeviceAPI()
const { openSnack } = useSnackbar() const { openSnack } = useSnackbar()
const [buttonClicked, setButtonClicked] = useState(false);
//const [addressType, setAddressType] = useState<quack.AddressType>(quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY); //const [addressType, setAddressType] = useState<quack.AddressType>(quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY);
const wizardMenu = () => { const wizardMenu = () => {
@ -125,7 +127,9 @@ export default function DeviceWizard(props: Props) {
<Tooltip title="Used to tell the Device to scan its I2C port for any plugged in sensors"> <Tooltip title="Used to tell the Device to scan its I2C port for any plugged in sensors">
<MenuItem <MenuItem
key={"scanI2C"} key={"scanI2C"}
disabled={scanInProgress || buttonClicked}
onClick={() => { onClick={() => {
setButtonClicked(true)
deviceAPI.detectI2C(device.id()) deviceAPI.detectI2C(device.id())
.then(resp => { .then(resp => {
openSnack("Device will scan port on next check-in") openSnack("Device will scan port on next check-in")

View file

@ -9,7 +9,7 @@ import ComponentForm from "component/ComponentForm";
import { Component, Device } from "models"; import { Component, Device } from "models";
import { DeviceAvailabilityMap, OffsetAvailabilityMap } from "pbHelpers/DeviceAvailability"; import { DeviceAvailabilityMap, OffsetAvailabilityMap } from "pbHelpers/DeviceAvailability";
import ResponsiveDialog from "common/ResponsiveDialog"; import ResponsiveDialog from "common/ResponsiveDialog";
import { useComponentAPI, useSnackbar } from "hooks"; import { useComponentAPI, useDeviceAPI, useSnackbar } from "hooks";
interface Props { interface Props {
scannedComponents: pond.ComponentAddressMap scannedComponents: pond.ComponentAddressMap
@ -27,6 +27,7 @@ interface CompStep {
export default function DeviceScannedComponents(props: Props){ export default function DeviceScannedComponents(props: Props){
const {scannedComponents, device, availablePositions, availableOffsets, refreshCallback} = props const {scannedComponents, device, availablePositions, availableOffsets, refreshCallback} = props
const compAPI = useComponentAPI(); const compAPI = useComponentAPI();
const deviceAPI = useDeviceAPI()
const [scannedI2C, setScannedI2C] = useState<pond.DetectI2C>() const [scannedI2C, setScannedI2C] = useState<pond.DetectI2C>()
const [components, setComponents] = useState<Component[]>([]) const [components, setComponents] = useState<Component[]>([])
const [steps, setSteps] = useState<CompStep[]>([]); const [steps, setSteps] = useState<CompStep[]>([]);
@ -180,6 +181,15 @@ export default function DeviceScannedComponents(props: Props){
setComponents(cloneList) setComponents(cloneList)
} }
const removeScan = (key: string) => {
deviceAPI.removeFoundComponents(device.settings.deviceId, key)
.then(resp => {
console.log("Cleared this scan")
}).catch(err => {
console.log("There was a problem clearing this scan")
})
}
return ( return (
@ -187,10 +197,11 @@ export default function DeviceScannedComponents(props: Props){
<Card raised sx={{padding: 1}}> <Card raised sx={{padding: 1}}>
{scannedI2C !== undefined && {scannedI2C !== undefined &&
<React.Fragment> <React.Fragment>
<Box> <Box justifyContent="space-between" display="flex">
<Typography sx={{fontWeight: 650}}> <Typography sx={{fontWeight: 650}}>
I2C Sensors I2C Sensors
</Typography> </Typography>
<Button variant="contained" color="primary" onClick={()=>{removeScan(scannedI2C.key)}}>Clear Scan</Button>
</Box> </Box>
{scannedI2C.settings?.foundAddresses && scannedI2C.settings.foundAddresses.length > 0 ? scannedI2C?.settings?.foundAddresses.map((addr, index) => { {scannedI2C.settings?.foundAddresses && scannedI2C.settings.foundAddresses.length > 0 ? scannedI2C?.settings?.foundAddresses.map((addr, index) => {
return ( return (

View file

@ -58,6 +58,7 @@ export default function DevicePage() {
const [components, setComponents] = useState<Map<string, Component>>(new Map()); const [components, setComponents] = useState<Map<string, Component>>(new Map());
const [diagnosticComponents, setDiagnosticComponents] = useState<Component[]>([]); const [diagnosticComponents, setDiagnosticComponents] = useState<Component[]>([]);
const [scannedAddresses, setScannedAddresses] = useState<pond.ComponentAddressMap | undefined>(undefined) const [scannedAddresses, setScannedAddresses] = useState<pond.ComponentAddressMap | undefined>(undefined)
const [scanInProgress, setScanInProgress] = useState(false)
// const [components, setComponents] = useState<Component[]>([]); // const [components, setComponents] = useState<Component[]>([]);
const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false) const [addComponentManualDialogOpen, setAddComponentManualDialogOpen] = useState(false)
@ -78,7 +79,8 @@ export default function DevicePage() {
deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes(), as).then(resp => { deviceAPI.getPageData(deviceID, getContextKeys(), getContextTypes(), as).then(resp => {
// setDevicePageData(resp.data) // setDevicePageData(resp.data)
let device = Device.any(resp.data.device) let device = Device.any(resp.data.device)
// console.log(resp.data.device) // console.log(resp.data)
setScanInProgress(resp.data.pendingRequests)
setDevice(device) setDevice(device)
let newPermissions: pond.Permission[] = [] let newPermissions: pond.Permission[] = []
resp.data.permissions.forEach(perm => { resp.data.permissions.forEach(perm => {
@ -400,6 +402,7 @@ export default function DevicePage() {
<Grid size={{ xs: 12 }}> <Grid size={{ xs: 12 }}>
<DeviceWizard <DeviceWizard
device={device} device={device}
scanInProgress={scanInProgress}
//permissions={permissions} //permissions={permissions}
components={Array.from(components.values())} components={Array.from(components.values())}
refreshCallback={loadDevice} refreshCallback={loadDevice}

View file

@ -148,6 +148,7 @@ export interface IDeviceAPIContext {
keys?: string[], keys?: string[],
types?: string[] types?: string[]
) => Promise<any>; ) => Promise<any>;
removeFoundComponents: (id: number, key: string, otherTeam?: string) => Promise<AxiosResponse<pond.RemoveFoundComponentsResponse>>;
} }
export const DeviceAPIContext = createContext<IDeviceAPIContext>({} as IDeviceAPIContext); export const DeviceAPIContext = createContext<IDeviceAPIContext>({} as IDeviceAPIContext);
@ -974,6 +975,19 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
}) })
} }
const removeFoundComponents = (id: number, key: string, otherTeam?: string) => {
let url = "/devices/" + id + "/removeFoundComponents/" + key;
const view = otherTeam ? otherTeam : as
if(view) url = url + "?as=" + view
return new Promise<AxiosResponse<pond.RemoveFoundComponentsResponse>>((resolve, reject) => {
del<pond.RemoveFoundComponentsResponse>(pondURL(url)).then(resp => {
return resolve(resp)
}).catch(err => {
return reject(err)
})
})
}
return ( return (
<DeviceAPIContext.Provider <DeviceAPIContext.Provider
value={{ value={{
@ -1021,7 +1035,8 @@ export default function DeviceProvider(props: PropsWithChildren<Props>) {
updateComponentPreferences, updateComponentPreferences,
listDeviceComponentPreferences, listDeviceComponentPreferences,
detectI2C, detectI2C,
listFoundComponents listFoundComponents,
removeFoundComponents
}}> }}>
{children} {children}
</DeviceAPIContext.Provider> </DeviceAPIContext.Provider>