Update playbooks page

* import react-icons react-tokens to use it the code
 * update patternfly-next to the latest version
 * fix icon issues in playbook summary
 * fix playbook summary layout on mobile

Change-Id: I1ec2e60b1433c42a8d02376ae5a508a6c8ef9439
This commit is contained in:
Guillaume Vincent 2019-01-17 13:52:25 +01:00
parent ddd1e712f8
commit 04a2d4a05e
4 changed files with 1582 additions and 1202 deletions

2624
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,9 @@
"private": true, "private": true,
"homepage": "http://localhost:3000/", "homepage": "http://localhost:3000/",
"dependencies": { "dependencies": {
"@patternfly/patternfly-next": "1.0.110", "@patternfly/patternfly-next": "1.0.128",
"@patternfly/react-icons": "2.9.7",
"@patternfly/react-tokens": "1.9.6",
"axios": "^0.18.0", "axios": "^0.18.0",
"react": "^16.5.1", "react": "^16.5.1",
"react-dom": "^16.5.1", "react-dom": "^16.5.1",

View File

@ -3,6 +3,7 @@ import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import "@patternfly/patternfly-next/patternfly.css"; import "@patternfly/patternfly-next/patternfly.css";
import "@patternfly/patternfly-next/patternfly-addons.css";
import store from "./store"; import store from "./store";
import { getConfig } from "./config/configActions"; import { getConfig } from "./config/configActions";
import * as Containers from "./containers"; import * as Containers from "./containers";

View File

@ -1,50 +1,73 @@
import React, { Component } from "react"; import React, { Component } from "react";
import styled from "styled-components"; import styled from "styled-components";
import {
CheckCircleIcon,
ExclamationCircleIcon,
PauseCircleIcon
} from "@patternfly/react-icons";
import {
global_danger_color_100,
global_success_color_100,
global_active_color_100,
global_warning_color_100,
global_Color_light_100
} from "@patternfly/react-tokens";
function _getIconInfo(status) { const StatusIcon = ({ status }) => {
switch (status) { switch (status) {
case "running": case "running":
return { return (
title: "Playbook is in progress.", <PauseCircleIcon
icon: "fa-pause", title="Playbook is in progress."
color: "blue" size="md"
}; style={{ color: global_active_color_100.value }}
/>
);
case "completed": case "completed":
return { return (
title: "Playbook has completed successfully.", <CheckCircleIcon
icon: "fa-check", title="Playbook has completed successfully."
color: "green" size="md"
}; style={{ color: global_success_color_100.value }}
/>
);
case "failed": case "failed":
return { return (
title: "Playbook has failed with one or more errors.", <ExclamationCircleIcon
icon: "fa-warning", title="Playbook has failed with one or more errors."
color: "red" size="md"
}; style={{ color: global_danger_color_100.value }}
/>
);
default: default:
return { return (
title: "Playbook's status is unknown.", <ExclamationCircleIcon
icon: "fa-warning", title="Playbook's status is unknown."
color: "red" size="md"
}; style={{ color: global_warning_color_100.value }}
/>
);
} }
} };
const IconWrapper = styled.i` function getBackground(status, backgroundColor = global_Color_light_100.value) {
color: ${props => props.color}; switch (status) {
`; case "running":
return `linear-gradient(to right,${global_active_color_100.value} 0,${
class StatusIcon extends Component { global_active_color_100.value
render() { } 5px,${backgroundColor} 5px,${backgroundColor} 100%) no-repeat`;
const { status } = this.props; case "completed":
const iconInfo = _getIconInfo(status); return `linear-gradient(to right,${global_success_color_100.value} 0,${
return ( global_success_color_100.value
<IconWrapper } 5px,${backgroundColor} 5px,${backgroundColor} 100%) no-repeat`;
color={iconInfo.color} case "failed":
className={`fa ${iconInfo.icon}`} return `linear-gradient(to right,${global_danger_color_100.value} 0,${
title={iconInfo.title} global_danger_color_100.value
/> } 5px,${backgroundColor} 5px,${backgroundColor} 100%) no-repeat`;
); default:
return `linear-gradient(to right,${global_warning_color_100.value} 0,${
global_warning_color_100.value
} 5px,${backgroundColor} 5px,${backgroundColor} 100%) no-repeat`;
} }
} }
@ -52,16 +75,7 @@ const PlaybookWrapper = styled.div`
cursor: pointer; cursor: pointer;
&:hover { &:hover {
.pf-c-card { .pf-c-card {
background: rgba(0, 0, 0, 0) background: ${props => getBackground(props.status)};
linear-gradient(
to right,
rgb(57, 165, 220) 0px,
rgb(57, 165, 220) 5px,
rgb(255, 255, 255) 5px,
rgb(255, 255, 255) 100%
)
no-repeat scroll 0% 0%;
}
} }
`; `;
@ -75,23 +89,33 @@ const StatusAndName = styled.div`
margin-bottom: 0; margin-bottom: 0;
} }
`; `;
const PlaybookInfo = styled.div`
display: flex; const PlaybookInfos = styled.div`
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
align-items: center; align-items: center;
width: 100%; width: 100%;
margin-bottom: 1em;
@media (min-width: 587px) { @media (min-width: 587px) {
width: 50%; width: 50%;
margin-bottom: 0;
} }
`; `;
const PlaybookInfo = styled.div`
width: 140px;
@media (min-width: 587px) {
text-align: center;
}
`;
const Duration = styled.div` const Duration = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
width: 100%; width: 100%;
margin-top: 1em;
@media (min-width: 587px) { @media (min-width: 587px) {
width: 25%; width: 25%;
justify-content: flex-end; justify-content: flex-end;
margin-top: 0;
} }
`; `;
@ -100,6 +124,7 @@ export default class Playbook extends Component {
const { playbook, history } = this.props; const { playbook, history } = this.props;
return ( return (
<PlaybookWrapper <PlaybookWrapper
status={playbook.status}
className="pf-u-mb-xs" className="pf-u-mb-xs"
onClick={() => history.push(`/playbooks/${playbook.id}`)} onClick={() => history.push(`/playbooks/${playbook.id}`)}
> >
@ -112,26 +137,26 @@ export default class Playbook extends Component {
{playbook.path.split("/").slice(-1)[0]} {playbook.path.split("/").slice(-1)[0]}
</h1> </h1>
</StatusAndName> </StatusAndName>
<PlaybookInfo> <PlaybookInfos>
<span className="pf-u-mr-xl"> <PlaybookInfo className="pf-u-mr-xl">
<b>{Object.keys(playbook.arguments).length}</b> arguments <b>{Object.keys(playbook.arguments).length}</b> arguments
</span> </PlaybookInfo>
<span className="pf-u-mr-xl"> <PlaybookInfo className="pf-u-mr-xl">
<b>{playbook.hosts.length}</b> Hosts <b>{playbook.hosts.length}</b> Hosts
</span> </PlaybookInfo>
<span className="pf-u-mr-xl"> <PlaybookInfo className="pf-u-mr-xl">
<b>{playbook.files.length}</b> Files <b>{playbook.files.length}</b> Files
</span> </PlaybookInfo>
<span className="pf-u-mr-xl"> <PlaybookInfo className="pf-u-mr-xl">
<b>{Object.keys(playbook.tasks).length}</b> tasks <b>{Object.keys(playbook.tasks).length}</b> tasks
</span> </PlaybookInfo>
<span className="pf-u-mr-xl"> <PlaybookInfo className="pf-u-mr-xl">
<b>{Object.keys(playbook.plays).length}</b> plays <b>{Object.keys(playbook.plays).length}</b> plays
</span> </PlaybookInfo>
<span className="pf-u-mr-xl"> <PlaybookInfo className="pf-u-mr-xl">
<b>{Object.keys(playbook.records).length}</b> records <b>{Object.keys(playbook.records).length}</b> records
</span> </PlaybookInfo>
</PlaybookInfo> </PlaybookInfos>
<Duration> <Duration>
<i className="fa fa-clock" /> <i className="fa fa-clock" />
<span className="pf-u-ml-xs"> <span className="pf-u-ml-xs">