1
0
mirror of https://github.com/yldio/copilot.git synced 2024-11-28 14:10:04 +02:00

Merge branch 'master' into seperating-normalize-css

This commit is contained in:
Alex Windett 2017-01-20 13:27:14 +00:00 committed by GitHub
commit 27fccb364d
28 changed files with 2384 additions and 1729 deletions

View File

@ -50,6 +50,18 @@ server.register(plugins, (err) => {
process.exit(1);
}
server.route({
method: 'GET',
path: '/static/images/{param*}',
handler: {
directory: {
path: './images/',
redirectToSlash: true,
index: false
}
}
});
server.route({
method: 'GET',
path: '/static/{param*}',

View File

@ -0,0 +1,100 @@
const Container = require('@ui/components/container');
const PropTypes = require('@root/prop-types');
const React = require('react');
const ReactRouter = require('react-router');
const Styled = require('styled-components');
const flatten = require('lodash.flatten');
const fns = require('@ui/shared/functions');
const {
remcalc
} = fns;
const {
default: styled
} = Styled;
// Main Contonent Wrapper Styles
const StyledDiv = styled.div`
background-color: #FAFAFA;
height: ${remcalc(91)};
border-bottom: solid ${remcalc(1)} #d8d8d8;
`;
const BreadcrumbA = styled.a`
text-decoration: none !important;
`;
const BreadcrumbSpan = styled.span`
color: #646464;
`;
const H1 = styled.h1`
margin: 0 0 0 0;
padding-top: ${remcalc(31)};
padding-bottom: ${remcalc(31)};
`;
const {
Link
} = ReactRouter;
function getNameLink(name) {
return flatten(name.map((part, i) => {
if (!part.name) {
return null;
}
const link = (
<Link key={part.pathname} to={part.pathname}>
{
({
href,
onClick,
}) =>
<BreadcrumbA href={href} onClick={onClick}>
{part.name}
</BreadcrumbA>
}
</Link>
);
const key = `${part.pathname}${i}`;
const slash = (
<BreadcrumbSpan key={key}> / </BreadcrumbSpan>
);
return (i === 0) ? link : [
slash,
link
];
}));
}
const Breadcrumb = ({
children,
links = [],
name = []
}) => {
return (
<Container>
<StyledDiv>
<H1
style={{
fontSize: remcalc(24)
}}
>
{getNameLink(name)}
</H1>
</StyledDiv>
</Container>
);
};
Breadcrumb.propTypes = {
children: React.PropTypes.node,
links: React.PropTypes.arrayOf(PropTypes.link),
name: React.PropTypes.arrayOf(PropTypes.link)
};
module.exports = Breadcrumb;

View File

@ -66,6 +66,8 @@ const StyledTooltipWrapper = styled.div`
`;
const StyledName = styled.span`
color: #646464;
font-size: ${remcalc(16)}
position: relative;
top: ${remcalc(-12)};
`;

View File

@ -42,6 +42,7 @@ const StyledNav = styled.div`
// TODO: refactor colours into constants in UI
const NavigationLinkContainer = styled.div`
position: relative;
padding: ${remcalc(11)} ${remcalc(12)} ${remcalc(12)};
color: #646464;
border: solid ${remcalc(1)} #d8d8d8;
@ -77,6 +78,17 @@ const NavLi = styled.li`
}
`;
const Shadow = styled.div`
z-index: 1;
position: absolute;
height: ${remcalc(5)};
width: 100%;
left: 0;
bottom: 0;
background-image:
linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.06));
`;
const OrgNavigation = ({
orgs = []
}) => {
@ -98,6 +110,7 @@ const OrgNavigation = ({
}) =>
<a href={href} onClick={onClick}>
<NavigationLinkContainer className={isActive ? 'active' : ''}>
{ !isActive && <Shadow />}
<OrgImage>
<OrgAvatar
height={remcalc(26)}

View File

@ -0,0 +1,31 @@
const React = require('react');
const PropTypes = require('@root/prop-types');
// const List = require('@ui/components/list');
// const {
// ListItem,
// ListItemView,
// ListItemMeta,
// ListItemTitle,
// ListItemOptions
// } = List;
const PersonItem = ({
person = {},
}) => {
return (
<tr>
<td>{person.uuid}</td>
<td>{person.uuid}</td>
<td>{person.uuid}</td>
</tr>
);
};
PersonItem.propTypes = {
person: PropTypes.person,
};
module.exports = PersonItem;

View File

@ -0,0 +1,39 @@
const React = require('react');
const PersonItem = require('@components/people-item');
const PropTypes = require('@root/prop-types');
const PeopleList = ({
people = []
}) => {
const peopleList = people.map((person) => (
<PersonItem
key={person.uuid}
person={person}
/>
));
return (
<div>
<table>
<thead>
<tr>
<th>Member</th>
<th>Status</th>
<th>Role</th>
</tr>
</thead>
<tbody>
{peopleList}
</tbody>
</table>
</div>
);
};
PeopleList.propTypes = {
people: React.PropTypes.arrayOf(PropTypes.person),
};
module.exports = PeopleList;

View File

@ -1,30 +1,11 @@
const flatten = require('lodash.flatten');
const React = require('react');
const ReactIntl = require('react-intl');
const Styled = require('styled-components');
const ReactRouter = require('react-router');
const H1 = require('@ui/components/base-elements').H1;
const Li = require('@ui/components/horizontal-list/li');
const PropTypes = require('@root/prop-types');
const Ul = require('@ui/components/horizontal-list/ul');
const fns = require('@ui/shared/functions');
const {
default: styled
} = Styled;
const BreadcrumbA = styled.a`
text-decoration: none !important;
`;
const BreadcrumbSpan = styled.span`
color: #646464;
`;
const {
remcalc
} = fns;
const Breadcrumb = require('@components/breadcrumb');
const {
FormattedMessage
@ -34,11 +15,12 @@ const {
Link
} = ReactRouter;
const Section = ({
const Section = (props) => {
const {
children,
links = [],
name = []
}) => {
} = props;
const navLinks = links.map((link) => (
<Li key={link.name}>
<Link activeClassName='active' to={link.pathname}>
@ -47,44 +29,9 @@ const Section = ({
</Li>
));
const nameLinks = flatten(name.map((part, i) => {
if (!part.name) {
return null;
}
const link = (
<Link key={part.pathname} to={part.pathname}>
{
({
href,
onClick,
}) =>
<BreadcrumbA href={href} onClick={onClick}>
{part.name}
</BreadcrumbA>
}
</Link>
);
const slash = (
<BreadcrumbSpan key={`${part.pathname}${i}`}> / </BreadcrumbSpan>
);
return (i === 0) ? link : [
slash,
link
];
}));
return (
<div>
<H1
style={{
fontSize: remcalc(24)
}}
>
{nameLinks}
</H1>
<Breadcrumb {...props} />
<Ul>
{navLinks}
</Ul>
@ -95,8 +42,7 @@ const Section = ({
Section.propTypes = {
children: React.PropTypes.node,
links: React.PropTypes.arrayOf(PropTypes.link),
name: React.PropTypes.arrayOf(PropTypes.link)
links: React.PropTypes.arrayOf(PropTypes.link)
};
module.exports = Section;

View File

@ -3,6 +3,13 @@ const React = require('react');
const ReactRedux = require('react-redux');
// const ReactRouter = require('react-router');
const Row = require('@ui/components/row');
const Column= require('@ui/components/column');
const Button= require('@ui/components/button');
const PropTypes = require('@root/prop-types');
const PeopleList = require('@components/people-list');
const selectors = require('@state/selectors');
const Section = require('./section');
// const {
@ -13,23 +20,53 @@ const {
connect
} = ReactRedux;
// const {
// Link,
// Match,
// Miss,
// Redirect
// } = ReactRouter;
const {
peopleByOrgIdSelector
} = selectors;
const buttonStyle = {
float: 'right'
};
const People = (props) => {
const {
people = []
} = props;
return (
<Section {...props}>
<p>people</p>
<Row>
<Column smOffset={9} xs={2}>
<Button style={buttonStyle}>Invite</Button>
</Column>
</Row>
<Row>
<Column>
<PeopleList
people={people}
/>
</Column>
</Row>
</Section>
);
};
People.propTypes = {};
People.propTypes = {
people: React.PropTypes.arrayOf(PropTypes.person)
// toggleCollapsed: React.PropTypes.func
};
const mapStateToProps = (state) => ({});
const mapStateToProps = (state, {
params = {}
}) => ({
people: peopleByOrgIdSelector(params.org)(state)
});
module.exports = connect(mapStateToProps)(People);
const mapDispatchToProps = (dispatch) => ({});
module.exports = connect(
mapStateToProps,
mapDispatchToProps
)(People);

View File

@ -211,18 +211,23 @@
"owner": "b94033c1-3665-4c36-afab-d9c3d0b51c01",
"id": "nicola",
"name": "Your dashboard",
"image": "https://pbs.twimg.com/profile_images/641289584580493312/VBfsPlff_400x400.jpg"
"image": "https://pbs.twimg.com/profile_images/641289584580493312/VBfsPlff_400x400.jpg",
"members": {}
}, {
"owner": "b94033c1-3665-4c36-afab-d9c3d0b51c01",
"uuid": "e12ad7db-91b2-4154-83dd-40dcfc700dcc",
"id": "biz-tech",
"name": "BizTech"
"name": "BizTech",
"members": [{
"uuid": "fd853d8f-e1dd-49b5-b7b3-ae9adfea1e2f"
}]
}, {
"owner": "b94033c1-3665-4c36-afab-d9c3d0b51c01",
"uuid": "551f316d-e414-480f-9787-b4c408db3edd",
"id": "make-us-proud",
"name": "Make Us Proud",
"image": "/static/images/make-us-proud.svg"
"image": "/static/images/make-us-proud.svg",
"members": {}
}]
},
"projects": {

View File

@ -61,6 +61,10 @@ const Sections = React.PropTypes.arrayOf(
React.PropTypes.string
);
const Person = React.PropTypes.shape({
...BaseObject
});
module.exports = {
account: Account,
link: Link,
@ -71,5 +75,6 @@ module.exports = {
instance: Instance,
metric: Metric,
metricType: MetricType,
dataset: Dataset
dataset: Dataset,
person: Person
};

View File

@ -18,6 +18,7 @@ const services = (state) => get(state, 'services.data', []);
const collapsedServices = (state) => get(state, 'services.ui.collapsed', []);
const collapsedInstances = (state) => get(state, 'instances.ui.collapsed', []);
const instances = (state) => get(state, 'instances.data', []);
const members = (state) => get(state, 'members.data', []);
const metricTypes = (state) => get(state, 'metrics.data.types', []);
const metricDatasets = (state) => get(state, 'metrics.data.datasets', []);
@ -110,6 +111,12 @@ const instancesByProjectId = (projectId) => createSelector(
}))
);
const peopleByOrgId = (orgId) => createSelector(
// [members, orgById(orgId)], (members, org) => org.members
[members, orgById(orgId)], (members, org) => org.members
);
module.exports = {
accountSelector: account,
accountUISelector: accountUi,
@ -126,5 +133,6 @@ module.exports = {
instancesByServiceIdSelector: instancesByServiceId,
metricsByServiceIdSelector: metricsByServiceId,
instancesByProjectIdSelector: instancesByProjectId,
metricTypeByUuidSelector: metricTypeByUuid
metricTypeByUuidSelector: metricTypeByUuid,
peopleByOrgIdSelector: peopleByOrgId
};

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ install-production: compile clean
.PHONY: compile
compile: install
mkdir -p dist
cp -R src/ dist/.
cp -R src/. dist/.
$(bindir)/babel src --out-dir dist --source-maps inline
.PHONY: build

View File

@ -27,6 +27,7 @@
"lodash.isfunction": "^3.0.8",
"lodash.isstring": "^4.0.1",
"lodash.isundefined": "^3.0.1",
"moment": "^2.17.1",
"param-case": "^2.1.0",
"random-natural": "^1.0.3",
"react": "^15.4.2",

View File

@ -69,14 +69,6 @@ const style = css`
padding: ${remcalc('14 16')};
position: relative;
font-family: -apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif;
font-size: ${remcalc(16)};
font-weight: 400;
text-align: center;
@ -130,6 +122,7 @@ const style = css`
`;
const StyledButton = styled.button`
min-width: ${remcalc(120)};
${style}
`;

View File

@ -1,13 +1,8 @@
const constants = require('../../shared/constants');
const fns = require('../../shared/functions');
const Item = require('./item');
const React = require('react');
const Styled = require('styled-components');
const {
colors
} = constants;
const {
remcalc
} = fns;
@ -19,8 +14,9 @@ const {
const StyledItem = styled(Item)`
position: absolute;
background-color: ${colors.brandPrimary};
border: solid ${remcalc(1)} ${colors.borderPrimary};
background-color: #3B4AAF;
border: solid ${remcalc(1)} #2D3884;
box-shadow: none;
width: calc(100% + ${remcalc(2)});

View File

@ -1,33 +0,0 @@
const React = require('react');
const Styled = require('styled-components');
const fns = require('../../shared/functions');
const {
remcalc
} = fns;
const {
default: styled
} = Styled;
const StyledBody = styled.div`
margin: 0;
width: 100%;
height: ${remcalc(264)};
`;
const Body = ({
children
}) => {
return (
<StyledBody name='metric-body'>
{children}
</StyledBody>
);
};
Body.propTypes = {
children: React.PropTypes.node
};
module.exports = Body;

View File

@ -0,0 +1,174 @@
const React = require('react');
const Styled = require('styled-components');
const moment = require('moment');
const Chart = require('chart.js');
const whisker = require('chartjs-chart-box-plot');
whisker(Chart);
const {
default: styled
} = Styled;
const Container = styled.div`
position: relative;
height: 100%;
width: 100%;
`;
const Canvas = styled.canvas`
`;
class Graph extends React.Component {
componentDidMount() {
const {
yMax = 100,
yMin = 0,
yMeasurement = '%'
} = this.props;
const {
data,
xMax,
xMin,
xUnitStepSize
} = this.processData(this.props);
this._chart = new Chart(this._refs.component, {
type: 'whisker',
responsive: true,
maintainAspectRatio: true,
data: {
datasets: [{
data: data
}]
},
options: {
layout: {
padding: 10
},
scales: {
xAxes: [{
display: true,
type: 'time',
time: {
unit: 'minute',
unitStepSize: xUnitStepSize,
max: xMax,
min: xMin,
/*displayFormats: {
hour: 'MMM D, hA'
}*/
},
}],
yAxes: [{
display: true,
ticks: {
min: yMin,
max: yMax,
callback: (value, index, values) => {
return `${value.toFixed(2)}${yMeasurement}`;
}
}
}]
},
legend: {
display: false
}
},
});
}
componentWillReceiveProps(nextProps) {
const {
data,
xMax,
xMin,
xUnitStepSize
} = this.processData(nextProps);
this._chart.data.datasets = [{
data
}];
this._chart.options.scales.xAxes[0].time.max = xMax;
this._chart.options.scales.xAxes[0].time.min = xMin;
this._chart.options.scales.xAxes[0].time.unitStepSize = xUnitStepSize;
this._chart.update(0);
}
processData(props) {
const {
data = [],
duration = 360
} = this.props;
// I'm going to assume that data will be structured in 10min intervals...
// And that newest data will be at the end...
// Let's rock and roll!
// All this shizzle below needs to be recalculated on new props, yay!
const now = moment();
// first time on scale x
const before = moment().subtract(duration, 'minutes');
// remove leading data before first time on scale x
const totalData = data.slice(data.length - 1 - duration/10);
// adjust time of first data, if there's less data than would fill the chart
const start = moment(before)
.add(duration - (totalData.length-1)*10, 'minutes');
// add times to data
const dataWithTime = totalData.map((d, i) => {
const add = i*10;
return Object.assign(
{},
d,
{
x: moment(start).add(add, 'minutes').toDate()
}
);
});
// set min and max
const xMax = now.toDate();
const xMin = before.toDate();
// calculate stepsize
const xUnitStepSize = duration/6;
return {
data: dataWithTime,
xMax,
xMin,
xUnitStepSize
};
}
ref(name) {
this._refs = this._refs || {};
return (el) => {
this._refs[name] = el;
};
}
render() {
return (
<Container name='metric-body'>
<Canvas
height={262}
innerRef={this.ref('component')}
width={940}
/>
</Container>
);
}
}
Graph.propTypes = {
data: React.PropTypes.array,
duration: React.PropTypes.number,
yMax: React.PropTypes.number,
yMeasurement: React.PropTypes.string,
yMin: React.PropTypes.number
};
module.exports = Graph;

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
<title>icon: settings </title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="project:-adding-metrics-1.4" transform="translate(-979.000000, -413.000000)" fill="#FFFFFF">
<g id="metric:-cpu" transform="translate(208.000000, 391.000000)">
<g id="metric-head" transform="translate(5.000000, 0.000000)">
<g id="button:-settinga" transform="translate(742.000000, 0.000000)">
<path d="M33,34 C31.3425,34 30,32.6575 30,31 C30,29.3425 31.3425,28 33,28 C34.6575,28 36,29.3425 36,31 C36,32.6575 34.6575,34 33,34 L33,34 Z M42,32.5 L42,29.5 L40.3485,29.5 C40.155,28.543 39.774,27.655 39.252,26.869 L40.425,25.696 L38.304,23.575 L37.131,24.748 C36.345,24.226 35.457,23.845 34.5,23.6515 L34.5,22 L31.5,22 L31.5,23.6515 C30.543,23.845 29.655,24.226 28.869,24.748 L27.696,23.575 L25.575,25.696 L26.748,26.869 C26.226,27.655 25.845,28.543 25.6515,29.5 L24,29.5 L24,32.5 L25.6515,32.5 C25.845,33.457 26.226,34.345 26.748,35.131 L25.575,36.304 L27.696,38.425 L28.869,37.252 C29.655,37.774 30.543,38.155 31.5,38.3485 L31.5,40 L34.5,40 L34.5,38.3485 C35.457,38.155 36.345,37.774 37.131,37.252 L38.304,38.425 L40.425,36.304 L39.252,35.131 C39.774,34.345 40.155,33.457 40.3485,32.5 L42,32.5 Z" id="icon:-settings-"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,5 +1,5 @@
module.exports = {
MetricBody: require('./body'),
MetricGraph: require('./graph'),
MetricCloseButton: require('./close-button'),
MetricHeader: require('./header'),
MetricSelect: require('./select'),

View File

@ -0,0 +1,307 @@
module.exports = [{
firstQuartile: 15,
thirdQuartile: 15,
median: 15,
max: 15,
min: 15,
}, {
firstQuartile: 26,
thirdQuartile: 26,
median: 26,
max: 26,
min: 26,
}, {
firstQuartile: 17,
thirdQuartile: 17,
median: 17,
max: 17,
min: 17,
}, {
firstQuartile: 15,
thirdQuartile: 25,
median: 19,
max: 19,
min: 20,
}, {
firstQuartile: 19,
thirdQuartile: 25,
median: 21,
max: 20,
min: 25,
}, {
firstQuartile: 24,
thirdQuartile: 30,
median: 25,
max: 26,
min: 27,
}, {
firstQuartile: 28,
thirdQuartile: 34,
median: 30,
max: 30,
min: 30,
}, {
firstQuartile: 30,
thirdQuartile: 45,
median: 35,
max: 40,
min: 40,
}, {
firstQuartile: 20,
thirdQuartile: 55,
median: 45,
max: 44,
min: 44,
}, {
firstQuartile: 55,
thirdQuartile: 55,
median: 55,
max: 55,
min: 55,
}, {
firstQuartile: 57,
thirdQuartile: 56,
median: 57,
max: 58,
min: 57,
}, {
firstQuartile: 57,
thirdQuartile: 56,
median: 56,
max: 56,
min: 56,
}, {
firstQuartile: 60,
thirdQuartile: 56,
median: 60,
max: 60,
min: 60,
}, {
firstQuartile: 57,
thirdQuartile: 57,
median: 57,
max: 57,
min: 57,
}, {
firstQuartile: 57,
thirdQuartile: 55,
median: 55,
max: 55,
min: 55,
}, {
firstQuartile: 20,
thirdQuartile: 45,
median: 45,
max: 45,
min: 45,
}, {
firstQuartile: 15,
thirdQuartile: 40,
median: 30,
max: 49,
min: 30,
}, {
firstQuartile: 15,
thirdQuartile: 15,
median: 15,
max: 15,
min: 15,
}, {
firstQuartile: 26,
thirdQuartile: 26,
median: 26,
max: 26,
min: 26,
}, {
firstQuartile: 17,
thirdQuartile: 17,
median: 17,
max: 17,
min: 17,
}, {
firstQuartile: 15,
thirdQuartile: 25,
median: 19,
max: 19,
min: 20,
}, {
firstQuartile: 19,
thirdQuartile: 25,
median: 21,
max: 20,
min: 25,
}, {
firstQuartile: 24,
thirdQuartile: 30,
median: 25,
max: 26,
min: 10,
}, {
firstQuartile: 28,
thirdQuartile: 34,
median: 30,
max: 30,
min: 30,
}, {
firstQuartile: 30,
thirdQuartile: 45,
median: 35,
max: 40,
min: 40,
}, {
firstQuartile: 20,
thirdQuartile: 55,
median: 45,
max: 44,
min: 44,
}, {
firstQuartile: 55,
thirdQuartile: 55,
median: 55,
max: 55,
min: 55,
}, {
firstQuartile: 57,
thirdQuartile: 56,
median: 57,
max: 58,
min: 57,
}, {
firstQuartile: 57,
thirdQuartile: 56,
median: 56,
max: 56,
min: 56,
}, {
firstQuartile: 60,
thirdQuartile: 56,
median: 60,
max: 60,
min: 60,
}, {
firstQuartile: 57,
thirdQuartile: 57,
median: 57,
max: 57,
min: 57,
}, {
firstQuartile: 57,
thirdQuartile: 55,
median: 55,
max: 55,
min: 55,
}, {
firstQuartile: 20,
thirdQuartile: 45,
median: 45,
max: 45,
min: 45,
}, {
firstQuartile: 15,
thirdQuartile: 40,
median: 30,
max: 49,
min: 30,
}, {
firstQuartile: 15,
thirdQuartile: 15,
median: 15,
max: 15,
min: 15,
}, {
firstQuartile: 26,
thirdQuartile: 26,
median: 26,
max: 26,
min: 26,
}, {
firstQuartile: 17,
thirdQuartile: 17,
median: 17,
max: 17,
min: 17,
}, {
firstQuartile: 15,
thirdQuartile: 25,
median: 19,
max: 19,
min: 20,
}, {
firstQuartile: 19,
thirdQuartile: 25,
median: 21,
max: 20,
min: 25,
}, {
firstQuartile: 24,
thirdQuartile: 30,
median: 25,
max: 26,
min: 27,
}, {
firstQuartile: 28,
thirdQuartile: 34,
median: 30,
max: 30,
min: 30,
}, {
firstQuartile: 30,
thirdQuartile: 45,
median: 35,
max: 40,
min: 40,
}, {
firstQuartile: 20,
thirdQuartile: 55,
median: 45,
max: 44,
min: 44,
}, {
firstQuartile: 55,
thirdQuartile: 55,
median: 55,
max: 55,
min: 55,
}, {
firstQuartile: 57,
thirdQuartile: 56,
median: 57,
max: 58,
min: 57,
}, {
firstQuartile: 57,
thirdQuartile: 56,
median: 56,
max: 56,
min: 56,
}, {
firstQuartile: 60,
thirdQuartile: 56,
median: 60,
max: 60,
min: 60,
}, {
firstQuartile: 57,
thirdQuartile: 57,
median: 57,
max: 57,
min: 57,
}, {
firstQuartile: 57,
thirdQuartile: 55,
median: 55,
max: 55,
min: 55,
}, {
firstQuartile: 20,
thirdQuartile: 45,
median: 45,
max: 45,
min: 45,
}, {
firstQuartile: 15,
thirdQuartile: 40,
median: 30,
max: 49,
min: 30,
}];

View File

@ -59,8 +59,10 @@ const Select = ({
form,
id = rndId(),
name,
onChange,
required,
selected
selected,
value
}) => {
return (
<SelectWrapper>
@ -70,8 +72,10 @@ const Select = ({
form={form}
id={id}
name={name}
onChange={onChange}
required={required}
selected={selected}
value={value}
>
{children}
</StyledSelect>
@ -86,8 +90,10 @@ Select.propTypes = {
form: React.PropTypes.string,
id: React.PropTypes.string,
name: React.PropTypes.string,
onChange: React.PropTypes.func,
required: React.PropTypes.bool,
selected: React.PropTypes.bool
selected: React.PropTypes.bool,
value: React.PropTypes.string
};
module.exports = Select;

View File

@ -3,7 +3,8 @@ const Styled = require('styled-components');
const fns = require('../../shared/functions');
const constants = require('../../shared/constants');
const Button = require('../button');
const SettingsIcon = require('!babel!svg-react!./close.svg?name=SettingsIcon');
const SettingsIcon =
require('!babel!svg-react!./icon-settings.svg?name=SettingsIcon');
const {
default: styled

View File

@ -6,7 +6,7 @@ const {
} = require('@kadira/storybook');
const {
MetricBody,
MetricGraph,
MetricCloseButton,
MetricHeader,
MetricSelect,
@ -15,7 +15,42 @@ const {
MetricView
} = require('./');
const MetricData = require('./metric-data');
const onButtonClick = () => {};
const onMetricSelect = () => {};
const hour = 60; // in minutes - for moment
const sixHours = 6*hour;
const twelveHours = 12*hour;
const oneDay = 24*hour;
const twoDays = 48*hour;
const withinRange = (
value,
newMin,
newMax,
precision = 2,
oldMin = 0,
oldMax = 100
) => {
const normalisedValue = value-oldMin;
const newRange = newMax-newMin;
const oldRange = oldMax-oldMin;
const newValue = newMin + normalisedValue*newRange/oldRange;
return newValue.toFixed(2);
};
const percentageMetricData = MetricData;
const kbMetricData = MetricData.map(m => {
return {
firstQuartile: withinRange(m.firstQuartile, 1.55, 2.0),
thirdQuartile: withinRange(m.thirdQuartile, 1.55, 2.0),
median: withinRange(m.median, 1.55, 2.0),
max: withinRange(m.max, 1.55, 2.0),
min: withinRange(m.min, 1.55, 2.0),
};
});
storiesOf('Metric', module)
.add('Metric', () => (
@ -23,16 +58,46 @@ storiesOf('Metric', module)
<MetricView>
<MetricHeader>
<MetricTitle>Aggregated CPU usage</MetricTitle>
<MetricSelect>
<option selected>6 hours</option>
<option>12 hours</option>
<option>24 hours</option>
<option>Two days</option>
<MetricSelect onChange={onMetricSelect} value={sixHours}>
<option value={sixHours}>6 hours</option>
<option value={twelveHours}>12 hours</option>
<option value={oneDay}>24 hours</option>
<option value={twoDays}>Two days</option>
</MetricSelect>
<MetricSettingsButton>Settings</MetricSettingsButton>
<MetricSettingsButton onClick={onButtonClick}>
Settings
</MetricSettingsButton>
<MetricCloseButton onClick={onButtonClick} />
</MetricHeader>
<MetricBody />
<MetricGraph
data={percentageMetricData}
duration={sixHours}
yMax={100}
yMeasurement='%'
yMin={0}
/>
</MetricView>
<MetricView>
<MetricHeader>
<MetricTitle>Aggregated CPU usage</MetricTitle>
<MetricSelect onChange={onMetricSelect} value={twoDays}>
<option value={sixHours}>6 hours</option>
<option value={twelveHours}>12 hours</option>
<option value={oneDay}>24 hours</option>
<option value={twoDays}>Two days</option>
</MetricSelect>
<MetricSettingsButton onClick={onButtonClick}>
Settings
</MetricSettingsButton>
<MetricCloseButton onClick={onButtonClick} />
</MetricHeader>
<MetricGraph
data={kbMetricData}
duration={oneDay}
yMax={2.0}
yMeasurement='kb'
yMin={1.55}
/>
</MetricView>
</Base>
));

View File

@ -1,4 +1,5 @@
const constants = require('../../shared/constants');
const fns = require('../../shared/functions');
const React = require('react');
const Styled = require('styled-components');
@ -7,6 +8,10 @@ const {
colors
} = constants;
const {
remcalc
} = fns;
const {
default: styled
} = Styled;
@ -15,6 +20,7 @@ const Container = styled.div`
position: relative;
box-sizing: border-box;
width: 100%;
max-width: ${remcalc(940)};
box-shadow: ${boxes.bottomShaddow};
border: 1px solid ${colors.borderSecondary};
`;

View File

@ -0,0 +1,55 @@
const React = require('react');
const Base = require('../base');
const Row = require('../row');
const Column = require('../column');
const {
storiesOf,
// action,
// linkTo
} = require('@kadira/storybook');
const {
MiniMetricGraph,
MiniMetricMeta,
MiniMetricTitle,
MiniMetricSubtitle,
MiniMetricView
} = require('./');
const MiniMetricData = require('../list/mini-metric-data');
storiesOf('Metric (Mini)', module)
.add('Mini Metric', () => (
<Base>
<Row around>
<Column xs={3}>
<MiniMetricView>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={3}>
<MiniMetricView>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={3}>
<MiniMetricView>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
</Row>
</Base>
));

View File

@ -4378,7 +4378,7 @@ mobx@^2.3.4:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mobx/-/mobx-2.7.0.tgz#cf3d82d18c0ca7f458d8f2a240817b3dc7e54a01"
moment@^2.10.6:
moment@^2.10.6, moment@^2.17.1:
version "2.17.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.17.1.tgz#fed9506063f36b10f066c8b59a144d7faebe1d82"