added sync device to device actions

This commit is contained in:
Carter 2025-03-25 11:45:10 -06:00
parent 55462f5ca6
commit 9bc2a5c4c4
3 changed files with 96 additions and 4 deletions

View file

@ -9,7 +9,7 @@ interface DraggableTabsProps extends TabsProps {
export default function DraggableTabs(props: DraggableTabsProps) {
const { startNode, endNode, children, ...tabsProps } = props;
const [selectedValue, setSelectedValue] = useState<any>(tabsProps.value);
const initialChildren = React.Children.toArray(children);
const [tabOrder, setTabOrder] = useState<number[]>([]);
const [hoveredIndex, setHoveredIndex] = useState<number>(-1); // Track hovered tab
@ -21,6 +21,13 @@ export default function DraggableTabs(props: DraggableTabsProps) {
tabRefs.current = new Array(newOrder.length).fill(null); // Initialize refs
}, [initialChildren.length]);
// Sync selectedValue with propValue if controlled
useEffect(() => {
if (tabsProps.value !== undefined) {
setSelectedValue(tabsProps.value); // Keep in sync with parent if controlled
}
}, [tabsProps.value]);
const flattenNodes = (nodes: React.ReactNode, prefix: string) =>
React.Children.toArray(nodes).flatMap((node, nodeIndex) => {
if (React.isValidElement(node) && (node.type as any) === React.Fragment) {

View file

@ -37,7 +37,7 @@ import NotificationButton from "common/NotificationButton";
// import { PauseData } from "device/PauseData";
// import { ResumeData } from "device/ResumeData";
// import SaveDeviceProfile from "device/SaveDeviceProfile";
// import SyncDevice from "device/SyncDevice";
import SyncDevice from "device/SyncDevice";
// import UpgradeDevice from "device/UpgradeDevice";
// import InteractionSettings from "interactions/InteractionSettings";
import { cloneDeep } from "lodash";
@ -396,12 +396,12 @@ export default function DeviceActions(props: Props) {
refreshCallback={refreshCallback}
canEdit={canWrite}
/>
{/* <SyncDevice
<SyncDevice
device={device}
isDialogOpen={or(isSyncDeviceDialogOpen, false)}
closeDialogCallback={() => closeDialog("isSyncDeviceDialogOpen")}
refreshCallback={refreshCallback}
/> */}
/>
<ShareObject
scope={deviceScope(device.id().toString())}
label={deviceName}

85
src/device/SyncDevice.tsx Normal file
View file

@ -0,0 +1,85 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Divider,
Theme,
Typography
} from "@mui/material";
import { makeStyles } from "@mui/styles";
import { useDeviceAPI, useSnackbar } from "hooks";
import { Device } from "models";
const useStyles = makeStyles((theme: Theme) => {
return ({
dialogContent: {
marginTop: theme.spacing(2)
}
})
});
interface Props {
device: Device;
isDialogOpen: boolean;
closeDialogCallback: () => void;
refreshCallback: () => void;
}
export default function SyncDevice(props: Props) {
const classes = useStyles();
const { success, error } = useSnackbar();
const { device, isDialogOpen, closeDialogCallback, refreshCallback } = props;
const deviceAPI = useDeviceAPI();
const close = () => {
closeDialogCallback();
};
const sync = () => {
deviceAPI
.sync(device.id())
.then(() => {
success("Device will sync with the current settings next time it checks in");
close();
refreshCallback();
})
.catch((err: any) => {
console.error(err);
error("Unable to resync device");
close();
});
};
return (
<Dialog
fullWidth
open={isDialogOpen}
onClose={closeDialogCallback}
aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">
Resync Device
<Typography variant="body2" color="textSecondary">
{device.name()}
</Typography>
</DialogTitle>
<Divider />
<DialogContent className={classes.dialogContent}>
<DialogContentText id="alert-dialog-slide-description">
Syncing the device will send all the current settings to the device the next time it
checks in.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={close} color="primary">
Cancel
</Button>
<Button onClick={sync} color="primary">
Sync
</Button>
</DialogActions>
</Dialog>
);
}