import {
Box,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Divider,
FormControl,
FormControlLabel,
Grid2 as Grid,
IconButton,
MenuItem,
Step,
StepLabel,
Stepper,
Switch,
Tab,
Tabs,
TextField,
Theme,
Tooltip,
Typography
} from "@mui/material";
import DeleteButton from "common/DeleteButton";
import ResponsiveDialog from "common/ResponsiveDialog";
import SearchSelect, { Option } from "common/SearchSelect";
import { useComponentAPI, useDeviceAPI, usePrevious, useSnackbar } from "hooks";
import { cloneDeep } from "lodash";
import { Component, Device } from "models";
import {
getFriendlyAddressTypeName,
getHumanReadableAddress,
isSingular
} from "pbHelpers/AddressType";
import {
extension,
FilterSubtypeI2C,
getAddressTypes,
GetComponentTypeOptions,
getFriendlyName,
getMeasurements,
isController,
} from "pbHelpers/ComponentType";
import PeriodSelect from "common/time/PeriodSelect";
import { bestUnit, milliToX } from "common/time/duration";
import {
ComponentAvailabilityMap,
DeviceAvailabilityMap,
OffsetAvailabilityMap
} from "pbHelpers/DeviceAvailability";
import { pond } from "protobuf-ts/pond";
import { quack } from "protobuf-ts/quack";
import React, { useCallback, useEffect, useState } from "react";
import { or } from "utils/types";
import { ConfigurablePin } from "pbHelpers/AddressTypes";
import ColourPicker from "common/ColourPicker";
import classNames from "classnames";
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
import ComponentForm from "./ComponentForm";
import { green, red } from "@mui/material/colors";
import { makeStyles } from "@mui/styles";
import {
Remove as RemoveIcon,
Add as AddIcon,
} from "@mui/icons-material"
import CancelSubmit from "common/CancelSubmit";
import { useGlobalState } from "providers";
const useStyles = makeStyles((theme: Theme) => {
return ({
stepper: {
paddingRight: 0,
paddingLeft: 0
},
switchControl: {
marginLeft: theme.spacing(0.25),
[theme.breakpoints.up("sm")]: {
marginLeft: theme.spacing(1)
}
},
selectInput: {
minHeight: "48px"
},
fullWidth: {
width: "100%"
},
heading: {
fontSize: theme.typography.pxToRem(13),
flexBasis: "25%",
flexShrink: 0
},
secondaryHeading: {
fontSize: theme.typography.pxToRem(13),
color: theme.palette.text.secondary
},
greenButton: {
color: green["600"]
},
redButton: {
color: red["600"]
},
noPadding: {
padding: 0
},
dataUsageCard: { width: "100%" },
dataUsageHeader: { paddingBottom: 0 },
dataUsageIcon: { color: "var(--status-warning)" },
dataUsageContent: { paddingTop: 0 }
})
});
interface Props {
device: Device;
component?: Component;
isDialogOpen: boolean;
closeDialogCallback: () => void;
availablePositions: DeviceAvailabilityMap;
availableOffsets: OffsetAvailabilityMap; //deprecated: this is no longer used with the change of cable id to be a number entry
mode?: "add" | "remove" | "update";
refreshCallback: () => void;
canEdit: boolean;
addressTypeRestriction?: quack.AddressType;
deviceComponentPrefs?: pond.DeviceComponentPreferences;
}
interface TabPanelProps {
children?: React.ReactNode;
index: any;
value: any;
}
function TabPanelMine(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
{value === index && {children}}
);
}
export default function ComponentSettings(props: Props) {
const classes = useStyles();
const componentAPI = useComponentAPI();
const deviceAPI = useDeviceAPI();
const { error, warning, success } = useSnackbar();
const {
device,
isDialogOpen,
closeDialogCallback,
availablePositions,
mode,
refreshCallback,
canEdit,
addressTypeRestriction,
deviceComponentPrefs
} = props;
const [{as}] = useGlobalState();
const prevComponent = usePrevious(props.component);
const prevIsDialogOpen = usePrevious(isDialogOpen);
const steps = [0, 1];
const [activeStep, setActiveStep] = useState(0);
const [componentType, setComponentType] = useState