Update Settings Page components (#2986)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -1,181 +0,0 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Box, Tab, TabProps } from "@mui/material";
|
||||
import { TabContext, TabList, TabPanel } from "@mui/lab";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Theme, useTheme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
export type TabItemProps = {
|
||||
tabConfig: TabProps | any;
|
||||
content?: JSX.Element | JSX.Element[];
|
||||
};
|
||||
|
||||
type VerticalTabsProps = {
|
||||
classes: any;
|
||||
children: TabItemProps[];
|
||||
selectedTab?: string;
|
||||
routes?: any;
|
||||
isRouteTabs?: boolean;
|
||||
};
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
tabsContainer: {
|
||||
display: "flex",
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
},
|
||||
tabsHeaderContainer: {
|
||||
width: "300px",
|
||||
background: "#F8F8F8",
|
||||
borderRight: "1px solid #EAEAEA",
|
||||
"& .MuiTabs-root": {
|
||||
"& .MuiTabs-indicator": {
|
||||
display: "none",
|
||||
},
|
||||
"& .MuiTab-root": {
|
||||
display: "flex",
|
||||
flexFlow: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
borderBottom: "1px solid #EAEAEA",
|
||||
"& .MuiSvgIcon-root": {
|
||||
marginRight: 8,
|
||||
marginBottom: 0,
|
||||
},
|
||||
"&.Mui-selected": {
|
||||
background: "#E5E5E5",
|
||||
fontWeight: 600,
|
||||
},
|
||||
},
|
||||
|
||||
"&. MuiTabs-scroller": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
tabContentContainer: {
|
||||
width: "100%",
|
||||
"& .MuiTabPanel-root": {
|
||||
height: "100%",
|
||||
},
|
||||
},
|
||||
tabPanel: {
|
||||
height: "100%",
|
||||
},
|
||||
/*Below md breakpoint make it horizontal and style it for scrolling tabs*/
|
||||
"@media (max-width: 900px)": {
|
||||
tabsContainer: {
|
||||
flexFlow: "column",
|
||||
flexDirection: "column",
|
||||
},
|
||||
tabsHeaderContainer: {
|
||||
width: "100%",
|
||||
borderBottom: " 1px solid #EAEAEA",
|
||||
"& .MuiTabs-root .MuiTabs-scroller .MuiButtonBase-root": {
|
||||
borderBottom: " 0px",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const tabStripStyle = {
|
||||
minHeight: 60,
|
||||
};
|
||||
|
||||
const VerticalTabs = ({
|
||||
children,
|
||||
classes,
|
||||
selectedTab = "0",
|
||||
routes,
|
||||
isRouteTabs,
|
||||
}: VerticalTabsProps) => {
|
||||
const theme = useTheme();
|
||||
const { pathname = "" } = useLocation();
|
||||
|
||||
const isSmallScreen = useMediaQuery(theme.breakpoints.down("md"));
|
||||
|
||||
const [value, setValue] = useState(selectedTab);
|
||||
|
||||
const headerList: TabProps[] = [];
|
||||
const contentList: React.ReactNode[] = [];
|
||||
useEffect(() => {
|
||||
if (isRouteTabs) {
|
||||
const tabConfigElement = children.find(
|
||||
(item) => item.tabConfig.to === pathname,
|
||||
);
|
||||
|
||||
if (tabConfigElement) {
|
||||
setValue(tabConfigElement.tabConfig.value);
|
||||
}
|
||||
}
|
||||
}, [isRouteTabs, children, pathname]);
|
||||
|
||||
if (!children) return null;
|
||||
|
||||
children.forEach((child) => {
|
||||
headerList.push(child.tabConfig);
|
||||
contentList.push(child.content);
|
||||
});
|
||||
|
||||
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
|
||||
setValue(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<TabContext value={`${value}`}>
|
||||
<Box className={classes.tabsContainer}>
|
||||
<Box className={classes.tabsHeaderContainer}>
|
||||
<TabList
|
||||
onChange={handleChange}
|
||||
orientation={isSmallScreen ? "horizontal" : "vertical"}
|
||||
variant={isSmallScreen ? "scrollable" : "standard"}
|
||||
scrollButtons="auto"
|
||||
className={classes.tabList}
|
||||
>
|
||||
{headerList.map((item, index) => {
|
||||
if (item) {
|
||||
return (
|
||||
<Tab
|
||||
className={classes.tabHeader}
|
||||
key={`v-tab-${index}`}
|
||||
value={`${index}`}
|
||||
style={tabStripStyle}
|
||||
{...item}
|
||||
disableRipple
|
||||
disableTouchRipple
|
||||
focusRipple={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
</TabList>
|
||||
</Box>
|
||||
|
||||
<Box className={classes.tabContentContainer}>
|
||||
{!isRouteTabs
|
||||
? contentList.map((item, index) => {
|
||||
return (
|
||||
<TabPanel
|
||||
classes={{ ...classes.tabPanel }}
|
||||
key={`v-tab-p-${index}`}
|
||||
value={`${index}`}
|
||||
>
|
||||
{item ? item : null}
|
||||
</TabPanel>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
{isRouteTabs ? (
|
||||
<div className={classes.tabPanel}>{routes}</div>
|
||||
) : null}
|
||||
</Box>
|
||||
</Box>
|
||||
</TabContext>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(VerticalTabs);
|
||||
@@ -15,27 +15,31 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useCallback, 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 {
|
||||
Box,
|
||||
Grid,
|
||||
HelpBox,
|
||||
PageLayout,
|
||||
ScreenTitle,
|
||||
SettingsIcon,
|
||||
Tabs,
|
||||
} from "mds";
|
||||
|
||||
import { configurationElements } from "../utils";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { HelpBox, PageLayout, SettingsIcon } from "mds";
|
||||
import { Link, Navigate, Route, Routes, useLocation } from "react-router-dom";
|
||||
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
|
||||
import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle";
|
||||
Navigate,
|
||||
Route,
|
||||
Routes,
|
||||
useLocation,
|
||||
useNavigate,
|
||||
} from "react-router-dom";
|
||||
|
||||
import ConfigurationForm from "./ConfigurationForm";
|
||||
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
|
||||
import PageHeaderWrapper from "../../Common/PageHeaderWrapper/PageHeaderWrapper";
|
||||
import ExportConfigButton from "./ExportConfigButton";
|
||||
import ImportConfigButton from "./ImportConfigButton";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
import HelpMenu from "../../HelpMenu";
|
||||
import { setErrorSnackMessage, setHelpName } from "../../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
@@ -43,26 +47,6 @@ import { api } from "../../../../api";
|
||||
import { IElement } from "../types";
|
||||
import { errorToHandler } from "../../../../api/errors";
|
||||
|
||||
interface IConfigurationOptions {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
settingsOptionsContainer: {
|
||||
display: "flex" as const,
|
||||
flexDirection: "row" as const,
|
||||
justifyContent: "flex-start" as const,
|
||||
flexWrap: "wrap" as const,
|
||||
border: "#E5E5E5 1px solid",
|
||||
borderRadius: 2,
|
||||
backgroundColor: "#fff",
|
||||
},
|
||||
...searchField,
|
||||
...actionsTray,
|
||||
...containerForHeader,
|
||||
});
|
||||
|
||||
const getRoutePath = (path: string) => {
|
||||
return `${IAM_PAGES.SETTINGS}/${path}`;
|
||||
};
|
||||
@@ -71,9 +55,10 @@ const getRoutePath = (path: string) => {
|
||||
const NON_SUB_SYS_CONFIG_ITEMS = ["region"];
|
||||
const IGNORED_CONFIG_SUB_SYS = ["cache"]; // cache config is not supported.
|
||||
|
||||
const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
|
||||
const ConfigurationOptions = () => {
|
||||
const { pathname = "" } = useLocation();
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [configSubSysList, setConfigSubSysList] = useState<string[]>([]);
|
||||
const fetchConfigSubSysList = useCallback(async () => {
|
||||
@@ -99,8 +84,6 @@ const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
|
||||
});
|
||||
}, [dispatch]);
|
||||
|
||||
let selConfigTab = pathname.substring(pathname.lastIndexOf("/") + 1);
|
||||
selConfigTab = selConfigTab === "settings" ? "region" : selConfigTab;
|
||||
useEffect(() => {
|
||||
fetchConfigSubSysList();
|
||||
dispatch(setHelpName("settings_Region"));
|
||||
@@ -121,59 +104,57 @@ const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
|
||||
<Fragment>
|
||||
<PageHeaderWrapper label={"Settings"} actions={<HelpMenu />} />
|
||||
<PageLayout>
|
||||
<Grid item xs={12}>
|
||||
<div
|
||||
id="settings-container"
|
||||
className={classes.settingsOptionsContainer}
|
||||
>
|
||||
<ScreenTitle
|
||||
icon={<SettingsIcon />}
|
||||
title={"MinIO Configuration:"}
|
||||
actions={
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<ImportConfigButton />
|
||||
<ExportConfigButton />
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<VerticalTabs
|
||||
selectedTab={selConfigTab}
|
||||
isRouteTabs
|
||||
routes={
|
||||
<Routes>
|
||||
{availableConfigSubSys.map((element) => (
|
||||
<Route
|
||||
key={`configItem-${element.configuration_label}`}
|
||||
path={`${element.configuration_id}`}
|
||||
element={<ConfigurationForm />}
|
||||
/>
|
||||
))}
|
||||
<Grid item xs={12} id={"settings-container"}>
|
||||
<ScreenTitle
|
||||
icon={<SettingsIcon />}
|
||||
title={"MinIO Configuration:"}
|
||||
actions={
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: 10,
|
||||
}}
|
||||
>
|
||||
<ImportConfigButton />
|
||||
<ExportConfigButton />
|
||||
</Box>
|
||||
}
|
||||
sx={{ marginBottom: 15 }}
|
||||
/>
|
||||
<Tabs
|
||||
currentTabOrPath={pathname}
|
||||
onTabClick={(path) => {
|
||||
navigate(path);
|
||||
}}
|
||||
useRouteTabs
|
||||
options={availableConfigSubSys.map((element) => {
|
||||
const { configuration_id, configuration_label, icon } = element;
|
||||
return {
|
||||
tabConfig: {
|
||||
id: `settings-tab-${configuration_label}`,
|
||||
label: configuration_label,
|
||||
value: configuration_id,
|
||||
icon: icon,
|
||||
to: getRoutePath(configuration_id),
|
||||
},
|
||||
};
|
||||
})}
|
||||
routes={
|
||||
<Routes>
|
||||
{availableConfigSubSys.map((element) => (
|
||||
<Route
|
||||
path={"/"}
|
||||
element={<Navigate to={`${IAM_PAGES.SETTINGS}/region`} />}
|
||||
key={`configItem-${element.configuration_label}`}
|
||||
path={`${element.configuration_id}`}
|
||||
element={<ConfigurationForm />}
|
||||
/>
|
||||
</Routes>
|
||||
}
|
||||
>
|
||||
{availableConfigSubSys.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>
|
||||
))}
|
||||
<Route
|
||||
path={"/"}
|
||||
element={<Navigate to={`${IAM_PAGES.SETTINGS}/region`} />}
|
||||
/>
|
||||
</Routes>
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ paddingTop: "15px" }}>
|
||||
<HelpBox
|
||||
@@ -203,4 +184,4 @@ const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ConfigurationOptions);
|
||||
export default ConfigurationOptions;
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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 from "react";
|
||||
import { Button, UploadIcon } from "mds";
|
||||
import useApi from "../../Common/Hooks/useApi";
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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, useEffect, useRef, useState } from "react";
|
||||
import { Button, DownloadIcon } from "mds";
|
||||
import useApi from "../../Common/Hooks/useApi";
|
||||
|
||||
@@ -14,38 +14,27 @@
|
||||
// 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 } 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, IOverrideEnv, KVField } from "../Configurations/types";
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import {
|
||||
formFieldStyles,
|
||||
modalBasic,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
CommentBox,
|
||||
ConsoleIcon,
|
||||
FormLayout,
|
||||
Grid,
|
||||
InputBox,
|
||||
ReadBox,
|
||||
Switch,
|
||||
Tooltip,
|
||||
} from "mds";
|
||||
import { IElementValue, IOverrideEnv, KVField } from "../Configurations/types";
|
||||
import CSVMultiSelector from "../Common/FormComponents/CSVMultiSelector/CSVMultiSelector";
|
||||
import CommentBoxWrapper from "../Common/FormComponents/CommentBoxWrapper/CommentBoxWrapper";
|
||||
import PredefinedList from "../Common/FormComponents/PredefinedList/PredefinedList";
|
||||
import { ConsoleIcon, InputBox, Switch, Tooltip } from "mds";
|
||||
|
||||
interface IConfGenericProps {
|
||||
onChange: (newValue: IElementValue[]) => void;
|
||||
fields: KVField[];
|
||||
defaultVals?: IElementValue[];
|
||||
overrideEnv?: IOverrideEnv;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...formFieldStyles,
|
||||
formFieldRow: {
|
||||
...formFieldStyles.formFieldRow,
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
// Function to get defined values,
|
||||
//we make this because the backed sometimes don't return all the keys when there is an initial configuration
|
||||
export const valueDef = (
|
||||
@@ -71,7 +60,6 @@ const ConfTargetGeneric = ({
|
||||
fields,
|
||||
defaultVals,
|
||||
overrideEnv,
|
||||
classes,
|
||||
}: IConfGenericProps) => {
|
||||
const [valueHolder, setValueHolder] = useState<IElementValue[]>([]);
|
||||
const fieldsElements = !fields ? [] : fields;
|
||||
@@ -113,9 +101,8 @@ const ConfTargetGeneric = ({
|
||||
|
||||
if (override) {
|
||||
return (
|
||||
<PredefinedList
|
||||
<ReadBox
|
||||
label={field.label}
|
||||
content={override.value}
|
||||
actionButton={
|
||||
<Grid
|
||||
item
|
||||
@@ -133,7 +120,10 @@ const ConfTargetGeneric = ({
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
}
|
||||
/>
|
||||
sx={{ width: "100%" }}
|
||||
>
|
||||
{override.value}
|
||||
</ReadBox>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -180,15 +170,13 @@ const ConfTargetGeneric = ({
|
||||
);
|
||||
case "comment":
|
||||
return (
|
||||
<CommentBoxWrapper
|
||||
<CommentBox
|
||||
id={field.name}
|
||||
name={field.name}
|
||||
label={field.label}
|
||||
tooltip={field.tooltip}
|
||||
value={holderItem ? holderItem.value : ""}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setValueElement(field.name, e.target.value, item)
|
||||
}
|
||||
onChange={(e) => setValueElement(field.name, e.target.value, item)}
|
||||
placeholder={field.placeholder}
|
||||
/>
|
||||
);
|
||||
@@ -210,16 +198,12 @@ const ConfTargetGeneric = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container>
|
||||
<Grid xs={12} item className={classes.fieldBox}>
|
||||
{fieldsElements.map((field, item) => (
|
||||
<Grid item xs={12} key={field.name} className={classes.formFieldRow}>
|
||||
{fieldDefinition(field, item)}
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<FormLayout withBorders={false} containerPadding={false}>
|
||||
{fieldsElements.map((field, item) => (
|
||||
<Fragment key={field.name}>{fieldDefinition(field, item)}</Fragment>
|
||||
))}
|
||||
</FormLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ConfTargetGeneric);
|
||||
export default ConfTargetGeneric;
|
||||
|
||||
@@ -15,20 +15,13 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useCallback, useEffect, useState } from "react";
|
||||
import { Button, Loader } from "mds";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import get from "lodash/get";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Box } from "@mui/material";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import ConfTargetGeneric from "../ConfTargetGeneric";
|
||||
|
||||
import {
|
||||
fieldBasic,
|
||||
settingsCommon,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { Box, Button, Grid, Loader } from "mds";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { api } from "api";
|
||||
import { Configuration, ConfigurationKV } from "api/consoleApi";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import {
|
||||
fieldsConfigurations,
|
||||
overrideFields,
|
||||
@@ -40,7 +33,6 @@ import {
|
||||
IOverrideEnv,
|
||||
KVField,
|
||||
} from "../../Configurations/types";
|
||||
import ResetConfigurationModal from "./ResetConfigurationModal";
|
||||
import {
|
||||
configurationIsLoading,
|
||||
setErrorSnackMessage,
|
||||
@@ -50,31 +42,16 @@ import {
|
||||
} from "../../../../systemSlice";
|
||||
import { AppState, useAppDispatch } from "../../../../store";
|
||||
import WebhookSettings from "../WebhookSettings/WebhookSettings";
|
||||
import { useSelector } from "react-redux";
|
||||
import { api } from "api";
|
||||
import { Configuration, ConfigurationKV } from "api/consoleApi";
|
||||
import { errorToHandler } from "api/errors";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...fieldBasic,
|
||||
...settingsCommon,
|
||||
settingsFormContainer: {
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
gridGap: "10px",
|
||||
},
|
||||
});
|
||||
import ConfTargetGeneric from "../ConfTargetGeneric";
|
||||
import ResetConfigurationModal from "./ResetConfigurationModal";
|
||||
|
||||
interface IAddNotificationEndpointProps {
|
||||
selectedConfiguration: IConfigurationElement;
|
||||
classes: any;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const EditConfiguration = ({
|
||||
selectedConfiguration,
|
||||
classes,
|
||||
className = "",
|
||||
}: IAddNotificationEndpointProps) => {
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -238,7 +215,15 @@ const EditConfiguration = ({
|
||||
flexFlow: "column",
|
||||
}}
|
||||
>
|
||||
<Grid item xs={12} className={classes.settingsFormContainer}>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
gap: "10px",
|
||||
}}
|
||||
>
|
||||
<ConfTargetGeneric
|
||||
fields={
|
||||
fieldsConfigurations[
|
||||
@@ -263,6 +248,7 @@ const EditConfiguration = ({
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type={"button"}
|
||||
id={"restore-defaults"}
|
||||
variant="secondary"
|
||||
onClick={resetConfigurationMOpen}
|
||||
@@ -287,4 +273,4 @@ const EditConfiguration = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(EditConfiguration);
|
||||
export default EditConfiguration;
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useState } from "react";
|
||||
import { Button, Grid } from "mds";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import { Button, FormLayout, Grid, InputBox } from "mds";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import { Webhook } from "@mui/icons-material";
|
||||
import { formFieldStyles } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import CallToActionIcon from "@mui/icons-material/CallToAction";
|
||||
import PendingActionsIcon from "@mui/icons-material/PendingActions";
|
||||
import {
|
||||
@@ -30,8 +30,7 @@ import {
|
||||
} from "../../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import { modalStyleUtils } from "../../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
interface IEndpointModal {
|
||||
open: boolean;
|
||||
@@ -148,8 +147,8 @@ const AddEndpointModal = ({ open, type, onCloseEndpoint }: IEndpointModal) => {
|
||||
onClose={onCloseEndpoint}
|
||||
titleIcon={icon}
|
||||
>
|
||||
<Grid item xs={12} sx={{ ...formFieldStyles.formFieldRow }}>
|
||||
<InputBoxWrapper
|
||||
<FormLayout containerPadding={false} withBorders={false}>
|
||||
<InputBox
|
||||
id="name"
|
||||
name="name"
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -167,9 +166,7 @@ const AddEndpointModal = ({ open, type, onCloseEndpoint }: IEndpointModal) => {
|
||||
pattern={"^(?=.*[a-zA-Z0-9]).{1,}$"}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ ...formFieldStyles.formFieldRow }}>
|
||||
<InputBoxWrapper
|
||||
<InputBox
|
||||
id="endpoint"
|
||||
name="endpoint"
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -190,9 +187,7 @@ const AddEndpointModal = ({ open, type, onCloseEndpoint }: IEndpointModal) => {
|
||||
}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ ...formFieldStyles.formFieldRow }}>
|
||||
<InputBoxWrapper
|
||||
<InputBox
|
||||
id="auth-token"
|
||||
name="auth-token"
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -202,7 +197,7 @@ const AddEndpointModal = ({ open, type, onCloseEndpoint }: IEndpointModal) => {
|
||||
label="Auth Token"
|
||||
value={authToken}
|
||||
/>
|
||||
</Grid>
|
||||
</FormLayout>
|
||||
{saving && (
|
||||
<Grid
|
||||
item
|
||||
@@ -214,14 +209,7 @@ const AddEndpointModal = ({ open, type, onCloseEndpoint }: IEndpointModal) => {
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Grid item xs={12} sx={modalStyleUtils.modalButtonBar}>
|
||||
<Button
|
||||
id={"reset"}
|
||||
type="button"
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
// 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 } from "react";
|
||||
import React, { useEffect, useState, Fragment } from "react";
|
||||
import { ConfirmDeleteIcon } from "mds";
|
||||
import { DialogContentText } from "@mui/material";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
import {
|
||||
configurationIsLoading,
|
||||
@@ -24,8 +25,6 @@ import {
|
||||
setServerNeedsRestart,
|
||||
} from "../../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
import { api } from "api";
|
||||
import { errorToHandler } from "api/errors";
|
||||
|
||||
interface IDeleteWebhookEndpoint {
|
||||
modalOpen: boolean;
|
||||
@@ -38,7 +37,6 @@ const DeleteWebhookEndpoint = ({
|
||||
modalOpen,
|
||||
onClose,
|
||||
selectedARN,
|
||||
type,
|
||||
}: IDeleteWebhookEndpoint) => {
|
||||
const [deleteLoading, setDeleteLoading] = useState<boolean>(false);
|
||||
|
||||
@@ -84,10 +82,10 @@ const DeleteWebhookEndpoint = ({
|
||||
titleIcon={<ConfirmDeleteIcon />}
|
||||
onClose={onClose}
|
||||
confirmationContent={
|
||||
<DialogContentText>
|
||||
<Fragment>
|
||||
{`${message} `}
|
||||
<strong>{selectedARN}</strong>?
|
||||
</DialogContentText>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -43,11 +43,10 @@ test("All vertical tab items exist", async (t) => {
|
||||
const settingsHealTabExists = elements.settingsHealTab.exists;
|
||||
const settingsScannerTabExists = elements.settingsScannerTab.exists;
|
||||
const settingsEtcdTabExists = elements.settingsEtcdTab.exists;
|
||||
const settingsOpenIdTabExists = elements.settingsOpenIdTab.exists;
|
||||
const settingsLdapTabExists = elements.settingsLdapTab.exists;
|
||||
const settingsLoggerWebhookTabExists =
|
||||
elements.settingsLoggerWebhookTab.exists;
|
||||
const settingsAuditWebhookTabExists = elements.settingsAuditWebhookTab.exists;
|
||||
const settingsAuditKafkaTabExists = elements.settingsAuditKafkaTab.exists;
|
||||
await t
|
||||
.navigateTo("http://localhost:9090/settings/configurations")
|
||||
.expect(settingsRegionTabExists)
|
||||
@@ -65,5 +64,7 @@ test("All vertical tab items exist", async (t) => {
|
||||
.expect(settingsLoggerWebhookTabExists)
|
||||
.ok()
|
||||
.expect(settingsAuditWebhookTabExists)
|
||||
.ok()
|
||||
.expect(settingsAuditKafkaTabExists)
|
||||
.ok();
|
||||
});
|
||||
|
||||
@@ -123,45 +123,41 @@ export const settingsWindow = Selector("#settings-container");
|
||||
//----------------------------------------------------
|
||||
// Settings page vertical tabs
|
||||
//----------------------------------------------------
|
||||
export const settingsRegionTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/region",
|
||||
export const settingsRegionTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Region",
|
||||
);
|
||||
export const settingsCompressionTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/compression",
|
||||
export const settingsCompressionTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Compression",
|
||||
);
|
||||
export const settingsApiTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/api",
|
||||
export const settingsApiTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-API",
|
||||
);
|
||||
export const settingsHealTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/heal",
|
||||
export const settingsHealTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Heal",
|
||||
);
|
||||
export const settingsScannerTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/scanner",
|
||||
export const settingsScannerTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Scanner",
|
||||
);
|
||||
export const settingsEtcdTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/etcd",
|
||||
export const settingsEtcdTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Etcd",
|
||||
);
|
||||
export const settingsOpenIdTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/identity_openid",
|
||||
export const settingsLoggerWebhookTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Logger Webhook",
|
||||
);
|
||||
export const settingsLdapTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/identity_ldap",
|
||||
export const settingsAuditWebhookTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Audit Webhook",
|
||||
);
|
||||
export const settingsLoggerWebhookTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/logger_webhook",
|
||||
);
|
||||
export const settingsAuditWebhookTab = Selector(".MuiTab-root").withAttribute(
|
||||
"href",
|
||||
"/settings/configurations/audit_webhook",
|
||||
export const settingsAuditKafkaTab = Selector("button").withAttribute(
|
||||
"id",
|
||||
"settings-tab-Audit Kafka",
|
||||
);
|
||||
|
||||
//----------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user