@material-ui/core#InputLabel TypeScript Examples

The following examples show how to use @material-ui/core#InputLabel. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx    From Nishan with MIT License 6 votes vote down vote up
export function BasicSelect(props: Props) {
  const classes = useStyles();
  const { filter_item_label } = useContext(NotionFilterContext)

  return <FormControl className={classes.formControl}>
    {filter_item_label && <InputLabel>{props.label}</InputLabel>}
    <Select
      value={props.value}
      onChange={props.onChange}
    >
      {props.items.map(({ value, label, icon = null }) => <MenuItem key={value} value={value}>{icon} {label}</MenuItem>)}
    </Select>
  </FormControl>
}
Example #2
Source File: AudioSelector.tsx    From Oratio with MIT License 6 votes vote down vote up
export default function AudioSelector() {
  const { t } = useTranslation();
  const [sound, setSound] = React.useState('');

  const handleSoundChange = (event: React.ChangeEvent<{ value: unknown }>) => {
    setSound(event.target.value as string);
    localStorage.setItem('soundFileName', event.target.value as string);
  };

  const classes = useStyles();
  return (
    <div>
      <FormControl className={classes.root}>
        <InputLabel id="demo-simple-select-label">
          {t('Speech Sound')}
        </InputLabel>
        <Select
          labelId="demo-simple-select-label"
          id="demo-simple-select"
          value={sound}
          autoWidth
          onChange={handleSoundChange}
        >
          {options.map((option) => (
            <MenuItem key={option} value={option}>
              {option}
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    </div>
  );
}
Example #3
Source File: StatusFilterOperators.tsx    From frontend with Apache License 2.0 6 votes vote down vote up
StatusInputComponent = (props: GridFilterInputValueProps) => {
  const { item, applyValue } = props;
  const { testRuns } = useTestRunState();

  const handleFilterChange = (event: any) => {
    applyValue({ ...item, value: event.target.value as string });
  };

  const filterOptions: Array<TestStatus> = Array.from(
    new Set(testRuns.map((item) => item.status))
  );

  return (
    <FormControl fullWidth>
      <InputLabel shrink id="statusFilter">
        Value
      </InputLabel>
      <Select
        id="statusFilter"
        native
        displayEmpty
        value={item.value}
        onChange={handleFilterChange}
      >
        <option aria-label="All" value="" />
        {filterOptions.map((item) => (
          <option key={item} value={item}>
            {item}
          </option>
        ))}
      </Select>
    </FormControl>
  );
}
Example #4
Source File: index.tsx    From back-home-safe with GNU General Public License v3.0 6 votes vote down vote up
CameraSetting = () => {
  const { t } = useTranslation("camera_setting");
  const { preferredCameraId, setPreferredCameraId, cameraList } = useCamera();

  return (
    <PageWrapper>
      <Header backPath="/" name={t("name")} />
      <FormWrapper>
        <StyledFormControl>
          <InputLabel id="cameraId">{t("form.camera_choice.label")}</InputLabel>
          <Select
            labelId="cameraId"
            id="demo-simple-select"
            value={preferredCameraId}
            onChange={(e) => {
              setPreferredCameraId((e.target.value as string) || "AUTO");
            }}
          >
            <MenuItem value="AUTO">{t("form.camera_choice.auto")}</MenuItem>
            {cameraList.map(({ deviceId, label }) => (
              <MenuItem value={deviceId} key="deviceId">
                {isNil(label) || isEmpty(label) ? deviceId : label}
              </MenuItem>
            ))}
          </Select>
          <FormHelperText>{t("form.camera_choice.explain")}</FormHelperText>
        </StyledFormControl>
      </FormWrapper>
      <VideoContainer>
        <MediaStream suppressError />
      </VideoContainer>
    </PageWrapper>
  );
}
Example #5
Source File: SelectApplicationView.tsx    From github-deploy-center with MIT License 6 votes vote down vote up
SelectApplicationView = () => {
  const { applicationsById, selectedApplicationId } = useAppState()
  const { selectApplication, editApplication, editDeployment } = useActions()
  const sortedApplications = orderBy(applicationsById, (x) =>
    x.name.toLowerCase()
  )
  return size(sortedApplications) ? (
    <Box display="flex" alignItems="center" style={{ gap: '1rem' }}>
      <FormControl variant="outlined" style={{ flex: 1 }}>
        <InputLabel id="application-select-label">Application</InputLabel>
        <Select
          labelId="application-select-label"
          label="Application"
          onChange={(event) => {
            selectApplication(event.target.value as string)
          }}
          value={selectedApplicationId}>
          {map(sortedApplications, (app) => (
            <MenuItem value={app.id} key={app.id}>
              {app.name}
            </MenuItem>
          ))}
        </Select>
      </FormControl>
      <Button color="secondary" variant="contained" onClick={editApplication}>
        Edit App
      </Button>
      <Button color="secondary" variant="contained" onClick={editDeployment}>
        Edit Deploy
      </Button>
    </Box>
  ) : null
}
Example #6
Source File: StationSelectInput.tsx    From metro-fare with MIT License 6 votes vote down vote up
StationSelectInput = ({
  title,
  value,
  onFocus,
}: StationSelectInputProps) => {
  const { i18n } = useTranslation();
  const stationElementId = `${title}-native-required`;
  const station = STATIONS.find((station) => station.id === value);
  const getStationLabel = (station: Station | undefined) => {
    if (!station) return "";

    const lineType = getLineTypeLabel(station.lineType);
    const stationName = getStationName(station, i18n.language);
    return station ? `${lineType} [${station.id}] ${stationName}` : "";
  };
  const label = getStationLabel(station);
  return (
    <div className="station-select-input" onFocus={onFocus}>
      <InputLabel htmlFor={stationElementId}>{title}</InputLabel>
      <Input className="station-input" value={label} />
    </div>
  );
}
Example #7
Source File: CustomSelect.tsx    From flect-chime-sdk-demo with Apache License 2.0 6 votes vote down vote up
CustomSelect = <T extends string | number | readonly string[] | undefined>(props: CustomSelectProps<T>) => {
    const classes = useCustomSelectStyles({ height: props.height, fontsize: props.fontsize, labelFontsize: props.labelFontsize });
    const [value, setValue] = useState<T | undefined>(props.defaultValue);
    const items = props.items.map((x) => {
        return (
            <MenuItem style={{ fontSize: props.fontsize }} key={x.label} value={x.value}>
                <em>{x.label}</em>
            </MenuItem>
        );
    });

    return (
        <FormControl>
            <InputLabel
                shrink={true}
                classes={{
                    root: classes.inputLabel,
                    focused: classes.inputLabelFocused,
                }}
            >
                {props.label}
            </InputLabel>
            <Select
                onChange={(e) => {
                    props.onChange(e.target.value as T);
                    setValue(e.target.value as T);
                }}
                defaultValue={value}
                inputProps={{
                    classes: {
                        root: classes.input,
                    },
                }}
            >
                {items}
            </Select>
        </FormControl>
    );
}
Example #8
Source File: SelectWorkflow.tsx    From github-deploy-center with MIT License 5 votes vote down vote up
export function SelectWorkflow({
  workflowId,
  onChange,
  FormControlProps = {},
}: {
  workflowId: number
  onChange: (workflowId: number) => void
  FormControlProps?: FormControlProps
}) {
  const workflows = useFetchWorkflows()
  const { selectedApplication } = useAppState()

  if (!selectedApplication) return null

  if (workflows.error) {
    return <Alert severity="error">Could not load workflows</Alert>
  }

  const workflowsSorted = (workflows.data ?? []).orderBy(
    [
      (workflow) => {
        const containsName = workflow.name
          .toLowerCase()
          .includes(selectedApplication.name.toLowerCase().split(' ')[0])
        const containsDeploy = workflow.name.toLowerCase().includes('deploy')
        return containsDeploy && containsName
          ? WorkflowRelevance.NameAndDeploy
          : containsName
          ? WorkflowRelevance.Name
          : containsDeploy
          ? WorkflowRelevance.Deploy
          : WorkflowRelevance.None
      },
      (w) => w.name,
    ],
    ['desc', 'asc']
  )
  return (
    <FormControl variant="outlined" {...FormControlProps}>
      <InputLabel id="workflow-select-label">Workflow</InputLabel>
      {workflows.isLoading ? (
        <CircularProgress />
      ) : workflows.data ? (
        <Select
          labelId="workflow-select-label"
          id="workflow-select"
          value={workflowId}
          label="Workflow"
          onChange={(e) => {
            const workflowId =
              typeof e.target.value === 'number'
                ? (e.target.value as number)
                : 0
            onChange(workflowId)
          }}>
          <MenuItem value={0}>
            <em>None</em>
          </MenuItem>
          {workflowsSorted.map((workflow) => (
            <MenuItem key={workflow.id} value={workflow.id}>
              {workflow.name}
            </MenuItem>
          ))}
        </Select>
      ) : null}
    </FormControl>
  )
}
Example #9
Source File: Dropdown.tsx    From glific-frontend with GNU Affero General Public License v3.0 5 votes vote down vote up
Dropdown: React.SFC<DropdownProps> = (props) => {
  const { options, placeholder, field, helperText, disabled, form, fieldValue, fieldChange } =
    props;

  const { onChange, value, ...rest } = field;

  let optionsList = null;
  if (options) {
    optionsList = options.map((option: any) => (
      <MenuItem value={option.id} key={option.id}>
        {option.label ? option.label : option.name}
      </MenuItem>
    ));
  }

  return (
    <div className={styles.Dropdown} data-testid="dropdown">
      <FormControl
        variant="outlined"
        fullWidth
        error={form && form.errors[field.name] && form.touched[field.name]}
      >
        {placeholder ? (
          <InputLabel id="simple-select-outlined-label" data-testid="inputLabel">
            {placeholder}
          </InputLabel>
        ) : null}
        <Select
          onChange={(event) => {
            onChange(event);
            if (fieldChange) {
              fieldChange(event);
            }
          }}
          MenuProps={{
            classes: {
              paper: styles.Paper,
            },
          }}
          value={fieldValue !== undefined ? fieldValue : value}
          {...rest}
          label={placeholder !== '' ? placeholder : undefined}
          fullWidth
          disabled={disabled}
        >
          {optionsList}
        </Select>
        {form && form.errors[field.name] && form.touched[field.name] ? (
          <FormHelperText>{form.errors[field.name]}</FormHelperText>
        ) : null}
        {helperText ? (
          <FormHelperText className={styles.HelperText}>{helperText}</FormHelperText>
        ) : null}
      </FormControl>
    </div>
  );
}
Example #10
Source File: TableProp.tsx    From clearflask with Apache License 2.0 5 votes vote down vote up
renderHeaderCell(key: string | number, name?: string, description?: string) {
    return (
      <TableCell key={key} align='center' style={{ fontWeight: 'normal', width: this.props.width }} size='small'>
        {name && (<InputLabel shrink={false}>{name}</InputLabel>)}
        {description && (<FormHelperText>{description}</FormHelperText>)}
      </TableCell>
    );
  }
Example #11
Source File: AccountPage.tsx    From signer with Apache License 2.0 5 votes vote down vote up
renderCreateForm() {
    const formData = this.accountForm as CreateAccountFormData;
    return (
      <form
        className={this.props.classes.root}
        onSubmit={e => {
          e.preventDefault();
        }}
      >
        <Typography variant="h6" style={{ marginTop: '-1em' }}>
          Create Account
        </Typography>
        <TextFieldWithFormState
          aria-label="Input for setting name of key"
          autoFocus
          fullWidth
          label="Name"
          placeholder="Human Readable Alias"
          id="import-name"
          fieldState={this.accountForm.name}
        />
        <FormControl fullWidth>
          <InputLabel id="algo-select-lbl">Algorithm</InputLabel>
          <SelectFieldWithFormState
            fullWidth
            labelId="algo-select-lbl"
            fieldState={this.accountForm.algorithm}
            selectItems={[
              { value: 'ed25519', text: 'ED25519' },
              { value: 'secp256k1', text: 'SECP256k1' }
            ]}
          />
        </FormControl>
        <TextFieldWithFormState
          fullWidth
          InputProps={{ readOnly: true, disabled: true }}
          label="Public Key"
          id="create-public-key"
          value={formData.publicKey.$ ? formData.publicKey.$ : ''}
        />
        <FormControl fullWidth margin={'normal'}>
          <Button
            type="submit"
            className="mt-5"
            disabled={this.accountForm.submitDisabled}
            color="primary"
            variant="contained"
            onClick={() => {
              this.onCreateAccount();
            }}
          >
            Create
          </Button>
        </FormControl>
      </form>
    );
  }
Example #12
Source File: SearchType.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
SearchType = (props: SearchTypeProps) => {
  const { className, defaultValue, name, values = [] } = props;
  const classes = useStyles();
  const { types, setTypes } = useSearch();

  useEffectOnce(() => {
    if (!types.length) {
      if (defaultValue && Array.isArray(defaultValue)) {
        setTypes(defaultValue);
      } else if (defaultValue) {
        setTypes([defaultValue]);
      }
    }
  });

  const handleChange = (e: ChangeEvent<{ value: unknown }>) => {
    const value = e.target.value as string[];
    setTypes(value as string[]);
  };

  return (
    <FormControl
      className={className}
      variant="filled"
      fullWidth
      data-testid="search-typefilter-next"
    >
      <InputLabel className={classes.label} margin="dense">
        {name}
      </InputLabel>
      <Select
        multiple
        variant="outlined"
        value={types}
        onChange={handleChange}
        placeholder="All Results"
        renderValue={selected => (
          <div className={classes.chips}>
            {(selected as string[]).map(value => (
              <Chip
                key={value}
                label={value}
                className={classes.chip}
                size="small"
              />
            ))}
          </div>
        )}
      >
        {values.map((value: string) => (
          <MenuItem key={value} value={value}>
            <Checkbox checked={types.indexOf(value) > -1} />
            <ListItemText primary={value} />
          </MenuItem>
        ))}
      </Select>
    </FormControl>
  );
}
Example #13
Source File: DepartmentSelector.tsx    From graphql-ts-client with MIT License 5 votes vote down vote up
DepartmentSelector: FC<{
    value?: string,
    onChange: (value?: string) => void
}> = memo(({value, onChange}) => {

    const [data, setData] = useState<ModelType<typeof DEPARTMENT_LIST_FETCHER>>();
    const [error, setError] = useState<Error>();
    const [loading, setLoading] = useState(false);

    const findDepartments = useCallback(async () => {
        setLoading(true);
        setData(undefined);
        setError(undefined);
        try {
            const data = await execute(DEPARTMENT_LIST_FETCHER);
            setData(data);
        } catch (e) {
            setError(e);
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => {
        findDepartments();
    }, [findDepartments]);

    const onSelectChange = useCallback((e: ChangeEvent<{value: any}>) => {
        const v = e.target.value;
        onChange(v === "" ? undefined : v);
    }, [onChange]);

    return (
        <FormControl fullWidth={true}>
            <InputLabel>
                Department
                { loading && <CircularProgress size="1rem"/> }
                { error && <span style={{color:"red"}}>Load failed...</span>}
            </InputLabel>
            <Select 
            disabled={data === undefined} 
            error={false}
            value={value ?? ""}
            onChange={onSelectChange}
            fullWidth={true}>
                <MenuItem key="Nonde" value="">
                    <em>Unspecified</em>
                </MenuItem>
                {
                    data?.connection?.edges?.map(edge =>
                        <MenuItem key={edge.node.id} value={edge.node.id}>{edge.node.name}</MenuItem>
                    )
                }
            </Select>
        </FormControl>
    );
})
Example #14
Source File: HubSortDropdown.tsx    From dashboard with Apache License 2.0 5 votes vote down vote up
SortLabel = styled(InputLabel)`
  margin-top: -0.125rem;
  background-color: ${(props) => props.theme.palette.background.default};
  padding: 0.25rem;
`
Example #15
Source File: 23_CreateMeetingRoom.tsx    From flect-chime-sdk-demo with Apache License 2.0 5 votes vote down vote up
CreateMeetingRoom = () => {
    const { chimeClientState, setMessage, setStage } = useAppState();
    const [meetingName, setMeetingName] = useState(chimeClientState.meetingName || "");
    const [region, setRegion] = useState(DEFAULT_REGION);
    const [isLoading, setIsLoading] = useState(false);

    const classes = useStyles();

    const onCreateMeetingClicked = async () => {
        setIsLoading(true);
        try {
            await chimeClientState.createMeeting(meetingName, region);
            setMessage("Info", "Room created", [`room created, please join.`]);
            setIsLoading(false);
            setStage(STAGE.ENTRANCE);
        } catch (e: any) {
            console.log(e);
            setMessage("Exception", "Creating meeting room failed", [`room(${e.meetingName}) exist?: ${!e.created}`]);
            setIsLoading(false);
        }
    };

    const forms = (
        <>
            <div className={classes.loginField}>
                <CustomTextField onChange={(e) => setMeetingName(e.target.value)} label="meeting name" secret={false} height={20} fontsize={16} defaultValue={meetingName} autofocus />
                <FormControl className={classes.formControl}>
                    <InputLabel>Region</InputLabel>
                    <Select value={region} onChange={(e: any) => setRegion(e.target.value)}>
                        <MenuItem disabled value="Video">
                            <em>Region</em>
                        </MenuItem>
                        {Object.keys(AVAILABLE_AWS_REGIONS).map((key) => {
                            return (
                                <MenuItem value={key} key={key}>
                                    {AVAILABLE_AWS_REGIONS[key]}
                                </MenuItem>
                            );
                        })}
                    </Select>
                </FormControl>
            </div>
            <div style={{ display: "flex", justifyContent: "flex-end", marginRight: 0 }}>
                {isLoading ? (
                    <CircularProgress />
                ) : (
                    <Button variant="contained" color="primary" className={classes.submit} onClick={onCreateMeetingClicked} id="submit">
                        Create Meeting
                    </Button>
                )}
            </div>
        </>
    );

    const links = [
        {
            title: "Join Meeting",
            onClick: () => {
                setStage(STAGE.ENTRANCE);
            },
        },
        {
            title: "Sign out",
            onClick: () => {
                setStage(STAGE.SIGNIN);
            },
        },
    ];

    return (
        <>
            <Questionnaire avatorIcon={<MeetingRoom />} title="Create Meeting" forms={forms} links={links} />
        </>
    );
}
Example #16
Source File: TagFilterOperators.tsx    From frontend with Apache License 2.0 5 votes vote down vote up
TagInputComponent = (props: GridFilterInputValueProps) => {
  const { item, applyValue } = props;
  const { testRuns } = useTestRunState();

  const handleFilterChange = (event: any) => {
    applyValue({ ...item, value: event.target.value as string });
  };

  const filterOptions: Array<string> = Array.from(
    new Set(
      testRuns
        .map((item) => item.os)
        .concat(testRuns.map((item) => item.browser))
        .concat(testRuns.map((item) => item.device))
        .concat(testRuns.map((item) => item.viewport))
        .concat(testRuns.map((item) => item.customTags))
    )
  );

  return (
    <FormControl fullWidth>
      <InputLabel shrink id="tagFilter">
        Value
      </InputLabel>
      <Select
        id="tagFilter"
        native
        displayEmpty
        value={item.value}
        onChange={handleFilterChange}
      >
        <option aria-label="All" value="" />
        {filterOptions.map(
          (item) =>
            item && (
              <option key={item} value={item}>
                {item}
              </option>
            )
        )}
      </Select>
    </FormControl>
  );
}
Example #17
Source File: AdvancedSettings.tsx    From wonderland-frontend with MIT License 5 votes vote down vote up
function AdvancedSettings({ open, handleClose, slippage, onSlippageChange }: IAdvancedSettingsProps) {
    const [value, setValue] = useState(slippage);

    useEffect(() => {
        let timeount: any = null;
        clearTimeout(timeount);

        timeount = setTimeout(() => onSlippageChange(value), 1000);
        return () => clearTimeout(timeount);
    }, [value]);

    return (
        <Modal id="hades" open={open} onClose={handleClose} hideBackdrop>
            <Paper className="ohm-card ohm-popover">
                <div className="cross-wrap">
                    <IconButton onClick={handleClose}>
                        <SvgIcon color="primary" component={XIcon} />
                    </IconButton>
                </div>

                <p className="hades-title">Settings</p>

                <Box className="card-content">
                    <InputLabel htmlFor="slippage">
                        <p className="input-lable">Slippage</p>
                    </InputLabel>
                    <FormControl variant="outlined" color="primary" fullWidth>
                        <OutlinedInput
                            id="slippage"
                            value={value}
                            onChange={(e: any) => setValue(e.target.value)}
                            fullWidth
                            type="number"
                            className="bond-input"
                            endAdornment={
                                <InputAdornment position="end">
                                    <p className="percent">%</p>
                                </InputAdornment>
                            }
                        />
                        <div className="help-text">
                            <p className="text-bond-desc">Transaction may revert if price changes by more than slippage %</p>
                        </div>
                    </FormControl>
                </Box>
            </Paper>
        </Modal>
    );
}
Example #18
Source File: ProjectSelect.tsx    From frontend with Apache License 2.0 5 votes vote down vote up
ProjectSelect: FunctionComponent<{
  projectId?: string;
  onProjectSelect: (id: string) => void;
}> = ({ projectId, onProjectSelect }) => {
  const classes = useStyles();
  const { projectList, selectedProjectId } = useProjectState();
  const projectDispatch = useProjectDispatch();

  React.useEffect(() => {
    if (projectId && projectId !== selectedProjectId) {
      selectProject(projectDispatch, projectId);
    }
  }, [projectId, selectedProjectId, projectDispatch]);

  return (
    <React.Fragment>
      {projectList.length > 0 && (
        <FormControl className={classes.formControl}>
          <InputLabel id="projectSelect" shrink>
            Project
          </InputLabel>
          <Select
            id="project-select"
            labelId="projectSelect"
            className={classes.input}
            displayEmpty
            value={selectedProjectId ?? ""}
            onChange={(event) => onProjectSelect(event.target.value as string)}
          >
            <MenuItem value="" disabled>
              <em>Select project</em>
            </MenuItem>
            {projectList.map((project) => (
              <MenuItem key={project.id} value={project.id}>
                {project.name}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
      )}
    </React.Fragment>
  );
}
Example #19
Source File: AdvancedSettings.tsx    From rugenerous-frontend with MIT License 5 votes vote down vote up
function AdvancedSettings({
  open,
  handleClose,
  slippage,
  recipientAddress,
  onRecipientAddressChange,
  onSlippageChange,
}: IAdvancedSettingsProps) {
  const [value, setValue] = useState(slippage);

  useEffect(() => {
    let timeount: any = null;
    clearTimeout(timeount);

    timeount = setTimeout(() => onSlippageChange(value), 1000);
    return () => clearTimeout(timeount);
  }, [value]);

  return (
    <Modal id="hades" open={open} onClose={handleClose} hideBackdrop>
      <Paper className="ohm-card ohm-popover">
        <div className="cross-wrap">
          <IconButton onClick={handleClose}>
            <SvgIcon color="primary" component={XIcon} />
          </IconButton>
        </div>

        <p className="hades-title">Settings</p>

        <Box className="card-content">
          <InputLabel htmlFor="slippage">
            <p className="input-lable">Slippage</p>
          </InputLabel>
          <FormControl variant="outlined" color="primary" fullWidth>
            <OutlinedInput
              id="slippage"
              value={value}
              onChange={(e: any) => setValue(e.target.value)}
              fullWidth
              type="number"
              className="bond-input"
              endAdornment={
                <InputAdornment position="end">
                  <p className="percent">%</p>
                </InputAdornment>
              }
            />
            <div className="help-text">
              <p className="text-bond-desc">Transaction may revert if price changes by more than slippage %</p>
            </div>
          </FormControl>

          <InputLabel htmlFor="recipient">
            <p className="input-lable">Recipient Address</p>
          </InputLabel>
          <FormControl variant="outlined" color="primary" fullWidth>
            <OutlinedInput
              className="bond-input"
              id="recipient"
              value={recipientAddress}
              onChange={onRecipientAddressChange}
              type="text"
            />
            <div className="help-text">
              <p className="text-bond-desc">
                Choose recipient address. By default, this is your currently connected address
              </p>
            </div>
          </FormControl>
        </Box>
      </Paper>
    </Modal>
  );
}
Example #20
Source File: AdvancedSettings.tsx    From lobis-frontend with MIT License 5 votes vote down vote up
function AdvancedSettings({ open, handleClose, slippage, recipientAddress, onRecipientAddressChange, onSlippageChange }: IAdvancedSettingsProps) {
    return (
        <Modal id="hades" open={open} onClose={handleClose} hideBackdrop>
            <Paper className="ohm-card ohm-popover">
                <div className="cross-wrap">
                    <IconButton onClick={handleClose}>
                        <SvgIcon color="primary" component={XIcon} />
                    </IconButton>
                </div>

                <Box className="card-content">
                    <InputLabel htmlFor="slippage">
                        <p className="input-lable">Slippage</p>
                    </InputLabel>
                    <FormControl variant="outlined" color="primary" fullWidth>
                        <OutlinedInput
                            id="slippage"
                            value={slippage}
                            onChange={onSlippageChange}
                            fullWidth
                            type="number"
                            //@ts-ignore
                            max="100"
                            min="100"
                            className="bond-input"
                            endAdornment={
                                <InputAdornment position="end">
                                    <p className="percent">%</p>
                                </InputAdornment>
                            }
                        />
                        <div className="help-text">
                            <p className="text-bond-desc">Transaction may revert if price changes by more than slippage %</p>
                        </div>
                    </FormControl>
                </Box>
            </Paper>
        </Modal>
    );
}
Example #21
Source File: LoadModal.tsx    From neodash with Apache License 2.0 4 votes vote down vote up
NeoLoadModal = ({ loadDashboard, loadDatabaseListFromNeo4j, loadDashboardFromNeo4j, loadDashboardListFromNeo4j }) => {
    const [loadModalOpen, setLoadModalOpen] = React.useState(false);
    const [loadFromNeo4jModalOpen, setLoadFromNeo4jModalOpen] = React.useState(false);
    const [text, setText] = React.useState("");
    const [rows, setRows] = React.useState([]);
    const { driver } = useContext<Neo4jContextState>(Neo4jContext);
    const [dashboardDatabase, setDashboardDatabase] = React.useState("neo4j");
    const [databases, setDatabases] = React.useState(["neo4j"]);

    const handleClickOpen = () => {
        setLoadModalOpen(true);
    };

    const handleClose = () => {
        setLoadModalOpen(false);
    };


    const handleCloseAndLoad = () => {
        setLoadModalOpen(false);
        loadDashboard(text);
        setText("");
    };

    function handleDashboardLoadedFromNeo4j(result) {
        setText(result);
        setLoadFromNeo4jModalOpen(false);
    }

    const reader = new FileReader();
    reader.onload = async (e) => {
        setText(e.target.result);
    };

    const uploadDashboard = async (e) => {
        e.preventDefault();
        reader.readAsText(e.target.files[0]);
    }

    const columns = [
        { field: 'id', hide: true, headerName: 'ID', width: 150 },
        { field: 'date', headerName: 'Date', width: 200 },
        { field: 'title', headerName: 'Title', width: 270 },
        { field: 'author', headerName: 'Author', width: 160 },
        { field: 'version', headerName: 'Version', width: 95 },
        {
            field: 'load', headerName: 'Select', renderCell: (c) => {
                return <Button onClick={(e) => { loadDashboardFromNeo4j(driver, dashboardDatabase, c.id, handleDashboardLoadedFromNeo4j) }} style={{ float: "right", backgroundColor: "white" }} variant="contained" size="medium" endIcon={<PlayArrow />}>Select</Button>
            }, width: 120
        },
    ]


    return (
        <div>
            <ListItem button onClick={handleClickOpen}>
                <ListItemIcon>
                    <IconButton style={{ padding: "0px" }} >
                        <SystemUpdateAltIcon />
                    </IconButton>
                </ListItemIcon>
                <ListItemText primary="Load" />
            </ListItem>

            <Dialog maxWidth={"lg"} open={loadModalOpen == true} onClose={handleClose} aria-labelledby="form-dialog-title">
                <DialogTitle id="form-dialog-title">
                    <SystemUpdateAltIcon style={{
                        height: "30px",
                        paddingTop: "4px",
                        marginBottom: "-8px",
                        marginRight: "5px",
                        paddingBottom: "5px"
                    }} />   Load Dashboard
                    <IconButton onClick={handleClose} style={{ padding: "3px", float: "right" }}>
                        <Badge badgeContent={""} >
                            <CloseIcon />
                        </Badge>
                    </IconButton>

                </DialogTitle>
                <DialogContent style={{ width: "1000px" }}>
                    {/* <DialogContentText> Paste your dashboard file here to load it into NeoDash.</DialogContentText> */}
                    <div>
                        <Button
                            component="label"
                            onClick={(e) => {
                                loadDashboardListFromNeo4j(driver, dashboardDatabase, (result) => { setRows(result) });
                                setLoadFromNeo4jModalOpen(true);
                                loadDatabaseListFromNeo4j(driver, (result) => { setDatabases(result) });
                            }}
                            style={{ marginBottom: "10px", backgroundColor: "white" }}
                            color="default"
                            variant="contained"
                            size="medium"
                            endIcon={<StorageIcon />}>

                            Select From Neo4j
                        </Button>
                        <Button
                            component="label"
                            // onClick={(e)=>uploadDashboard(e)}
                            style={{ marginLeft: "10px", backgroundColor: "white", marginBottom: "10px" }}
                            color="default"
                            variant="contained"
                            size="medium"
                            endIcon={<PostAddIcon />}>
                            <input
                                type="file"
                                onChange={(e) => uploadDashboard(e)}
                                hidden
                            />
                            Select From File
                        </Button>

                        <Button onClick={(text.length > 0) ? handleCloseAndLoad : null}
                            style={{ color: text.length > 0 ? "white" : "lightgrey", float: "right", marginLeft: "10px", marginBottom: "10px", backgroundColor: text.length > 0 ? "green" : "white" }}
                            color="default"
                            variant="contained"
                            size="medium"
                            endIcon={<PlayArrow />}>
                            Load Dashboard
                        </Button>
                    </div>


                    <TextareaAutosize
                        style={{ minHeight: "500px", width: "100%", border: "1px solid lightgray" }}
                        className={"textinput-linenumbers"}
                        onChange={(e) => setText(e.target.value)}
                        value={text}
                        aria-label=""
                        placeholder="Select a dashboard first, then preview it here..." />

                </DialogContent>
                {/* <DialogActions> */}
                {/* </DialogActions> */}
            </Dialog>
            <Dialog maxWidth={"lg"} open={loadFromNeo4jModalOpen == true} onClose={(e) => { setLoadFromNeo4jModalOpen(false) }} aria-labelledby="form-dialog-title">
                <DialogTitle id="form-dialog-title">
                    Select From Neo4j
                    <IconButton onClick={(e) => { setLoadFromNeo4jModalOpen(false) }} style={{ padding: "3px", float: "right" }}>
                        <Badge badgeContent={""} >
                            <CloseIcon />
                        </Badge>
                    </IconButton>
                </DialogTitle>
                <DialogContent style={{ width: "900px" }}>
                    <DialogContentText>If dashboards are saved in your current database, choose a dashboard below.
                    </DialogContentText>

                    <div style={{ height: "380px", borderBottom: "1px solid lightgrey" }}>
                        <DataGrid
                            rows={rows}
                            columns={columns}

                            pageSize={5}
                            rowsPerPageOptions={[5]}
                            disableSelectionOnClick
                            components={{
                                ColumnSortedDescendingIcon: () => <></>,
                                ColumnSortedAscendingIcon: () => <></>,
                            }}
                        /></div>
                    <FormControl style={{ marginTop: "-58px", marginLeft: "10px" }}>
                        <InputLabel id="demo-simple-select-label">Database</InputLabel>
                        <Select
                            labelId="demo-simple-select-label"
                            id="demo-simple-select"
                            style={{ width: "150px" }}
                            value={dashboardDatabase}
                            onChange={(e) => {
                                setRows([]);
                                setDashboardDatabase(e.target.value);
                                loadDashboardListFromNeo4j(driver, e.target.value, (result) => {  setRows(result); });
                            }}
                        >
                            {databases.map(database => {
                                return <MenuItem value={database}>{database}</MenuItem>
                            })}
                        </Select>
                    </FormControl>
                </DialogContent>
            </Dialog>
        </div>
    );
}
Example #22
Source File: SQFormMultiSelect.tsx    From SQForm with MIT License 4 votes vote down vote up
function SQFormMultiSelect({
  children,
  isDisabled = false,
  label,
  name,
  onChange,
  size = 'auto',
  useSelectAll = true,
  toolTipPlacement = 'bottom',
  muiFieldProps = {},
  showTooltip = true,
  tooltipText,
}: SQFormMultiSelectProps): React.ReactElement {
  const classes = useStyles();

  const {setFieldValue} = useFormikContext();
  const [toolTipEnabled, setToolTipEnabled] = React.useState(true);
  const {
    formikField: {field},
    fieldState: {isFieldError, isFieldRequired},
    fieldHelpers: {handleBlur, HelperTextComponent},
  } = useForm<SQFormOption['value'][], unknown>({name});

  React.useEffect(() => {
    if (!children) {
      console.warn(getUndefinedChildrenWarning('SQFormMultiSelect', name));
    }

    if (field.value === undefined || field.value === null) {
      console.warn(getUndefinedValueWarning('SQFormMultiSelect', name));
    }
  }, [children, field.value, name]);

  const labelID = label.toLowerCase();
  const toolTipTitle = getToolTipTitle(field.value, children);

  const getIsSelectAllChecked = (value: SQFormOption['value'][]) =>
    value.includes('ALL');
  const getIsSelectNoneChecked = (value: SQFormOption['value'][]) =>
    value.includes('NONE');

  const getValues = (
    children: SQFormMultiSelectProps['children'],
    isSelectAllChecked: boolean,
    isSelectNoneChecked: boolean,
    value: SQFormOption['value'][]
  ) => {
    if (isSelectAllChecked) {
      return children?.map((option) => option.value);
    }

    if (isSelectNoneChecked) {
      return [];
    }

    return value;
  };

  const handleMultiSelectChange = (
    event: React.ChangeEvent<{name?: string; value: unknown}>,
    _child: ReactNode
  ) => {
    const value = event.target.value as unknown as SQFormOption['value'][];
    const isSelectAllChecked = getIsSelectAllChecked(value);
    const isSelectNoneChecked = getIsSelectNoneChecked(value);
    const values = getValues(
      children,
      isSelectAllChecked,
      isSelectNoneChecked,
      value
    );

    setFieldValue(name, values);
    onChange && onChange(event, value);
  };

  const toggleTooltip = () => {
    setToolTipEnabled(!toolTipEnabled);
  };

  /**
   * this handles scenarios where label and value are not the same,
   * e.g., if value is an "ID"
   */
  const getRenderValue = (selected: unknown) => {
    const getValue = (selectedValues: SQFormOption['value'][]) => {
      if (!selectedValues?.length) {
        return EMPTY_LABEL;
      }

      return selectedDisplayValue(selectedValues, children, name);
    };

    return getValue(selected as SQFormOption['value'][]);
  };

  const renderTooltip = () => {
    if (!showTooltip || !toolTipEnabled) {
      return '';
    }

    return tooltipText || toolTipTitle;
  };

  return (
    <Grid item sm={size}>
      <FormControl
        error={isFieldError}
        disabled={isDisabled}
        required={isFieldRequired}
        fullWidth={true}
      >
        <InputLabel shrink={true} id={labelID}>
          {label}
        </InputLabel>
        <Tooltip
          placement={toolTipPlacement}
          arrow={true}
          enterDelay={1000}
          leaveDelay={100}
          title={renderTooltip()}
        >
          <Select
            className={classes.selectHeight}
            multiple
            displayEmpty
            input={<Input disabled={isDisabled} name={name} />}
            value={(field.value as SQFormOption['value'][]) || []}
            onBlur={handleBlur}
            onChange={handleMultiSelectChange}
            fullWidth={true}
            labelId={labelID}
            renderValue={getRenderValue}
            MenuProps={MenuProps}
            onOpen={toggleTooltip}
            onClose={toggleTooltip}
            {...muiFieldProps}
          >
            {useSelectAll && (
              <MenuItem
                value={
                  children?.length === field.value?.length ? 'NONE' : 'ALL'
                }
              >
                <Checkbox checked={children?.length === field.value?.length} />
                <ListItemText
                  primary="Select All"
                  primaryTypographyProps={{variant: 'body2'}}
                />
              </MenuItem>
            )}
            {children?.map((option) => {
              return (
                <MenuItem key={`${name}_${option.value}`} value={option.value}>
                  <Checkbox checked={field.value?.includes(option.value)} />
                  <ListItemText
                    primary={option.label}
                    primaryTypographyProps={{variant: 'body2'}}
                  />
                </MenuItem>
              );
            })}
          </Select>
        </Tooltip>
        {!isDisabled && <FormHelperText>{HelperTextComponent}</FormHelperText>}
      </FormControl>
    </Grid>
  );
}
Example #23
Source File: Input.tsx    From glific-frontend with GNU Affero General Public License v3.0 4 votes vote down vote up
Input: React.SFC<InputProps> = ({ textArea = false, disabled = false, ...props }) => {
  const {
    field,
    form,
    helperText,
    type,
    togglePassword,
    endAdornmentCallback,
    emojiPicker,
    placeholder,
    editor,
    rows,
    endAdornment,
    inputProp,
    translation,
  } = props;

  let fieldType = type;
  let fieldEndAdorment = null;
  if (type === 'password') {
    // we should change the type to text if user has clicked on show password
    if (togglePassword) {
      fieldType = 'text';
    }
    fieldEndAdorment = (
      <InputAdornment position="end">
        <IconButton
          aria-label="toggle password visibility"
          data-testid="passwordToggle"
          onClick={endAdornmentCallback}
          edge="end"
        >
          {togglePassword ? (
            <Visibility classes={{ root: styles.Visibility }} />
          ) : (
            <VisibilityOff classes={{ root: styles.Visibility }} />
          )}
        </IconButton>
      </InputAdornment>
    );
  } else if (emojiPicker) {
    fieldEndAdorment = emojiPicker;
  } else if (type === 'otp') {
    fieldType = 'text';
    fieldEndAdorment = (
      <InputAdornment position="end">
        <IconButton
          aria-label="resend otp"
          data-testid="resendOtp"
          onClick={endAdornmentCallback}
          edge="end"
        >
          <p className={styles.Resend}>resend</p>{' '}
          <RefreshIcon classes={{ root: styles.ResendButton }} />
        </IconButton>
      </InputAdornment>
    );
  }

  let showError = false;
  if (form && form.errors[field.name] && form.touched[field.name]) {
    showError = true;
  }

  return (
    <>
      {translation && <div className={styles.Translation}>{translation}</div>}
      <div className={styles.Input} data-testid="input">
        <FormControl fullWidth error={showError}>
          <InputLabel variant="outlined" className={styles.Label} data-testid="inputLabel">
            {placeholder}
          </InputLabel>
          <OutlinedInput
            data-testid="outlinedInput"
            inputComponent={editor ? editor.inputComponent : undefined}
            inputProps={editor ? editor.inputProps : inputProp}
            type={fieldType}
            classes={{ multiline: styles.Multiline }}
            disabled={disabled}
            error={showError}
            multiline={textArea}
            rows={rows}
            className={styles.OutlineInput}
            label={placeholder}
            fullWidth
            {...field}
            endAdornment={endAdornment || fieldEndAdorment}
          />
          {form && form.errors[field.name] && form.touched[field.name] ? (
            <FormHelperText className={styles.DangerText}>{form.errors[field.name]}</FormHelperText>
          ) : null}
          {helperText && (
            <div id="helper-text" className={styles.HelperText}>
              {helperText}
            </div>
          )}
        </FormControl>
      </div>
    </>
  );
}
Example #24
Source File: StationSelect.tsx    From metro-fare with MIT License 4 votes vote down vote up
StationSelect = ({
  title,
  value,
  onChange,
}: {
  title: string;
  value: string;
  onChange: Function;
}) => {
  const { t: translate, i18n } = useTranslation();
  const [lineType, setLineType] = useState<LineType>(LineType.MRT_BLUE);
  const lineElementId = `${title}-line-native-required`;
  const selectElementId = `${title}-native-required`;
  const isStationAvailable = (station: Station) => station.lineType === lineType && !station.isNotAvailable
  const stationsName = STATIONS.filter(isStationAvailable);

  const handleLineTypeSelectChange = (value: string) => {
    setLineType(value as LineType);
    onChange("");
  };

  useEffect(() => {
    if (Object.values(BTS_SILOM_STATION_ID).find((btsId) => btsId === value)) {
      setLineType(LineType.BTS_SILOM);
    } else if (Object.values(BTS_SUKHUMVIT_STATION_ID).find((btsId) => btsId === value)) {
      setLineType(LineType.BTS_SUKHUMVIT);
    } else if (Object.values(ARL_STATION_ID).find((arlId) => arlId === value)) {
      setLineType(LineType.ARL);
    } else if (Object.values(BRT_STATION_ID).find((brtId) => brtId === value)) {
      setLineType(LineType.BRT);
    } else if (value.length !== 0) {
      setLineType(LineType.MRT_BLUE);
    }
  }, [value]);

  return (
    <section>
      <FormControl className="line-type-select" required variant="standard">
        <InputLabel htmlFor={lineElementId}>
          {translate("lineType.line")}
        </InputLabel>
        <Select
          native
          onChange={(e: any) => handleLineTypeSelectChange(e.target.value)}
          name={"Line"}
          value={lineType}
          inputProps={{
            id: lineElementId,
          }}
          variant="standard">
          <option value={"MRT_BLUE"}>{translate("lineType.mrtBlue")}</option>
          <option value={"BTS_SILOM"}>{translate("lineType.btsSilom")}</option>
          <option value={"BTS_SUKHUMVIT"}>{translate("lineType.btsSukhumvit")}</option>
          <option value={"ARL"}>{translate("lineType.arl")}</option>
          <option value={"BRT"}>{translate("lineType.brt")}</option>
        </Select>
        <FormHelperText>{translate("common.required")}</FormHelperText>
      </FormControl>
      <FormControl className="station-select" required variant="standard">
        <InputLabel htmlFor={selectElementId}>{title}</InputLabel>
        <Select
          native
          onChange={(e) => onChange(e.target.value)}
          name={title}
          value={value}
          inputProps={{
            id: selectElementId,
          }}
          variant="standard">
          <option value="" disabled></option>
          {stationsName.map((station: Station) => {
            const label = `(${station.id}) ${getStationName(station, i18n.language)}`;
            return (
              <option key={station.id} value={station.id}>
                {label}
              </option>
            );
          })}
        </Select>
        <FormHelperText>{translate("common.required")}</FormHelperText>
      </FormControl>
    </section>
  );
}
Example #25
Source File: CardViewFooter.tsx    From neodash with Apache License 2.0 4 votes vote down vote up
NeoCardViewFooter = ({ fields, settings, selection, type, showOptionalSelections, onSelectionUpdate }) => {
    /**
     * For each selectable field in the visualization, give the user an option to select them from the query output fields.
    */
    const selectableFields = REPORT_TYPES[type].selection;
    const selectables = (selectableFields) ? Object.keys(selectableFields) : [];
    const nodeColorScheme = settings && settings.nodeColorScheme ? settings.nodeColorScheme : "neodash";
    const hideSelections = settings && settings.hideSelections ? settings.hideSelections : false;

    if (!fields || fields.length == 0 || hideSelections) {
        return <div></div>
    }
    return (
        <CardActions style={{ position: "relative", paddingLeft: "15px", marginTop: "-5px", overflowX: "scroll" }} disableSpacing>
            {selectables.map((selectable, index) => {
                const selectionIsMandatory = (selectableFields[selectable]['optional']) ? false : true;

                // Creates the component for node property selections.
                if (selectableFields[selectable].type == SELECTION_TYPES.NODE_PROPERTIES) {
                    // Only show optional selections if we explicitly allow it.
                    if (showOptionalSelections || selectionIsMandatory) {
                        const fieldSelections = fields.map((field, i) => {
                            const nodeLabel = field[0];
                            const discoveredProperties = field.slice(1);
                            const properties = (discoveredProperties ? [...discoveredProperties].sort() : []).concat(["(label)", "(id)", "(no label)"]);
                            const totalColors = categoricalColorSchemes[nodeColorScheme] ? categoricalColorSchemes[nodeColorScheme].length : 0;
                            const color = totalColors > 0 ? categoricalColorSchemes[nodeColorScheme][i % totalColors] : "grey";
                            return <FormControl key={nodeLabel}>
                                <InputLabel style={{ paddingLeft: "10px" }} id={nodeLabel}>{nodeLabel}</InputLabel>
                                <Select labelId={nodeLabel}
                                    id={nodeLabel}
                                    className={'MuiChip-root'}
                                    style={{ backgroundColor: color, paddingLeft: 10, minWidth: 75, marginRight: 5 }}
                                    onChange={e => onSelectionUpdate(nodeLabel, e.target.value)}
                                    value={(selection && selection[nodeLabel]) ? selection[nodeLabel] : ""}>
                                    {/* Render choices */}
                                    {properties.length && properties.map && properties.map((field, index) => {
                                        return <MenuItem key={field} value={field}>
                                            {field}
                                        </MenuItem>
                                    })}
                                </Select>
                            </FormControl>;
                        });
                        return fieldSelections;
                    }
                }
                // Creates the selection for all other types of components
                if (selectableFields[selectable].type == SELECTION_TYPES.LIST ||
                    selectableFields[selectable].type == SELECTION_TYPES.NUMBER ||
                    selectableFields[selectable].type == SELECTION_TYPES.NUMBER_OR_DATETIME ||
                    selectableFields[selectable].type == SELECTION_TYPES.TEXT) {
                    if (selectionIsMandatory || showOptionalSelections) {
                        const sortedFields = fields ? [...fields].sort() : [];

                        const fieldsToRender = (selectionIsMandatory ? sortedFields : sortedFields.concat(["(none)"]));
                        return <FormControl key={index}>
                            <InputLabel id={selectable}>{selectableFields[selectable].label}</InputLabel>
                            <Select labelId={selectable}
                                id={selectable}
                                multiple={selectableFields[selectable].multiple}
                                style={{ minWidth: 120, marginRight: 20 }}
                                onChange={e => onSelectionUpdate(selectable, e.target.value)}
                                renderValue={(selected) => Array.isArray(selected) ? selected.join(', ') : selected}
                                value={
                                    (selection && selection[selectable]) ?
                                        (selectableFields[selectable].multiple && !Array.isArray(selection[selectable])) ? 
                                        [selection[selectable]] : 
                                        selection[selectable]
                                    : 
                                        (selectableFields[selectable].multiple) ? 
                                            (selection[selectable] && selection[selectable].length > 0 ? 
                                             selection[selectable][0] 
                                            : 
                                            [])
                                        : "(no data)"}>

                                {/* Render choices */}
                                {fieldsToRender.map((field) => {
                                    return <MenuItem key={field} value={field}>
                                        {selectableFields[selectable].multiple && Array.isArray(selection[selectable]) ?
                                            <Checkbox checked={selection[selectable].indexOf(field) > -1} /> :
                                            <></>
                                        }
                                        {field}
                                        {/* <ListItemText primary={field} /> */}
                                    </MenuItem>
                                })}
                            </Select>
                        </FormControl>
                    }
                }

            })
            }
        </CardActions >
    );
}
Example #26
Source File: minimax.tsx    From Figurify with Apache License 2.0 4 votes vote down vote up
export default function MinimaxPage(props: { size: 3 | 4 }) {
    const [board, setBoard] = useState(Array.from({length: props.size},
        () => Array.from({length: props.size},
            () => 0
        )
    ) as number[][]);
    const [player, setPlayer] = useState(1);
    const [result, setResult] = useState({} as resultFromGo);

    const [loading, setLoading] = useState(false);

    const [depth, setDepth] = useState(4);

    const [rich, setRich] = useState(true);

    useEffect(() => {
        fetchResult("t".repeat(props.size))();
    }, [board, rich, depth]);

    useEffect(() => {
        fetchResult("t".repeat(props.size))();
    }, []);

    function fetchResult(name_: string): () => Promise<void> {
        return async () => {
            setLoading(true);

            let res = await fetch(
                `/api/${name_}/${name_}`, {
                    body: JSON.stringify({
                        Board: board.flat(),
                        Player: player,
                        Depth: depth,
                        Rich: rich,
                    }),
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    method: 'POST'
                }
            );

            if (res.status >= 500) {
                console.error(await res.text());
                return;
            }

            let result = await res.json();

            //console.log(result);

            //console.log(loading);

            setLoading(false);
            setResult(result as resultFromGo);
        };
    }

    function toJSX(ele: resultFromGo, last: number = -1, key: number = 0, mode: number = player - 1) {
        return [
            <TreeItem key={key} nodeId={String(last++)} label=
                {
                    <Typography variant={"subtitle2"}>
                         <pre style={OpenSans}>
                             {`#${ele.Move + 1} | Score: ${ele.Score} (${ele.Children ? (mode === 1 ? "max" : "min") : "end of branch"})`}
                         </pre>
                    </Typography>
                }
            >
                {
                    ele.Children ?
                        ele.Children.sort((a, b) =>
                            (mode === 0 ? 1 : -1) * (b.Score - a.Score)
                        ).map(
                            (x, i) => {
                                let [v, l] = toJSX(x, last, i, mode ^ 1);
                                last = l as number;
                                return v;
                            }
                        )
                        : null
                }
            </TreeItem>
            , last];
    }

    function display() {
        let last = -1;
        return result.Children ?
            result.Children.sort((a, b) =>
                (player - 1 === 0 ? 1 : -1) * (b.Score - a.Score)
            ).map(
                (x, i) => {
                    let [v, l] = toJSX(x, last, i);
                    last = l as number;
                    return v;
                }
            )
            : null;
    }

    const handleChange = (event: ChangeEvent<{ value: unknown }>) => {
        setDepth(event.target.value as number);
    };

    const handleChangeRich = (event: ChangeEvent<HTMLInputElement>) => {
        setRich(event.target.checked as boolean);
    };

    return <div className="m-4">
        <div className={styles.inputDiv}>
            <br/>
            <br/>
            <TicTacToe size={props.size} onBoardChange={setBoard} onPlayerChange={setPlayer}/>

            <div className="text-center">
                <br/>
                <FormControlLabel
                    control={<Switch checked={rich} onChange={handleChangeRich} name="Rich Mode"/>}
                    label="Rich Mode"
                />
                <FormControl variant="filled" style={{width: "8rem", height: "6rem", marginRight: "1rem"}}>
                    <InputLabel id="depth selector">Depth</InputLabel>
                    <Select
                        labelId="depth selector"
                        value={depth}
                        onChange={handleChange}
                    >
                        <MenuItem value={1}>1</MenuItem>
                        <MenuItem value={2}>2</MenuItem>
                        <MenuItem value={3}>3</MenuItem>
                        <MenuItem value={4}>4</MenuItem>
                        <MenuItem value={5}>5</MenuItem>
                        <MenuItem value={6}>6</MenuItem>
                        <MenuItem value={9}>9 (Unbeatable)</MenuItem>
                    </Select>
                </FormControl>
                <Button onClick={
                    () => {
                        fetchResult("t".repeat(props.size))();
                    }
                } style={{...noBorder, height: "3.5rem"}} variant={"contained"}>
                    <Typography variant="subtitle2">
                        Analyze Position
                    </Typography>
                </Button>
            </div>
        </div>
        <div className={styles.resultCard}>
            <div className={styles.tree}>
                {
                    !loading ? <TreeView
                        defaultCollapseIcon={<ExpandMoreIcon/>}
                        defaultExpandIcon={<ChevronRightIcon/>}>
                        <FlipMove>
                            {
                                display()
                            }
                        </FlipMove>
                    </TreeView> : <Typography variant={"subtitle2"}>
                        Loading...
                    </Typography>
                }
            </div>

            <br/>
            <br/>

            <LinearProgressWithLabel value={result.Score}/>
        </div>
    </div>;
}
Example #27
Source File: SaveModal.tsx    From neodash with Apache License 2.0 4 votes vote down vote up
NeoSaveModal = ({ dashboard, connection, saveDashboardToNeo4j, loadDatabaseListFromNeo4j }) => {
    const [saveModalOpen, setSaveModalOpen] = React.useState(false);
    const [saveToNeo4jModalOpen, setSaveToNeo4jModalOpen] = React.useState(false);
    const [overwriteExistingDashboard, setOverwriteExistingDashboard] = React.useState(false);
    const [dashboardDatabase, setDashboardDatabase] = React.useState("neo4j");
    const [databases, setDatabases] = React.useState(["neo4j"]);

    const { driver } = useContext<Neo4jContextState>(Neo4jContext);

    useEffect(() => {
        loadDatabaseListFromNeo4j(driver, (result) => { setDatabases(result) });
    }, [])


    const handleClickOpen = () => {
        setSaveModalOpen(true);
    };

    const handleClose = () => {
        setSaveModalOpen(false);
    };

    const filteredDashboard = filterNestedDict(dashboard, ["fields", "settingsOpen", "advancedSettingsOpen", "collapseTimeout"]);
    const dashboardString = JSON.stringify(filteredDashboard, null, 2);
    const downloadDashboard = () => {
        const element = document.createElement("a");
        const file = new Blob([dashboardString], { type: 'text/plain' });
        element.href = URL.createObjectURL(file);
        element.download = "dashboard.json";
        document.body.appendChild(element); // Required for this to work in FireFox
        element.click();
    }

    return (
        <div>
            <ListItem button onClick={handleClickOpen}>
                <ListItemIcon>
                    <IconButton style={{ padding: "0px" }} >
                        <SaveIcon />
                    </IconButton>
                </ListItemIcon>
                <ListItemText primary="Save" />
            </ListItem>

            <Dialog maxWidth={"lg"} open={saveModalOpen == true} onClose={handleClose} aria-labelledby="form-dialog-title">
                <DialogTitle id="form-dialog-title">
                    <SaveIcon style={{
                        height: "30px",
                        paddingTop: "4px",
                        marginBottom: "-8px",
                        marginRight: "5px",
                        paddingBottom: "5px"
                    }} />
                    Save Dashboard

                    <IconButton onClick={handleClose} style={{ padding: "3px", float: "right" }}>
                        <Badge badgeContent={""} >
                            <CloseIcon />
                        </Badge>
                    </IconButton>
                </DialogTitle>
                <DialogContent style={{ width: "1000px" }}>
                    <Button
                        component="label"
                        onClick={(e) => { setSaveToNeo4jModalOpen(true) }}
                        style={{ backgroundColor: "white" }}
                        color="default"
                        variant="contained"
                        size="medium"
                        endIcon={<StorageIcon />}>
                        Save to Neo4j
                    </Button>
                    <Button
                        component="label"
                        onClick={downloadDashboard}
                        style={{ backgroundColor: "white", marginLeft: "10px" }}
                        color="default"
                        variant="contained"
                        size="medium"
                        endIcon={<GetAppIcon />}>
                        Save to File
                    </Button>
                    <br /><br />
                    <TextareaAutosize
                        style={{ minHeight: "500px", width: "100%", border: "1px solid lightgray" }}
                        className={"textinput-linenumbers"}
                        value={dashboardString}
                        aria-label=""
                        placeholder="Your dashboard JSON should show here" />
                </DialogContent>
                <DialogActions>

                </DialogActions>
            </Dialog>

            <Dialog maxWidth={"lg"} open={saveToNeo4jModalOpen == true} onClose={(e) => { setSaveToNeo4jModalOpen(false) }} aria-labelledby="form-dialog-title">
                <DialogTitle id="form-dialog-title">

                    Save to Neo4j

                    <IconButton onClick={(e) => { setSaveToNeo4jModalOpen(false) }} style={{ padding: "3px", float: "right" }}>
                        <Badge badgeContent={""} >
                            <CloseIcon />
                        </Badge>
                    </IconButton>
                </DialogTitle>
                <DialogContent style={{ width: "800px" }}>
                    <DialogContentText>This will save your current dashboard as a node to your active Neo4j database.
                        <br />Ensure you have write permissions to the database to use this feature.
                    </DialogContentText>

                    <TextareaAutosize
                        style={{ width: "100%", border: "1px solid lightgray" }}
                        className={"textinput-linenumbers"}
                        value={"{\n    title: '" + dashboard.title + "',\n" +
                            "    date: '" + new Date().toISOString() + "',\n" +
                            "    user: '" + connection.username + "',\n" +
                            "    content: " + "{...}" + "\n}"}
                        aria-label=""
                        placeholder="" />

                    <FormControl style={{ marginTop: "10px" }}>
                        <InputLabel id="demo-simple-select-label">Save to Database</InputLabel>


                        <Select
                            labelId="demo-simple-select-label"
                            id="demo-simple-select"
                            style={{ width: "150px" }}
                            value={dashboardDatabase}
                            onChange={(e) => setDashboardDatabase(e.target.value)}
                        >
                            {databases.map(database => {
                                return <MenuItem value={database}>{database}</MenuItem>
                            })}
                        </Select>

                    </FormControl>

                    <FormControl style={{ marginTop: "20px", marginLeft: "10px" }}>
                        <Tooltip title="Overwrite dashboard(s) with the same name." aria-label="">
                            <FormControlLabel
                                control={<Checkbox style={{ fontSize: "small", color: "grey" }} checked={overwriteExistingDashboard} onChange={e => setOverwriteExistingDashboard(!overwriteExistingDashboard)} name="overwrite" />}
                                label="Overwrite"
                            />
                        </Tooltip>
                    </FormControl>

                    <Button
                        component="label"
                        onClick={e => {
                            saveDashboardToNeo4j(driver, dashboardDatabase, dashboard, new Date().toISOString(), connection.username, overwriteExistingDashboard);
                            setSaveToNeo4jModalOpen(false);
                            setSaveModalOpen(false);
                        }}
                        style={{ backgroundColor: "white", marginTop: "20px", float: "right" }}
                        color="default"
                        variant="contained"
                        endIcon={<SaveIcon />}
                        size="medium">
                        Save
                    </Button>
                    <Button
                        component="label"
                        onClick={(e) => { setSaveToNeo4jModalOpen(false) }}
                        style={{ float: "right", marginTop: "20px", marginRight: "10px", backgroundColor: "white" }}
                        color="default"
                        variant="contained"
                        size="medium">
                        Cancel
                    </Button>
                </DialogContent>
                <DialogActions>

                </DialogActions>
            </Dialog>
        </div>
    );
}
Example #28
Source File: EditServerDialog.tsx    From shadowsocks-electron with GNU General Public License v3.0 4 votes vote down vote up
EditServerDialog: React.FC<EditServerDialogProps> = props => {
  const styles = useStyles();
  const { t } = useTranslation();
  const dispatch = useDispatch();

  const { open, onClose, defaultValues, onValues } = props;


  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.down("sm"));

  const enqueueSnackbar = (message: SnackbarMessage, options: Notification) => {
    dispatch(enqueueSnackbarAction(message, options))
  };

  const [values, setValues] = useState<Partial<Config>>(
    defaultValues ?? {
      timeout: 60,
      encryptMethod: "none",
      type: 'ss'
    }
  );

  useLayoutEffect(() => {
    setValues(
      defaultValues ?? {
        timeout: 60,
        encryptMethod: "none",
        type: 'ss'
      }
    );
  }, [defaultValues]);

  const handleValueChange = (
    key: keyof Config,
    value: boolean | string | number
  ) => {
    setValues({
      ...values,
      // [key]: e.target[attr || 'value'].trim()
      [key]: value
    });
  };

  const handleCancel = () => {
    onValues(null);
  };

  const handleAdd = () => {
    if (!values.serverHost) {
      enqueueSnackbar(t("invalid_server_address"), { variant: "warning" });
      return;
    }
    if (
      !(
        values.serverPort &&
        values.serverPort > 0 &&
        values.serverPort <= 65535
      )
    ) {
      enqueueSnackbar(t("invalid_server_port"), { variant: "warning" });
      return;
    }
    if (!values.password) {
      enqueueSnackbar(t("invalid_password"), { variant: "warning" });
      return;
    }
    if (!values.timeout) {
      enqueueSnackbar(t("invalid_timeout"), { variant: "warning" });
      return;
    }

    onValues(values as Config);
  };

  const [showPassword, setShowPassword] = useState(false);

  const handleClickShowPassword = () => {
    setShowPassword(v => !v);
  };

  const handleMouseDownPassword = (
    event: React.MouseEvent<HTMLButtonElement>
  ) => {
    event.preventDefault();
  };

  const isSSR = values.type === 'ssr';
  const isSS = values.type === 'ss';

  return (
    <StyledDialog
      fullScreen={fullScreen}
      open={open}
      onClose={onClose}
    >
      <AdaptiveAppBar className={fullScreen ? styles.appBar : styles.appBarRelative}>
        <Toolbar>
          <IconButton edge="start" color="inherit" onClick={handleCancel}>
            <CloseIcon />
          </IconButton>
          <Typography variant="h6" className={styles.title}>
            { t('edit_server') }
          </Typography>
          <Button color="inherit" onClick={handleAdd}>
            { t('save') }
          </Button>
        </Toolbar>
      </AdaptiveAppBar>
      <Container className={`${styles.container}`}>
        {fullScreen && <div className={`${styles.toolbar}`} />}
        <InputLabel required style={{ marginBottom: 0 }}>
          {t('server_type')}
        </InputLabel>
        <Select
          required
          label={t('server_type')}
          displayEmpty
          fullWidth
          value={values.type ?? "ss"}
          onChange={(e: any) => handleValueChange("type", e.target.value.trim())}
        >
          {serverTypes.map(serverType => (
            <MenuItem key={serverType} value={serverType}>
              {serverType}
            </MenuItem>
          ))}
        </Select>
        <TextField
          fullWidth
          label={t('remark')}
          value={values.remark ?? ""}
          onChange={e => handleValueChange("remark", e.target.value.trim())}
        />
        <TextField
          required
          fullWidth
          label={t('server_address')}
          value={values.serverHost ?? ""}
          onChange={e => handleValueChange("serverHost", e.target.value.trim())}
        />
        <TextField
          required
          fullWidth
          type="number"
          label={t('server_port')}
          value={values.serverPort ?? ""}
          onChange={e => handleValueChange("serverPort", e.target.value.trim())}
        />
        <FormControl required fullWidth>
          <InputLabel htmlFor="password">{t('password')}</InputLabel>
          <Input
            id="password"
            type={showPassword ? "text" : "password"}
            value={values.password ?? ""}
            onChange={e => handleValueChange("password", e.target.value.trim())}
            endAdornment={
              <InputAdornment position="end">
                <IconButton
                  onClick={handleClickShowPassword}
                  onMouseDown={handleMouseDownPassword}
                >
                  {showPassword ? <Visibility /> : <VisibilityOff />}
                </IconButton>
              </InputAdornment>
            }
          />
        </FormControl>
        <InputLabel required style={{ marginBottom: 0 }}>
          {t('encryption')}
        </InputLabel>
        <Select
          required
          label={t('encryption')}
          displayEmpty
          fullWidth
          value={values.encryptMethod ?? "none"}
          onChange={(e: any) => handleValueChange("encryptMethod", e.target.value.trim())}
        >
          {encryptMethods.map(method => (
            <MenuItem key={method} value={method}>
              {method}
            </MenuItem>
          ))}
        </Select>
        {
          isSSR && (
            <>
              <InputLabel required style={{ marginBottom: 0 }}>
                {t('protocol')}
              </InputLabel>
              <Select
                required
                label={t('protocol')}
                displayEmpty
                fullWidth
                value={values.protocol ?? "origin"}
                onChange={(e: any) => handleValueChange("protocol", e.target.value.trim())}
              >
                {protocols.map(protocol => (
                  <MenuItem key={protocol} value={protocol}>
                    {protocol}
                  </MenuItem>
                ))}
              </Select>
              <TextField
                fullWidth
                label={t('protocolParam')}
                value={values.protocolParam ?? ""}
                onChange={e => handleValueChange("protocolParam", e.target.value.trim())}
              />
            </>
          )
        }
        {
          isSSR && (
            <>
              <InputLabel required style={{ marginBottom: 0 }}>
                {t('obfs')}
              </InputLabel>
              <Select
                required
                label={t('obfs')}
                displayEmpty
                fullWidth
                value={values.obfs ?? "plain"}
                onChange={(e: any) => handleValueChange("obfs", e.target.value.trim())}
              >
                {obfs.map(value => (
                  <MenuItem key={value} value={value}>
                    {value}
                  </MenuItem>
                ))}
              </Select>
              <TextField
                fullWidth
                label={t('obfsParam')}
                value={values.obfsParam ?? ""}
                onChange={e => handleValueChange("obfsParam", e.target.value.trim())}
              />
            </>
          )
        }
        <TextField
          required
          fullWidth
          label={t('timeout')}
          value={values.timeout ?? 60}
          onChange={e => handleValueChange("timeout", e.target.value)}
        />
        <List>
          <ListItem>
            <ListItemText primary="TCP Fast Open" />
            <ListItemSecondaryAction>
              <Switch checked={!!values.fastOpen} edge="end" color="primary" onChange={(e) => handleValueChange('fastOpen', e.target.checked)} />
            </ListItemSecondaryAction>
          </ListItem>
          {
            isSS && (
              <ListItem>
                <ListItemText primary="TCP No Delay" />
                <ListItemSecondaryAction>
                  <Switch checked={!!values.noDelay} edge="end" color="primary" onChange={(e) => handleValueChange('noDelay', e.target.checked)} />
                </ListItemSecondaryAction>
              </ListItem>
            )
          }
          <ListItem>
            <ListItemText primary="UDP Relay" />
            <ListItemSecondaryAction>
              <Switch checked={!!values.udp} edge="end" color="primary" onChange={(e) => handleValueChange('udp', e.target.checked)} />
            </ListItemSecondaryAction>
          </ListItem>
        </List>
        <InputLabel style={{ marginBottom: 0 }}><TextWithTooltip text={t('plugin')} tooltip={t('readme')} /></InputLabel>
        {
          isSS && (
            <>
              <Select
                label={t('plugin')}
                displayEmpty
                fullWidth
                value={values.plugin ?? ""}
                onChange={(e: any) => handleValueChange("plugin", e.target.value.trim())}
              >
                <MenuItem key="none" value="">
                  <em>{t('none')}</em>
                </MenuItem>
                {plugins.map(plugin => (
                  <MenuItem key={plugin.name} value={plugin.name}>
                    {plugin.name} {plugin.tips ? `(${t(plugin.tips)})` : ""}
                  </MenuItem>
                ))}
              </Select>
              <TextField
                fullWidth
                multiline
                label={t('plugin_options')}
                value={values.pluginOpts ?? ""}
                onChange={e => handleValueChange("pluginOpts", e.target.value.trim())}
              />
            </>
          )
        }
      </Container>
    </StyledDialog>
  );
}
Example #29
Source File: App.tsx    From isitworththecost with MIT License 4 votes vote down vote up
function App() {
    const classes = useStyles()

    const [values, setValues] = React.useState({
        timeCost: { value: 25, unit: 'dollars', period: 'hour' },
        serviceCost: { value: 125, unit: 'dollars', period: 'month' },
        trainingTime: { value: 2, unit: 'hour', period: null },
        timeSavings: { value: 60, unit: 'min', period: 'day' },
        peopleCount: { value: 1, unit: null, period: null },

        savingPeriodCost: 'year',
        savingPeriodPeople: 'day',
        paybackPeriod: 'day',
    })

    const [costs, setCosts] = React.useState({
        employeePerYear: 0,
        servicePerYear: 0,
        trainingPerYear: 0,
        savingsPerYear: 0,
        freeTimePerYear: 0,
        paybackTimePerYear: 0,
    })

    const handleChange = (prop: string, key: string | null = null) => (
        event: ChangeEvent<HTMLInputElement | { value: unknown }>,
    ): void => {
        let val: any = event.target.value
        if (key === null) {
            setValues({
                ...values,
                [prop]: val,
            })
        } else {
            if (key === 'value' && (val < 0 || isNaN(val))) {
                val = 0
            }
            setValues({
                ...values,
                [prop]: {
                    //@ts-ignore
                    value: values[prop].value,
                    //@ts-ignore
                    unit: values[prop].unit,
                    //@ts-ignore
                    period: values[prop].period,
                    //@ts-ignore
                    [key]: val,
                },
            })
        }
    }

    useEffect(() => {
        // save this to state for now for ease of visibility
        const employeePerYear =
            values.timeCost.value * periodToYear(values.timeCost.period, 1)
        const servicePerYear =
            values.serviceCost.value *
            periodToYear(values.serviceCost.period, 1)

        // assumes amortisation period of 1 year
        const trainingPerYear =
            unitToYear(values.trainingTime.unit, values.trainingTime.value) *
            employeePerYear *
            values.peopleCount.value

        const freeTimePerYear =
            periodToYear(
                values.timeSavings.period,
                unitToYear(values.timeSavings.unit, values.timeSavings.value),
            ) * values.peopleCount.value

        const savingsPerYear =
            employeePerYear * freeTimePerYear - servicePerYear - trainingPerYear

        const paybackTimePerYear =
            (trainingPerYear + servicePerYear) / employeePerYear

        setCosts({
            employeePerYear,
            servicePerYear,
            trainingPerYear,
            savingsPerYear,
            freeTimePerYear,
            paybackTimePerYear,
        })
    }, [values])

    return (
        <Container maxWidth={'md'}>
            <Paper className={classes.root} variant={'outlined'}>
                <div className={classes.heading}>
                    <TopControls />
                    <Typography variant="h2" component="h1">
                        Is it worth the cost?
                    </Typography>
                    <Typography variant="h5" component="p" gutterBottom>
                        A simple check on whether purchasing a service is worth
                        the cost.
                    </Typography>
                </div>
                <Grid container>
                    <Grid item xs={12} md={6}>
                        <h2>Basics</h2>
                        <p>1. Cost of your time or an employees time.</p>
                        <FormControl
                            className={clsx(classes.margin, classes.textField)}
                            variant="outlined"
                        >
                            <InputLabel htmlFor="time-cost">
                                Time Cost
                            </InputLabel>
                            <OutlinedInput
                                id="time-cost"
                                value={values.timeCost.value}
                                type="number"
                                onChange={handleChange('timeCost', 'value')}
                                startAdornment={
                                    <InputAdornment position="start">
                                        <AttachMoneyIcon />
                                    </InputAdornment>
                                }
                                labelWidth={80}
                            />
                        </FormControl>
                        <FormControl
                            variant="outlined"
                            className={classes.margin}
                        >
                            <InputLabel htmlFor="time-cost-unit">
                                per
                            </InputLabel>
                            <Select
                                native
                                value={values.timeCost.period}
                                onChange={handleChange('timeCost', 'period')}
                                labelWidth={40}
                                inputProps={{
                                    name: 'per',
                                    id: 'time-cost-unit',
                                }}
                            >
                                <option value={'hour'}>hour</option>
                                <option value={'day'}>day</option>
                                <option value={'week'}>week</option>
                                <option value={'month'}>month</option>
                                <option value={'year'}>year</option>
                            </Select>
                        </FormControl>
                        <p>2. Cost of the service under consideration.</p>
                        <FormControl
                            className={clsx(classes.margin, classes.textField)}
                            variant="outlined"
                        >
                            <InputLabel htmlFor="service-cost">
                                Service Cost
                            </InputLabel>
                            <OutlinedInput
                                id="service-cost"
                                value={values.serviceCost.value}
                                type="number"
                                onChange={handleChange('serviceCost', 'value')}
                                startAdornment={
                                    <InputAdornment position="start">
                                        <AttachMoneyIcon />
                                    </InputAdornment>
                                }
                                labelWidth={95}
                            />
                        </FormControl>
                        <FormControl
                            variant="outlined"
                            className={classes.margin}
                        >
                            <InputLabel htmlFor="service-cost-period">
                                per
                            </InputLabel>
                            <Select
                                native
                                value={values.serviceCost.period}
                                onChange={handleChange('serviceCost', 'period')}
                                labelWidth={40}
                                inputProps={{
                                    name: 'per',
                                    id: 'service-cost-period',
                                }}
                            >
                                {/*<option value={'hour'}>hour</option>*/}
                                <option value={'day'}>day</option>
                                <option value={'week'}>week</option>
                                <option value={'month'}>month</option>
                                <option value={'year'}>year</option>
                            </Select>
                        </FormControl>
                        <p>
                            3. Estimate the training time required (one person).
                        </p>
                        <FormControl
                            fullWidth
                            className={clsx(classes.margin, classes.textField)}
                            variant="outlined"
                        >
                            <InputLabel htmlFor="training-time">
                                Training Time
                            </InputLabel>
                            <OutlinedInput
                                id="training-time"
                                value={values.trainingTime.value}
                                type="number"
                                onChange={handleChange('trainingTime', 'value')}
                                startAdornment={
                                    <InputAdornment position="start">
                                        <AccessTimeIcon />
                                    </InputAdornment>
                                }
                                labelWidth={105}
                            />
                        </FormControl>
                        <FormControl
                            variant="outlined"
                            className={classes.margin}
                        >
                            <Select
                                native
                                value={values.trainingTime.unit}
                                onChange={handleChange('trainingTime', 'unit')}
                                inputProps={{
                                    name: 'per',
                                    id: 'training-time-unit',
                                }}
                            >
                                <option value={'hour'}>hours</option>
                                <option value={'day'}>days</option>
                                <option value={'week'}>weeks</option>
                                <option value={'month'}>months</option>
                                {/*<option value={'year'}>years</option>*/}
                            </Select>
                        </FormControl>
                        <p>
                            4. Estimate the time this service will save (one
                            person).
                        </p>
                        <FormControl
                            className={clsx(classes.margin, classes.textField)}
                            variant="outlined"
                        >
                            <InputLabel htmlFor="time-savings">
                                Time Saved
                            </InputLabel>
                            <OutlinedInput
                                id="time-savings"
                                type="number"
                                value={values.timeSavings.value}
                                onChange={handleChange('timeSavings', 'value')}
                                startAdornment={
                                    <InputAdornment position="start">
                                        <AccessTimeIcon />
                                    </InputAdornment>
                                }
                                labelWidth={80}
                            />
                        </FormControl>
                        <FormControl
                            variant="outlined"
                            className={classes.margin}
                        >
                            <Select
                                native
                                value={values.timeSavings.unit}
                                onChange={handleChange('timeSavings', 'unit')}
                            >
                                <option value={'minute'}>minutes</option>
                                <option value={'hour'}>hours</option>
                                <option value={'day'}>days</option>
                                <option value={'week'}>weeks</option>
                                <option value={'month'}>months</option>
                            </Select>
                        </FormControl>
                        <FormControl
                            variant="outlined"
                            className={classes.margin}
                        >
                            <InputLabel htmlFor="time-savings-period">
                                per
                            </InputLabel>
                            <Select
                                id={'time-savings-period'}
                                native
                                value={values.timeSavings.period}
                                onChange={handleChange('timeSavings', 'period')}
                                labelWidth={40}
                            >
                                <option value={'hour'}>hour</option>
                                <option value={'day'}>day</option>
                                <option value={'week'}>week</option>
                                <option value={'month'}>month</option>
                                <option value={'year'}>year</option>
                            </Select>
                        </FormControl>
                        <p>5. Number of people using the service.</p>
                        <FormControl
                            className={clsx(classes.margin, classes.textField)}
                            variant="outlined"
                        >
                            <InputLabel htmlFor="people-count">
                                People
                            </InputLabel>
                            <OutlinedInput
                                id="people-count"
                                type="number"
                                value={values.peopleCount.value}
                                onChange={handleChange('peopleCount', 'value')}
                                startAdornment={
                                    <InputAdornment position="start">
                                        <EmojiPeopleIcon />
                                    </InputAdornment>
                                }
                                labelWidth={50}
                            />
                        </FormControl>
                    </Grid>
                    <Grid item xs={12} md={6}>
                        <Breakdown
                            values={values}
                            costs={costs}
                            handleChange={handleChange}
                        />
                    </Grid>
                </Grid>
            </Paper>
        </Container>
    )
}