Merge branch 'dev_environment' of gitlab.com:brandx/bxt-app into dev_environment
This commit is contained in:
commit
765395608f
4 changed files with 134 additions and 20 deletions
|
|
@ -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) {
|
||||
|
|
@ -60,30 +67,54 @@ export default function DraggableTabs(props: DraggableTabsProps) {
|
|||
}
|
||||
|
||||
if (draggedIndex !== dropIndex && draggedIndex >= 0 && dropIndex >= 0 && draggedIndex < tabOrder.length && dropIndex < tabOrder.length) {
|
||||
|
||||
// console.log("draggedItem: ", draggedItem)
|
||||
// console.log("props value: ", tabsProps.value)
|
||||
// console.log("draggedTabValue: ", draggedTabValue)
|
||||
console.log("dropIndex: ", dropIndex)
|
||||
// console.log("startTabs.length: ", startTabs.length)
|
||||
|
||||
const newOrder = [...tabOrder];
|
||||
const [draggedItem] = newOrder.splice(draggedIndex, 1);
|
||||
newOrder.splice(dropIndex, 0, draggedItem);
|
||||
|
||||
setTabOrder(newOrder);
|
||||
|
||||
const selectedIndex = selectedValue-startTabs.length
|
||||
if (draggedIndex === selectedIndex)
|
||||
setSelectedValue(dropIndex+startTabs.length)
|
||||
else if (draggedIndex > selectedIndex && dropIndex <= selectedIndex)
|
||||
setSelectedValue(selectedValue+1)
|
||||
else if (draggedIndex < selectedIndex && dropIndex >= selectedIndex)
|
||||
setSelectedValue(selectedValue-1)
|
||||
} else {
|
||||
console.log("Drop skipped: invalid indices or same position");
|
||||
}
|
||||
setHoveredIndex(-1); // Reset hovered index
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// console.log(hoveredIndex)
|
||||
// }, [hoveredIndex])
|
||||
|
||||
// useEffect(() => {
|
||||
// console.log(props.value)
|
||||
// }, [props.value])
|
||||
|
||||
// useEffect(() => {
|
||||
// console.log(selectedValue)
|
||||
// }, [selectedValue])
|
||||
|
||||
const enhancedChildren = React.Children.map(initialChildren, (child, originalIndex) => {
|
||||
if (React.isValidElement(child)) {
|
||||
const currentIndex = tabOrder.indexOf(originalIndex);
|
||||
return (
|
||||
<div
|
||||
ref={(el) => (tabRefs.current[currentIndex] = el)} // Assign ref to each tab
|
||||
draggable
|
||||
onDragStart={(e) => handleDragStart(e, currentIndex)}
|
||||
onDragOver={(e) => handleDragOver(e, currentIndex)}
|
||||
onDrop={handleDrop} // Handle drop on individual tabs
|
||||
>
|
||||
{React.cloneElement(child)}
|
||||
</div>
|
||||
);
|
||||
return React.cloneElement(child, {
|
||||
...child.props,
|
||||
draggable: true,
|
||||
onDragStart: (e: React.DragEvent<HTMLDivElement>) => handleDragStart(e, currentIndex),
|
||||
onDragOver: (e: React.DragEvent<HTMLDivElement>) => handleDragOver(e, currentIndex),
|
||||
onDrop: handleDrop,
|
||||
});
|
||||
}
|
||||
return child;
|
||||
}) || [];
|
||||
|
|
@ -91,5 +122,5 @@ export default function DraggableTabs(props: DraggableTabsProps) {
|
|||
const orderedChildren = tabOrder.map((index) => enhancedChildren[index]);
|
||||
const allTabs = [...startTabs, ...orderedChildren, ...endTabs];
|
||||
|
||||
return <Tabs {...tabsProps}>{allTabs}</Tabs>;
|
||||
return <Tabs {...tabsProps} value={selectedValue} >{allTabs}</Tabs>;
|
||||
}
|
||||
|
|
@ -313,12 +313,10 @@ export default function SmartBreadcrumb(props: Props) {
|
|||
variant={lastPath ? "filled" : "outlined"}
|
||||
label={
|
||||
<LinkRouter
|
||||
//color={lastPath ? "textPrimary" : "textSecondary"}
|
||||
color={lastPath ? "textPrimary" : "textSecondary"}
|
||||
variant="subtitle1"
|
||||
to={to}
|
||||
sx={{ '&:hover': { color: getThemeType() === "dark" ? 'white' : "black" },
|
||||
color: lastPath ? "HighlightText" : "GrayText"
|
||||
}}
|
||||
sx={{ '&:hover': { color: getThemeType() === "dark" ? 'white' : "black" }}}
|
||||
className={classes.textOverflow}>
|
||||
{label}
|
||||
</LinkRouter>
|
||||
|
|
|
|||
|
|
@ -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
85
src/device/SyncDevice.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue