Skip to content

Commit 7e9d581

Browse files
bexsoftBenjamin Perez
andauthored
Updated styles & behavior for settings page (#334)
Updated styles & behavior for settings page, also implemented a couple of performance improvements on some fields Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
1 parent c928972 commit 7e9d581

File tree

11 files changed

+323
-151
lines changed

11 files changed

+323
-151
lines changed

portal-ui/bindata_assetfs.go

Lines changed: 97 additions & 97 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

portal-ui/src/icons/AddIcon.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2020 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import React from "react";
18+
import { SvgIcon } from "@material-ui/core";
19+
class AddIcon extends React.Component {
20+
render() {
21+
return (
22+
<SvgIcon viewBox="0 0 12 12">
23+
<path
24+
fill="#081c42"
25+
className="a"
26+
d="M-13160.269,1885.114h-3.235v-4.381h-4.382V1877.5h4.382v-4.381h3.235v4.381h4.383v3.238h-4.383v4.38Z"
27+
transform="translate(13167.886 -1873.114)"
28+
/>
29+
</SvgIcon>
30+
);
31+
}
32+
}
33+
34+
export default AddIcon;

portal-ui/src/icons/RemoveIcon.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2020 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import React from "react";
18+
import { SvgIcon } from "@material-ui/core";
19+
class RemoveIcon extends React.Component {
20+
render() {
21+
return (
22+
<SvgIcon viewBox="0 0 11.656 3.101">
23+
<path
24+
fill="#081c42"
25+
d="M-13157.172,1879.551h-11.656v-3.1h11.656v3.1Z"
26+
transform="translate(13168.828 -1876.449)"
27+
/>
28+
</SvgIcon>
29+
);
30+
}
31+
}
32+
33+
export default RemoveIcon;

portal-ui/src/screens/Console/Common/FormComponents/CSVMultiSelector/CSVMultiSelector.tsx

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// This file is part of MinIO Console Server
2-
// Copyright (c) 2019 MinIO, Inc.
2+
// Copyright (c) 2020 MinIO, Inc.
33
//
44
// This program is free software: you can redistribute it and/or modify
55
// it under the terms of the GNU Affero General Public License as published by
@@ -13,38 +13,46 @@
1313
//
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
import React, { useState, useEffect, createRef, ChangeEvent } from "react";
16+
import React, {
17+
useState,
18+
useEffect,
19+
createRef,
20+
useLayoutEffect,
21+
ChangeEvent,
22+
useRef,
23+
} from "react";
24+
import get from "lodash/get";
25+
import debounce from "lodash/debounce";
1726
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
1827
import Grid from "@material-ui/core/Grid";
19-
import get from "lodash/get";
20-
import InputBoxWrapper from "../InputBoxWrapper/InputBoxWrapper";
28+
import HelpIcon from "@material-ui/icons/Help";
2129
import { InputLabel, Tooltip } from "@material-ui/core";
2230
import { fieldBasic, tooltipHelper } from "../common/styleLibrary";
23-
import HelpIcon from "@material-ui/icons/Help";
31+
import InputBoxWrapper from "../InputBoxWrapper/InputBoxWrapper";
32+
import AddIcon from "../../../../../icons/AddIcon";
2433

2534
interface ICSVMultiSelector {
2635
elements: string;
2736
name: string;
2837
label: string;
2938
tooltip?: string;
39+
commonPlaceholder?: string;
3040
classes: any;
41+
withBorder?: boolean;
3142
onChange: (elements: string) => void;
3243
}
3344

3445
const styles = (theme: Theme) =>
3546
createStyles({
3647
...fieldBasic,
3748
...tooltipHelper,
38-
inputLabel: {
39-
...fieldBasic.inputLabel,
40-
width: 116,
41-
},
42-
inputContainer: {
49+
inputWithBorder: {
50+
border: "1px solid #EAEAEA",
51+
padding: 15,
4352
height: 150,
4453
overflowY: "auto",
45-
padding: 15,
4654
position: "relative",
47-
border: "1px solid #c4c4c4",
55+
marginTop: 15,
4856
},
4957
labelContainer: {
5058
display: "flex",
@@ -56,7 +64,9 @@ const CSVMultiSelector = ({
5664
name,
5765
label,
5866
tooltip = "",
67+
commonPlaceholder = "",
5968
onChange,
69+
withBorder = false,
6070
classes,
6171
}: ICSVMultiSelector) => {
6272
const [currentElements, setCurrentElements] = useState<string[]>([""]);
@@ -75,29 +85,37 @@ const CSVMultiSelector = ({
7585

7686
setCurrentElements(elementsSplit);
7787
}
88+
89+
// eslint-disable-next-line react-hooks/exhaustive-deps
7890
}, [elements, currentElements]);
7991

8092
// Use effect to send new values to onChange
8193
useEffect(() => {
82-
const elementsString = currentElements
83-
.filter((element) => element.trim() !== "")
84-
.join(",");
85-
onChange(elementsString);
94+
const refScroll = bottomList.current;
95+
if (refScroll) {
96+
refScroll.scrollIntoView(false);
97+
}
8698
// eslint-disable-next-line react-hooks/exhaustive-deps
8799
}, [currentElements]);
88100

101+
// We avoid multiple re-renders / hang issue typing too fast
102+
const firstUpdate = useRef(true);
103+
useLayoutEffect(() => {
104+
if (firstUpdate.current) {
105+
firstUpdate.current = false;
106+
return;
107+
}
108+
109+
debouncedOnChange();
110+
}, [currentElements]);
111+
89112
// If the last input is not empty, we add a new one
90113
const addEmptyLine = (elementsUp: string[]) => {
91114
if (elementsUp[elementsUp.length - 1].trim() !== "") {
92-
elementsUp.push("");
93-
const refScroll = bottomList.current;
94-
95-
if (refScroll) {
96-
refScroll.scrollIntoView(false);
97-
}
115+
const cpList = [...elementsUp];
116+
cpList.push("");
117+
setCurrentElements(cpList);
98118
}
99-
100-
return elementsUp;
101119
};
102120

103121
// Onchange function for input box, we get the dataset-index & only update that value in the array
@@ -108,10 +126,18 @@ const CSVMultiSelector = ({
108126
const index = get(e.target, "dataset.index", 0);
109127
updatedElement[index] = e.target.value;
110128

111-
updatedElement = addEmptyLine(updatedElement);
112129
setCurrentElements(updatedElement);
113130
};
114131

132+
// Debounce for On Change
133+
const debouncedOnChange = debounce(() => {
134+
const elementsString = currentElements
135+
.filter((element) => element.trim() !== "")
136+
.join(",");
137+
138+
onChange(elementsString);
139+
}, 500);
140+
115141
const inputs = currentElements.map((element, index) => {
116142
return (
117143
<InputBoxWrapper
@@ -122,6 +148,11 @@ const CSVMultiSelector = ({
122148
onChange={onChangeElement}
123149
index={index}
124150
key={`csv-${name}-${index.toString()}`}
151+
placeholder={commonPlaceholder}
152+
overlayIcon={index === currentElements.length - 1 ? <AddIcon /> : null}
153+
overlayAction={() => {
154+
addEmptyLine(currentElements);
155+
}}
125156
/>
126157
);
127158
});
@@ -139,13 +170,16 @@ const CSVMultiSelector = ({
139170
</div>
140171
)}
141172
</InputLabel>
142-
<Grid item xs={12} className={classes.inputContainer}>
173+
<Grid
174+
item
175+
xs={12}
176+
className={`${withBorder ? classes.inputWithBorder : ""}`}
177+
>
143178
{inputs}
144179
<div ref={bottomList} />
145180
</Grid>
146181
</Grid>
147182
</React.Fragment>
148183
);
149184
};
150-
151185
export default withStyles(styles)(CSVMultiSelector);

portal-ui/src/screens/Console/Common/FormComponents/CommentBoxWrapper/CommentBoxWrapper.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@ const styles = (theme: Theme) =>
6868
},
6969
cssOutlinedInput: {
7070
borderColor: "#9C9C9C",
71+
padding: 16,
7172
},
72-
rootTest: {
73+
rootContainer: {
7374
"& .MuiOutlinedInput-inputMultiline": {
7475
...fieldBasic.inputLabel,
7576
fontSize: 13,
77+
minHeight: 150,
7678
},
7779
},
7880
});
@@ -142,7 +144,7 @@ const CommentBoxWrapper = ({
142144
InputProps={{
143145
classes: {
144146
notchedOutline: classes.cssOutlinedInput,
145-
root: classes.rootTest,
147+
root: classes.rootContainer,
146148
},
147149
}}
148150
variant="outlined"

portal-ui/src/screens/Console/Common/FormComponents/InputBoxWrapper/InputBoxWrapper.tsx

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import React from "react";
1717
import {
1818
Grid,
19+
IconButton,
1920
InputLabel,
2021
TextField,
2122
TextFieldProps,
@@ -49,6 +50,8 @@ interface InputBoxProps {
4950
placeholder?: string;
5051
min?: string;
5152
max?: string;
53+
overlayIcon?: any;
54+
overlayAction?: () => void;
5255
}
5356

5457
const styles = (theme: Theme) =>
@@ -57,7 +60,10 @@ const styles = (theme: Theme) =>
5760
...tooltipHelper,
5861
textBoxContainer: {
5962
flexGrow: 1,
63+
},
64+
textBoxWithIcon: {
6065
position: "relative",
66+
paddingRight: 25,
6167
},
6268
errorState: {
6369
color: "#b53b4b",
@@ -66,6 +72,15 @@ const styles = (theme: Theme) =>
6672
top: 7,
6773
right: 7,
6874
},
75+
overlayAction: {
76+
position: "absolute",
77+
right: 0,
78+
top: 15,
79+
"& svg": {
80+
maxWidth: 15,
81+
maxHeight: 15,
82+
},
83+
},
6984
});
7085

7186
const inputStyles = makeStyles((theme: Theme) =>
@@ -83,7 +98,7 @@ const inputStyles = makeStyles((theme: Theme) =>
8398
},
8499
},
85100
input: {
86-
padding: "15px 5px 10px",
101+
padding: "15px 30px 10px 5px",
87102
color: "#393939",
88103
fontSize: 13,
89104
fontWeight: 600,
@@ -127,6 +142,8 @@ const InputBoxWrapper = ({
127142
placeholder = "",
128143
min,
129144
max,
145+
overlayIcon = null,
146+
overlayAction,
130147
classes,
131148
}: InputBoxProps) => {
132149
let inputProps: any = { "data-index": index };
@@ -184,12 +201,28 @@ const InputBoxWrapper = ({
184201
error={error !== ""}
185202
helperText={error}
186203
placeholder={placeholder}
187-
InputLabelProps={{
188-
shrink: true,
189-
}}
190204
className={classes.inputRebase}
191205
/>
192206
</div>
207+
{overlayIcon && (
208+
<div className={classes.overlayAction}>
209+
<IconButton
210+
onClick={
211+
overlayAction
212+
? () => {
213+
overlayAction();
214+
}
215+
: () => null
216+
}
217+
size={"small"}
218+
disableFocusRipple={false}
219+
disableRipple={false}
220+
disableTouchRipple={false}
221+
>
222+
{overlayIcon}
223+
</IconButton>
224+
</div>
225+
)}
193226
</Grid>
194227
</React.Fragment>
195228
);

portal-ui/src/screens/Console/Common/FormComponents/common/styleLibrary.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const fieldBasic = {
3535
},
3636
fieldContainer: {
3737
marginBottom: 20,
38+
position: "relative" as const,
3839
},
3940
tooltipContainer: {
4041
marginLeft: 5,

portal-ui/src/screens/Console/Configurations/ConfTargetGeneric.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ const ConfTargetGeneric = ({
123123
setValueElement(field.name, value, item)
124124
}
125125
tooltip={field.tooltip}
126+
commonPlaceholder={field.placeholder}
127+
withBorder={!!field.withBorder}
126128
/>
127129
);
128130
case "comment":

portal-ui/src/screens/Console/Configurations/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface KVField {
4040
options?: SelectorTypes[];
4141
multiline?: boolean;
4242
placeholder?: string;
43+
withBorder?: boolean;
4344
}
4445

4546
export interface IConfigurationElement {

0 commit comments

Comments
 (0)