Skip to content

Commit

Permalink
feat: Some info cards in dashboard (#873)
Browse files Browse the repository at this point in the history
Add a clock and some more cards to the dashboard home
  • Loading branch information
Victor Castell authored Dec 20, 2020
1 parent b6432e8 commit 0b27010
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 87 deletions.
132 changes: 66 additions & 66 deletions dkron/assets_ui/assets_vfsdata.go

Large diffs are not rendered by default.

24 changes: 23 additions & 1 deletion dkron/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,30 @@ func (h *HTTPTransport) UI(r *gin.RouterGroup) {
if err == nil && p != "/" && p != "/index.html" {
ctx.FileFromFS(p, assets_ui.Assets)
} else {
jobs, err := h.agent.Store.GetJobs(nil)
if err != nil {
log.Error(err)
}
totalJobs := len(jobs)
successfulJobs := 0
failedJobs := 0
for _, j := range jobs {
if j.Status == "success" {
successfulJobs++
} else {
failedJobs++
}
}
l, err := h.agent.leaderMember()
if err != nil {
log.Error(err)
}
ctx.HTML(http.StatusOK, "index.html", gin.H{
"DKRON_API_URL": fmt.Sprintf("/%s", apiPathPrefix),
"DKRON_API_URL": fmt.Sprintf("/%s", apiPathPrefix),
"DKRON_LEADER": l.Name,
"DKRON_TOTAL_JOBS": totalJobs,
"DKRON_FAILED_JOBS": failedJobs,
"DKRON_SUCCESSFUL_JOBS": successfulJobs,
})
}
})
Expand Down
10 changes: 10 additions & 0 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import { Layout } from './layout';
import customRoutes from './routes';
import themeReducer from './themeReducer';

declare global {
interface Window {
DKRON_API_URL: string;
DKRON_LEADER: string;
DKRON_FAILED_JOBS: string;
DKRON_SUCCESSFUL_JOBS: string;
DKRON_TOTAL_JOBS: string;
}
}

const App = () => (
<Admin
dashboard={Dashboard}
Expand Down
73 changes: 73 additions & 0 deletions ui/src/dashboard/CardWithIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as React from 'react';
import { FC, createElement } from 'react';
import { Card, Box, Typography, Divider } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import { Link } from 'react-router-dom';

import cartouche from './cartouche.png';
import cartoucheDark from './cartoucheDark.png';

interface Props {
icon: FC<any>;
to: string;
title?: string;
subtitle?: string | number;
}

const useStyles = makeStyles(theme => ({
card: {
minHeight: 52,
display: 'flex',
flexDirection: 'column',
flex: '1',
'& a': {
textDecoration: 'none',
color: 'inherit',
},
},
main: (props: Props) => ({
overflow: 'inherit',
padding: 16,
background: `url(${
theme.palette.type === 'dark' ? cartoucheDark : cartouche
}) no-repeat`,
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
'& .icon': {
color: theme.palette.type === 'dark' ? 'inherit' : '#dc2440',
},
}),
title: {},
}));

const CardWithIcon: FC<Props> = props => {
const { icon, title, subtitle, to, children } = props;
const classes = useStyles(props);
return (
<Card className={classes.card}>
<Link to={to}>
<div className={classes.main}>
<Box width="3em" className="icon">
{createElement(icon, { fontSize: 'large' })}
</Box>
<Box textAlign="right">
<Typography
className={classes.title}
color="textSecondary"
>
{title}
</Typography>
<Typography variant="h5" component="h2">
{subtitle || ' '}
</Typography>
</Box>
</div>
</Link>
{children && <Divider />}
{children}
</Card>
);
};

export default CardWithIcon;
62 changes: 48 additions & 14 deletions ui/src/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import * as React from "react";
import { Card, CardContent, CardHeader } from '@material-ui/core';
import { List, Datagrid, TextField } from 'react-admin';
import { TagsField } from '../TagsField'
import Leader from './Leader';
import FailedJobs from './FailedJobs';
import SuccessfulJobs from './SuccessfulJobs';
import TotalJobs from './TotalJobs';

let fakeProps = {
basePath: "/members",
Expand All @@ -17,20 +21,50 @@ let fakeProps = {
resource: "members"
}

const styles = {
flex: { display: 'flex' },
flexColumn: { display: 'flex', flexDirection: 'column' },
leftCol: { flex: 1, marginRight: '0.5em' },
rightCol: { flex: 1, marginLeft: '0.5em' },
singleCol: { marginTop: '1em', marginBottom: '1em' },
};

const Spacer = () => <span style={{ width: '1em' }} />;

const Dashboard = () => (
<Card>
<CardHeader title="Nodes" />
<CardContent>
<List {...fakeProps}>
<Datagrid isRowSelectable={ record => false }>
<TextField source="Name" sortable={false} />
<TextField source="Addr" sortable={false} />
<TextField source="Port" sortable={false} />
<TextField source="Status" sortable={false} />
<TagsField source="Tags" sortable={false} />
</Datagrid>
</List>
</CardContent>
</Card>
<div>
<Card>
<CardHeader title="Welcome" />
<CardContent>
<div style={styles.flex}>
<div style={styles.leftCol}>
<div style={styles.flex}>
<Leader value={window.DKRON_LEADER || "devel"} />
<Spacer />
<TotalJobs value={window.DKRON_TOTAL_JOBS || "0"} />
<Spacer />
<SuccessfulJobs value={window.DKRON_SUCCESSFUL_JOBS || "0"} />
<Spacer />
<FailedJobs value={window.DKRON_FAILED_JOBS || "0"} />
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader title="Nodes" />
<CardContent>
<List {...fakeProps}>
<Datagrid isRowSelectable={ record => false }>
<TextField source="Name" sortable={false} />
<TextField source="Addr" sortable={false} />
<TextField source="Port" sortable={false} />
<TextField source="Status" sortable={false} />
<TagsField source="Tags" sortable={false} />
</Datagrid>
</List>
</CardContent>
</Card>
</div>
);
export default Dashboard;
22 changes: 22 additions & 0 deletions ui/src/dashboard/FailedJobs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import { FC } from 'react';
import Icon from '@material-ui/icons/ThumbDown';

import CardWithIcon from './CardWithIcon';

interface Props {
value?: string;
}

const FailedJobs: FC<Props> = ({ value }) => {
return (
<CardWithIcon
to='/jobs?filter={"status":"failed"}'
icon={Icon}
title='Failed Jobs'
subtitle={value}
/>
);
};

export default FailedJobs;
22 changes: 22 additions & 0 deletions ui/src/dashboard/Leader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import { FC } from 'react';
import Icon from '@material-ui/icons/DeviceHub';

import CardWithIcon from './CardWithIcon';

interface Props {
value?: string;
}

const Leader: FC<Props> = ({ value }) => {
return (
<CardWithIcon
to="/jobs"
icon={Icon}
title='Leader'
subtitle={value}
/>
);
};

export default Leader;
22 changes: 22 additions & 0 deletions ui/src/dashboard/SuccessfulJobs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import { FC } from 'react';
import Icon from '@material-ui/icons/ThumbUp';

import CardWithIcon from './CardWithIcon';

interface Props {
value?: string;
}

const SuccessfulJobs: FC<Props> = ({ value }) => {
return (
<CardWithIcon
to='/jobs?filter={"status":"success"}'
icon={Icon}
title='Successful Jobs'
subtitle={value}
/>
);
};

export default SuccessfulJobs;
22 changes: 22 additions & 0 deletions ui/src/dashboard/TotalJobs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import { FC } from 'react';
import Icon from '@material-ui/icons/Update';

import CardWithIcon from './CardWithIcon';

interface Props {
value?: string;
}

const TotalJobs: FC<Props> = ({ value }) => {
return (
<CardWithIcon
to="/jobs"
icon={Icon}
title='Total Jobs'
subtitle={value}
/>
);
};

export default TotalJobs;
Binary file added ui/src/dashboard/cartouche.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/dashboard/cartoucheDark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 0 additions & 6 deletions ui/src/dataProvider.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { fetchUtils } from 'ra-core';
import jsonServerProvider from 'ra-data-json-server';

declare global {
interface Window {
DKRON_API_URL:any;
}
}

export const apiUrl = window.DKRON_API_URL || 'http://localhost:8080/v1'
const dataProvider = jsonServerProvider(apiUrl);

Expand Down
2 changes: 2 additions & 0 deletions ui/src/layout/AppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AppBar, UserMenu, MenuItemLink } from 'react-admin';
import Typography from '@material-ui/core/Typography';
import SettingsIcon from '@material-ui/icons/Settings';
import { makeStyles } from '@material-ui/core/styles';
import Clock from './Clock';

import logo from '../images/dkron-logo.png';

Expand Down Expand Up @@ -53,6 +54,7 @@ const CustomAppBar = (props: any) => {
/>
<img src={logo} alt="logo" className={classes.logo} />
<span className={classes.spacer} />
<Clock/>
</AppBar>
);
};
Expand Down
30 changes: 30 additions & 0 deletions ui/src/layout/Clock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, {Component} from 'react';

class Clock extends Component<{}, { date: Date }> {
timer: any;

constructor(props: any){
super(props);
this.state = {date: new Date()};
}

componentDidMount() {
this.timer = setInterval(
() => this.setState({date: new Date()}),
1000
);
}

componentWillUnmount() {
clearInterval(this.timer);
}

render(){
return(
<div>
<div>{this.state.date.toLocaleTimeString()}</div>
</div>
)
}
}
export default Clock

0 comments on commit 0b27010

Please sign in to comment.