Settings page ux refactor (#1242)
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
575bf2927d
commit
f56b4905c9
@@ -146,6 +146,7 @@ const CSVMultiSelector = ({
|
||||
<InputBoxWrapper
|
||||
id={`${name}-${index.toString()}`}
|
||||
label={""}
|
||||
classes={classes}
|
||||
name={`${name}-${index.toString()}`}
|
||||
value={currentElements[index]}
|
||||
onChange={onChangeElement}
|
||||
|
||||
@@ -148,7 +148,9 @@ const InputBoxWrapper = ({
|
||||
<React.Fragment>
|
||||
<Grid
|
||||
container
|
||||
className={` ${error !== "" ? classes.errorInField : ""}`}
|
||||
className={` ${
|
||||
error !== "" ? classes.errorInField : classes.inputBoxContainer
|
||||
}`}
|
||||
>
|
||||
{label !== "" && (
|
||||
<InputLabel
|
||||
|
||||
@@ -388,8 +388,7 @@ export const settingsCommon = {
|
||||
margin: "15px 38px 27px",
|
||||
},
|
||||
settingsFormContainer: {
|
||||
height: "calc(100vh - 421px)",
|
||||
padding: "15px 38px",
|
||||
padding: 38,
|
||||
overflowY: "auto" as const,
|
||||
scrollbarWidth: "none" as const,
|
||||
"&::-webkit-scrollbar": {
|
||||
@@ -397,7 +396,6 @@ export const settingsCommon = {
|
||||
},
|
||||
},
|
||||
settingsButtonContainer: {
|
||||
borderTop: "1px solid #EAEAEA",
|
||||
padding: "15px 38px",
|
||||
textAlign: "right" as const,
|
||||
},
|
||||
|
||||
@@ -24,6 +24,7 @@ const styles = (theme: Theme) =>
|
||||
tabsContainer: {
|
||||
display: "flex",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
},
|
||||
tabsHeaderContainer: {
|
||||
width: "300px",
|
||||
@@ -39,11 +40,9 @@ const styles = (theme: Theme) =>
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
borderBottom: "1px solid #EAEAEA",
|
||||
"& .min-icon": {
|
||||
marginRight: ".3rem",
|
||||
"& .MuiSvgIcon-root": {
|
||||
marginRight: 8,
|
||||
marginBottom: 0,
|
||||
height: ".8rem",
|
||||
width: ".8rem",
|
||||
},
|
||||
"&.Mui-selected": {
|
||||
background: "#E5E5E5",
|
||||
|
||||
@@ -18,15 +18,13 @@ import React from "react";
|
||||
import { Route, Router, Switch } from "react-router-dom";
|
||||
import history from "../../../history";
|
||||
import ConfigurationOptions from "./ConfigurationPanels/ConfigurationOptions";
|
||||
import ConfigurationForm from "./ConfigurationPanels/ConfigurationForm";
|
||||
import NotFoundPage from "../../NotFoundPage";
|
||||
|
||||
const ConfigurationMain = () => {
|
||||
return (
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path="/settings" exact component={ConfigurationOptions} />
|
||||
<Route path="/settings/:option" component={ConfigurationForm} />
|
||||
<Route path="/settings" component={ConfigurationOptions} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</Router>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment } from "react";
|
||||
import React from "react";
|
||||
import get from "lodash/get";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
@@ -28,8 +28,6 @@ import {
|
||||
searchField,
|
||||
settingsCommon,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import BackLink from "../../../../common/BackLink";
|
||||
import PageHeader from "../../Common/PageHeader/PageHeader";
|
||||
|
||||
interface IListConfiguration {
|
||||
classes: any;
|
||||
@@ -65,36 +63,27 @@ const styles = (theme: Theme) =>
|
||||
},
|
||||
});
|
||||
|
||||
const ConfigurationsList = ({
|
||||
classes,
|
||||
match,
|
||||
history,
|
||||
}: IListConfiguration) => {
|
||||
const configurationName = get(match, "params.option", "");
|
||||
const ConfigurationsList = ({ match, history }: IListConfiguration) => {
|
||||
const activeConfRoute = get(match, "url", "");
|
||||
|
||||
const findConfiguration = configurationElements.find(
|
||||
(element) => element.configuration_id === configurationName
|
||||
const configName = activeConfRoute.substring(
|
||||
activeConfRoute.lastIndexOf("/") + 1
|
||||
);
|
||||
|
||||
const validActiveConfig = configurationElements.find(
|
||||
(element) => element.configuration_id === configName
|
||||
);
|
||||
const containerClassName = `${configName}`;
|
||||
return (
|
||||
<Fragment>
|
||||
<PageHeader
|
||||
label={`${findConfiguration?.configuration_label} Settings`}
|
||||
/>
|
||||
<Grid container className={classes.container}>
|
||||
<Grid item xs={12} className={classes.mainTitle}>
|
||||
<BackLink to="/settings" label="Return to Settings" />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{findConfiguration && (
|
||||
<EditConfiguration
|
||||
selectedConfiguration={findConfiguration}
|
||||
history={history}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
<Grid item xs={12}>
|
||||
{validActiveConfig && (
|
||||
<EditConfiguration
|
||||
className={`${containerClassName}`}
|
||||
selectedConfiguration={validActiveConfig}
|
||||
history={history}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -27,12 +27,19 @@ import {
|
||||
searchField,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import PageHeader from "../../Common/PageHeader/PageHeader";
|
||||
import SettingsCard from "../../Common/SettingsCard/SettingsCard";
|
||||
import HelpBox from "../../../../common/HelpBox";
|
||||
import { SettingsIcon } from "../../../../icons";
|
||||
import { Link, Redirect, Route, Router, Switch } from "react-router-dom";
|
||||
import ConfigurationForm from "./ConfigurationForm";
|
||||
import history from "../../../../history";
|
||||
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
|
||||
import PageLayout from "../../Common/Layout/PageLayout";
|
||||
import get from "lodash/get";
|
||||
import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle";
|
||||
|
||||
interface IConfigurationOptions {
|
||||
classes: any;
|
||||
match: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -60,7 +67,6 @@ const styles = (theme: Theme) =>
|
||||
flexWrap: "wrap" as const,
|
||||
border: "#E5E5E5 1px solid",
|
||||
borderRadius: 2,
|
||||
padding: 5,
|
||||
backgroundColor: "#fff",
|
||||
},
|
||||
configurationLink: {
|
||||
@@ -76,20 +82,63 @@ const styles = (theme: Theme) =>
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
|
||||
const getRoutePath = (path: string) => {
|
||||
return `/settings/${path}`;
|
||||
};
|
||||
|
||||
const ConfigurationOptions = ({ classes, match }: IConfigurationOptions) => {
|
||||
const configurationName = get(match, "url", "");
|
||||
let selConfigTab = configurationName.substring(
|
||||
configurationName.lastIndexOf("/") + 1
|
||||
);
|
||||
selConfigTab = selConfigTab === "settings" ? "region" : selConfigTab;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageHeader label={"Settings"} />
|
||||
<Grid container className={classes.container}>
|
||||
|
||||
<PageLayout>
|
||||
<Grid item xs={12}>
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.settingsOptionsContainer}>
|
||||
{configurationElements.map((element) => (
|
||||
<SettingsCard
|
||||
configuration={element}
|
||||
key={`configItem-${element.configuration_label}`}
|
||||
/>
|
||||
))}
|
||||
<ScreenTitle icon={<SettingsIcon />} title={"Configuration:"} />
|
||||
<VerticalTabs
|
||||
selectedTab={selConfigTab}
|
||||
isRouteTabs
|
||||
routes={
|
||||
<div className={classes.contentSpacer}>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
{configurationElements.map((element) => (
|
||||
<Route
|
||||
exact
|
||||
key={`configItem-${element.configuration_label}`}
|
||||
path={`/settings/${element.configuration_id}`}
|
||||
component={ConfigurationForm}
|
||||
/>
|
||||
))}
|
||||
<Route exact path="/settings">
|
||||
<Redirect to="/settings/region" />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{configurationElements.map((element) => {
|
||||
const { configuration_id, configuration_label, icon } =
|
||||
element;
|
||||
return {
|
||||
tabConfig: {
|
||||
label: configuration_label,
|
||||
value: configuration_id,
|
||||
icon: icon,
|
||||
component: Link,
|
||||
to: getRoutePath(configuration_id),
|
||||
},
|
||||
};
|
||||
})}
|
||||
</VerticalTabs>
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -116,7 +165,7 @@ const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</PageLayout>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -86,6 +86,7 @@ const IconsScreen = React.lazy(() => import("./Common/IconsScreen"));
|
||||
|
||||
const Speedtest = React.lazy(() => import("./Speedtest/Speedtest"));
|
||||
|
||||
|
||||
const drawerWidth = 245;
|
||||
|
||||
const Buckets = React.lazy(() => import("./Buckets/Buckets"));
|
||||
@@ -102,6 +103,7 @@ const TenantDetails = React.lazy(
|
||||
() => import("./Tenants/TenantDetails/TenantDetails")
|
||||
);
|
||||
const License = React.lazy(() => import("./License/License"));
|
||||
const ConfigurationOptions = React.lazy(() => import("./Configurations/ConfigurationPanels/ConfigurationOptions"));
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -341,11 +343,11 @@ const Console = ({
|
||||
path: "/tools",
|
||||
},
|
||||
{
|
||||
component: ConfigurationMain,
|
||||
component: ConfigurationOptions,
|
||||
path: "/settings",
|
||||
},
|
||||
{
|
||||
component: ConfigurationMain,
|
||||
component: ConfigurationOptions,
|
||||
path: "/settings/:option",
|
||||
},
|
||||
{
|
||||
|
||||
@@ -14,13 +14,17 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { useEffect, useState, Fragment } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { IElementValue, KVField } from "../Configurations/types";
|
||||
import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
fieldBasic,
|
||||
formFieldStyles,
|
||||
modalBasic,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import CSVMultiSelector from "../Common/FormComponents/CSVMultiSelector/CSVMultiSelector";
|
||||
import CommentBoxWrapper from "../Common/FormComponents/CommentBoxWrapper/CommentBoxWrapper";
|
||||
@@ -35,6 +39,52 @@ interface IConfGenericProps {
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...formFieldStyles,
|
||||
formFieldRow: {
|
||||
...formFieldStyles.formFieldRow,
|
||||
},
|
||||
inputBoxContainer: {
|
||||
marginBottom: 7,
|
||||
"& .MuiInputLabel-root": {
|
||||
minWidth: 200,
|
||||
"& svg": {
|
||||
width: 16,
|
||||
height: 16,
|
||||
},
|
||||
},
|
||||
"& div[class|='InputBoxWrapper-textBoxContainer']": {
|
||||
display: "flex",
|
||||
},
|
||||
},
|
||||
overlayAction: {
|
||||
top: 0,
|
||||
right: 0,
|
||||
position: "relative",
|
||||
marginLeft: 10,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
"& button": {
|
||||
background: "#EAEAEA",
|
||||
},
|
||||
},
|
||||
fieldContainer: {
|
||||
"& .MuiInputLabel-root": {
|
||||
flex: 1,
|
||||
minWidth: 200,
|
||||
},
|
||||
"& div[class|='CommentBoxWrapper-textBoxContainer']": {
|
||||
flexGrow: 1,
|
||||
width: "100%",
|
||||
},
|
||||
},
|
||||
tooltipContainer: {
|
||||
...fieldBasic.tooltipContainer,
|
||||
"& svg": {
|
||||
width: 16,
|
||||
height: 16,
|
||||
},
|
||||
},
|
||||
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
@@ -102,6 +152,7 @@ const ConfTargetGeneric = ({
|
||||
|
||||
return (
|
||||
<FormSwitchWrapper
|
||||
classes={classes}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.checked ? "true" : "false";
|
||||
setValueElement(field.name, value, item);
|
||||
@@ -117,6 +168,7 @@ const ConfTargetGeneric = ({
|
||||
case "csv":
|
||||
return (
|
||||
<CSVMultiSelector
|
||||
classes={classes}
|
||||
elements={valueHolder[item] ? valueHolder[item].value : ""}
|
||||
label={field.label}
|
||||
name={field.name}
|
||||
@@ -125,12 +177,13 @@ const ConfTargetGeneric = ({
|
||||
}
|
||||
tooltip={field.tooltip}
|
||||
commonPlaceholder={field.placeholder}
|
||||
withBorder={!!field.withBorder}
|
||||
withBorder={true}
|
||||
/>
|
||||
);
|
||||
case "comment":
|
||||
return (
|
||||
<CommentBoxWrapper
|
||||
classes={classes}
|
||||
id={field.name}
|
||||
name={field.name}
|
||||
label={field.label}
|
||||
@@ -145,6 +198,7 @@ const ConfTargetGeneric = ({
|
||||
default:
|
||||
return (
|
||||
<InputBoxWrapper
|
||||
classes={classes}
|
||||
id={field.name}
|
||||
name={field.name}
|
||||
label={field.label}
|
||||
@@ -162,13 +216,11 @@ const ConfTargetGeneric = ({
|
||||
|
||||
return (
|
||||
<Grid container>
|
||||
<Grid xs={12} item>
|
||||
<Grid xs={12} item className={classes.fieldBox}>
|
||||
{fieldsElements.map((field, item) => (
|
||||
<Fragment key={field.name}>
|
||||
<Grid item xs={12}>
|
||||
{fieldDefinition(field, item)}
|
||||
</Grid>
|
||||
</Fragment>
|
||||
<Grid item xs={12} key={field.name} className={classes.formFieldRow}>
|
||||
{fieldDefinition(field, item)}
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -68,6 +68,7 @@ interface IAddNotificationEndpointProps {
|
||||
selectedConfiguration: IConfigurationElement;
|
||||
classes: any;
|
||||
history: any;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const EditConfiguration = ({
|
||||
@@ -76,6 +77,7 @@ const EditConfiguration = ({
|
||||
setErrorSnackMessage,
|
||||
classes,
|
||||
history,
|
||||
className = "",
|
||||
}: IAddNotificationEndpointProps) => {
|
||||
//Local States
|
||||
const [valuesObj, setValueObj] = useState<IElementValue[]>([]);
|
||||
@@ -147,7 +149,7 @@ const EditConfiguration = ({
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<form noValidate onSubmit={submitForm}>
|
||||
<form noValidate onSubmit={submitForm} className={className}>
|
||||
<Grid item xs={12} className={classes.settingsFormContainer}>
|
||||
{loadingConfig && (
|
||||
<Grid item xs={12}>
|
||||
|
||||
Reference in New Issue
Block a user