import { Box, Button, Checkbox, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Divider, 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, getAddressTypes, GetComponentTypeOptions, getFriendlyName, getMeasurements, isController } from "pbHelpers/ComponentType"; 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"; 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 ( ); } 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 prevComponent = usePrevious(props.component); const prevIsDialogOpen = usePrevious(isDialogOpen); const steps = [0, 1]; const [activeStep, setActiveStep] = useState(0); const [componentType, setComponentType] = useState