@material-ui/core#Switch TypeScript Examples

The following examples show how to use @material-ui/core#Switch. 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: UserEdit.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
renderCategorySubscribeControl(category: Client.Category, isMe: boolean, user: Client.UserMe | Admin.UserAdmin) {
    if (!category.subscription) return null;

    const isSubscribed = user?.categorySubscriptions?.includes(category.categoryId);

    if (!isMe) {
      return user.browserPush ? this.props.t('subscribed') : this.props.t('not-subscribed');
    }

    return (
      <FormControlLabel
        control={(
          <Switch
            color='default'
            checked={!!isSubscribed}
            onChange={async (e, checked) => {
              const dispatcher = await this.props.server.dispatch();
              await dispatcher.categorySubscribe({
                projectId: this.props.server.getProjectId(),
                categoryId: category.categoryId,
                subscribe: !isSubscribed,
              });
            }}
          />
        )}
        label={(
          <FormHelperText component='span'>
            {isSubscribed ? this.props.t('subscribed') : this.props.t('not-subscribed')}
          </FormHelperText>
        )}
      />
    );
  }
Example #2
Source File: Settings.tsx    From SpaceEye with MIT License 6 votes vote down vote up
SettingsSwitch: React.FC<SettingsSwitchProps> = props => {
    const { label, isChecked, onChange } = props
    return (
        <FormControl component="fieldset">
            <FormControlLabel
                control={
                    <Switch
                        checked={isChecked}
                        onChange={(_, checked) => onChange(checked)}
                        name={label}
                        color="primary"
                    />
                }
                label={label}
                labelPlacement="top"
            />
        </FormControl>
    )
}
Example #3
Source File: SettingsNotifications.tsx    From twitch-live-extension with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
AntSwitch = withStyles(() => ({
    switchBase: {
        '&$checked': {
            color: blue[200],
            transform: 'translateX(21px)',
        },
        '&$checked + $track': {
            backgroundColor: blue[200],
        },
    },
    checked: {},
    track: {},
}))(Switch)
Example #4
Source File: Settings.tsx    From swap-ui with Apache License 2.0 6 votes vote down vote up
function CloseNewAccountsSwitch() {
  const styles = useStyles();
  const { isClosingNewAccounts, setIsClosingNewAccounts } = useSwapContext();

  return (
    <FormGroup style={{ display: "none" }} row>
      <FormControlLabel
        classes={{ label: styles.closeAccountSwitchLabel }}
        labelPlacement="start"
        style={{
          display: "flex",
          justifyContent: "space-between",
          marginLeft: 0,
          width: "100%",
        }}
        control={
          <Switch
            checked={isClosingNewAccounts}
            onChange={() => setIsClosingNewAccounts(!isClosingNewAccounts)}
            color="primary"
          />
        }
        label="Close new accounts"
      />
    </FormGroup>
  );
}
Example #5
Source File: toggle_switch_input.tsx    From jupyter-extensions with Apache License 2.0 6 votes vote down vote up
/** Material style toggle switch */
export function ToggleSwitch(props: LabelProps) {
  const { name, checked, label, onChange } = props;
  return (
    <StyledLabel
      control={
        <Switch
          checked={checked}
          onChange={onChange}
          name={name}
          color="default"
        />
      }
      label={label}
      className={css.primaryTextColor}
    />
  );
}
Example #6
Source File: Switch.tsx    From shadowsocks-electron with GNU General Public License v3.0 6 votes vote down vote up
AdaptiveSwitch = withStyles((theme: Theme) => (
  createStyles({
    switchBase: {
      color: theme.palette.secondary.light,
      '&$checked': {
        color: theme.palette.primary.light,
      },
      '&$checked + $track': {
        backgroundColor: theme.palette.primary.light,
      },
    },
    checked: {},
    track: {

    },
  })
))(Switch)
Example #7
Source File: Settings.tsx    From firetable with Apache License 2.0 6 votes vote down vote up
Settings = ({ config, handleChange }) => {
  return (
    <>
      <FormControlLabel
        control={
          <Switch
            checked={config.isArray}
            onChange={() => handleChange("isArray")(!Boolean(config.isArray))}
            name="isArray"
          />
        }
        label="Set as an array"
      />
    </>
  );
}
Example #8
Source File: Settings.tsx    From max-todos with MIT License 6 votes vote down vote up
Settings = () => {
  const { isDeleteConfirmation, changeDeleteConfirm } = useContext(
    DeleteConfirmContext
  )!;
  const { isDark, changeTheme } = useContext(ThemeContext)!;
  const { isSmallText, changeSmallText } = useContext(SmallTextContext)!;
  const matches = useMediaQuery("(max-width: 768px)");

  return (
    <>
      <Container>
        <h3>
          Dark Mode:
          <Switch onChange={changeTheme} checked={isDark} color="primary" />
        </h3>
        <h3>
          Small Text Mode:
          <Switch
            onChange={changeSmallText}
            checked={isSmallText}
            color="primary"
            disabled={matches}
          />
        </h3>
        <h3>
          Disable Delete Confirmation:
          <Switch
            onChange={changeDeleteConfirm}
            checked={isDeleteConfirmation}
            color="primary"
          />
        </h3>
      </Container>
    </>
  );
}
Example #9
Source File: PrioritizationControlsVoting.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
render() {
    return (
      <div className={this.props.classes.extraControls}>
        <FormControlLabel
          control={(
            <Switch
              color='primary'
              checked={!!this.state.votingEnableDownvote}
              onChange={this.handleChangeEnableDownvote.bind(this)}
            />
          )}
          label={<FormHelperText component='span'>Downvoting</FormHelperText>}
        />
      </div>
    );
  }
Example #10
Source File: AdvancedSettings.tsx    From backstage with Apache License 2.0 6 votes vote down vote up
export function AdvancedSettings() {
  const [value, setValue] = useLocalStorage<'on' | 'off'>(
    'advanced-option',
    'off',
  );

  const toggleValue = (ev: React.ChangeEvent<HTMLInputElement>) => {
    setValue(ev.currentTarget.checked ? 'on' : 'off');
  };

  return (
    <Grid container direction="row" spacing={3}>
      <Grid item xs={12} md={6}>
        <InfoCard title="Advanced settings" variant="gridItem">
          <List>
            <ListItem>
              <ListItemText
                primary="Advanced user option"
                secondary="An extra settings tab to further customize the experience"
              />
              <ListItemSecondaryAction>
                <Switch
                  color="primary"
                  value={value}
                  onChange={toggleValue}
                  name="advanced"
                />
              </ListItemSecondaryAction>
            </ListItem>
          </List>
        </InfoCard>
      </Grid>
    </Grid>
  );
}
Example #11
Source File: PrioritizationControlsExpressions.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
render() {
    return (
      <div className={this.props.classes.extraControls}>
        <FormControlLabel
          control={(
            <Switch
              color='primary'
              checked={!!this.state.expressionsLimitEmojis}
              onChange={this.handleChangeExpressionsLimitEmojis.bind(this)}
            />
          )}
          label={<FormHelperText component='span'>Limit available emojis</FormHelperText>}
        />
        <FormControlLabel
          control={(
            <Switch
              color='primary'
              checked={!!this.state.expressionsAllowMultiple}
              onChange={this.handleChangeExpressionsLimitSingle.bind(this)}
            />
          )}
          label={<FormHelperText component='span'>Allow selecting multiple</FormHelperText>}
        />
      </div>
    );
  }
Example #12
Source File: toggle.tsx    From backstage with Apache License 2.0 6 votes vote down vote up
export function Toggle({
  checked,
  setChecked,
  children,
}: PropsWithChildren<ToggleProps>) {
  const toggler = useCallback(() => {
    setChecked(!checked);
  }, [checked, setChecked]);

  return (
    <FormControlLabel
      control={<Switch checked={checked} onChange={toggler} />}
      label={children}
    />
  );
}
Example #13
Source File: PostCreateForm.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
renderEditNotify(
    draft: Partial<Admin.IdeaDraftAdmin>,
    selectedCategory?: Client.Category,
    FormControlLabelProps?: Partial<React.ComponentProps<typeof FormControlLabel>>,
    SwitchProps?: Partial<React.ComponentProps<typeof Switch>>,
  ): React.ReactNode | null {
    if (!this.showModOptions()
      || !selectedCategory?.subscription) return null;
    return (
      <FormControlLabel
        disabled={this.state.isSubmitting}
        control={(
          <Switch
            checked={!!draft.notifySubscribers}
            onChange={(e, checked) => this.setState({
              draftFieldNotifySubscribers: !draft.notifySubscribers,
              draftFieldNotifyTitle: undefined,
              draftFieldNotifyBody: undefined,
            })}
            color='primary'
            {...SwitchProps}
          />
        )}
        label='Notify all subscribers'
        {...FormControlLabelProps}
      />
    );
  }
Example #14
Source File: BatchBar.tsx    From homebase-app with MIT License 5 votes vote down vote up
BatchBar = ({isBatch, handleIsBatchChange, onClickAdd, items, activeItem, setActiveItem}: Props) => {
  return (
    <ProposalFormInput>
      <Grid container direction="row" alignItems={"center"}>
        <Grid item xs={6}>
          <Typography variant="subtitle2" color="textPrimary">
            Batch Transfer?
          </Typography>
        </Grid>
        <Grid item xs={6}>
          <SwitchContainer item xs={12} justify="flex-end">
            <Switch
              type="checkbox"
              onChange={handleIsBatchChange}
              checked={isBatch}
            />
          </SwitchContainer>
        </Grid>
      </Grid>
      {isBatch ? (
        <BatchBarContainer container direction="row" wrap="nowrap" style={{gap: 8}}>
          {items.map((_, index) => {
            return (
              <TransferActive
                item
                key={index}
                onClick={() => setActiveItem(index)}
                style={
                  Number(index + 1) === activeItem
                    ? {background: "#4BCF93"}
                    : undefined
                }
              >
                <Typography variant="subtitle2" color="textPrimary">
                  #{index + 1}
                </Typography>
              </TransferActive>
            );
          })}

          <AddButton
            onClick={onClickAdd}
          >
            +
          </AddButton>
        </BatchBarContainer>
      ) : null}
    </ProposalFormInput>
  )
}
Example #15
Source File: Switch.tsx    From halstack-react with Apache License 2.0 5 votes vote down vote up
DxcSwitch = ({
  defaultChecked,
  checked,
  value,
  label = "",
  labelPosition = "before",
  name = "",
  disabled = false,
  optional = false,
  onChange,
  margin,
  size = "fitContent",
  tabIndex = 0,
}: SwitchPropsType): JSX.Element => {
  const [switchId] = useState(`switch-${uuidv4()}`);
  const labelId = `label-${switchId}`;
  const [innerChecked, setInnerChecked] = useState(defaultChecked ?? false);
  const colorsTheme = useTheme();
  const translatedLabels = useTranslatedLabels();
  const backgroundType = useContext(BackgroundColorContext);

  const handlerSwitchChange = (event) => {
    if (checked === undefined) {
      const isChecked = event.target.checked ?? !innerChecked;
      setInnerChecked(isChecked);
      onChange?.(isChecked);
    } else onChange?.(!checked);
  };

  const labelComponent = (
    <LabelContainer
      id={labelId}
      labelPosition={labelPosition}
      onClick={!disabled && handlerSwitchChange}
      disabled={disabled}
      backgroundType={backgroundType}
    >
      {labelPosition === "before" ? (
        <>
          {label} {optional && <span>{translatedLabels.formFields.optionalLabel}</span>}
        </>
      ) : (
        <>
          {optional && <span>{translatedLabels.formFields.optionalLabel}</span>} {label}
        </>
      )}
    </LabelContainer>
  );

  return (
    <ThemeProvider theme={colorsTheme.switch}>
      <SwitchContainer
        margin={margin}
        disabled={disabled}
        labelPosition={labelPosition}
        size={size}
        backgroundType={backgroundType}
      >
        {labelPosition === "before" && labelComponent}
        <Switch
          checked={checked ?? innerChecked}
          inputProps={{
            name: name,
            "aria-labelledby": labelId,
            role: "switch",
            "aria-checked": checked ?? innerChecked,
            tabIndex: tabIndex,
          }}
          onChange={handlerSwitchChange}
          value={value}
          disabled={disabled}
          disableRipple
        />
        {labelPosition === "after" && labelComponent}
      </SwitchContainer>
    </ThemeProvider>
  );
}
Example #16
Source File: PixelmatchConfigForm.tsx    From frontend with Apache License 2.0 5 votes vote down vote up
PixelmatchConfigForm: React.FunctionComponent = () => {
  const [config, updateConfig] = useConfigHook<PixelmatchConfig>();

  return (
    <React.Fragment>
      <Tooltip
        title="Enable comparison of images with different sizes."
      >
        <FormControlLabel
          label="Allow diff dimensions"
          control={
            <Switch
              checked={config.allowDiffDimensions}
              onChange={(event, checked) =>
                updateConfig("allowDiffDimensions", checked)
              }
              color="primary"
              name="diffDimensionsFeature"
            />
          }
        />
      </Tooltip>
      <Tooltip
        title="Ignore detecting and ignoring anti-aliased pixels."
      >
        <FormControlLabel
          label="Ignore anti-aliasing"
          control={
            <Switch
              checked={config.ignoreAntialiasing}
              onChange={(event, checked) =>
                updateConfig("ignoreAntialiasing", checked)
              }
              color="primary"
              name="ignoreAntialiasing"
            />
          }
        />
      </Tooltip>
      <TextValidator
        name="threshold"
        validators={["minNumber:0", "maxNumber:1"]}
        errorMessages={["Enter greater than 0", "Enter less than 1"]}
        InputProps={{ inputProps: { min: 0, max: 1, step: 0.001 } }}
        margin="dense"
        id="threshold"
        label="Pixel diff threshold"
        helperText="The threshold of how much a pixel can deviate until it is detected as change (0-1)."
        type="number"
        fullWidth
        required
        value={config.threshold}
        onChange={(event) => {
          const value = (event.target as HTMLInputElement).value;
          updateConfig("threshold", parseFloat(value));
        }}
      />
    </React.Fragment>
  );
}
Example #17
Source File: OwnershipCard.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
OwnershipCard = (props: {
  variant?: InfoCardVariants;
  entityFilterKind?: string[];
  hideRelationsToggle?: boolean;
  relationsType?: string;
}) => {
  const { variant, entityFilterKind, hideRelationsToggle, relationsType } =
    props;
  const relationsToggle =
    hideRelationsToggle === undefined ? false : hideRelationsToggle;
  const classes = useStyles();
  const { entity } = useEntity();
  const isGroup = entity.kind === 'Group';
  const [getRelationsType, setRelationsType] = useState(
    relationsType || 'direct',
  );

  return (
    <InfoCard title="Ownership" variant={variant}>
      {!relationsToggle && (
        <List dense>
          <ListItem className={classes.list}>
            <ListItemText className={classes.listItemText} />
            <ListItemSecondaryAction
              className={classes.listItemSecondaryAction}
            >
              Direct Relations
              <Tooltip
                placement="top"
                arrow
                title={`${
                  getRelationsType === 'direct' ? 'Direct' : 'Aggregated'
                } Relations`}
              >
                <Switch
                  color="primary"
                  checked={getRelationsType !== 'direct'}
                  onChange={() =>
                    getRelationsType === 'direct'
                      ? setRelationsType('aggregated')
                      : setRelationsType('direct')
                  }
                  name="pin"
                  inputProps={{ 'aria-label': 'Ownership Type Switch' }}
                  disabled={!isGroup}
                />
              </Tooltip>
              Aggregated Relations
            </ListItemSecondaryAction>
          </ListItem>
        </List>
      )}
      <ComponentsGrid
        entity={entity}
        relationsType={getRelationsType}
        isGroup={isGroup}
        entityFilterKind={entityFilterKind}
      />
    </InfoCard>
  );
}
Example #18
Source File: UserEdit.tsx    From clearflask with Apache License 2.0 5 votes vote down vote up
renderBrowserPushControl(isMe: boolean, user: Client.UserMe | Admin.UserAdmin): React.ReactNode | null {
    if (!this.props.config || !user || (!this.props.config.users.onboarding.notificationMethods.browserPush && !user.browserPush)) {
      return null;
    }

    if (!isMe) {
      return user.browserPush ? this.props.t('receiving') : this.props.t('not-receiving');
    }

    const browserPushStatus = WebNotification.getInstance().getStatus();
    var browserPushEnabled = !!user.browserPush;
    var browserPushControlDisabled;
    var browserPushLabel;
    if (user.browserPush) {
      browserPushControlDisabled = false;
      browserPushLabel = this.props.t('enabled');
    } else {
      switch (browserPushStatus) {
        case WebNotificationStatus.Unsupported:
          browserPushControlDisabled = true;
          browserPushLabel = 'Not supported by your browser';
          break;
        case WebNotificationStatus.Denied:
          browserPushControlDisabled = true;
          browserPushLabel = 'You have declined access to notifications';
          break;
        default:
        case WebNotificationStatus.Available:
        case WebNotificationStatus.Granted:
          browserPushControlDisabled = false;
          browserPushLabel = this.props.t('disabled');
          break;
      }
    }

    return (
      <FormControlLabel
        control={(
          <Switch
            color='default'
            disabled={browserPushControlDisabled}
            checked={browserPushEnabled}
            onChange={(e, checked) => {
              if (checked) {
                WebNotification.getInstance().askPermission()
                  .then(r => {
                    if (r.type === 'success') {
                      this.props.server.dispatch().then(d => d.userUpdate({
                        projectId: this.props.server.getProjectId(),
                        userId: user.userId,
                        userUpdate: { browserPushToken: r.token },
                      }));
                    } else if (r.type === 'error') {
                      if (r.userFacingMsg) {
                        this.props.enqueueSnackbar(r.userFacingMsg || 'Failed to setup browser notifications', { variant: 'error', preventDuplicate: true });
                      }
                      this.forceUpdate();
                    }
                  });
              } else {
                this.props.server.dispatch().then(d => d.userUpdate({
                  projectId: this.props.server.getProjectId(),
                  userId: user.userId,
                  userUpdate: { browserPushToken: '' },
                }));
              }
            }}
          />
        )}
        label={<FormHelperText component='span' error={browserPushControlDisabled}>{browserPushLabel}</FormHelperText>}
      />
    );
  }
Example #19
Source File: TableCell.tsx    From firetable with Apache License 2.0 5 votes vote down vote up
export default function Checkbox({
  row,
  column,
  value,
  onSubmit,
  disabled,
}: IHeavyCellProps) {
  const classes = useStyles();
  const switchClasses = useSwitchStyles();

  let component = (
    <Switch
      checked={!!value}
      onChange={() => onSubmit(!value)}
      disabled={disabled}
      classes={switchClasses}
    />
  );

  if (column?.config?.confirmation)
    component = (
      <Confirmation
        message={{
          title: column.config.confirmation.title,
          body: column.config.confirmation.body.replace(
            /\{\{(.*?)\}\}/g,
            replacer(row)
          ),
        }}
        functionName="onChange"
      >
        {component}
      </Confirmation>
    );

  return (
    <FormControlLabel
      control={component}
      label={column.name}
      labelPlacement="start"
      className="cell-collapse-padding"
      classes={{ root: classes.root, label: classes.label }}
    />
  );
}
Example #20
Source File: Performance.tsx    From TidGi-Desktop with Mozilla Public License 2.0 5 votes vote down vote up
export function Performance(props: Required<ISectionProps>): JSX.Element {
  const { t } = useTranslation();

  const preference = usePreferenceObservable();

  return (
    <>
      <SectionTitle ref={props.sections.performance.ref}>{t('Preference.Performance')}</SectionTitle>
      <Paper elevation={0}>
        <List dense disablePadding>
          {preference === undefined ? (
            <ListItem>{t('Loading')}</ListItem>
          ) : (
            <>
              <ListItem>
                <ListItemText primary={t('Preference.HibernateAllUnusedWorkspaces')} secondary={t('Preference.HibernateAllUnusedWorkspacesDescription')} />
                <ListItemSecondaryAction>
                  <Switch
                    edge="end"
                    color="primary"
                    checked={preference.hibernateUnusedWorkspacesAtLaunch}
                    onChange={async (event) => {
                      await window.service.preference.set('hibernateUnusedWorkspacesAtLaunch', event.target.checked);
                    }}
                  />
                </ListItemSecondaryAction>
              </ListItem>

              <Divider />
              <ListItem>
                <ListItemText primary={t('Preference.hardwareAcceleration')} />
                <ListItemSecondaryAction>
                  <Switch
                    edge="end"
                    color="primary"
                    checked={preference.useHardwareAcceleration}
                    onChange={async (event) => {
                      await window.service.preference.set('useHardwareAcceleration', event.target.checked);
                      props.requestRestartCountDown();
                    }}
                  />
                </ListItemSecondaryAction>
              </ListItem>
            </>
          )}
        </List>
      </Paper>
    </>
  );
}
Example #21
Source File: List.tsx    From Demae with MIT License 5 votes vote down vote up
SKUListItem = ({ sku }: { sku: SKU }) => {
	const classes = useStyles();
	const [user] = useUser()
	const { productID, skuID } = useParams<{ productID?: string, skuID?: string }>()
	const currency = sku.currency
	const amount = sku.price || 0
	const price = new Intl.NumberFormat("ja-JP", { style: "currency", currency: currency }).format(amount)
	const imageURL = sku.imageURLs().length > 0 ? sku.imageURLs()[0] : undefined
	const [setProcessing] = useProcessing()
	const [setMessage] = useSnackbar()

	return (
		<Link className={classes.list} to={`/admin/products/public/${productID}/skus/${sku.id}`}>
			<Box>
				<Box padding={1} paddingY={2} style={{
					backgroundColor: skuID === sku.id ? "rgba(0, 0, 140, 0.03)" : "inherit"
				}}>
					<Grid container>
						<Grid item xs={1}>
						</Grid>
						<Grid item xs={2}>
							<Avatar variant="rounded" src={imageURL} >
								<ImageIcon />
							</Avatar>
						</Grid>
						<Grid item xs={9}>
							<Box display="flex" justifyContent="space-between">
								<Box>
									<Typography variant="subtitle1">{sku.name}</Typography>
									<Typography variant="body2">{price}</Typography>
								</Box>
								<Box>
									<Switch
										edge="end"
										onChange={async (e) => {
											e.preventDefault()
											setProcessing(true)
											if (!sku.isAvailable) {
												if (sku.inventory.type === "finite") {
													const snapshot = await sku.stocks.collectionReference.get()
													const count = snapshot.docs.reduce((prev, current) => {
														return prev + current.data()!["count"]
													}, 0)
													if (count <= 0) {
														setProcessing(false)
														setMessage("error", `To publish ${sku.name}, Add stock or change the inventory.`)
														return
													}
												}
											}
											sku.isAvailable = !sku.isAvailable
											await sku.save()
											setProcessing(false)
											setMessage("success", `${sku.name} is published`)
										}}
										checked={sku.isAvailable}
									/>
								</Box>
							</Box>

							<Box className={classes.tags}>
								{
									sku.tags.map((tag, index) => {
										return <Chip key={index} size="small" label={tag} />
									})
								}
							</Box>
						</Grid>
					</Grid>
				</Box>
				<Divider />
			</Box>
		</Link>
	)
}
Example #22
Source File: NotificationContent.tsx    From anchor-web-app with Apache License 2.0 5 votes vote down vote up
function NotificationContentBase({ className }: NotificationContentProps) {
  const { liquidationAlert, updateLiquidationAlert } = useJobs();

  const { focusVisible, ...switchClasses } = useSwitchStyle();
  const sliderClasses = useSliderStyle();

  const testNotifications = useCallback(() => {
    new Notification('Anchor Borrow Usage Notification', {
      body: 'Notifications have been enabled.',
    });
  }, []);

  return (
    <div className={className}>
      <h2>
        <NotificationsNone />
        <IconSpan>
          Notification{' '}
          <InfoTooltip>
            Currently notifications only support desktop browsers and require
            the webapp to be open in a tab
          </InfoTooltip>
        </IconSpan>
      </h2>

      <div className="switch">
        <p>Anchor Borrow Usage</p>
        <Switch
          focusVisibleClassName={focusVisible}
          classes={switchClasses}
          checked={liquidationAlert.enabled}
          onChange={({ target }: ChangeEvent<HTMLInputElement>) =>
            updateLiquidationAlert({
              ...liquidationAlert,
              enabled: target.checked,
            })
          }
        />
      </div>

      {liquidationAlert.enabled && (
        <Slider
          classes={sliderClasses}
          valueLabelDisplay="on"
          valueLabelFormat={valueLabelFormat}
          marks={sliderMarks}
          value={liquidationAlert.ratio * 100}
          min={notificationMin}
          max={notificationMax}
          onChange={(_: any, newValue: number) => {
            updateLiquidationAlert({
              ...liquidationAlert,
              ratio: newValue / 100,
            });
          }}
        />
      )}

      {liquidationAlert.enabled && (
        <ActionButton
          className="test-notifications"
          onClick={testNotifications}
        >
          Test Notifications
        </ActionButton>
      )}
    </div>
  );
}
Example #23
Source File: Downloads.tsx    From TidGi-Desktop with Mozilla Public License 2.0 5 votes vote down vote up
export function Downloads(props: Required<ISectionProps>): JSX.Element {
  const { t } = useTranslation();

  const preference = usePreferenceObservable();

  return (
    <>
      <SectionTitle ref={props.sections.downloads.ref}>{t('Preference.Downloads')}</SectionTitle>
      <Paper elevation={0}>
        <List dense disablePadding>
          {preference === undefined ? (
            <ListItem>{t('Loading')}</ListItem>
          ) : (
            <>
              <ListItem
                button
                onClick={() => {
                  window.service.native
                    .pickDirectory(preference.downloadPath)
                    .then(async (filePaths) => {
                      if (filePaths.length > 0) {
                        await window.service.preference.set('downloadPath', filePaths[0]);
                      }
                    })
                    .catch((error: Error) => {
                      console.log(error); // eslint-disable-line no-console
                    });
                }}>
                <ListItemText primary={t('Preference.DownloadLocation')} secondary={preference.downloadPath} />
                <ChevronRightIcon color="action" />
              </ListItem>
              <Divider />
              <ListItem>
                <ListItemText primary={t('Preference.AskDownloadLocation')} />
                <ListItemSecondaryAction>
                  <Switch
                    edge="end"
                    color="primary"
                    checked={preference.askForDownloadPath}
                    onChange={async (event) => {
                      await window.service.preference.set('askForDownloadPath', event.target.checked);
                    }}
                  />
                </ListItemSecondaryAction>
              </ListItem>
            </>
          )}
        </List>
      </Paper>
    </>
  );
}
Example #24
Source File: SideDrawerField.tsx    From firetable with Apache License 2.0 5 votes vote down vote up
export default function Checkbox({
  column,
  control,
  disabled,
}: ISideDrawerFieldProps) {
  const classes = useStyles();
  const fieldClasses = useFieldStyles();
  const switchClasses = useSwitchStyles();

  return (
    <Controller
      control={control}
      name={column.key}
      render={({ onChange, onBlur, value }) => {
        const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
          onChange(event.target.checked);
        };

        return (
          <ButtonBase
            className={clsx(fieldClasses.root, classes.root)}
            disabled={disabled}
          >
            <FormControlLabel
              control={
                <Switch
                  checked={value}
                  onChange={handleChange}
                  onBlur={onBlur}
                  disabled={disabled}
                  classes={switchClasses}
                />
              }
              label={column.name}
              labelPlacement="start"
              classes={{ root: classes.formControlLabel, label: classes.label }}
            />
          </ButtonBase>
        );
      }}
    />
  );
}
Example #25
Source File: Updates.tsx    From TidGi-Desktop with Mozilla Public License 2.0 5 votes vote down vote up
export function Updates(props: Required<ISectionProps>): JSX.Element {
  const { t } = useTranslation();

  const preference = usePreferenceObservable();
  const updaterMetaData = useUpdaterObservable();

  return (
    <>
      <SectionTitle ref={props.sections.updates.ref}>{t('Preference.Network')}</SectionTitle>
      <Paper elevation={0}>
        <List dense disablePadding>
          {preference === undefined || updaterMetaData === undefined ? (
            <ListItem>{t('Loading')}</ListItem>
          ) : (
            <>
              <ListItem
                button
                onClick={
                  updaterMetaData.status === IUpdaterStatus.updateAvailable
                    ? async () => await window.service.native.open(updaterMetaData.info?.latestReleasePageUrl ?? latestStableUpdateUrl)
                    : async () => await window.service.updater.checkForUpdates()
                }
                disabled={updaterMetaData.status === IUpdaterStatus.checkingForUpdate || updaterMetaData.status === IUpdaterStatus.downloadProgress}>
                {updaterMetaData.status !== undefined && (
                  <ListItemText
                    primary={t(`Updater.${updaterMetaData.status}`)}
                    secondary={getUpdaterMessage(updaterMetaData.status, updaterMetaData.info, t)}
                  />
                )}
                <ChevronRightIcon color="action" />
              </ListItem>
              <Divider />
              <ListItem>
                <ListItemText primary={t('Preference.ReceivePreReleaseUpdates')} />
                <ListItemSecondaryAction>
                  <Switch
                    edge="end"
                    color="primary"
                    checked={preference.allowPrerelease}
                    onChange={async (event) => {
                      await window.service.preference.set('allowPrerelease', event.target.checked);
                      await window.service.updater.checkForUpdates();
                    }}
                  />
                </ListItemSecondaryAction>
              </ListItem>
            </>
          )}
        </List>
      </Paper>
    </>
  );
}
Example #26
Source File: MonitoringDialog.tsx    From Pi-Tool with GNU General Public License v3.0 5 votes vote down vote up
MonitoringDialog: React.FC<MonitoringDialogProps> = ({ onClose, open }) => {
    const dispatch = useDispatch();
    const activeMetrics = useSelector((state: RootState) => state.monitoring.activeMetrics);
    const classes = useStyles();

    const metricList = Object.keys(activeMetrics).map((key, index) => {
        return (
            <ListItem key={index}>
                <ListItemIcon>
                    {metricLookup[key].icon}
                </ListItemIcon>
                <ListItemText id="switch-list-label-wifi" primary={metricLookup[key].label} />
                <ListItemSecondaryAction>
                    <Switch
                        edge="end"
                        onChange={(_event, checked) => dispatch(setMonitoringMetric(key, checked))}
                        checked={activeMetrics[key as MonitoringMetric].active}
                        inputProps={{ 'aria-labelledby': 'switch-list-label-wifi' }}
                    />
                </ListItemSecondaryAction>
            </ListItem>
        );
    });

    return (
        <Dialog aria-labelledby="simple-dialog-title" open={open} onClose={onClose}>
            <DialogTitle id="simple-dialog-title">
                <Typography variant="h5">
                    Select monitoring metrics
	      </Typography>
            </DialogTitle>
            <List className={classes.root}>
                {metricList}
            </List>
        </Dialog>
    );

}
Example #27
Source File: VariationsTab.tsx    From prompts-ai with MIT License 5 votes vote down vote up
export default function VariationsTab() {
    const styles = useStyles();
    const dispatch = useDispatch();

    const maxCompletions = useSelector(selectMaxVariations);
    const handleMaxVariationsChange = (event: React.ChangeEvent<{}>, value: number | number[]) => {
        dispatch(editMaxVariations(value as number));
    }

    const showPrompt = useSelector(selectShowPromptForVariations);
    const handlePromptSwitchChange = (event: React.ChangeEvent<{}>, value: boolean) => {
        dispatch(updateShowPromptForVariations(value));
    }

    return <Box>
        <Box mb={1}>
            <Card className={styles.instructionCard}>
                <CardContent>
                    <Typography variant="subtitle1">Variations</Typography>
                    <Typography variant="body2">
                        This is a tool to generate multiple completions from the same prompt. Use it to explore the variety
                        of GPT-3 completions and impact of parameters on them. If you like a completion, add it to the prompt
                        and GPT-3 will generate more similar completions.
                    </Typography>
                    <Box mt={1}>
                        <Typography id="max-variations-slider" gutterBottom>
                            How many samples to generate (impacts processing time):
                        </Typography>
                        <Slider
                            defaultValue={10}
                            value={maxCompletions}
                            onChange={handleMaxVariationsChange}
                            aria-labelledby="max-variations-slider"
                            valueLabelDisplay="auto"
                            step={1}
                            marks={[{
                                value: 1,
                                label: '0',
                            }, {
                                value: 15,
                                label: '15',
                            }]}
                            min={1}
                            max={15}
                        />
                    </Box>

                    <Grid container spacing={1} alignItems="center">
                        <Grid item><FetchVariationsButton/></Grid>
                        <Grid item><Button
                            onClick={() => dispatch(cleanVariations())}
                        >Clean all</Button></Grid>
                    </Grid>
                    <Grid container spacing={1} alignItems="center">
                        <Grid item><FormControlLabel
                            control={<Switch checked={showPrompt} onChange={handlePromptSwitchChange}
                                             name="variations-prompt-switch" color="primary"/>}
                            label="Show prompt"
                        /></Grid>
                    </Grid>
                </CardContent>
            </Card>
        </Box>
        <VariationsCollection/>
    </Box>;
}
Example #28
Source File: Property.tsx    From clearflask with Apache License 2.0 4 votes vote down vote up
render() {
    const prop = this.props.prop;
    const description = this.props.overrideDescription !== undefined ? this.props.overrideDescription : prop.description;
    const name = this.props.overrideName !== undefined ? this.props.overrideName : prop.name || prop.pathStr;
    const inputMinWidth = this.props.inputMinWidth !== undefined ? this.props.inputMinWidth : PropertyInputMinWidth;
    var marginTop = this.props.marginTop !== undefined ? this.props.marginTop : 30;
    var propertySetter;
    var shrink = (this.state.value !== undefined && this.state.value !== '') ? true : undefined;

    if (prop.hide && !this.props.unhide) {
      return null;
    }

    OUTER: switch (prop.type) {
      case ConfigEditor.PropertyType.Number:
      case ConfigEditor.PropertyType.Integer:
      case ConfigEditor.PropertyType.String:
        switch (prop.subType) {
          case ConfigEditor.PropSubType.Color:
            propertySetter = (
              <div style={{
                display: 'inline-flex',
                flexDirection: 'column',
              }}>
                <div ref={this.colorRef} style={{ position: 'relative' }}> {/* Div-wrapped so the absolutely positioned picker shows up in the right place */}
                  <MyColorPicker
                    preview
                    clearable={!prop.required}
                    label={!this.props.bare ? name : undefined}
                    name='color'
                    placeholder='#FFF'
                    defaultValue={prop.defaultValue}
                    value={this.state.value || ''}
                    onChange={color => this.propSet(color || undefined)}
                    error={!!prop.errorMsg}
                    InputLabelProps={{
                      shrink: shrink,
                      error: !!prop.errorMsg,
                    }}
                    TextFieldProps={{
                      variant: 'outlined',
                      size: 'small',
                      InputProps: {
                        readOnly: true,
                        style: {
                          minWidth: inputMinWidth,
                          width: this.props.width,
                        },
                        error: !!prop.errorMsg,
                      },
                      ...this.props.TextFieldProps,
                    }}
                  />
                </div>
                {(!this.props.bare && description || prop.errorMsg) && (<FormHelperText style={{ minWidth: inputMinWidth, width: this.props.width }} error={!!prop.errorMsg}>{prop.errorMsg || description}</FormHelperText>)}
              </div>
            );
            break OUTER;
          default:
          // Fall through to below
        }
        var fieldType;
        if (prop.type === ConfigEditor.PropertyType.String) {
          switch (prop.format) {
            case ConfigEditor.StringFormat.DateTime:
              fieldType = 'datetime-local';
              shrink = true;
              break;
            case ConfigEditor.StringFormat.Date:
            case ConfigEditor.StringFormat.Time:
              fieldType = prop.format;
              shrink = true;
              break;
            default:
              fieldType = 'text';
              break;
          }
        } else {
          fieldType = 'number';
        }
        const TextFieldCmpt = prop.subType === ConfigEditor.PropSubType.Rich
          ? RichEditor : TextField;
        const translatedValue = prop.subType === ConfigEditor.PropSubType.I18n
          && this.props.i18n.exists(this.state.value)
          && this.props.t(this.state.value)
          || undefined;
        propertySetter = (
          <>
            <TextFieldCmpt
              variant='outlined'
              size='small'
              id={prop.pathStr}
              label={!this.props.bare && name}
              {...({ iAgreeInputIsSanitized: true })}
              value={translatedValue || this.state.value || ''}
              onChange={e => this.propSet(e.target.value as never)}
              error={!!prop.errorMsg}
              placeholder={prop.placeholder !== undefined ? (prop.placeholder + '') : undefined}
              helperText={prop.errorMsg || (!this.props.bare && description)}
              margin='none'
              multiline={(prop.subType === ConfigEditor.PropSubType.Multiline
                || prop.subType === ConfigEditor.PropSubType.Rich) as any}
              type={fieldType}
              InputLabelProps={{
                shrink: shrink,
                error: !!prop.errorMsg,
              }}
              InputProps={{
                style: {
                  minWidth: inputMinWidth,
                  width: this.props.width,
                },
                readOnly: prop.subType === ConfigEditor.PropSubType.Emoji || prop.subType === ConfigEditor.PropSubType.Id,
                onFocus: prop.subType === ConfigEditor.PropSubType.KeyGen ? () => {
                  if (!this.state.value) this.propSet(randomUuid());
                } : undefined,
                endAdornment: prop.subType === ConfigEditor.PropSubType.KeyGen ? (
                  <InputAdornment position='end'>
                    <IconButton
                      aria-label='Re-generate key'
                      onClick={() => this.propSet(randomUuid())}
                    >
                      <KeyRefreshIcon fontSize='small' />
                    </IconButton>
                  </InputAdornment>
                ) : (prop.subType === ConfigEditor.PropSubType.Icon ? (
                  <InputAdornment position='end'>
                    <DynamicMuiIcon name={this.state.value || ''} />
                  </InputAdornment>
                ) : (prop.subType === ConfigEditor.PropSubType.I18n ? (
                  <InputAdornment position='end'>
                    <LanguageKeySelect
                      ns='app'
                      value={this.state.value}
                      setValue={value => this.propSet(value)}
                    />
                  </InputAdornment>
                ) : undefined)),
              }}
              FormHelperTextProps={{
                style: {
                  minWidth: inputMinWidth,
                  width: this.props.width,
                },
              }}
              {...{
                uploadImage: prop.subType === ConfigEditor.PropSubType.Rich
                  ? (file) => this.richEditorImageUploadRef.current!.uploadImage(file)
                  : undefined
              }}
              {...this.props.TextFieldProps}
            />
            {prop.subType === ConfigEditor.PropSubType.Rich && (
              <RichEditorImageUpload
                ref={this.richEditorImageUploadRef}
                server={this.props.server}
              />
            )}
          </>
        );
        if (prop.subType === ConfigEditor.PropSubType.Emoji) {
          propertySetter = (
            <Overlay
              isInsideMuiTable={this.props.isInsideMuiTable}
              popup={(
                <EmojiPicker
                  onSelect={emoji => this.propSet(((emoji as BaseEmoji).native) as never)}
                />
              )}
            >
              {propertySetter}
            </Overlay>
          );
        }
        break;
      case ConfigEditor.PageType:
        const link = !!this.props.pageClicked && (
          <div>
            <IconButton aria-label="Open" onClick={() => {
              this.props.pageClicked && this.props.pageClicked(prop.path);
            }}>
              <VisitPageIcon />
            </IconButton>
          </div>
        );
        const descriptionOrError = (description || prop.errorMsg)
          ? (<FormHelperText style={{ minWidth: inputMinWidth, width: this.props.width }} error={!!prop.errorMsg}>{prop.errorMsg || description}</FormHelperText>)
          : null;
        var content;
        if (prop.required) {
          content = (
            <>
              {descriptionOrError}
              {link}
            </>
          );
        } else {
          content = (
            <div>
              <div>
                <FormControlLabel
                  control={(
                    <Switch
                      checked={!!this.state.value}
                      onChange={(e, checked) => this.propSet(checked ? true : undefined)}
                      color='default'
                    />
                  )}
                  label={!!description && (<FormHelperText >{description}</FormHelperText>)}
                  style={{
                    width: this.props.width,
                    minWidth: inputMinWidth,
                  }}
                />
              </div>
              <Collapse in={this.state.value}>
                {link}
              </Collapse>
            </div>
          );
        }
        marginTop += 16;
        propertySetter = (
          <div>
            <InputLabel error={!!prop.errorMsg}>{name}</InputLabel>
            {content}
          </div>
        );
        break;
      case ConfigEditor.PropertyType.Boolean:
      case ConfigEditor.PropertyType.Enum:
        if (prop.required && prop.type === ConfigEditor.PropertyType.Boolean) {
          propertySetter = (
            <div>
              {!this.props.bare && (<InputLabel error={!!prop.errorMsg}>{name}</InputLabel>)}
              {(!this.props.bare && description || prop.errorMsg) && (<FormHelperText style={{ minWidth: inputMinWidth, width: this.props.width }} error={!!prop.errorMsg}>{prop.errorMsg || description}</FormHelperText>)}
              <div>
                <FormControlLabel
                  control={(
                    <Switch
                      checked={!!this.state.value}
                      onChange={(e, checked) => this.propSet(checked)}
                      color='default'
                    />
                  )}
                  label={!this.props.bare && (<FormHelperText component='span' error={!!prop.errorMsg}>
                    {!!this.state.value
                      ? (prop.trueLabel || 'Enabled')
                      : (prop.falseLabel || 'Disabled')}
                  </FormHelperText>)}
                  style={{
                    width: this.props.width,
                    minWidth: inputMinWidth,
                  }}
                />
              </div>
            </div>
          );
          break;
        }
        var items: ConfigEditor.EnumItem[];
        var currentItem;
        if (prop.type === ConfigEditor.PropertyType.Boolean) {
          items = [
            { name: 'Default', value: 'undefined' },
            { name: 'Enabled', value: 'true' },
            { name: 'Disabled', value: 'false' },
          ];
          if (this.state.value === undefined) {
            currentItem = items.find(item => item.value === 'undefined');
          } else if (this.state.value === true) {
            currentItem = items.find(item => item.value === 'true');
          } else if (this.state.value === false) {
            currentItem = items.find(item => item.value === 'false');
          }
        } else {
          items = prop.items;
          currentItem = items.find(item => item.value === this.state.value);
        }
        shrink = !!(this.state.value !== undefined && currentItem && currentItem.name);
        propertySetter = (
          <FormControl
            variant='outlined'
            size='small'
            style={{
              minWidth: inputMinWidth,
              width: this.props.width,
            }}
          >
            {!this.props.bare && (<InputLabel error={!!prop.errorMsg} shrink={shrink}>{name}</InputLabel>)}
            <Select
              label={!this.props.bare ? name : undefined}
              value={this.state.value !== undefined && currentItem.value ? currentItem.value : ''}
              onChange={e => {
                if (prop.type === ConfigEditor.PropertyType.Boolean) {
                  switch (e.target.value) {
                    case 'undefined':
                      this.propSet(undefined as never)
                      break;
                    case 'true':
                      this.propSet(true as never)
                      break;
                    case 'false':
                      this.propSet(false as never)
                      break;
                  }
                } else {
                  this.propSet((e.target.value) as never)
                }
              }}
              error={!!prop.errorMsg}
            >
              {items.map((item, index) => (
                <MenuItem key={item.name} value={item.value || ''}>{item.value === 'undefined'
                  ? (<em>{item.name}</em>)
                  : item.name
                }</MenuItem>
              ))}
            </Select>
            {(!this.props.bare && description || prop.errorMsg) && (<FormHelperText style={{ minWidth: inputMinWidth, width: this.props.width }} error={!!prop.errorMsg}>{prop.errorMsg || description}</FormHelperText>)}
          </FormControl>
        );
        break;
      case ConfigEditor.PageGroupType:
      case ConfigEditor.PropertyType.Array:
        if (prop.type === ConfigEditor.PropertyType.Array && prop.subType === ConfigEditor.PropSubType.Language) {
          const values: Label[] = [];
          const options: Label[] = [];
          const selected = new Set((prop.childProperties || []).map(childProp => (childProp as ConfigEditor.StringProperty).value));
          supportedLanguages.forEach(lang => {
            const label = { label: lang.label, value: lang.code };
            options.push(label);
            if (selected.has(lang.code)) {
              values.push(label);
            }
          });
          propertySetter = (
            <SelectionPicker
              TextFieldProps={{
                variant: 'outlined',
                size: 'small',
                ...this.props.TextFieldProps,
              }}
              label={this.props.bare ? undefined : name}
              helperText={this.props.bare ? undefined : description}
              placeholder={prop.placeholder !== undefined ? (prop.placeholder + '') : undefined}
              errorMsg={prop.errorMsg}
              value={values}
              options={options}
              isMulti
              clearOnBlur
              width={this.props.width || 'max-content'}
              minWidth={inputMinWidth}
              onValueChange={labels => prop
                .setRaw(labels.map(label => label.value))}
              {...this.props.SelectionPickerProps}
            />
          );
        } else if (prop.type === ConfigEditor.PropertyType.Array && prop.childType === ConfigEditor.PropertyType.Enum && prop.childEnumItems && prop.required && prop.uniqueItems) {
          const values: Label[] = [];
          const options: Label[] = [];
          const enumValues = new Set((prop.childProperties || []).map(childProp => (childProp as ConfigEditor.EnumProperty)
            .value));
          prop.childEnumItems.forEach(enumItem => {
            const label = { label: enumItem!.name, value: enumItem!.value };
            options.push(label);
            if (enumValues.has(enumItem.value)) {
              values.push(label);
            }
          });
          propertySetter = (
            <SelectionPicker
              TextFieldProps={{
                variant: 'outlined',
                size: 'small',
                ...this.props.TextFieldProps,
              }}
              label={this.props.bare ? undefined : name}
              helperText={this.props.bare ? undefined : description}
              placeholder={prop.placeholder !== undefined ? (prop.placeholder + '') : undefined}
              errorMsg={prop.errorMsg}
              value={values}
              options={options}
              isMulti
              clearOnBlur
              width={this.props.width || 'max-content'}
              minWidth={inputMinWidth}
              onValueChange={labels => prop
                .setRaw(labels.map(label => label.value))}
              {...this.props.SelectionPickerProps}
            />
          );
        } else {
          propertySetter = (
            <TableProp
              key={prop.key}
              server={this.props.server}
              data={prop}
              errorMsg={prop.errorMsg}
              label={name}
              helperText={description}
              width={this.props.width}
              pageClicked={this.props.pageClicked}
              bare={this.props.bare}
              {...this.props.TablePropProps}
            />
          );
        }
        break;
      case ConfigEditor.PropertyType.Object:
        const subProps = (
          <Collapse mountOnEnter in={this.state.value} style={{ marginLeft: '30px' }}>
            {prop.childProperties && prop.childProperties
              .filter(childProp => !childProp.hide)
              .map(childProp => (
                <Property {...this.props} bare={false} key={childProp.key} prop={childProp} />
              ))
            }
          </Collapse>
        );
        const enableObject = !prop.required && (
          <div>
            <FormControlLabel
              control={(
                <Switch
                  checked={!!this.state.value}
                  onChange={(e, checked) => this.propSet(checked ? true : undefined)}
                  color='default'
                />
              )}
              label={!this.props.bare && (<FormHelperText style={{ minWidth: inputMinWidth, width: this.props.width }} error={!!prop.errorMsg}>{!!this.state.value ? 'Enabled' : 'Disabled'}</FormHelperText>)}
              style={{
                marginBottom: '-10px',
                width: this.props.width,
                minWidth: inputMinWidth,
              }}
            />
          </div>
        );
        marginTop += 16;
        propertySetter = (
          <div style={{ marginBottom: '10px' }}>
            {!this.props.bare && (<InputLabel error={!!prop.errorMsg}>{name}</InputLabel>)}
            {(!this.props.bare && description || prop.errorMsg) && (<FormHelperText style={{ minWidth: inputMinWidth, width: this.props.width }} error={!!prop.errorMsg}>{prop.errorMsg || description}</FormHelperText>)}
            {enableObject}
            {subProps}
          </div>
        );
        break;
      case ConfigEditor.PropertyType.Link:
      case ConfigEditor.PropertyType.LinkMulti:
        const onValueChange = labels => {
          if (prop.type === ConfigEditor.PropertyType.LinkMulti) {
            this.propSet(new Set<string>(labels.map(o => o.value)));
          } else {
            this.propSet(labels.length === 0 ? undefined : labels[0].value);
          }
        };
        const onValueCreate = prop.allowCreate ? prop.create.bind(this) : undefined;
        const values: Label[] = [];
        const options: Label[] = [];
        prop.getOptions()
          .forEach(o => {
            options.push({
              label: o.name,
              filterString: o.name,
              value: o.id,
              color: o.color,
            });
          });
        if (this.state.value !== undefined) {
          (prop.type === ConfigEditor.PropertyType.Link
            ? [prop.getOptions().find(o => o.id === this.state.value)]
              .filter(o => o !== undefined)
            : prop.getOptions().filter(o => (this.state.value as Set<string>).has(o.id)))
            .forEach(o => {
              values.push({
                label: o!.name,
                value: o!.id,
                color: o!.color,
              });
            })
        }
        propertySetter = (
          <SelectionPicker
            TextFieldProps={{
              variant: 'outlined',
              size: 'small',
              ...this.props.TextFieldProps,
            }}
            disableInput={!prop.allowCreate}
            disableClearable={prop.required}
            label={this.props.bare ? undefined : name}
            helperText={this.props.bare ? undefined : description}
            placeholder={prop.placeholder !== undefined ? (prop.placeholder + '') : undefined}
            errorMsg={prop.errorMsg}
            value={values}
            options={options}
            showTags
            bareTags={prop.type === ConfigEditor.PropertyType.Link}
            isMulti={prop.type === ConfigEditor.PropertyType.LinkMulti}
            width={this.props.width || 'max-content'}
            minWidth={inputMinWidth}
            onValueChange={onValueChange}
            onValueCreate={onValueCreate}
            {...this.props.SelectionPickerProps}
          />
        );
        break;
      default:
        throw Error(`Unknown property type ${prop['type']}`);
    }

    if (!propertySetter) {
      return null;
    }

    propertySetter = (
      <div style={{ marginTop: this.props.bare ? undefined : marginTop + 'px' }}>
        {propertySetter}
      </div>
    );

    propertySetter = (
      <UpgradeWrapper
        propertyPath={this.props.prop.path}
      >
        {propertySetter}
      </UpgradeWrapper>
    );

    return propertySetter;
  }
Example #29
Source File: chart-filters.tsx    From backstage with Apache License 2.0 4 votes vote down vote up
export function ChartFilters(props: ChartFiltersProps) {
  const {
    analysis,
    cicdConfiguration,
    initialFetchFilter,
    currentFetchFilter,
    onChangeFetchFilter,
    updateFetchFilter,
    initialViewOptions,
    onChangeViewOptions,
  } = props;

  const classes = useStyles();

  const [internalRef] = useState<InternalRef>({ first: true });

  const [useNowAsToDate, setUseNowAsToDate] = useState(true);
  const [toDate, setToDate] = useState(initialFetchFilter.toDate);
  const [fromDate, setFromDate] = useState(initialFetchFilter.fromDate);

  const [branch, setBranch] = useState(initialFetchFilter.branch);

  const statusValues: ReadonlyArray<StatusSelection> =
    cicdConfiguration.availableStatuses;
  const [selectedStatus, setSelectedStatus] = useState(
    initialFetchFilter.status,
  );

  const [viewOptions, setViewOptions] = useState(initialViewOptions);

  const setLowercaseNames = useCallback(
    (lowercaseNames: boolean) => {
      setViewOptions(old => ({ ...old, lowercaseNames }));
    },
    [setViewOptions],
  );

  const setNormalizeTimeRange = useCallback(
    (normalizeTimeRange: boolean) => {
      setViewOptions(old => ({ ...old, normalizeTimeRange }));
    },
    [setViewOptions],
  );

  const setHideLimit = useCallback(
    (value: number) => {
      setViewOptions(old => ({ ...old, hideLimit: value }));
    },
    [setViewOptions],
  );

  const setCollapseLimit = useCallback(
    (value: number) => {
      setViewOptions(old => ({ ...old, collapsedLimit: value }));
    },
    [setViewOptions],
  );

  const setChartType = useCallback(
    (statusType: FilterStatusType, chartTypes: ChartTypes) => {
      setViewOptions(old => ({
        ...old,
        chartTypes: { ...old.chartTypes, [statusType]: chartTypes },
      }));
    },
    [setViewOptions],
  );
  const setChartTypeSpecific = useMemo(
    () =>
      Object.fromEntries(
        statusTypes.map(
          status =>
            [
              status,
              (chartTypes: ChartTypes) => setChartType(status, chartTypes),
            ] as const,
        ),
      ),
    [setChartType],
  );

  useEffect(() => {
    onChangeViewOptions(viewOptions);
  }, [onChangeViewOptions, viewOptions]);

  useEffect(() => {
    if (internalRef.first) {
      // Skip calling onChangeFetchFilter first time
      internalRef.first = false;
      return;
    }
    onChangeFetchFilter({
      toDate,
      fromDate,
      branch,
      status: selectedStatus,
    });
  }, [
    internalRef,
    toDate,
    fromDate,
    branch,
    selectedStatus,
    onChangeFetchFilter,
  ]);

  const toggleUseNowAsDate = useCallback(() => {
    setUseNowAsToDate(!useNowAsToDate);
    if (!DateTime.fromJSDate(toDate).hasSame(DateTime.now(), 'day')) {
      setToDate(new Date());
    }
  }, [useNowAsToDate, toDate]);

  const hasFetchFilterChanges = useMemo(
    () =>
      !currentFetchFilter ||
      !isSameChartFilter(
        {
          toDate,
          fromDate,
          branch,
          status: selectedStatus,
        },
        currentFetchFilter,
      ),
    [toDate, fromDate, branch, selectedStatus, currentFetchFilter],
  );

  const updateFilter = useCallback(() => {
    updateFetchFilter({
      toDate,
      fromDate,
      branch,
      status: selectedStatus,
    });
  }, [toDate, fromDate, branch, selectedStatus, updateFetchFilter]);

  const inrefferedStatuses = analysis?.statuses ?? selectedStatus;

  return (
    <MuiPickersUtilsProvider utils={LuxonUtils}>
      <Card className={classes.rootCard}>
        <CardHeader
          action={
            <Button
              size="small"
              color="secondary"
              variant="contained"
              onClick={updateFilter}
              disabled={!hasFetchFilterChanges}
            >
              Update
            </Button>
          }
          title={
            <Typography variant="subtitle2" className={classes.header}>
              Fetching options
            </Typography>
          }
        />
        <CardContent>
          <Typography
            variant="subtitle2"
            className={`${classes.title} ${classes.title}`}
          >
            Date range
          </Typography>
          <KeyboardDatePicker
            autoOk
            variant="inline"
            inputVariant="outlined"
            label="From date"
            format="yyyy-MM-dd"
            value={fromDate}
            InputAdornmentProps={{ position: 'start' }}
            onChange={date => setFromDate(date?.toJSDate() ?? new Date())}
          />
          <br />
          <FormControl component="fieldset">
            <FormGroup>
              <FormControlLabel
                control={
                  <Switch
                    checked={useNowAsToDate}
                    onChange={toggleUseNowAsDate}
                  />
                }
                label={<Label>To today</Label>}
              />
              {useNowAsToDate ? null : (
                <KeyboardDatePicker
                  autoOk
                  variant="inline"
                  inputVariant="outlined"
                  label="To date"
                  format="yyyy-MM-dd"
                  value={toDate}
                  InputAdornmentProps={{ position: 'start' }}
                  onChange={date => setToDate(date?.toJSDate() ?? new Date())}
                />
              )}
            </FormGroup>
          </FormControl>
          <Typography
            variant="subtitle2"
            className={`${classes.title} ${classes.title}`}
          >
            Branch
          </Typography>
          <ButtonSwitch<string>
            values={branchValues}
            selection={branch}
            onChange={setBranch}
          />
          <Typography
            variant="subtitle2"
            className={`${classes.title} ${classes.title}`}
          >
            Status
          </Typography>
          <ButtonSwitch<string>
            values={statusValues}
            multi
            vertical
            selection={selectedStatus}
            onChange={setSelectedStatus}
          />
        </CardContent>
      </Card>
      <Card className={classes.rootCard}>
        <CardHeader
          title={
            <Typography variant="subtitle2" className={classes.header}>
              View options
            </Typography>
          }
        />
        <CardContent>
          <Toggle
            checked={viewOptions.lowercaseNames}
            setChecked={setLowercaseNames}
          >
            <Tooltip
              arrow
              title={
                'Lowercasing names can reduce duplications ' +
                'when stage names have changed casing'
              }
            >
              <Label>Lowercase names</Label>
            </Tooltip>
          </Toggle>
          <Toggle
            checked={viewOptions.normalizeTimeRange}
            setChecked={setNormalizeTimeRange}
          >
            <Tooltip
              arrow
              title={
                'All charts will use the same x-axis. ' +
                'This reduces confusion when stages have been altered over time ' +
                'and only appear in a part of the time range.'
              }
            >
              <Label>Normalize time range</Label>
            </Tooltip>
          </Toggle>
          <DurationSlider
            header="Hide under peak"
            value={viewOptions.hideLimit}
            setValue={setHideLimit}
          />
          <DurationSlider
            header="Collapse under peak"
            value={viewOptions.collapsedLimit}
            setValue={setCollapseLimit}
          />
          <Typography
            variant="subtitle2"
            className={`${classes.title} ${classes.title}`}
          >
            Chart styles
          </Typography>
          {inrefferedStatuses.map(status => (
            <Grid key={status} container spacing={0}>
              <Grid item>
                <ButtonSwitch<ChartType>
                  values={chartTypeValues}
                  selection={viewOptions.chartTypes[status as FilterStatusType]}
                  onChange={setChartTypeSpecific[status]}
                  multi
                />
              </Grid>
              <Grid item className={classes.buttonDescription}>
                <div>{status}</div>
              </Grid>
            </Grid>
          ))}
        </CardContent>
      </Card>
    </MuiPickersUtilsProvider>
  );
}