First set of changes for settings pages new design (#493)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -22,7 +22,7 @@ import (
|
|||||||
|
|
||||||
// endpoints definition
|
// endpoints definition
|
||||||
var (
|
var (
|
||||||
configuration = "/configurations-list"
|
configuration = "/settings"
|
||||||
users = "/users"
|
users = "/users"
|
||||||
groups = "/groups"
|
groups = "/groups"
|
||||||
iamPolicies = "/policies"
|
iamPolicies = "/policies"
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
53
portal-ui/src/icons/BackSettingsIcon.tsx
Normal file
53
portal-ui/src/icons/BackSettingsIcon.tsx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// This file is part of MinIO Console Server
|
||||||
|
// Copyright (c) 2020 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 { SvgIcon } from "@material-ui/core";
|
||||||
|
|
||||||
|
const BackSettingsIcon = () => (
|
||||||
|
<SvgIcon viewBox="0 0 10.847 6.572">
|
||||||
|
<g transform="translate(-84.793 -81.193)">
|
||||||
|
<line
|
||||||
|
x2="9.64"
|
||||||
|
transform="translate(85.5 84.5)"
|
||||||
|
fill="none"
|
||||||
|
stroke="#000"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
y1="2.558"
|
||||||
|
x2="2.645"
|
||||||
|
transform="translate(85.5 81.9)"
|
||||||
|
fill="none"
|
||||||
|
stroke="#000"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
x2="2.645"
|
||||||
|
y2="2.558"
|
||||||
|
transform="translate(85.5 84.5)"
|
||||||
|
fill="none"
|
||||||
|
stroke="#000"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</SvgIcon>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default BackSettingsIcon;
|
||||||
@@ -105,10 +105,9 @@ const Account = ({ classes }: IServiceAccountsProps) => {
|
|||||||
newServiceAccount,
|
newServiceAccount,
|
||||||
setNewServiceAccount,
|
setNewServiceAccount,
|
||||||
] = useState<NewServiceAccount | null>(null);
|
] = useState<NewServiceAccount | null>(null);
|
||||||
const [
|
const [changePasswordModalOpen, setChangePasswordModalOpen] = useState<
|
||||||
changePasswordModalOpen,
|
boolean
|
||||||
setChangePasswordModalOpen,
|
>(false);
|
||||||
] = useState<boolean>(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchRecords();
|
fetchRecords();
|
||||||
|
|||||||
@@ -217,10 +217,9 @@ const ViewBucket = ({ classes, match }: IViewBucketProps) => {
|
|||||||
);
|
);
|
||||||
const [curTab, setCurTab] = useState<number>(0);
|
const [curTab, setCurTab] = useState<number>(0);
|
||||||
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
|
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
|
||||||
const [
|
const [enableEncryptionScreenOpen, setEnableEncryptionScreenOpen] = useState<
|
||||||
enableEncryptionScreenOpen,
|
boolean
|
||||||
setEnableEncryptionScreenOpen,
|
>(false);
|
||||||
] = useState<boolean>(false);
|
|
||||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||||
const [selectedEvent, setSelectedEvent] = useState<BucketEvent | null>(null);
|
const [selectedEvent, setSelectedEvent] = useState<BucketEvent | null>(null);
|
||||||
const [bucketSize, setBucketSize] = useState<string>("0");
|
const [bucketSize, setBucketSize] = useState<string>("0");
|
||||||
|
|||||||
@@ -238,3 +238,29 @@ export const selectorsCommon = {
|
|||||||
height: 200,
|
height: 200,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const settingsCommon = {
|
||||||
|
customTitle: {
|
||||||
|
fontSize: 18,
|
||||||
|
color: "#000",
|
||||||
|
fontWeight: 600,
|
||||||
|
padding: "12px 0",
|
||||||
|
borderBottom: "#eaedee 1px solid",
|
||||||
|
marginBottom: 10,
|
||||||
|
margin: "15px 38px 27px",
|
||||||
|
},
|
||||||
|
settingsFormContainer: {
|
||||||
|
height: "calc(100vh - 421px)",
|
||||||
|
padding: "15px 38px",
|
||||||
|
overflowY: "auto" as const,
|
||||||
|
scrollbarWidth: "none" as const,
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
display: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
settingsButtonContainer: {
|
||||||
|
borderTop: "1px solid #EAEAEA",
|
||||||
|
padding: "15px 38px",
|
||||||
|
textAlign: "right" as const,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
// This file is part of MinIO Console Server
|
||||||
|
// Copyright (c) 2019 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 } from "react";
|
||||||
|
import { AutoSizer } from "react-virtualized";
|
||||||
|
import { createStyles, withStyles } from "@material-ui/core/styles";
|
||||||
|
|
||||||
|
interface ISlideOptions {
|
||||||
|
classes: any;
|
||||||
|
slideOptions: any;
|
||||||
|
currentSlide: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = () =>
|
||||||
|
createStyles({
|
||||||
|
masterContainer: {
|
||||||
|
overflowX: "hidden",
|
||||||
|
overflowY: "auto",
|
||||||
|
},
|
||||||
|
sliderContainer: {
|
||||||
|
width: "auto",
|
||||||
|
transitionDuration: "0.3s",
|
||||||
|
position: "relative",
|
||||||
|
},
|
||||||
|
slide: {
|
||||||
|
float: "left",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const SlideOptions = ({
|
||||||
|
classes,
|
||||||
|
slideOptions,
|
||||||
|
currentSlide,
|
||||||
|
}: ISlideOptions) => {
|
||||||
|
return (
|
||||||
|
<AutoSizer>
|
||||||
|
{({ width, height }: any) => {
|
||||||
|
console.log(width, height);
|
||||||
|
const currentSliderPosition = currentSlide * width;
|
||||||
|
const containerSize = width * slideOptions.length;
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<div className={classes.masterContainer} style={{ width, height }}>
|
||||||
|
<div
|
||||||
|
className={classes.sliderContainer}
|
||||||
|
style={{
|
||||||
|
left: `-${currentSliderPosition}px`,
|
||||||
|
width: `${containerSize}px`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{slideOptions.map((block: any) => {
|
||||||
|
return (
|
||||||
|
<div className={classes.slide} style={{ width }}>
|
||||||
|
{block}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</AutoSizer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withStyles(styles)(SlideOptions);
|
||||||
@@ -66,6 +66,7 @@ interface TableWrapperProps {
|
|||||||
radioSelection?: boolean;
|
radioSelection?: boolean;
|
||||||
customEmptyMessage?: string;
|
customEmptyMessage?: string;
|
||||||
customPaperHeight?: string;
|
customPaperHeight?: string;
|
||||||
|
noBackground?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const borderColor = "#9c9c9c80";
|
const borderColor = "#9c9c9c80";
|
||||||
@@ -103,6 +104,10 @@ const styles = () =>
|
|||||||
height: 3,
|
height: 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
noBackground: {
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
border: 0,
|
||||||
|
},
|
||||||
defaultPaperHeight: {
|
defaultPaperHeight: {
|
||||||
height: "calc(100vh - 205px)",
|
height: "calc(100vh - 205px)",
|
||||||
},
|
},
|
||||||
@@ -362,6 +367,7 @@ const TableWrapper = ({
|
|||||||
radioSelection = false,
|
radioSelection = false,
|
||||||
customEmptyMessage = "",
|
customEmptyMessage = "",
|
||||||
customPaperHeight = "",
|
customPaperHeight = "",
|
||||||
|
noBackground = false,
|
||||||
}: TableWrapperProps) => {
|
}: TableWrapperProps) => {
|
||||||
const findView = itemActions
|
const findView = itemActions
|
||||||
? itemActions.find((el) => el.type === "view")
|
? itemActions.find((el) => el.type === "view")
|
||||||
@@ -385,6 +391,8 @@ const TableWrapper = ({
|
|||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Paper
|
<Paper
|
||||||
className={`${classes.paper} ${
|
className={`${classes.paper} ${
|
||||||
|
noBackground ? classes.noBackground : ""
|
||||||
|
} ${
|
||||||
customPaperHeight !== ""
|
customPaperHeight !== ""
|
||||||
? customPaperHeight
|
? customPaperHeight
|
||||||
: classes.defaultPaperHeight
|
: classes.defaultPaperHeight
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ const ConfTargetGeneric = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid xs={12} item className={classes.formScrollable}>
|
<Grid xs={12} item>
|
||||||
{fieldsElements.map((field, item) => (
|
{fieldsElements.map((field, item) => (
|
||||||
<React.Fragment key={field.name}>
|
<React.Fragment key={field.name}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import React, { Fragment, useState } from "react";
|
||||||
|
import PageHeader from "../Common/PageHeader/PageHeader";
|
||||||
|
import { Grid } from "@material-ui/core";
|
||||||
|
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||||
|
import { containerForHeader } from "../Common/FormComponents/common/styleLibrary";
|
||||||
|
import Tab from "@material-ui/core/Tab";
|
||||||
|
import Tabs from "@material-ui/core/Tabs";
|
||||||
|
import ConfigurationsList from "./ConfigurationPanels/ConfigurationsList";
|
||||||
|
|
||||||
|
interface IConfigurationMain {
|
||||||
|
classes: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = (theme: Theme) =>
|
||||||
|
createStyles({
|
||||||
|
headerLabel: {
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: 600,
|
||||||
|
color: "#000",
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
|
...containerForHeader(theme.spacing(4)),
|
||||||
|
});
|
||||||
|
|
||||||
|
const ConfigurationMain = ({ classes }: IConfigurationMain) => {
|
||||||
|
const [selectedTab, setSelectedTab] = useState<number>(0);
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<PageHeader label="Settings" />
|
||||||
|
<Grid container>
|
||||||
|
<Grid item xs={12} className={classes.container}>
|
||||||
|
<Grid item xs={12} className={classes.headerLabel}>
|
||||||
|
All Settings
|
||||||
|
</Grid>
|
||||||
|
<Tabs
|
||||||
|
value={selectedTab}
|
||||||
|
indicatorColor="primary"
|
||||||
|
textColor="primary"
|
||||||
|
onChange={(_, newValue: number) => {
|
||||||
|
setSelectedTab(newValue);
|
||||||
|
}}
|
||||||
|
aria-label="tenant-tabs"
|
||||||
|
>
|
||||||
|
<Tab label="Configurations" />
|
||||||
|
<Tab label="Lambda Notifications" />
|
||||||
|
</Tabs>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
{selectedTab === 0 && (
|
||||||
|
<Grid item xs={12}>
|
||||||
|
<ConfigurationsList />
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
{selectedTab === 1 && <div>Lambda notifications</div>}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withStyles(styles)(ConfigurationMain);
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { useState } from "react";
|
import React, { useState, Fragment } from "react";
|
||||||
import get from "lodash/get";
|
import get from "lodash/get";
|
||||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
@@ -30,8 +30,10 @@ import {
|
|||||||
actionsTray,
|
actionsTray,
|
||||||
containerForHeader,
|
containerForHeader,
|
||||||
searchField,
|
searchField,
|
||||||
|
settingsCommon,
|
||||||
} from "../../Common/FormComponents/common/styleLibrary";
|
} from "../../Common/FormComponents/common/styleLibrary";
|
||||||
import PageHeader from "../../Common/PageHeader/PageHeader";
|
import SlideOptions from "../../Common/SlideOptions/SlideOptions";
|
||||||
|
import BackSettingsIcon from "../../../../icons/BackSettingsIcon";
|
||||||
|
|
||||||
interface IListConfiguration {
|
interface IListConfiguration {
|
||||||
classes: any;
|
classes: any;
|
||||||
@@ -51,18 +53,59 @@ const styles = (theme: Theme) =>
|
|||||||
iconText: {
|
iconText: {
|
||||||
lineHeight: "24px",
|
lineHeight: "24px",
|
||||||
},
|
},
|
||||||
|
customConfigurationPage: {
|
||||||
|
height: "calc(100vh - 324px)",
|
||||||
|
scrollbarWidth: "none" as const,
|
||||||
|
"&::-webkit-scrollbar": {
|
||||||
|
display: "none",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
settingsOptionsContainer: {
|
||||||
|
height: "calc(100vh - 244px)",
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
border: "#EAEDEE 1px solid",
|
||||||
|
borderRadius: 3,
|
||||||
|
marginTop: 15,
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: 600,
|
||||||
|
color: "#000",
|
||||||
|
backgroundColor: "transparent",
|
||||||
|
border: 0,
|
||||||
|
padding: 0,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
"&:active, &:focus": {
|
||||||
|
outline: 0,
|
||||||
|
},
|
||||||
|
"& svg": {
|
||||||
|
width: 10,
|
||||||
|
marginRight: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
backContainer: {
|
||||||
|
margin: "20px 38px 0",
|
||||||
|
},
|
||||||
...searchField,
|
...searchField,
|
||||||
...actionsTray,
|
...actionsTray,
|
||||||
|
...settingsCommon,
|
||||||
...containerForHeader(theme.spacing(4)),
|
...containerForHeader(theme.spacing(4)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const initialConfiguration = {
|
||||||
|
configuration_id: "",
|
||||||
|
configuration_label: "",
|
||||||
|
};
|
||||||
|
|
||||||
const ConfigurationsList = ({ classes }: IListConfiguration) => {
|
const ConfigurationsList = ({ classes }: IListConfiguration) => {
|
||||||
const [editScreenOpen, setEditScreenOpen] = useState(false);
|
const [editScreenOpen, setEditScreenOpen] = useState(false);
|
||||||
const [selectedConfiguration, setSelectedConfiguration] = useState({
|
const [selectedConfiguration, setSelectedConfiguration] = useState(
|
||||||
configuration_id: "",
|
initialConfiguration
|
||||||
configuration_label: "",
|
);
|
||||||
});
|
|
||||||
const [filter, setFilter] = useState("");
|
const [filter, setFilter] = useState("");
|
||||||
|
const [currentConfiguration, setCurrentConfiguration] = useState<number>(0);
|
||||||
|
|
||||||
const tableActions = [
|
const tableActions = [
|
||||||
{
|
{
|
||||||
@@ -73,8 +116,8 @@ const ConfigurationsList = ({ classes }: IListConfiguration) => {
|
|||||||
// We redirect Browser
|
// We redirect Browser
|
||||||
history.push(url);
|
history.push(url);
|
||||||
} else {
|
} else {
|
||||||
|
setCurrentConfiguration(1);
|
||||||
setSelectedConfiguration(element);
|
setSelectedConfiguration(element);
|
||||||
setEditScreenOpen(true);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -87,53 +130,64 @@ const ConfigurationsList = ({ classes }: IListConfiguration) => {
|
|||||||
.includes(filter.toLocaleLowerCase())
|
.includes(filter.toLocaleLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const backToInitialConfig = () => {
|
||||||
|
setCurrentConfiguration(0);
|
||||||
|
setSelectedConfiguration(initialConfiguration);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{editScreenOpen && (
|
|
||||||
<EditConfiguration
|
|
||||||
open={editScreenOpen}
|
|
||||||
closeModalAndRefresh={() => {
|
|
||||||
setEditScreenOpen(false);
|
|
||||||
}}
|
|
||||||
selectedConfiguration={selectedConfiguration}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<PageHeader label="Configurations List" />
|
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item xs={12} className={classes.container}>
|
<Grid item xs={12}>
|
||||||
<Grid item xs={12} className={classes.actionsTray}>
|
|
||||||
<TextField
|
|
||||||
placeholder="Filter"
|
|
||||||
className={classes.searchField}
|
|
||||||
id="search-resource"
|
|
||||||
label=""
|
|
||||||
onChange={(event) => {
|
|
||||||
setFilter(event.target.value);
|
|
||||||
}}
|
|
||||||
InputProps={{
|
|
||||||
disableUnderline: true,
|
|
||||||
startAdornment: (
|
|
||||||
<InputAdornment position="start">
|
|
||||||
<SearchIcon />
|
|
||||||
</InputAdornment>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<br />
|
<div className={classes.settingsOptionsContainer}>
|
||||||
</Grid>
|
<SlideOptions
|
||||||
<Grid item xs={12}>
|
slideOptions={[
|
||||||
<TableWrapper
|
<Fragment>
|
||||||
itemActions={tableActions}
|
<Grid item xs={12} className={classes.customTitle}>
|
||||||
columns={[
|
Configuration Types
|
||||||
{ label: "Configuration", elementKey: "configuration_id" },
|
</Grid>
|
||||||
]}
|
<TableWrapper
|
||||||
isLoading={false}
|
itemActions={tableActions}
|
||||||
records={filteredRecords}
|
columns={[
|
||||||
entityName="Configurations"
|
{
|
||||||
idField="configuration_id"
|
label: "Configuration",
|
||||||
/>
|
elementKey: "configuration_id",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
isLoading={false}
|
||||||
|
records={filteredRecords}
|
||||||
|
entityName="Configurations"
|
||||||
|
idField="configuration_id"
|
||||||
|
customPaperHeight={classes.customConfigurationPage}
|
||||||
|
noBackground
|
||||||
|
/>
|
||||||
|
</Fragment>,
|
||||||
|
<Fragment>
|
||||||
|
<Grid item xs={12} className={classes.backContainer}>
|
||||||
|
<button
|
||||||
|
onClick={backToInitialConfig}
|
||||||
|
className={classes.backButton}
|
||||||
|
>
|
||||||
|
<BackSettingsIcon />
|
||||||
|
Back To Configurations
|
||||||
|
</button>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12}>
|
||||||
|
{currentConfiguration === 1 ? (
|
||||||
|
<EditConfiguration
|
||||||
|
closeModalAndRefresh={() => {
|
||||||
|
setCurrentConfiguration(0);
|
||||||
|
}}
|
||||||
|
selectedConfiguration={selectedConfiguration}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</Grid>
|
||||||
|
</Fragment>,
|
||||||
|
]}
|
||||||
|
currentSlide={currentConfiguration}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ const WebhookPanel = ({ match, classes }: IWebhookPanel) => {
|
|||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{addWebhookOpen && (
|
{addWebhookOpen && (
|
||||||
<EditConfiguration
|
<EditConfiguration
|
||||||
open={addWebhookOpen}
|
|
||||||
closeModalAndRefresh={() => {
|
closeModalAndRefresh={() => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setAddWebhookOpen(false);
|
setAddWebhookOpen(false);
|
||||||
|
|||||||
@@ -14,24 +14,27 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { Fragment, useCallback, useEffect, useState } from "react";
|
||||||
import get from "lodash/get";
|
import get from "lodash/get";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||||
import { Button, LinearProgress } from "@material-ui/core";
|
import { Button, LinearProgress } from "@material-ui/core";
|
||||||
import Grid from "@material-ui/core/Grid";
|
import Grid from "@material-ui/core/Grid";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
|
||||||
import api from "../../../../common/api";
|
import api from "../../../../common/api";
|
||||||
import ConfTargetGeneric from "../ConfTargetGeneric";
|
import ConfTargetGeneric from "../ConfTargetGeneric";
|
||||||
import { serverNeedsRestart } from "../../../../actions";
|
import { serverNeedsRestart } from "../../../../actions";
|
||||||
import { fieldBasic } from "../../Common/FormComponents/common/styleLibrary";
|
import {
|
||||||
|
fieldBasic,
|
||||||
|
settingsCommon,
|
||||||
|
} from "../../Common/FormComponents/common/styleLibrary";
|
||||||
import { fieldsConfigurations, removeEmptyFields } from "../utils";
|
import { fieldsConfigurations, removeEmptyFields } from "../utils";
|
||||||
import { IConfigurationElement, IElementValue } from "../types";
|
import { IConfigurationElement, IElementValue } from "../types";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
...fieldBasic,
|
...fieldBasic,
|
||||||
|
...settingsCommon,
|
||||||
errorBlock: {
|
errorBlock: {
|
||||||
color: "red",
|
color: "red",
|
||||||
},
|
},
|
||||||
@@ -47,10 +50,14 @@ const styles = (theme: Theme) =>
|
|||||||
logoButton: {
|
logoButton: {
|
||||||
height: "80px",
|
height: "80px",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
customTitle: {
|
||||||
|
...settingsCommon.customTitle,
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IAddNotificationEndpointProps {
|
interface IAddNotificationEndpointProps {
|
||||||
open: boolean;
|
|
||||||
closeModalAndRefresh: any;
|
closeModalAndRefresh: any;
|
||||||
serverNeedsRestart: typeof serverNeedsRestart;
|
serverNeedsRestart: typeof serverNeedsRestart;
|
||||||
selectedConfiguration: IConfigurationElement;
|
selectedConfiguration: IConfigurationElement;
|
||||||
@@ -58,7 +65,6 @@ interface IAddNotificationEndpointProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const EditConfiguration = ({
|
const EditConfiguration = ({
|
||||||
open,
|
|
||||||
closeModalAndRefresh,
|
closeModalAndRefresh,
|
||||||
serverNeedsRestart,
|
serverNeedsRestart,
|
||||||
selectedConfiguration,
|
selectedConfiguration,
|
||||||
@@ -134,32 +140,38 @@ const EditConfiguration = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalWrapper
|
<Fragment>
|
||||||
modalOpen={open}
|
<Grid item xs={12} className={classes.customTitle}>
|
||||||
onClose={closeModalAndRefresh}
|
{selectedConfiguration.configuration_label}
|
||||||
title={selectedConfiguration.configuration_label}
|
</Grid>
|
||||||
>
|
<Fragment>
|
||||||
<React.Fragment>
|
|
||||||
{errorConfig !== "" && (
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<Typography
|
|
||||||
component="p"
|
|
||||||
variant="body1"
|
|
||||||
className={classes.errorBlock}
|
|
||||||
>
|
|
||||||
{errorConfig}
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
)}
|
|
||||||
<form noValidate onSubmit={submitForm}>
|
<form noValidate onSubmit={submitForm}>
|
||||||
<ConfTargetGeneric
|
<Grid item xs={12} className={classes.settingsFormContainer}>
|
||||||
fields={
|
{loadingConfig && (
|
||||||
fieldsConfigurations[selectedConfiguration.configuration_id]
|
<Grid item xs={12}>
|
||||||
}
|
<LinearProgress />
|
||||||
onChange={onValueChange}
|
</Grid>
|
||||||
defaultVals={configValues}
|
)}
|
||||||
/>
|
{errorConfig !== "" && (
|
||||||
<Grid item xs={12} className={classes.buttonContainer}>
|
<Grid item xs={12}>
|
||||||
|
<Typography
|
||||||
|
component="p"
|
||||||
|
variant="body1"
|
||||||
|
className={classes.errorBlock}
|
||||||
|
>
|
||||||
|
{errorConfig}
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
<ConfTargetGeneric
|
||||||
|
fields={
|
||||||
|
fieldsConfigurations[selectedConfiguration.configuration_id]
|
||||||
|
}
|
||||||
|
onChange={onValueChange}
|
||||||
|
defaultVals={configValues}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} className={classes.settingsButtonContainer}>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
@@ -169,15 +181,9 @@ const EditConfiguration = ({
|
|||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
{loadingConfig && (
|
|
||||||
<Grid item xs={12}>
|
|
||||||
<LinearProgress />
|
|
||||||
</Grid>
|
|
||||||
)}
|
|
||||||
<Grid item xs={9} />
|
|
||||||
</form>
|
</form>
|
||||||
</React.Fragment>
|
</Fragment>
|
||||||
</ModalWrapper>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,10 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React from "react";
|
import React, { Fragment } from "react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||||
|
import { Button, LinearProgress } from "@material-ui/core";
|
||||||
import CssBaseline from "@material-ui/core/CssBaseline";
|
import CssBaseline from "@material-ui/core/CssBaseline";
|
||||||
import Drawer from "@material-ui/core/Drawer";
|
import Drawer from "@material-ui/core/Drawer";
|
||||||
import Container from "@material-ui/core/Container";
|
import Container from "@material-ui/core/Container";
|
||||||
@@ -29,6 +30,7 @@ import {
|
|||||||
serverNeedsRestart,
|
serverNeedsRestart,
|
||||||
setMenuOpen,
|
setMenuOpen,
|
||||||
} from "../../actions";
|
} from "../../actions";
|
||||||
|
import { ISessionResponse } from "./types";
|
||||||
import Buckets from "./Buckets/Buckets";
|
import Buckets from "./Buckets/Buckets";
|
||||||
import Policies from "./Policies/Policies";
|
import Policies from "./Policies/Policies";
|
||||||
import Dashboard from "./Dashboard/Dashboard";
|
import Dashboard from "./Dashboard/Dashboard";
|
||||||
@@ -38,11 +40,9 @@ import Account from "./Account/Account";
|
|||||||
import Users from "./Users/Users";
|
import Users from "./Users/Users";
|
||||||
import Groups from "./Groups/Groups";
|
import Groups from "./Groups/Groups";
|
||||||
import ListNotificationEndpoints from "./NotificationEndopoints/ListNotificationEndpoints";
|
import ListNotificationEndpoints from "./NotificationEndopoints/ListNotificationEndpoints";
|
||||||
import ConfigurationsList from "./Configurations/ConfigurationPanels/ConfigurationsList";
|
import ConfigurationMain from "./Configurations/ConfigurationMain";
|
||||||
import { Button, LinearProgress } from "@material-ui/core";
|
|
||||||
import WebhookPanel from "./Configurations/ConfigurationPanels/WebhookPanel";
|
import WebhookPanel from "./Configurations/ConfigurationPanels/WebhookPanel";
|
||||||
import ListTenants from "./Tenants/ListTenants/ListTenants";
|
import ListTenants from "./Tenants/ListTenants/ListTenants";
|
||||||
import { ISessionResponse } from "./types";
|
|
||||||
import TenantDetails from "./Tenants/TenantDetails/TenantDetails";
|
import TenantDetails from "./Tenants/TenantDetails/TenantDetails";
|
||||||
import ObjectBrowser from "./ObjectBrowser/ObjectBrowser";
|
import ObjectBrowser from "./ObjectBrowser/ObjectBrowser";
|
||||||
import ObjectRouting from "./Buckets/ListBuckets/Objects/ListObjects/ObjectRouting";
|
import ObjectRouting from "./Buckets/ListBuckets/Objects/ListObjects/ObjectRouting";
|
||||||
@@ -253,8 +253,8 @@ const Console = ({
|
|||||||
path: "/notification-endpoints",
|
path: "/notification-endpoints",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: ConfigurationsList,
|
component: ConfigurationMain,
|
||||||
path: "/configurations-list",
|
path: "/settings",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: Account,
|
component: Account,
|
||||||
@@ -284,7 +284,7 @@ const Console = ({
|
|||||||
const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]);
|
const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<Fragment>
|
||||||
{session.status === "ok" ? (
|
{session.status === "ok" ? (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
@@ -305,12 +305,12 @@ const Console = ({
|
|||||||
{needsRestart && (
|
{needsRestart && (
|
||||||
<div className={classes.warningBar}>
|
<div className={classes.warningBar}>
|
||||||
{isServerLoading ? (
|
{isServerLoading ? (
|
||||||
<React.Fragment>
|
<Fragment>
|
||||||
The server is restarting.
|
The server is restarting.
|
||||||
<LinearProgress />
|
<LinearProgress />
|
||||||
</React.Fragment>
|
</Fragment>
|
||||||
) : (
|
) : (
|
||||||
<React.Fragment>
|
<Fragment>
|
||||||
The instance needs to be restarted for configuration changes
|
The instance needs to be restarted for configuration changes
|
||||||
to take effect.{" "}
|
to take effect.{" "}
|
||||||
<Button
|
<Button
|
||||||
@@ -322,7 +322,7 @@ const Console = ({
|
|||||||
>
|
>
|
||||||
Restart
|
Restart
|
||||||
</Button>
|
</Button>
|
||||||
</React.Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -346,7 +346,7 @@ const Console = ({
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</React.Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -286,8 +286,8 @@ const Menu = ({ userLoggedIn, classes, pages }: IMenuProps) => {
|
|||||||
group: "Admin",
|
group: "Admin",
|
||||||
type: "item",
|
type: "item",
|
||||||
component: NavLink,
|
component: NavLink,
|
||||||
to: "/configurations-list",
|
to: "/settings",
|
||||||
name: "Configurations List",
|
name: "Settings",
|
||||||
icon: <ConfigurationsListIcon />,
|
icon: <ConfigurationsListIcon />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user