@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 |
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 |
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 |
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 |
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 |
export default function DetailLoading() {
return (
<div className={styles.main}>
<Typography color="textSecondary">Getting your messages…</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 |
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 |
/**
* 페이지 로딩 애니메이션입니다.
*/
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 |
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 |
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 |
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 |
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 |
BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
height: 10,
borderRadius: 5,
}))
Example #13
Source File: MarketItem.tsx From Cromwell with MIT License | 5 votes |
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 |
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 |
function AppLoading() {
return <LinearProgress />;
}
Example #16
Source File: index.tsx From ExpressLRS-Configurator with GNU General Public License v3.0 | 5 votes |
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 |
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 |
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 |
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 |
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 |
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,
<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 |
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 |
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
<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 |
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 |
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 |
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 |
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>
<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 |
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 |
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>
);
}