@mui/material#LinearProgress TypeScript Examples

The following examples show how to use @mui/material#LinearProgress. 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 yearn-watch-legacy with GNU Affero General Public License v3.0 6 votes vote down vote up
BorderLinearProgress = styled(LinearProgress)`
    && {
        height: 12px !important;
        border-radius: 5px !important;
        background-color: #f2f2f2 !important;
        margin-top: 10px;
        .MuiLinearProgress-bar {
            background-color: ${({ theme }) => theme.bodyBlue} !important;
        }
    }
`
Example #2
Source File: LoadingScreen.tsx    From GTAV-NativeDB with MIT License 6 votes vote down vote up
LoadingPage = () => {
  return (
    <Box 
      sx={{
        p: 2,
        display: 'flex',
        flexDirection: 'column',
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      }}
    >
      <Stack spacing={2}>
        <img 
          src="/splash.png" 
          alt="grand theft auto 5 logo" 
          height="225"
          style={{ objectFit: 'contain' }}
        />
        <Typography 
          variant="h2" 
          component="h1"
          align="center"
          gutterBottom
        >
          Loading Natives
        </Typography>
        <LinearProgress />
      </Stack>
    </Box>
  )
}
Example #3
Source File: QueryStateEditor.tsx    From mui-toolpad with MIT License 6 votes vote down vote up
function PreviewQueryStateResult({ node }: PreviewQueryStateResultProps) {
  const { pageState } = usePageEditorState();
  const actualNodeState: UseDataQuery | undefined = pageState[node.name] as any;
  if (!node.attributes.api.value) {
    return null;
  }
  return (
    <Box sx={{ maxHeight: 150, overflow: 'auto' }}>
      {actualNodeState?.isLoading ? <LinearProgress /> : null}
      {actualNodeState?.error ? (
        <Alert severity="error">
          {actualNodeState?.error.message || actualNodeState?.error || 'Something went wrong'}
        </Alert>
      ) : null}
      {actualNodeState?.data ? <JsonView src={actualNodeState.data} /> : null}
    </Box>
  );
}
Example #4
Source File: EventsList.tsx    From console with GNU Affero General Public License v3.0 6 votes vote down vote up
EventsList = ({ classes, events, loading }: IEventsListProps) => {
  if (loading) {
    return <LinearProgress />;
  }
  return (
    <TableContainer component={Paper}>
      <Table aria-label="collapsible table">
        <TableHead>
          <TableRow>
            <TableCell>Type</TableCell>
            <TableCell>Reason</TableCell>
            <TableCell>Age</TableCell>
            <TableCell>Message</TableCell>
            <TableCell />
          </TableRow>
        </TableHead>
        <TableBody>
          {events.map((event) => (
            <Event key={`${event.event_type}-${event.seen}`} event={event} />
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
}
Example #5
Source File: DetailLoading.tsx    From airmessage-web with Apache License 2.0 6 votes vote down vote up
export default function DetailLoading() {
	return (
		<div className={styles.main}>
			<Typography color="textSecondary">Getting your messages&#8230;</Typography>
			<LinearProgress
				className={styles.progress}
				sx={{
					borderRadius: 8,
					[`& .${linearProgressClasses.bar}`]: {
						borderRadius: 8
					},
				}} />
		</div>
	);
}
Example #6
Source File: LinearProgressWithLabel.tsx    From multi-downloader-nx with MIT License 6 votes vote down vote up
LinearProgressWithLabel: React.FC<LinearProgressWithLabelProps> = (props) => {
  return (
    <Box sx={{ display: 'flex', alignItems: 'center' }}>
      <Box sx={{ width: '100%', mr: 1 }}>
        <LinearProgress variant="determinate" {...props} />
      </Box>
      <Box sx={{ minWidth: 35 }}>
        <Typography variant="body2" color="text.secondary">{`${Math.round(
          props.value,
        )}%`}</Typography>
      </Box>
    </Box>
  );
}
Example #7
Source File: PageLoadingView.tsx    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
/**
 * 페이지 로딩 애니메이션입니다.
 */
export function PageLoadingView() {
  const classes = usePageLoadingViewStyles();

  return (
    <AppBar
      position="fixed"
      color="transparent"
      elevation={0}
      className={classes.appbar}>
      <LinearProgress color="secondary" />
    </AppBar>
  );
}
Example #8
Source File: UsageBarWrapper.tsx    From console with GNU Affero General Public License v3.0 6 votes vote down vote up
BorderLinearProgress = withStyles((theme) => ({
  root: {
    height: 10,
    borderRadius: 5,
  },
  colorPrimary: {
    backgroundColor: "#F4F4F4",
  },
  bar: {
    borderRadius: 5,
    backgroundColor: "#081C42",
  },
  padChart: {
    padding: "5px",
  },
}))(LinearProgress)
Example #9
Source File: ChangeEmail.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function ChangeEmail() {
    useTitle("Abrechnung - Change E-Mail");

    const handleSubmit = (values, { setSubmitting }) => {
        changeEmail({
            password: values.password,
            newEmail: values.newEmail,
        })
            .then((res) => {
                setSubmitting(false);
                toast.success("Requested email change, you should receive an email with a confirmation link soon");
            })
            .catch((error) => {
                setSubmitting(false);
                toast.error(error);
            });
    };

    return (
        <MobilePaper>
            <Typography component="h3" variant="h5">
                Change E-Mail
            </Typography>
            <Formik initialValues={{ password: "", newEmail: "" }} onSubmit={handleSubmit}>
                {({ values, handleChange, handleBlur, handleSubmit, isSubmitting }) => (
                    <Form>
                        <TextField
                            required
                            fullWidth
                            margin="normal"
                            autoFocus
                            type="password"
                            name="password"
                            variant="standard"
                            value={values.password}
                            onChange={handleChange}
                            onBlur={handleBlur}
                            label="Password"
                        />

                        <TextField
                            required
                            fullWidth
                            margin="normal"
                            type="email"
                            name="newEmail"
                            variant="standard"
                            value={values.newEmail}
                            onChange={handleChange}
                            onBlur={handleBlur}
                            label="New E-Mail"
                        />

                        {isSubmitting && <LinearProgress />}
                        <Button type="submit" color="primary" disabled={isSubmitting}>
                            Save
                        </Button>
                    </Form>
                )}
            </Formik>
        </MobilePaper>
    );
}
Example #10
Source File: WizardPage.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
WizardPage = ({
  classes,
  page,
  pageChange,
  loadingStep,
  forModal,
}: IWizardPage) => {
  const buttonAction = (btn: IWizardButton) => {
    switch (btn.type) {
      case "next":
        pageChange("++");
        break;
      case "back":
        pageChange("--");
        break;
      case "to":
        pageChange(btn.toPage || 0);
        break;
      case "custom":
      default:
    }

    if (btn.action) {
      btn.action(pageChange);
    }
  };

  return (
    <div className={classes.wizardStepContainer}>
      <div className={forModal ? classes.wizardModal : classes.wizardComponent}>
        {page.componentRender}
      </div>
      {loadingStep && (
        <div>
          <LinearProgress />
        </div>
      )}
      <div
        className={`${classes.buttonsContainer} ${forModal ? "forModal" : ""}`}
      >
        <div className={classes.buttonInnerContainer}>
          {page.buttons.map((btn) => {
            if (btn.componentRender) {
              return btn.componentRender;
            }
            return (
              <Button
                id={"wizard-button-" + btn.label}
                variant="contained"
                color="primary"
                size="small"
                onClick={() => {
                  buttonAction(btn);
                }}
                disabled={!btn.enabled}
                key={`button-${page.label}-${btn.label}`}
              >
                {btn.label}
              </Button>
            );
          })}
        </div>
      </div>
    </div>
  );
}
Example #11
Source File: Importer.tsx    From your_spotify with GNU General Public License v3.0 5 votes vote down vote up
export default function Importer() {
  const dispatch = useAppDispatch();
  const imports = useSelector(selectImportStates);
  const [importType, setImportType] = useState<ImporterStateTypes>(ImporterStateTypes.privacy);

  const fetch = useCallback(
    async (force = false) => {
      dispatch(getImports(force));
    },
    [dispatch],
  );

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

  const running = useMemo(() => imports?.find((st) => st.status === 'progress'), [imports]);
  const Component = useMemo(
    () => (importType ? ImportTypeToComponent[importType] : null),
    [importType],
  );

  if (!imports) {
    return <CircularProgress />;
  }

  return (
    <div>
      <div>
        {running && (
          <div>
            <Text>Importing...</Text>
            <div className={s.progress}>
              <Text>
                {running.current} / {running.total}
              </Text>
            </div>
            <LinearProgress
              style={{ width: '100%' }}
              variant="determinate"
              value={(running.current / running.total) * 100}
            />
          </div>
        )}
      </div>
      {!running && (
        <div>
          <FormControl className={s.selectimport}>
            <InputLabel id="import-type-select">Import type</InputLabel>
            <Select
              labelId="import-type-select"
              value={importType}
              label="Import type"
              onChange={(ev) => setImportType(ev.target.value as ImporterStateTypes)}>
              {Object.values(ImporterStateTypes).map((typ) => (
                <MenuItem value={typ} key={typ}>
                  {typ}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
          {Component && <Component />}
        </div>
      )}
      {imports.length > 0 && <ImportHistory />}
    </div>
  );
}
Example #12
Source File: BuildAlert.tsx    From genshin-optimizer with MIT License 5 votes vote down vote up
BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
  height: 10,
  borderRadius: 5,
}))
Example #13
Source File: MarketItem.tsx    From Cromwell with MIT License 5 votes vote down vote up
export default function MarketItem(props: PropsType) {
    const data = props?.data;
    const [installing, setInstalling] = useState(false);
    const [installed, setInstalled] = useState(!!(props.data?.name
        && props?.listItemProps?.installedModules?.find(inst => inst.name === props.data?.name)));

    const installModule = async () => {
        if (!props.listItemProps?.install || !data) return;

        setInstalling(true);
        const success = await props.listItemProps.install(data);
        if (success) setInstalled(true);
        setInstalling(false);
    }

    return (
        <Grid item xs={6} lg={4} className={styles.listItem}>
            <div className={clsx(styles.listItemContent, installing && styles.installing)}>
                {data?.image && (
                    <CardActionArea
                        onClick={() => props.listItemProps?.open(props.data)}
                        className={styles.cardActionArea}
                    >
                        <img src={data.image} className={styles.image} />
                    </CardActionArea>
                )}
                <div className={styles.caption}>
                    <Badge color="secondary" badgeContent={installed ? 'installed' : null}>
                        <Typography gutterBottom variant="h5" component="h3" className={styles.title}>
                            {data?.title ?? ''}
                        </Typography>
                    </Badge>
                    <p className={styles.version}>{data?.version ?? ''}</p>
                    <p className={styles.excerpt}>{data?.excerpt ?? ''}</p>
                </div>
                <div className={styles.actions}>
                    <Button
                        size="small" color="primary" variant="contained"
                        onClick={() => props.listItemProps?.open(props.data)}
                    >Open</Button>
                    <Button
                        disabled={installed || installing}
                        size="small" color="primary" variant="contained"
                        onClick={installModule}
                    >Install</Button>
                </div>
                {installing && (
                    <LinearProgress className={styles.updateProgress} />
                )}
            </div>
        </Grid>
    )
}
Example #14
Source File: Dashboard.tsx    From console with GNU Affero General Public License v3.0 5 votes vote down vote up
Dashboard = ({ classes }: IDashboardSimple) => {
  const dispatch = useDispatch();
  const [loading, setLoading] = useState<boolean>(true);
  const [basicResult, setBasicResult] = useState<Usage | null>(null);

  const fetchUsage = useCallback(() => {
    api
      .invoke("GET", `/api/v1/admin/info`)
      .then((res: Usage) => {
        setBasicResult(res);
        setLoading(false);
      })
      .catch((err: ErrorResponseHandler) => {
        dispatch(setErrorSnackMessage(err));
        setLoading(false);
      });
  }, [setBasicResult, setLoading, dispatch]);

  useEffect(() => {
    if (loading) {
      fetchUsage();
    }
  }, [loading, fetchUsage]);

  const widgets = get(basicResult, "widgets", null);

  return (
    <Fragment>
      <PageHeader label="Metrics" />
      {loading ? (
        <Grid container>
          <Grid item xs={12} className={classes.container}>
            <LinearProgress />
          </Grid>
        </Grid>
      ) : (
        <Fragment>
          {widgets !== null ? (
            <PrDashboard />
          ) : (
            <BasicDashboard usage={basicResult} />
          )}
        </Fragment>
      )}
    </Fragment>
  );
}
Example #15
Source File: ToolpadApp.tsx    From mui-toolpad with MIT License 5 votes vote down vote up
function AppLoading() {
  return <LinearProgress />;
}
Example #16
Source File: index.tsx    From ExpressLRS-Configurator with GNU General Public License v3.0 5 votes vote down vote up
BuildProgressBar: FunctionComponent<BuildProgressBarProps> = memo(
  ({ inProgress, jobType, progressNotification }) => {
    const toProgressValue = (
      notification: BuildProgressNotification | null
    ): number => {
      if (notification === null) {
        return 0;
      }
      if (!inProgress) {
        return 100;
      }
      switch (jobType) {
        case BuildJobType.Build:
          switch (notification.step) {
            case BuildFirmwareStep.VERIFYING_BUILD_SYSTEM:
              return 10;
            case BuildFirmwareStep.DOWNLOADING_FIRMWARE:
              return 35;
            case BuildFirmwareStep.BUILDING_USER_DEFINES:
              return 37;
            case BuildFirmwareStep.BUILDING_FIRMWARE:
              return 77;
            default:
          }
          break;
        case BuildJobType.BuildAndFlash:
        case BuildJobType.ForceFlash:
          switch (notification.step) {
            case BuildFirmwareStep.VERIFYING_BUILD_SYSTEM:
              return 5;
            case BuildFirmwareStep.DOWNLOADING_FIRMWARE:
              return 15;
            case BuildFirmwareStep.BUILDING_USER_DEFINES:
              return 28;
            case BuildFirmwareStep.BUILDING_FIRMWARE:
              return 56;
            case BuildFirmwareStep.FLASHING_FIRMWARE:
              return 89;
            default:
          }
          break;
        default:
          throw new Error(`unhandled job type: ${jobType}`);
      }

      return 100;
    };
    return (
      <LinearProgress
        sx={styles.root}
        variant="determinate"
        value={toProgressValue(progressNotification)}
      />
    );
  }
)
Example #17
Source File: SetPolicy.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
SetPolicy = ({
  classes,
  closeModalAndRefresh,
  selectedUser,
  selectedGroup,
  open,
}: ISetPolicyProps) => {
  const dispatch = useDispatch();
  //Local States
  const [loading, setLoading] = useState<boolean>(false);
  const [actualPolicy, setActualPolicy] = useState<string[]>([]);
  const [selectedPolicy, setSelectedPolicy] = useState<string[]>([]);

  const setPolicyAction = () => {
    let entity = "user";
    let value = null;
    if (selectedGroup !== null) {
      entity = "group";
      value = selectedGroup;
    } else {
      if (selectedUser !== null) {
        value = selectedUser.accessKey;
      }
    }

    setLoading(true);

    api
      .invoke("PUT", `/api/v1/set-policy`, {
        name: selectedPolicy,
        entityName: value,
        entityType: entity,
      })
      .then(() => {
        setLoading(false);
        closeModalAndRefresh();
      })
      .catch((err: ErrorResponseHandler) => {
        setLoading(false);
        dispatch(setModalErrorSnackMessage(err));
      });
  };

  const fetchGroupInformation = () => {
    if (selectedGroup) {
      api
        .invoke("GET", `/api/v1/group/${encodeURLString(selectedGroup)}`)
        .then((res: any) => {
          const groupPolicy: String = get(res, "policy", "");
          setActualPolicy(groupPolicy.split(","));
          setSelectedPolicy(groupPolicy.split(","));
        })
        .catch((err: ErrorResponseHandler) => {
          dispatch(setModalErrorSnackMessage(err));
          setLoading(false);
        });
    }
  };

  const resetSelection = () => {
    setSelectedPolicy(actualPolicy);
  };

  useEffect(() => {
    if (open) {
      if (selectedGroup !== null) {
        fetchGroupInformation();
        return;
      }

      const userPolicy: string[] = get(selectedUser, "policy", []);
      setActualPolicy(userPolicy);
      setSelectedPolicy(userPolicy);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open, selectedGroup, selectedUser]);

  const userName = get(selectedUser, "accessKey", "");

  return (
    <ModalWrapper
      onClose={() => {
        closeModalAndRefresh();
      }}
      modalOpen={open}
      title="Set Policies"
    >
      <Grid container>
        <Grid item xs={12}>
          <PredefinedList
            label={`Selected ${selectedGroup !== null ? "Group" : "User"}`}
            content={selectedGroup !== null ? selectedGroup : userName}
          />
        </Grid>
        <Grid item xs={12}>
          <PredefinedList
            label={"Current Policy"}
            content={actualPolicy.join(", ")}
          />
        </Grid>
        <Grid item xs={12}>
          <div className={classes.tableBlock}>
            <PolicySelectors
              selectedPolicy={selectedPolicy}
              setSelectedPolicy={setSelectedPolicy}
            />
          </div>
        </Grid>
      </Grid>
      <Grid item xs={12} className={classes.buttonContainer}>
        <Button
          type="button"
          variant="outlined"
          color="primary"
          className={classes.spacerRight}
          onClick={resetSelection}
        >
          Reset
        </Button>
        <Button
          type="button"
          variant="contained"
          color="primary"
          disabled={loading}
          onClick={setPolicyAction}
        >
          Save
        </Button>
      </Grid>
      {loading && (
        <Grid item xs={12}>
          <LinearProgress />
        </Grid>
      )}
    </ModalWrapper>
  );
}
Example #18
Source File: CreateClearingAccountModal.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function CreateClearingAccountModal({ show, onClose, group, initialValues }) {
    const setAccounts = useSetRecoilState(groupAccounts(group.id));
    const accounts = useRecoilValue(accountsSeenByUser(group.id));

    const initial =
        initialValues != null
            ? initialValues
            : {
                  name: "",
                  description: "",
                  clearing_shares: accounts.reduce((map, curr) => {
                      map[curr.id] = 0.0;
                      return map;
                  }, {}),
              };

    const handleSubmit = (values, { setSubmitting }) => {
        createAccount({
            groupID: group.id,
            name: values.name,
            accountType: "clearing",
            description: values.description,
            clearingShares: values.clearing_shares,
        })
            .then((account) => {
                toast.success(`Created account ${values.name}`);
                addAccount(account, setAccounts);
                setSubmitting(false);
                onClose();
            })
            .catch((err) => {
                toast.error(err);
                setSubmitting(false);
            });
    };

    return (
        <Dialog open={show} onClose={onClose}>
            <DialogTitle>Create Clearing Account</DialogTitle>

            <DialogContent>
                <Formik
                    initialValues={initial}
                    onSubmit={handleSubmit}
                    enableReinitialize={true}
                    validationSchema={validationSchema}
                >
                    {({
                        values,
                        touched,
                        errors,
                        setFieldValue,
                        handleChange,
                        handleBlur,
                        handleSubmit,
                        isSubmitting,
                    }) => (
                        <Form>
                            <TextField
                                margin="normal"
                                required
                                fullWidth
                                autoFocus
                                variant="standard"
                                name="name"
                                label="Account Name"
                                onBlur={handleBlur}
                                onChange={handleChange}
                                value={values.name}
                                error={touched.name && Boolean(errors.name)}
                                helperText={touched.name && (errors.name as ReactNode)}
                            />
                            <TextField
                                margin="normal"
                                fullWidth
                                variant="standard"
                                name="description"
                                label="Description"
                                onBlur={handleBlur}
                                onChange={handleChange}
                                value={values.description}
                                error={touched.description && Boolean(errors.description)}
                                helperText={touched.description && (errors.description as ReactNode)}
                            />

                            <ClearingSharesFormElement
                                group={group}
                                clearingShares={values.clearing_shares}
                                setClearingShares={(clearingShares) => setFieldValue("clearing_shares", clearingShares)}
                            />

                            {isSubmitting && <LinearProgress />}
                            <DialogActions>
                                <Button color="error" onClick={onClose}>
                                    Cancel
                                </Button>
                                <Button type="submit" color="primary" disabled={isSubmitting}>
                                    Save
                                </Button>
                            </DialogActions>
                        </Form>
                    )}
                </Formik>
            </DialogContent>
        </Dialog>
    );
}
Example #19
Source File: TenantDetails.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
TenantDetails = ({ classes, match, history }: ITenantDetailsProps) => {
  const dispatch = useDispatch();

  const loadingTenant = useSelector(
    (state: AppState) => state.tenants.loadingTenant
  );
  const selectedTenant = useSelector(
    (state: AppState) => state.tenants.currentTenant
  );
  const selectedNamespace = useSelector(
    (state: AppState) => state.tenants.currentNamespace
  );
  const tenantInfo = useSelector((state: AppState) => state.tenants.tenantInfo);

  const [yamlScreenOpen, setYamlScreenOpen] = useState<boolean>(false);

  const tenantName = match.params["tenantName"];
  const tenantNamespace = match.params["tenantNamespace"];
  const [deleteOpen, setDeleteOpen] = useState<boolean>(false);

  // if the current tenant selected is not the one in the redux, reload it
  useEffect(() => {
    if (
      selectedNamespace !== tenantNamespace ||
      selectedTenant !== tenantName
    ) {
      dispatch(
        setTenantName({
          name: tenantName,
          namespace: tenantNamespace,
        })
      );
      dispatch(getTenantAsync());
    }
  }, [
    selectedTenant,
    selectedNamespace,
    dispatch,
    tenantName,
    tenantNamespace,
  ]);

  const path = get(match, "path", "/");
  const splitSections = path.split("/");

  let highlightedTab = splitSections[splitSections.length - 1] || "summary";
  if (highlightedTab === ":podName" || highlightedTab === "pods") {
    // It has SUB Route
    highlightedTab = "pods";
  }
  const [activeTab, setActiveTab] = useState(highlightedTab);

  useEffect(() => {
    setActiveTab(highlightedTab);
  }, [highlightedTab]);

  const editYaml = () => {
    setYamlScreenOpen(true);
  };

  const closeYAMLModalAndRefresh = () => {
    setYamlScreenOpen(false);
    dispatch(setTenantDetailsLoad(true));
  };

  const getRoutePath = (newValue: string) => {
    return `/namespaces/${tenantNamespace}/tenants/${tenantName}/${newValue}`;
  };

  const confirmDeleteTenant = () => {
    setDeleteOpen(true);
  };

  const closeDeleteModalAndRefresh = (reloadData: boolean) => {
    setDeleteOpen(false);

    if (reloadData) {
      dispatch(setSnackBarMessage("Tenant Deleted"));
      history.push(`/tenants`);
    }
  };

  const healthStatusToClass = (health_status: string) => {
    return health_status === "red"
      ? classes.redState
      : health_status === "yellow"
      ? classes.yellowState
      : health_status === "green"
      ? classes.greenState
      : classes.greyState;
  };

  return (
    <Fragment>
      {yamlScreenOpen && (
        <TenantYAML
          open={yamlScreenOpen}
          closeModalAndRefresh={closeYAMLModalAndRefresh}
          tenant={tenantName}
          namespace={tenantNamespace}
        />
      )}
      {deleteOpen && tenantInfo !== null && (
        <DeleteTenant
          deleteOpen={deleteOpen}
          selectedTenant={tenantInfo}
          closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
        />
      )}

      <PageHeader
        label={
          <Fragment>
            <BackLink to={IAM_PAGES.TENANTS} label="Tenants" />
          </Fragment>
        }
        actions={<React.Fragment />}
      />

      <PageLayout className={classes.pageContainer}>
        {loadingTenant && (
          <Grid item xs={12}>
            <LinearProgress />
          </Grid>
        )}
        <Grid item xs={12}>
          <ScreenTitle
            icon={
              <Fragment>
                <div className={classes.healthStatusIcon}>
                  {tenantInfo && tenantInfo.status && (
                    <span
                      className={healthStatusToClass(
                        tenantInfo.status.health_status
                      )}
                    >
                      <CircleIcon />
                    </span>
                  )}
                </div>
                <TenantsIcon />
              </Fragment>
            }
            title={match.params["tenantName"]}
            subTitle={
              <Fragment>
                Namespace: {tenantNamespace} / Capacity:{" "}
                {niceBytes((tenantInfo?.total_size || 0).toString(10))}
              </Fragment>
            }
            actions={
              <div>
                <BoxIconButton
                  id={"delete-tenant"}
                  tooltip={"Delete"}
                  variant="outlined"
                  aria-label="Delete"
                  onClick={() => {
                    confirmDeleteTenant();
                  }}
                  color="secondary"
                  classes={{
                    root: `${classes.tenantActionButton} ${classes.deleteBtn}`,
                  }}
                  size="large"
                >
                  <span>Delete</span> <TrashIcon />
                </BoxIconButton>
                <BoxIconButton
                  classes={{
                    root: classes.tenantActionButton,
                  }}
                  tooltip={"Edit YAML"}
                  color="primary"
                  variant="outlined"
                  aria-label="Edit YAML"
                  onClick={() => {
                    editYaml();
                  }}
                  size="large"
                >
                  <span>YAML</span>
                  <EditIcon />
                </BoxIconButton>
                <BoxIconButton
                  classes={{
                    root: classes.tenantActionButton,
                  }}
                  tooltip={"Management Console"}
                  onClick={() => {
                    history.push(
                      `/namespaces/${tenantNamespace}/tenants/${tenantName}/hop`
                    );
                  }}
                  disabled={!tenantInfo || !tenantIsOnline(tenantInfo)}
                  variant={"outlined"}
                  color="primary"
                >
                  <span>Console</span>{" "}
                  <MinIOTierIconXs style={{ height: 16 }} />
                </BoxIconButton>
                <BoxIconButton
                  classes={{
                    root: classes.tenantActionButton,
                  }}
                  tooltip={"Refresh"}
                  color="primary"
                  variant="outlined"
                  aria-label="Refresh List"
                  onClick={() => {
                    dispatch(getTenantAsync());
                  }}
                >
                  <span>Refresh</span> <RefreshIcon />
                </BoxIconButton>
              </div>
            }
          />
        </Grid>

        <VerticalTabs
          selectedTab={activeTab}
          isRouteTabs
          routes={
            <div className={classes.contentSpacer}>
              <Router history={history}>
                <Switch>
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_SUMMARY}
                    component={TenantSummary}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_METRICS}
                    component={TenantMetrics}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_TRACE}
                    component={TenantTrace}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_IDENTITY_PROVIDER}
                    component={TenantIdentityProvider}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_SECURITY}
                    component={TenantSecurity}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_ENCRYPTION}
                    component={TenantEncryption}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_POOLS}
                    component={PoolsSummary}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_PODS}
                    component={PodDetails}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_PODS_LIST}
                    component={PodsSummary}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_PVCS}
                    component={TenantVolumes}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_VOLUMES}
                    component={VolumesSummary}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_LICENSE}
                    component={TenantLicense}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_MONITORING}
                    component={TenantMonitoring}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_LOGGING}
                    component={TenantLogging}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_EVENTS}
                    component={TenantEvents}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT_CSR}
                    component={TenantCSR}
                  />
                  <Route
                    path={IAM_PAGES.NAMESPACE_TENANT}
                    component={() => (
                      <Redirect
                        to={`/namespaces/${tenantNamespace}/tenants/${tenantName}/summary`}
                      />
                    )}
                  />
                </Switch>
              </Router>
            </div>
          }
        >
          {{
            tabConfig: {
              label: "Summary",
              value: "summary",
              component: Link,
              to: getRoutePath("summary"),
            },
          }}
          {{
            tabConfig: {
              label: "Metrics",
              value: "metrics",
              component: Link,
              to: getRoutePath("metrics"),
            },
          }}
          {{
            tabConfig: {
              label: "Identity Provider",
              value: "identity-provider",
              component: Link,
              to: getRoutePath("identity-provider"),
            },
          }}
          {{
            tabConfig: {
              label: "Security",
              value: "security",
              component: Link,
              to: getRoutePath("security"),
            },
          }}
          {{
            tabConfig: {
              label: "Encryption",
              value: "encryption",
              component: Link,
              to: getRoutePath("encryption"),
            },
          }}
          {{
            tabConfig: {
              label: "Pools",
              value: "pools",
              component: Link,
              to: getRoutePath("pools"),
            },
          }}
          {{
            tabConfig: {
              label: "Pods",
              value: "pods",
              component: Link,
              id: "tenant-pod-tab",
              to: getRoutePath("pods"),
            },
          }}

          {{
            tabConfig: {
              label: "Monitoring",
              value: "monitoring",
              component: Link,
              to: getRoutePath("monitoring"),
            },
          }}
          {{
            tabConfig: {
              label: "Audit Log",
              value: "logging",
              component: Link,
              to: getRoutePath("logging"),
            },
          }}
          {{
            tabConfig: {
              label: "Volumes",
              value: "volumes",
              component: Link,
              to: getRoutePath("volumes"),
            },
          }}
          {{
            tabConfig: {
              label: "Events",
              value: "events",
              component: Link,
              to: getRoutePath("events"),
            },
          }}
          {{
            tabConfig: {
              label: "License",
              value: "license",
              component: Link,
              to: getRoutePath("license"),
            },
          }}
          {{
            tabConfig: {
              label: "Certificate Signing Request",
              value: "csr",
              component: Link,
              to: getRoutePath("csr"),
            },
          }}
        </VerticalTabs>
      </PageLayout>
    </Fragment>
  );
}
Example #20
Source File: EditAccountModal.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function EditAccountModal({ group, show, onClose, account }) {
    const setAccounts = useSetRecoilState(groupAccounts(group.id));
    const userPermissions = useRecoilValue(currUserPermissions(group.id));
    const currentUser = useRecoilValue(userData);
    const memberIDToUsername = useRecoilValue(groupMemberIDsToUsername(group.id));

    const handleSubmit = (values, { setSubmitting }) => {
        updateAccountDetails({
            accountID: values.accountID,
            name: values.name,
            description: values.description,
            owningUserID: values.owningUserID,
        })
            .then((account) => {
                console.log(account);
                updateAccount(account, setAccounts);
                setSubmitting(false);
                onClose();
            })
            .catch((err) => {
                toast.error(err);
                setSubmitting(false);
            });
    };

    return (
        <Dialog open={show} onClose={onClose}>
            <DialogTitle>Edit Personal Account</DialogTitle>
            <DialogContent>
                <Formik
                    initialValues={{
                        accountID: account?.id,
                        name: account?.name,
                        description: account?.description,
                        owningUserID: account?.owning_user_id,
                    }}
                    onSubmit={handleSubmit}
                    enableReinitialize={true}
                >
                    {({ values, handleChange, handleBlur, handleSubmit, isSubmitting, setFieldValue }) => (
                        <Form>
                            <TextField
                                margin="normal"
                                required
                                fullWidth
                                variant="standard"
                                autoFocus
                                name="name"
                                label="Account Name"
                                value={values.name}
                                onBlur={handleBlur}
                                onChange={handleChange}
                            />
                            <TextField
                                margin="normal"
                                fullWidth
                                variant="standard"
                                name="description"
                                label="Description"
                                value={values.description}
                                onBlur={handleBlur}
                                onChange={handleChange}
                            />
                            {userPermissions.is_owner ? (
                                <GroupMemberSelect
                                    margin="normal"
                                    group={group}
                                    label="Owning user"
                                    value={values.owningUserID}
                                    onChange={(user_id) => setFieldValue("owningUserID", user_id)}
                                />
                            ) : account?.owning_user_id === null || account?.owning_user_id === currentUser.id ? (
                                <FormControlLabel
                                    control={
                                        <Checkbox
                                            name="owningUserID"
                                            onChange={(e) =>
                                                setFieldValue("owningUserID", e.target.checked ? currentUser.id : null)
                                            }
                                            checked={values.owningUserID === currentUser.id}
                                        />
                                    }
                                    label="This is me"
                                />
                            ) : (
                                <span>
                                    Owned by{" "}
                                    <Chip
                                        size="small"
                                        component="span"
                                        color="primary"
                                        label={memberIDToUsername[account?.owning_user_id]}
                                    />
                                </span>
                            )}

                            {isSubmitting && <LinearProgress />}
                            <DialogActions>
                                <Button color="primary" type="submit">
                                    Save
                                </Button>
                                <Button color="error" onClick={onClose}>
                                    Cancel
                                </Button>
                            </DialogActions>
                        </Form>
                    )}
                </Formik>
            </DialogContent>
        </Dialog>
    );
}
Example #21
Source File: ListTenants.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
ListTenants = ({ classes }: ITenantsList) => {
  const dispatch = useDispatch();
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [filterTenants, setFilterTenants] = useState<string>("");
  const [records, setRecords] = useState<ITenant[]>([]);
  const [showNewCredentials, setShowNewCredentials] = useState<boolean>(false);
  const [createdAccount, setCreatedAccount] =
    useState<NewServiceAccount | null>(null);
  const [sortValue, setSortValue] = useState<string>("name");

  const closeCredentialsModal = () => {
    setShowNewCredentials(false);
    setCreatedAccount(null);
  };

  const filteredRecords = records.filter((b: any) => {
    if (filterTenants === "") {
      return true;
    } else {
      if (b.name.indexOf(filterTenants) >= 0) {
        return true;
      } else {
        return false;
      }
    }
  });

  filteredRecords.sort((a, b) => {
    switch (sortValue) {
      case "capacity":
        if (!a.capacity || !b.capacity) {
          return 0;
        }

        if (a.capacity > b.capacity) {
          return 1;
        }

        if (a.capacity < b.capacity) {
          return -1;
        }

        return 0;
      case "usage":
        if (!a.capacity_usage || !b.capacity_usage) {
          return 0;
        }

        if (a.capacity_usage > b.capacity_usage) {
          return 1;
        }

        if (a.capacity_usage < b.capacity_usage) {
          return -1;
        }

        return 0;
      case "active_status":
        if (a.health_status === "red" && b.health_status !== "red") {
          return 1;
        }

        if (a.health_status !== "red" && b.health_status === "red") {
          return -1;
        }

        return 0;
      case "failing_status":
        if (a.health_status === "green" && b.health_status !== "green") {
          return 1;
        }

        if (a.health_status !== "green" && b.health_status === "green") {
          return -1;
        }

        return 0;
      default:
        if (a.name > b.name) {
          return 1;
        }
        if (a.name < b.name) {
          return -1;
        }
        return 0;
    }
  });

  useEffect(() => {
    if (isLoading) {
      const fetchRecords = () => {
        api
          .invoke("GET", `/api/v1/tenants`)
          .then((res: ITenantsResponse) => {
            if (res === null) {
              setIsLoading(false);
              return;
            }
            let resTenants: ITenant[] = [];
            if (res.tenants !== null) {
              resTenants = res.tenants;
            }

            for (let i = 0; i < resTenants.length; i++) {
              resTenants[i].total_capacity = niceBytes(
                resTenants[i].total_size + ""
              );
            }

            setRecords(resTenants);
            setIsLoading(false);
          })
          .catch((err: ErrorResponseHandler) => {
            dispatch(setErrorSnackMessage(err));
            setIsLoading(false);
          });
      };
      fetchRecords();
    }
  }, [isLoading, dispatch]);

  useEffect(() => {
    setIsLoading(true);
  }, []);

  const renderItemLine = (index: number) => {
    const tenant = filteredRecords[index] || null;

    if (tenant) {
      return <TenantListItem tenant={tenant} />;
    }

    return null;
  };

  return (
    <Fragment>
      {showNewCredentials && (
        <CredentialsPrompt
          newServiceAccount={createdAccount}
          open={showNewCredentials}
          closeModal={() => {
            closeCredentialsModal();
          }}
          entity="Tenant"
        />
      )}
      <PageHeader
        label="Tenants"
        middleComponent={
          <SearchBox
            placeholder={"Filter Tenants"}
            onChange={(val) => {
              setFilterTenants(val);
            }}
            value={filterTenants}
          />
        }
        actions={
          <Grid item xs={12} marginRight={"30px"}>
            <RBIconButton
              id={"refresh-tenant-list"}
              tooltip={"Refresh Tenant List"}
              text={""}
              onClick={() => {
                setIsLoading(true);
              }}
              icon={<RefreshIcon />}
              color="primary"
              variant={"outlined"}
            />
            <RBIconButton
              id={"create-tenant"}
              tooltip={"Create Tenant"}
              text={"Create Tenant"}
              onClick={() => {
                history.push("/tenants/add");
              }}
              icon={<AddIcon />}
              color="primary"
              variant={"contained"}
            />
          </Grid>
        }
      />
      <PageLayout>
        <Grid item xs={12} className={classes.tenantsList}>
          {isLoading && <LinearProgress />}
          {!isLoading && (
            <Fragment>
              {filteredRecords.length !== 0 && (
                <Fragment>
                  <Grid item xs={12} className={classes.sortByContainer}>
                    <div className={classes.innerSort}>
                      <span className={classes.sortByLabel}>Sort by</span>
                      <SelectWrapper
                        id={"sort-by"}
                        label={""}
                        value={sortValue}
                        onChange={(e: SelectChangeEvent<string>) => {
                          setSortValue(e.target.value as string);
                        }}
                        name={"sort-by"}
                        options={[
                          { label: "Name", value: "name" },
                          {
                            label: "Capacity",
                            value: "capacity",
                          },
                          {
                            label: "Usage",
                            value: "usage",
                          },
                          {
                            label: "Active Status",
                            value: "active_status",
                          },
                          {
                            label: "Failing Status",
                            value: "failing_status",
                          },
                        ]}
                      />
                    </div>
                  </Grid>
                  <VirtualizedList
                    rowRenderFunction={renderItemLine}
                    totalItems={filteredRecords.length}
                  />
                </Fragment>
              )}
              {filteredRecords.length === 0 && (
                <Grid
                  container
                  justifyContent={"center"}
                  alignContent={"center"}
                  alignItems={"center"}
                >
                  <Grid item xs={8}>
                    <HelpBox
                      iconComponent={<TenantsIcon />}
                      title={"Tenants"}
                      help={
                        <Fragment>
                          Tenant is the logical structure to represent a MinIO
                          deployment. A tenant can have different size and
                          configurations from other tenants, even a different
                          storage class.
                          <br />
                          <br />
                          To get started,&nbsp;
                          <AButton
                            onClick={() => {
                              history.push("/tenants/add");
                            }}
                          >
                            Create a Tenant.
                          </AButton>
                        </Fragment>
                      }
                    />
                  </Grid>
                </Grid>
              )}
            </Fragment>
          )}
        </Grid>
      </PageLayout>
    </Fragment>
  );
}
Example #22
Source File: EditClearingAccountModal.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function EditClearingAccountModal({ group, show, onClose, account }) {
    const setAccounts = useSetRecoilState(groupAccounts(group.id));

    const handleSubmit = (values, { setSubmitting }) => {
        updateAccountDetails({
            accountID: values.accountID,
            name: values.name,
            description: values.description,
            clearingShares: values.clearingShares,
        })
            .then((account) => {
                updateAccount(account, setAccounts);
                setSubmitting(false);
                onClose();
            })
            .catch((err) => {
                toast.error(err);
                setSubmitting(false);
            });
    };

    return (
        <Dialog open={show} onClose={onClose}>
            <DialogTitle>Edit Clearing Account</DialogTitle>
            <DialogContent>
                <Formik
                    initialValues={{
                        accountID: account?.id,
                        name: account?.name,
                        description: account?.description,
                        clearingShares: account?.clearing_shares,
                    }}
                    onSubmit={handleSubmit}
                    enableReinitialize={true}
                    validationSchema={validationSchema}
                >
                    {({ values, handleChange, setFieldValue, handleBlur, handleSubmit, isSubmitting }) => (
                        <Form>
                            <TextField
                                margin="normal"
                                required
                                fullWidth
                                variant="standard"
                                autoFocus
                                name="name"
                                label="Account Name"
                                value={values.name}
                                onBlur={handleBlur}
                                onChange={handleChange}
                            />
                            <TextField
                                margin="normal"
                                fullWidth
                                variant="standard"
                                name="description"
                                label="Description"
                                value={values.description}
                                onBlur={handleBlur}
                                onChange={handleChange}
                            />

                            <ClearingSharesFormElement
                                group={group}
                                clearingShares={values.clearingShares}
                                accountID={account?.id}
                                setClearingShares={(clearingShares) => setFieldValue("clearingShares", clearingShares)}
                            />

                            {isSubmitting && <LinearProgress />}
                            <DialogActions>
                                <Button color="primary" type="submit">
                                    Save
                                </Button>
                                <Button color="error" onClick={onClose}>
                                    Close
                                </Button>
                            </DialogActions>
                        </Form>
                    )}
                </Formik>
            </DialogContent>
        </Dialog>
    );
}
Example #23
Source File: AddTenant.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
AddTenant = () => {
  const dispatch = useDispatch();
  const classes = useStyles();

  const features = useSelector(selFeatures);

  // Fields
  const addSending = useSelector(
    (state: AppState) => state.createTenant.addingTenant
  );
  const [formRender, setFormRender] = useState<IMkEnvs | null>(null);

  useEffect(() => {
    let setConfiguration = IMkEnvs.default;

    if (features && features.length !== 0) {
      const possibleVariables = Object.keys(resourcesConfigurations);

      possibleVariables.forEach((element) => {
        if (features.includes(element)) {
          setConfiguration = get(
            resourcesConfigurations,
            element,
            IMkEnvs.default
          );
        }
      });
    }

    setFormRender(setConfiguration);
  }, [features]);

  const cancelButton = {
    label: "Cancel",
    type: "other",
    enabled: true,
    action: () => {
      dispatch(resetAddTenantForm());
      history.push("/tenants");
    },
  };

  const createButton: IWizardButton = {
    componentRender: <CreateTenantButton key={"create-tenant"} />,
  };

  const wizardSteps: IWizardElement[] = [
    {
      label: "Setup",
      componentRender: <TenantResources />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Configure",
      advancedOnly: true,
      componentRender: <Configure />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Images",
      advancedOnly: true,
      componentRender: <Images />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Pod Placement",
      advancedOnly: true,
      componentRender: <Affinity />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Identity Provider",
      advancedOnly: true,
      componentRender: <IdentityProvider />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Security",
      advancedOnly: true,
      componentRender: <Security />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Encryption",
      advancedOnly: true,
      componentRender: <Encryption />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Audit Log",
      advancedOnly: true,
      componentRender: <ConfigLogSearch />,
      buttons: [cancelButton, createButton],
    },
    {
      label: "Monitoring",
      advancedOnly: true,
      componentRender: <ConfigPrometheus />,
      buttons: [cancelButton, createButton],
    },
  ];

  let filteredWizardSteps = wizardSteps;

  return (
    <Fragment>
      <NewTenantCredentials />
      <PageHeader
        label={
          <BackLink
            to={"/tenants"}
            label={"Tenants"}
            executeOnClick={() => {
              dispatch(resetAddTenantForm());
            }}
          />
        }
      />

      <PageLayout>
        {addSending && (
          <Grid item xs={12}>
            <LinearProgress />
          </Grid>
        )}
        <Grid item xs={12} className={classes.pageBox}>
          <GenericWizard wizardSteps={filteredWizardSteps} />
        </Grid>
        {formRender === IMkEnvs.aws && (
          <Grid item xs={12} style={{ marginTop: 16 }}>
            <HelpBox
              title={"EBS Volume Configuration."}
              iconComponent={<StorageIcon />}
              help={
                <Fragment>
                  <b>Performance Optimized</b>: Uses the <i>gp3</i> EBS storage
                  class class configured at 1,000Mi/s throughput and 16,000
                  IOPS, however the minimum volume size for this type of EBS
                  volume is <b>32Gi</b>.
                  <br />
                  <br />
                  <b>Storage Optimized</b>: Uses the <i>sc1</i> EBS storage
                  class, however the minimum volume size for this type of EBS
                  volume is &nbsp;
                  <b>16Ti</b> to unlock their maximum throughput speed of
                  250Mi/s.
                </Fragment>
              }
            />
          </Grid>
        )}
      </PageLayout>
    </Fragment>
  );
}
Example #24
Source File: CreateAccountModal.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function CreateAccountModal({ show, onClose, group }) {
    const setAccounts = useSetRecoilState(groupAccounts(group.id));
    const userPermissions = useRecoilValue(currUserPermissions(group.id));
    const currentUser = useRecoilValue(userData);

    const handleSubmit = (values, { setSubmitting }) => {
        createAccount({
            groupID: group.id,
            name: values.name,
            owningUserID: values.owningUserID,
            description: values.description,
        })
            .then((account) => {
                toast.success(`Created account ${values.name}`);
                addAccount(account, setAccounts);
                setSubmitting(false);
                onClose();
            })
            .catch((err) => {
                toast.error(err);
                setSubmitting(false);
            });
    };
    return (
        <Dialog open={show} onClose={onClose}>
            <DialogTitle>Create Personal Account</DialogTitle>

            <DialogContent>
                <Formik
                    initialValues={{ name: "", description: "", owningUserID: null }}
                    onSubmit={handleSubmit}
                    validationSchema={validationSchema}
                >
                    {({
                        values,
                        touched,
                        errors,
                        handleChange,
                        handleBlur,
                        handleSubmit,
                        isSubmitting,
                        setFieldValue,
                    }) => (
                        <Form>
                            <TextField
                                margin="normal"
                                required
                                fullWidth
                                autoFocus
                                variant="standard"
                                name="name"
                                label="Account Name"
                                onBlur={handleBlur}
                                onChange={handleChange}
                                value={values.name}
                                error={touched.name && Boolean(errors.name)}
                                helperText={touched.name && (errors.name as ReactNode)}
                            />
                            <TextField
                                margin="normal"
                                name="description"
                                fullWidth
                                variant="standard"
                                label="Description"
                                onBlur={handleBlur}
                                onChange={handleChange}
                                value={values.description}
                                error={touched.description && Boolean(errors.description)}
                                helperText={touched.description && (errors.description as ReactNode)}
                            />
                            {userPermissions.is_owner ? (
                                <GroupMemberSelect
                                    margin="normal"
                                    group={group}
                                    label="Owning user"
                                    value={values.owningUserID}
                                    onChange={(user_id) => setFieldValue("owningUserID", user_id)}
                                />
                            ) : (
                                <FormControlLabel
                                    control={
                                        <Checkbox
                                            name="owningUserID"
                                            onChange={(e) =>
                                                setFieldValue("owningUserID", e.target.checked ? currentUser.id : null)
                                            }
                                            checked={values.owningUserID === currentUser.id}
                                        />
                                    }
                                    label="This is me"
                                />
                            )}

                            {isSubmitting && <LinearProgress />}
                            <DialogActions>
                                <Button type="submit" color="primary" disabled={isSubmitting}>
                                    Save
                                </Button>
                                <Button color="error" onClick={onClose}>
                                    Cancel
                                </Button>
                            </DialogActions>
                        </Form>
                    )}
                </Formik>
            </DialogContent>
        </Dialog>
    );
}
Example #25
Source File: PolicySelectors.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
PolicySelectors = ({
  classes,
  selectedPolicy = [],
  setSelectedPolicy,
}: ISelectPolicyProps) => {
  const dispatch = useDispatch();
  // Local State
  const [records, setRecords] = useState<any[]>([]);
  const [loading, isLoading] = useState<boolean>(false);
  const [filter, setFilter] = useState<string>("");

  const fetchPolicies = useCallback(() => {
    isLoading(true);

    api
      .invoke("GET", `/api/v1/policies?limit=1000`)
      .then((res: PolicyList) => {
        const policies = res.policies === null ? [] : res.policies;
        isLoading(false);
        setRecords(policies.sort(policySort));
      })
      .catch((err: ErrorResponseHandler) => {
        isLoading(false);
        dispatch(setModalErrorSnackMessage(err));
      });
  }, [dispatch]);

  //Effects
  useEffect(() => {
    isLoading(true);
  }, []);

  useEffect(() => {
    if (loading) {
      fetchPolicies();
    }
  }, [loading, fetchPolicies]);

  const selectionChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
    const targetD = e.target;
    const value = targetD.value;
    const checked = targetD.checked;

    let elements: string[] = [...selectedPolicy]; // We clone the checkedUsers array

    if (checked) {
      // If the user has checked this field we need to push this to checkedUsersList
      elements.push(value);
    } else {
      // User has unchecked this field, we need to remove it from the list
      elements = elements.filter((element) => element !== value);
    }
    // remove empty values
    elements = elements.filter((element) => element !== "");

    setSelectedPolicy(elements);
  };

  const filteredRecords = records.filter((elementItem) =>
    elementItem.name.includes(filter)
  );

  return (
    <React.Fragment>
      <Grid item xs={12}>
        {loading && <LinearProgress />}
        {records.length > 0 ? (
          <React.Fragment>
            <Grid item xs={12} className={classes.filterBox}>
              <span className={classes.fieldLabel}>Assign Policies</span>
              <div className={classes.searchBox}>
                <SearchBox
                  placeholder="Start typing to search for a Policy"
                  onChange={(value) => {
                    setFilter(value);
                  }}
                  value={filter}
                />
              </div>
            </Grid>
            <Grid item xs={12} className={classes.tableBlock}>
              <TableWrapper
                columns={[{ label: "Policy", elementKey: "name" }]}
                onSelect={selectionChanged}
                selectedItems={selectedPolicy}
                isLoading={loading}
                records={filteredRecords}
                entityName="Policies"
                idField="name"
                customPaperHeight={classes.multiSelectTable}
              />
            </Grid>
          </React.Fragment>
        ) : (
          <div className={classes.noFound}>No Policies Available</div>
        )}
      </Grid>
    </React.Fragment>
  );
}
Example #26
Source File: GroupCreateModal.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function GroupCreateModal({ show, onClose }) {
    const handleSubmit = (values, { setSubmitting }) => {
        createGroup({
            name: values.name,
            description: values.description,
            addUserAccountOnJoin: values.addUserAccountOnJoin,
        })
            .then((result) => {
                setSubmitting(false);
                onClose();
            })
            .catch((err) => {
                toast.error(err);
                setSubmitting(false);
            });
    };

    return (
        <Dialog open={show} onClose={onClose}>
            <DialogTitle>Create Group</DialogTitle>
            <DialogContent>
                <Formik
                    initialValues={{ name: "", description: "", addUserAccountOnJoin: false }}
                    onSubmit={handleSubmit}
                    validationSchema={validationSchema}
                >
                    {({
                        values,
                        touched,
                        errors,
                        handleBlur,
                        handleChange,
                        handleSubmit,
                        isSubmitting,
                        setFieldValue,
                    }) => (
                        <Form>
                            <TextField
                                margin="normal"
                                required
                                fullWidth
                                autoFocus
                                variant="standard"
                                type="text"
                                name="name"
                                label="Group Name"
                                value={values.name}
                                onBlur={handleBlur}
                                onChange={handleChange}
                                error={touched.name && Boolean(errors.name)}
                                helperText={touched.name && (errors.name as ReactNode)}
                            />
                            <TextField
                                margin="normal"
                                fullWidth
                                variant="standard"
                                type="text"
                                name="description"
                                label="Description"
                                value={values.description}
                                onBlur={handleBlur}
                                onChange={handleChange}
                                error={touched.description && Boolean(errors.description)}
                                helperText={touched.description && (errors.description as ReactNode)}
                            />
                            <FormControlLabel
                                control={
                                    <Checkbox
                                        name="addUserAccountOnJoin"
                                        onChange={(e) => setFieldValue("addUserAccountOnJoin", e.target.checked)}
                                        checked={values.addUserAccountOnJoin}
                                    />
                                }
                                label="Automatically add accounts for newly joined group members"
                            />
                            {isSubmitting && <LinearProgress />}
                            <DialogActions>
                                <Button type="submit" color="primary" disabled={isSubmitting}>
                                    Save
                                </Button>
                                <Button color="error" onClick={onClose}>
                                    Cancel
                                </Button>
                            </DialogActions>
                        </Form>
                    )}
                </Formik>
            </DialogContent>
        </Dialog>
    );
}
Example #27
Source File: EditConfiguration.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
EditConfiguration = ({
  selectedConfiguration,
  classes,
  history,
  className = "",
}: IAddNotificationEndpointProps) => {
  const dispatch = useDispatch();
  //Local States
  const [valuesObj, setValueObj] = useState<IElementValue[]>([]);
  const [saving, setSaving] = useState<boolean>(false);
  const [loadingConfig, setLoadingConfig] = useState<boolean>(true);
  const [configValues, setConfigValues] = useState<IElementValue[]>([]);
  const [resetConfigurationOpen, setResetConfigurationOpen] =
    useState<boolean>(false);
  //Effects
  useEffect(() => {
    if (loadingConfig) {
      const configId = get(selectedConfiguration, "configuration_id", false);

      if (configId) {
        api
          .invoke("GET", `/api/v1/configs/${configId}`)
          .then((res) => {
            const keyVals = get(res, "key_values", []);
            setConfigValues(keyVals);
            setLoadingConfig(false);
          })
          .catch((err: ErrorResponseHandler) => {
            setLoadingConfig(false);
            dispatch(setErrorSnackMessage(err));
          });

        return;
      }
      setLoadingConfig(false);
    }
  }, [loadingConfig, selectedConfiguration, dispatch]);

  useEffect(() => {
    if (saving) {
      const payload = {
        key_values: removeEmptyFields(valuesObj),
      };
      api
        .invoke(
          "PUT",
          `/api/v1/configs/${selectedConfiguration.configuration_id}`,
          payload
        )
        .then((res) => {
          setSaving(false);
          dispatch(setServerNeedsRestart(res.restart));

          history.push("/settings");
        })
        .catch((err: ErrorResponseHandler) => {
          setSaving(false);
          dispatch(setErrorSnackMessage(err));
        });
    }
  }, [saving, history, dispatch, selectedConfiguration, valuesObj]);

  //Fetch Actions
  const submitForm = (event: React.FormEvent) => {
    event.preventDefault();
    setSaving(true);
  };

  const onValueChange = useCallback(
    (newValue: IElementValue[]) => {
      setValueObj(newValue);
    },
    [setValueObj]
  );

  const continueReset = (restart: boolean) => {
    setResetConfigurationOpen(false);
    dispatch(setServerNeedsRestart(restart));
    if (restart) {
      setLoadingConfig(true);
    }
  };

  return (
    <Fragment>
      {resetConfigurationOpen && (
        <ResetConfigurationModal
          configurationName={selectedConfiguration.configuration_id}
          closeResetModalAndRefresh={continueReset}
          resetOpen={resetConfigurationOpen}
        />
      )}
      {loadingConfig ? (
        <Grid item xs={12}>
          <LinearProgress />
        </Grid>
      ) : (
        <Box
          sx={{
            padding: "15px",
            height: "100%",
          }}
        >
          <form
            noValidate
            onSubmit={submitForm}
            className={className}
            style={{
              height: "100%",
              display: "flex",
              flexFlow: "column",
            }}
          >
            <Grid item xs={12} className={classes.settingsFormContainer}>
              <ConfTargetGeneric
                fields={
                  fieldsConfigurations[selectedConfiguration.configuration_id]
                }
                onChange={onValueChange}
                defaultVals={configValues}
              />
            </Grid>
            <Grid
              item
              xs={12}
              sx={{
                paddingTop: "15px ",
                textAlign: "right" as const,
                maxHeight: "60px",
                display: "flex",
                alignItems: "center",
                justifyContent: "flex-end",
              }}
            >
              <Button
                type="button"
                variant="outlined"
                color="secondary"
                sx={{
                  padding: {
                    xs: "3px", //avoid wrapping on smaller screens
                    md: "20px",
                  },
                }}
                onClick={() => {
                  setResetConfigurationOpen(true);
                }}
              >
                Restore Defaults
              </Button>
              &nbsp; &nbsp;
              <Button
                type="submit"
                variant="contained"
                color="primary"
                disabled={saving}
              >
                Save
              </Button>
            </Grid>
          </form>
        </Box>
      )}
    </Fragment>
  );
}
Example #28
Source File: ModalBody.tsx    From mojito_pdm with Creative Commons Attribution Share Alike 4.0 International 4 votes vote down vote up
ModalBody: React.FC<Modal> = ({name, brand, description, price, trunkspace, setOpen, performance, spawncode}) => {
    const [modalStyle] = useState(getModalStyle)
    const theme = useTheme()
    const [pDialogueOpen, setpDialogueOpen] = useState(false) // Purchase Dialogue
    const [fDialogueOpen, setfDialogueOpen] = useState(false) // Finance Dialogue
    const {visible} = useVisibility()

    useEffect(() => {
        if (visible) return
        setOpen(false)
    }, [visible, setOpen])

    const handleClose = () => {
        setOpen(false)
    }
    const handlepDialogueClose = () => {
        setpDialogueOpen(false)
    }

    const handlefDialogueClose = () => {
        setfDialogueOpen(false)
    }

    const buyEnabled = useRecoilValue(GlobalState.canBuy)

    return (
        <>
            <div style={{
                ...modalStyle,
                position: "absolute",
                width: 600,
                backgroundColor: theme.palette.background.paper,
                boxShadow: theme.shadows[7],
                padding: theme.spacing(2, 4, 3),
                color: theme.palette.mode === "dark" ? "white" : "black"
            }}>
                <h2>{`${brand} ${name}`}</h2>
                <h4>
                    Price: {price} <br/>
                    Trunk Space: {trunkspace}
                </h4>
                {performance &&
                <Typography>
                    Power <LinearProgress value={performance.power} variant="determinate"/>
                    Acceleration <LinearProgress value={performance.acceleration} variant="determinate"/>
                    Handling <LinearProgress value={performance.handling} variant="determinate"/>
                    Top Speed <LinearProgress value={performance.topspeed} variant="determinate"/>
                </Typography>
                }
                <p>
                    {description}
                </p>
                <Stack direction="row" spacing={2}>
                    <Button size="small" variant="outlined" color="error" onClick={handleClose}>Close</Button>
                    { buyEnabled && <Button size="small" variant="outlined" color="primary" onClick={() => setpDialogueOpen(true)}> Buy </Button> }
                    { buyEnabled && <Button size="small" variant="outlined" color="primary" onClick={() => setfDialogueOpen(true)}> Finance </Button> }
                </Stack>
                <Dialog
                    open={pDialogueOpen}
                    TransitionComponent={Transition}
                    keepMounted
                    onClose={handlepDialogueClose}
                >
                    <PurchaseDialogueBody
                        spawncode={spawncode}
                        price={price}
                        setDialogueOpen={setpDialogueOpen}
                        setModalOpen={setOpen}
                    />
                </Dialog>
                <Dialog
                    open={fDialogueOpen}
                    TransitionComponent={Transition}
                    keepMounted
                    onClose={handlefDialogueClose}
                    fullWidth
                    maxWidth={"xs"}
                >
                    <FinanceDialogueBody
                        spawncode={spawncode}
                        price={price}
                        setDialogueOpen={setfDialogueOpen}
                        setModalOpen={setOpen}
                    />
                </Dialog>
            </div>
        </>
    )
}
Example #29
Source File: AddUserScreen.tsx    From console with GNU Affero General Public License v3.0 4 votes vote down vote up
AddUser = ({ classes }: IAddUserProps) => {
  const dispatch = useDispatch();
  const [addLoading, setAddLoading] = useState<boolean>(false);
  const [accessKey, setAccessKey] = useState<string>("");
  const [secretKey, setSecretKey] = useState<string>("");
  const [selectedGroups, setSelectedGroups] = useState<string[]>([]);
  const [selectedPolicies, setSelectedPolicies] = useState<string[]>([]);
  const [showPassword, setShowPassword] = useState<boolean>(false);

  const sendEnabled = accessKey.trim() !== "";

  const saveRecord = (event: React.FormEvent) => {
    event.preventDefault();

    if (secretKey.length < 8) {
      dispatch(
        setErrorSnackMessage({
          errorMessage: "Passwords must be at least 8 characters long",
          detailedError: "",
        })
      );
      setAddLoading(false);
      return;
    }

    if (addLoading) {
      return;
    }
    setAddLoading(true);
    api
      .invoke("POST", "/api/v1/users", {
        accessKey,
        secretKey,
        groups: selectedGroups,
        policies: selectedPolicies,
      })
      .then((res) => {
        setAddLoading(false);
        history.push(`${IAM_PAGES.USERS}`);
      })
      .catch((err: ErrorResponseHandler) => {
        setAddLoading(false);
        dispatch(setErrorSnackMessage(err));
      });
  };

  const resetForm = () => {
    setSelectedGroups([]);
    setAccessKey("");
    setSecretKey("");
    setSelectedPolicies([]);
    setShowPassword(false);
  };

  return (
    <Fragment>
      <Grid item xs={12}>
        <PageHeader label={<BackLink to={IAM_PAGES.USERS} label={"Users"} />} />
        <PageLayout>
          <FormLayout
            title={"Create User"}
            icon={<CreateUserIcon />}
            helpbox={<AddUserHelpBox />}
          >
            <form
              noValidate
              autoComplete="off"
              onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
                saveRecord(e);
              }}
            >
              <Grid item xs={12}>
                <div className={classes.formFieldRow}>
                  <InputBoxWrapper
                    className={classes.spacerBottom}
                    classes={{
                      inputLabel: classes.sizedLabel,
                    }}
                    id="accesskey-input"
                    name="accesskey-input"
                    label="User Name"
                    value={accessKey}
                    autoFocus={true}
                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                      setAccessKey(e.target.value);
                    }}
                  />
                </div>
                <div className={classes.formFieldRow}>
                  <InputBoxWrapper
                    className={classes.spacerBottom}
                    classes={{
                      inputLabel: classes.sizedLabel,
                    }}
                    id="standard-multiline-static"
                    name="standard-multiline-static"
                    label="Password"
                    type={showPassword ? "text" : "password"}
                    value={secretKey}
                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                      setSecretKey(e.target.value);
                    }}
                    autoComplete="current-password"
                    overlayIcon={
                      showPassword ? (
                        <VisibilityOffIcon />
                      ) : (
                        <RemoveRedEyeIcon />
                      )
                    }
                    overlayAction={() => setShowPassword(!showPassword)}
                  />
                </div>
                <Grid container item spacing="20">
                  <Grid item xs={12}>
                    <PolicySelectors
                      selectedPolicy={selectedPolicies}
                      setSelectedPolicy={setSelectedPolicies}
                    />
                  </Grid>
                  <Grid item xs={12}>
                    <GroupsSelectors
                      selectedGroups={selectedGroups}
                      setSelectedGroups={(elements: string[]) => {
                        setSelectedGroups(elements);
                      }}
                    />
                  </Grid>
                </Grid>
                {addLoading && (
                  <Grid item xs={12}>
                    <LinearProgress />
                  </Grid>
                )}
              </Grid>
              <Grid item xs={12} className={classes.modalButtonBar}>
                <Button
                  type="button"
                  variant="outlined"
                  color="primary"
                  onClick={resetForm}
                >
                  Clear
                </Button>

                <Button
                  type="submit"
                  variant="contained"
                  color="primary"
                  disabled={addLoading || !sendEnabled}
                >
                  Save
                </Button>
              </Grid>
            </form>
          </FormLayout>
        </PageLayout>
      </Grid>
    </Fragment>
  );
}