Skip to content

Commit 46151a5

Browse files
authored
UX basic dashboard (#1866)
1 parent f36c07a commit 46151a5

File tree

8 files changed

+297
-42
lines changed

8 files changed

+297
-42
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2022 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, { SVGProps } from "react";
18+
19+
const SuccessIcon = (props: SVGProps<SVGSVGElement>) => {
20+
return (
21+
<svg
22+
xmlns="http://www.w3.org/2000/svg"
23+
className={`min-icon`}
24+
fill={"currentcolor"}
25+
viewBox="0 0 10.155 8.367"
26+
{...props}
27+
>
28+
<path
29+
id="Intersección_8"
30+
data-name="Intersección 8"
31+
d="M14368.751,22047.6a1.045,1.045,0,1,1,1.467-1.488l1.411,1.395,3.98-3.918h0c.008-.01.017-.018.025-.027a1.048,1.048,0,0,1,1.451,1.514l-5.456,5.361Z"
32+
transform="translate(-14367.849 -22042.768)"
33+
fill={"currentcolor"}
34+
stroke="rgba(0,0,0,0)"
35+
strokeWidth="1"
36+
/>
37+
</svg>
38+
);
39+
};
40+
41+
export default SuccessIcon;

portal-ui/src/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,4 @@ export { default as BackIcon } from "./BackIcon";
183183
export { default as DeleteNonCurrentIcon } from "./DeleteNonCurrentIcon";
184184
export { default as FilterIcon } from "./FilterIcon";
185185
export { default as EditTenantIcon } from "./EditTenantIcon";
186+
export { default as SuccessIcon } from "./SuccessIcon";

portal-ui/src/screens/Console/Common/IconsScreen.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,11 @@ const IconsScreen = ({ classes }: IIconsScreenSimple) => {
11051105
<br />
11061106
FilterIcon
11071107
</Grid>
1108+
<Grid item xs={3} sm={2} md={1}>
1109+
<cicons.SuccessIcon />
1110+
<br />
1111+
SuccessIcon
1112+
</Grid>
11081113
</Grid>
11091114
<h1>Menu Icons</h1>
11101115
<Grid

portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx

Lines changed: 169 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
import React, { Fragment } from "react";
1818
import { Box } from "@mui/material";
1919
import {
20+
ArrowRightIcon,
2021
BucketsIcon,
2122
DrivesIcon,
23+
HealIcon,
2224
PrometheusErrorIcon,
2325
ServersIcon,
26+
SuccessIcon,
2427
TotalObjectsIcon,
28+
UptimeIcon,
2529
} from "../../../../icons";
2630
import HelpBox from "../../../../common/HelpBox";
2731
import { calculateBytes, representationNumber } from "../../../../common/utils";
@@ -31,13 +35,21 @@ import groupBy from "lodash/groupBy";
3135
import ServersList from "./ServersList";
3236
import CounterCard from "./CounterCard";
3337
import ReportedUsage from "./ReportedUsage";
38+
import { DiagnosticsMenuIcon } from "../../../../icons/SidebarMenus";
39+
import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton";
40+
import { Link } from "react-router-dom";
41+
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
3442

3543
const BoxItem = ({ children }: { children: any }) => {
3644
return (
3745
<Box
3846
sx={{
3947
border: "1px solid #f1f1f1",
40-
padding: "25px",
48+
padding: {
49+
md: "15px",
50+
xs: "5px",
51+
},
52+
height: "136px",
4153
maxWidth: {
4254
sm: "100%",
4355
},
@@ -48,6 +60,63 @@ const BoxItem = ({ children }: { children: any }) => {
4860
);
4961
};
5062

63+
const TimeStatItem = ({
64+
icon,
65+
label,
66+
value,
67+
}: {
68+
icon: any;
69+
label: any;
70+
value: string;
71+
}) => {
72+
return (
73+
<Box
74+
sx={{
75+
display: "grid",
76+
alignItems: "center",
77+
gap: "8px",
78+
height: "33px",
79+
paddingLeft: "15px",
80+
gridTemplateColumns: {
81+
md: "20px 1.5fr .5fr 20px",
82+
xs: "20px 1fr 1fr",
83+
},
84+
background: "#EBF9EE",
85+
86+
"& .min-icon": {
87+
height: "12px",
88+
width: "12px",
89+
fill: "#4CCB92",
90+
},
91+
92+
"& .ok-icon": {
93+
height: "8px",
94+
width: "8px",
95+
fill: "#4CCB92",
96+
color: "#4CCB92",
97+
display: {
98+
md: "block",
99+
xs: "none",
100+
},
101+
},
102+
}}
103+
>
104+
{icon}
105+
<Box
106+
sx={{
107+
fontSize: "12px",
108+
color: "#4CCB92",
109+
fontWeight: 600,
110+
}}
111+
>
112+
{label}
113+
</Box>
114+
<Box sx={{ fontSize: "12px", color: "#4CCB92" }}>{value}</Box>
115+
{value !== "n/a" ? <SuccessIcon className="ok-icon" /> : null}
116+
</Box>
117+
);
118+
};
119+
51120
interface IDashboardProps {
52121
usage: Usage | null;
53122
}
@@ -82,6 +151,8 @@ const BasicDashboard = ({ usage }: IDashboardProps) => {
82151
const usageValue = usage && usage.usage ? usage.usage.toString() : "0";
83152
const usageToRepresent = prettyUsage(usageValue);
84153

154+
const { lastScan = "n/a", lastHeal = "n/a", upTime = "n/a" } = usage || {};
155+
85156
const serverList = getServersList(usage || null);
86157

87158
let allDrivesArray: IDriveInfo[] = [];
@@ -180,28 +251,49 @@ const BasicDashboard = ({ usage }: IDashboardProps) => {
180251
<Box
181252
sx={{
182253
display: "grid",
183-
gridTemplateRows: "1fr .2fr auto",
184254
gridTemplateColumns: "1fr",
185255
gap: "40px",
186256
}}
187257
>
188258
<Box
189259
sx={{
190260
display: "grid",
191-
gridTemplateRows: "1fr",
261+
gridTemplateRows: "136px",
192262
gridTemplateColumns: {
193-
lg: "1fr 1fr 1fr 1fr ",
194-
sm: "1fr 1fr",
263+
sm: "1fr 1fr 1fr",
195264
xs: "1fr",
196265
},
197-
gap: "40px",
266+
gap: {
267+
md: "40px",
268+
xs: "20px",
269+
},
198270
}}
199271
>
200272
<BoxItem>
201273
<CounterCard
202274
label={"Buckets"}
203275
icon={<BucketsIcon />}
204276
counterValue={usage ? representationNumber(usage.buckets) : 0}
277+
actions={
278+
<Link
279+
to={IAM_PAGES.BUCKETS}
280+
style={{
281+
textDecoration: "none",
282+
top: "40px",
283+
position: "relative",
284+
marginRight: "75px",
285+
}}
286+
>
287+
<RBIconButton
288+
tooltip={"Browse"}
289+
onClick={() => {}}
290+
text={"Browse"}
291+
icon={<ArrowRightIcon />}
292+
color={"primary"}
293+
variant={"outlined"}
294+
/>
295+
</Link>
296+
}
205297
/>
206298
</BoxItem>
207299
<BoxItem>
@@ -211,6 +303,7 @@ const BasicDashboard = ({ usage }: IDashboardProps) => {
211303
counterValue={usage ? representationNumber(usage.objects) : 0}
212304
/>
213305
</BoxItem>
306+
214307
<BoxItem>
215308
<StatusCountCard
216309
onlineCount={onlineServers.length}
@@ -227,15 +320,78 @@ const BasicDashboard = ({ usage }: IDashboardProps) => {
227320
icon={<DrivesIcon />}
228321
/>
229322
</BoxItem>
323+
324+
<Box
325+
sx={{
326+
gridRowStart: "1",
327+
gridRowEnd: "3",
328+
gridColumnStart: "3",
329+
border: "1px solid #f1f1f1",
330+
padding: "15px",
331+
display: "grid",
332+
justifyContent: "stretch",
333+
}}
334+
>
335+
<ReportedUsage
336+
usageValue={usageValue}
337+
total={usageToRepresent.total}
338+
unit={usageToRepresent.unit}
339+
/>
340+
341+
<Box
342+
sx={{
343+
display: "flex",
344+
flexFlow: "column",
345+
gap: "14px",
346+
}}
347+
>
348+
<TimeStatItem
349+
icon={<HealIcon />}
350+
label={
351+
<Box>
352+
<Box
353+
sx={{
354+
display: {
355+
md: "inline",
356+
xs: "none",
357+
},
358+
}}
359+
>
360+
Time since last
361+
</Box>{" "}
362+
Heal Activity
363+
</Box>
364+
}
365+
value={lastHeal}
366+
/>
367+
<TimeStatItem
368+
icon={<DiagnosticsMenuIcon />}
369+
label={
370+
<Box>
371+
<Box
372+
sx={{
373+
display: {
374+
md: "inline",
375+
xs: "none",
376+
},
377+
}}
378+
>
379+
Time since last
380+
</Box>{" "}
381+
Scan Activity
382+
</Box>
383+
}
384+
value={lastScan}
385+
/>
386+
<TimeStatItem
387+
icon={<UptimeIcon />}
388+
label={"Uptime"}
389+
value={upTime}
390+
/>
391+
</Box>
392+
</Box>
230393
</Box>
231394

232-
<BoxItem>
233-
<ReportedUsage
234-
usageValue={usageValue}
235-
total={usageToRepresent.total}
236-
unit={usageToRepresent.unit}
237-
/>
238-
</BoxItem>
239395
<Box
240396
sx={{
241397
display: "grid",

portal-ui/src/screens/Console/Dashboard/BasicDashboard/CounterCard.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,30 @@ const CounterCard = ({
2121
counterValue,
2222
label = "",
2323
icon = null,
24+
actions = null,
2425
}: {
2526
counterValue: string | number;
2627
label?: any;
2728
icon?: any;
29+
actions?: any;
2830
}) => {
2931
return (
3032
<Box
3133
sx={{
3234
fontFamily: "Lato,sans-serif",
3335
color: "#07193E",
3436
maxWidth: "300px",
35-
minHeight: "143px",
3637
display: "flex",
3738
marginLeft: "auto",
3839
marginRight: "auto",
3940
cursor: "default",
4041
position: "relative",
4142
width: "100%",
42-
//marginLeft: "25px",
4343
}}
4444
>
4545
<Box
4646
sx={{
4747
flex: 1,
48-
minHeight: "200px",
4948
display: "flex",
5049
width: "100%",
5150
padding: {
@@ -60,7 +59,7 @@ const CounterCard = ({
6059
flex: 1,
6160
display: "flex",
6261
flexFlow: "column",
63-
marginTop: "22px",
62+
marginTop: "8px",
6463
zIndex: 10,
6564
overflow: "hidden",
6665
}}
@@ -103,9 +102,11 @@ const CounterCard = ({
103102
</Box>
104103
<Box
105104
sx={{
106-
width: "20px",
107-
height: "20px",
108-
marginTop: "26px",
105+
display: "flex",
106+
flexFlow: "column",
107+
alignItems: "center",
108+
justifyContent: "flex-start",
109+
marginTop: "8px",
109110
maxWidth: "26px",
110111
"& .min-icon": {
111112
width: "16px",
@@ -114,6 +115,8 @@ const CounterCard = ({
114115
}}
115116
>
116117
{icon}
118+
119+
<Box>{actions}</Box>
117120
</Box>
118121
</Box>
119122
</Box>

0 commit comments

Comments
 (0)