Resolving conflict

This commit is contained in:
JUDIT GRESKOVITS 2017-01-12 12:17:25 +00:00
commit 894189e890
38 changed files with 1508 additions and 779 deletions

View File

@ -0,0 +1,56 @@
const React = require('react');
const Styled = require('styled-components');
const Column = require('@ui/components/column');
const MiniMetric = require('@ui/components/mini-metric');
const PropTypes = require('@root/prop-types');
const Row = require('@ui/components/row');
const {
default: styled
} = Styled;
const {
MiniMetricGraph,
MiniMetricMeta,
MiniMetricTitle,
MiniMetricSubtitle,
MiniMetricView
} = MiniMetric;
const StyledRow = styled(Row)`
margin: 0;
& > div {
padding-left: 0;
padding-right: 0;
}
`;
const MetricsRow = ({
datasets = []
}) => {
const _datasets = datasets.map((metric, i) => (
<Column key={i} xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={metric.data} />
</MiniMetricView>
</Column>
));
return (
<StyledRow>
{_datasets}
</StyledRow>
);
};
MetricsRow.propTypes = {
datasets: React.PropTypes.arrayOf(PropTypes.dataset)
};
module.exports = MetricsRow;

View File

@ -1,8 +1,10 @@
const forceArray = require('force-array');
const React = require('react');
const ReactRouter = require('react-router');
const Anchor = require('@ui/components/anchor');
const List = require('@ui/components/list');
const MetricsRow = require('@components/metrics-row');
const PropTypes = require('@root/prop-types');
const {
@ -27,26 +29,51 @@ const ServiceItem = ({
project = '',
service = {}
}) => {
const isChild = !!service.parent;
const childs = forceArray(service.services).map((service) => (
<ServiceItem
key={service.uuid}
org={org}
project={project}
service={service}
/>
));
const to = `/${org}/projects/${project}/services/${service.id}`;
const childs = service.services.map((service) => (
<ListItem
collapsed={service.collapsed}
flat
key={service.uuid}
stacked={service.instances > 1}
>
<ListItemView>
<ListItemMeta>
<ListItemTitle>{service.name}</ListItemTitle>
<ListItemSubTitle>{service.instances} instances</ListItemSubTitle>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
));
const title = isChild ? (
<ListItemTitle>{service.name}</ListItemTitle>
) : (
<ListItemTitle>
<Link to={to}>
{Anchor.fn(
<Anchor secondary>
{service.name}
</Anchor>
)}
</Link>
</ListItemTitle>
);
const subtitle = (
<ListItemSubTitle>{service.instances} instances</ListItemSubTitle>
);
const description = (
<ListItemDescription>Flags</ListItemDescription>
);
const header = isChild ? null : (
<ListItemHeader>
<ListItemMeta>
{title}
{subtitle}
{description}
</ListItemMeta>
<ListItemOptions></ListItemOptions>
</ListItemHeader>
);
const view = childs.length ? (
<ListItemGroupView>
@ -55,10 +82,12 @@ const ServiceItem = ({
) : (
<ListItemView>
<ListItemMeta>
<ListItemDescription>Flags</ListItemDescription>
{isChild && title}
{isChild && subtitle}
{description}
</ListItemMeta>
<ListItemOutlet>
Metrics
<MetricsRow metrics={service.metrics} />
</ListItemOutlet>
</ListItemView>
);
@ -66,23 +95,12 @@ const ServiceItem = ({
return (
<ListItem
collapsed={service.collapsed}
headed
flat={isChild}
headed={!isChild}
key={service.uuid}
stacked={isChild && (service.instances > 1)}
>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>
<Link to={to}>
{Anchor.fn(
<Anchor secondary>
{service.name}
</Anchor>
)}
</Link>
</ListItemTitle>
<ListItemSubTitle>{service.instances} instance</ListItemSubTitle>
</ListItemMeta>
<ListItemOptions></ListItemOptions>
</ListItemHeader>
{header}
{view}
</ListItem>
);

View File

@ -24,7 +24,7 @@ const AddMetrics = ({
const added = (metric) =>
Boolean(metrics.filter((m) => m.id === metric).length);
const addButton = (metric) => (
<AddMetricButton onClick={onAddMetric(metric)}>
<AddMetricButton metric={metric} onClick={onAddMetric}>
<FormattedMessage id={'metrics.add.add-label'} onClick={onAddMetric} />
</AddMetricButton>
);

View File

@ -1,11 +1,17 @@
const React = require('react');
const ReactRedux = require('react-redux');
const actions = require('@state/actions');
const EmptyInstances = require('@components/empty/instances');
const PropTypes = require('@root/prop-types');
const List = require('@ui/components/list');
const DatasetsRow = require('@components/metrics-row');
const selectors = require('@state/selectors');
const {
toggleInstanceCollapsed
} = actions;
const {
connect
} = ReactRedux;
@ -19,22 +25,29 @@ const {
ListItemView,
ListItemMeta,
ListItemTitle,
ListItemOptions
ListItemOptions,
ListItemOutlet
} = List;
const Instances = ({
instances = []
instances = [],
toggleCollapsed = () => null
}) => {
const onClick = (uuid) => () => toggleCollapsed(uuid);
const empty = instances.length ? null : (
<EmptyInstances />
);
const instanceList = instances.map((service) => (
<ListItem collapsed key={service.uuid}>
const instanceList = instances.map((instance) => (
<ListItem collapsed={!instance.collapsed} key={instance.uuid} >
<ListItemView>
<ListItemMeta>
<ListItemTitle>{service.name}</ListItemTitle>
<ListItemMeta onClick={onClick(instance.uuid)}>
<ListItemTitle>{instance.name}</ListItemTitle>
</ListItemMeta>
<ListItemOutlet>
<DatasetsRow metrics={instance.metrics} />
</ListItemOutlet>
</ListItemView>
<ListItemOptions>
@ -51,7 +64,8 @@ const Instances = ({
};
Instances.propTypes = {
instances: React.PropTypes.arrayOf(PropTypes.instance)
instances: React.PropTypes.arrayOf(PropTypes.instance),
toggleCollapsed: React.PropTypes.func
};
const mapStateToProps = (state, {
@ -60,6 +74,11 @@ const mapStateToProps = (state, {
instances: instancesByServiceIdSelector(params.serviceId)(state)
});
const mapDispatchToProps = (dispatch) => ({
toggleCollapsed: (uuid) => dispatch(toggleInstanceCollapsed(uuid))
});
module.exports = connect(
mapStateToProps
mapStateToProps,
mapDispatchToProps
)(Instances);

View File

@ -65,19 +65,129 @@
"time_of_day"
]
},
"data": [{
"uuid": "dca08514-72e5-46ce-ad91-e68b3b0914d4",
"id": "cpu_agg_usage",
"service": "081a792c-47e0-4439-924b-2efa9788ae9e"
}, {
"uuid": "9e77b50e-42d7-425d-8daf-c0e98e2bdd6a",
"id": "zfs_used",
"service": "081a792c-47e0-4439-924b-2efa9788ae9e"
}, {
"uuid": "347dbdc7-15e3-4e12-8dfb-865d38526e14",
"id": "mem_limit",
"service": "081a792c-47e0-4439-924b-2efa9788ae9e"
}]
"data": {
"types": [{
"uuid": "dca08514-72e5-46ce-ad91-e68b3b0914d4",
"id": "agg-cpu-usage"
}, {
"uuid": "9e77b50e-42d7-425d-8daf-c0e98e2bdd6a",
"id": "mem-res-set-size"
}, {
"uuid": "347dbdc7-15e3-4e12-8dfb-865d38526e14",
"id": "apache-http-reqs"
}, {
"uuid": "2aaa237d-42b3-442f-9094-a17aa470014b",
"name": "Memory",
"id": "memory"
}],
"datasets": [{
"type": "2aaa237d-42b3-442f-9094-a17aa470014b",
"uuid": "3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"data": [{
"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
}]
}]
}
},
"orgs": {
"ui": {
@ -180,120 +290,218 @@
"id": "nginx",
"name": "Nginx",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 1
"instances": 1,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "be227788-74f1-4e5b-a85f-b5c71cbae8d8",
"id": "wordpress",
"name": "Wordpress",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 1
"instances": 1,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "6a0eee76-c019-413b-9d5f-44712b55b993",
"id": "nfs",
"name": "NFS",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 1
"instances": 1,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"id": "memcached",
"name": "Memcached",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 1
"instances": 5,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "4ee4103e-1a52-4099-a48e-01588f597c70",
"id": "percona",
"name": "Percona",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 5
"instances": 5,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "9572d367-c4ae-4fb1-8ad5-f5e3830e7034",
"id": "primary",
"name": "Primary",
"parent": "4ee4103e-1a52-4099-a48e-01588f597c70",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 1
"instances": 1,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "c8411ef0-ab39-42cb-a704-d20b170eff31",
"id": "secondaries",
"name": "Secondaries",
"parent": "4ee4103e-1a52-4099-a48e-01588f597c70",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 4
"instances": 4,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "97c68055-db88-45c9-ad49-f26da4264777",
"id": "consul",
"name": "Consul",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"instances": 1
"instances": 1,
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}]
},
"instances": {
"ui": {
"collapsed": []
},
"data": [{
"uuid": "309ecd9f-ac03-474b-aff7-4bd2e743296c",
"name": "wordpress_01",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "be227788-74f1-4e5b-a85f-b5c71cbae8d8",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "0db6db53-de6f-4378-839e-5d5b452fbaf2",
"name": "nfs_01",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "6a0eee76-c019-413b-9d5f-44712b55b993",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "250c8a6c-7d02-49a9-8abd-e1c22773041d",
"name": "consul",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "97c68055-db88-45c9-ad49-f26da4264777",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "2c921f3a-8bc3-4f57-9cd7-789ebae72061",
"name": "memcache_01",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "68d3046e-8e34-4f5d-a0e5-db3795a250fd",
"name": "memcache_02",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "2ea99763-3b44-4179-8393-d66d94961051",
"name": "memcache_03",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "25f6bc62-63b8-4959-908e-1f6d7ff6341d",
"name": "memcache_04",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "8be01042-0281-4a77-a357-25979e87bf3d",
"name": "memcache_05",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "6d31aff4-de1e-4042-a983-fbd23d5c530c",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "3d652e9d-73e8-4a6f-8171-84fa83740662",
"name": "nginx",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "081a792c-47e0-4439-924b-2efa9788ae9e",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "c3ec7633-a02b-4615-86a0-9e6faeaae94b",
"name": "percona-primary",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "9572d367-c4ae-4fb1-8ad5-f5e3830e7034",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"service": "4ee4103e-1a52-4099-a48e-01588f597c70",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}, {
"uuid": "c2b5fec2-31e2-41a7-b7fc-cd0bb1822e76",
"name": "percona-secundary",
"datacenter": "f018da03-41c8-4619-a36a-ab8b706160cb",
"service": "c8411ef0-ab39-42cb-a704-d20b170eff31",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401"
"service": "4ee4103e-1a52-4099-a48e-01588f597c70",
"project": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
"metrics": [
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec",
"3e6ee79a-7453-4fc6-b9da-7ae1e41138ec"
]
}]
}
}

View File

@ -39,6 +39,20 @@ const Metric = React.PropTypes.shape({
...BaseObject
});
const Dataset = React.PropTypes.shape({
uuid: React.PropTypes.string,
type: React.PropTypes.string,
data: React.PropTypes.arrayOf(
React.PropTypes.shape({
firstQuartile: React.PropTypes.string,
thirdQuartile: React.PropTypes.string,
median: React.PropTypes.string,
max: React.PropTypes.string,
min: React.PropTypes.string
})
)
});
const Sections = React.PropTypes.arrayOf(
React.PropTypes.string
);
@ -58,5 +72,6 @@ module.exports = {
instance: Instance,
metric: Metric,
// consinder renaming this to 'Types' as it could be used for any
metricTypes: MetricTypes
metricTypes: MetricTypes,
dataset: Dataset
};

View File

@ -12,5 +12,6 @@ module.exports = {
updateRouter: createAction(`${APP}/APP/UPDATE_ROUTER`),
toggleHeaderTooltip: createAction(`${APP}/APP/TOGGLE_HEADER_TOOLTIP`),
toggleServiceCollapsed: createAction(`${APP}/APP/TOGGLE_SERVICE_COLLAPSED`),
addMetric: createAction(`${APP}/APP/ADD_METRIC`)
addMetric: createAction(`${APP}/APP/ADD_METRIC`),
toggleInstanceCollapsed: createAction(`${APP}/APP/TOGGLE_INSTANCE_COLLAPSED`)
};

View File

@ -0,0 +1,25 @@
const toggleCollapsed = (state, action) => {
const {
ui
} = state;
const {
collapsed = []
} = ui;
const _collapsed = collapsed.indexOf(action.payload) >= 0
? collapsed.filter((uuid) => uuid !== action.payload)
: [...collapsed, action.payload];
return {
...state,
ui: {
...ui,
collapsed: _collapsed
}
};
};
module.exports = {
toggleCollapsed
};

View File

@ -1,9 +1,20 @@
const ReduxActions = require('redux-actions');
const actions = require('@state/actions');
const common = require('@state/reducers/common');
const {
handleActions
} = ReduxActions;
const {
toggleInstanceCollapsed
} = actions;
const {
toggleCollapsed
} = common;
module.exports = handleActions({
'x': (state) => state // somehow handleActions needs at least one reducer
[toggleInstanceCollapsed.toString()]: toggleCollapsed
}, {});

View File

@ -16,10 +16,15 @@ module.exports = handleActions({
[addMetric.toString()]: (state, action) => {
return ({
...state,
data: [
...state.data,
action.payload
]
data: {
types: [
...state.data.types,
action.payload
],
datasets: [
...state.data.datasets
]
}
});
}
}, {});

View File

@ -1,6 +1,7 @@
const ReduxActions = require('redux-actions');
const actions = require('@state/actions');
const common = require('@state/reducers/common');
const {
handleActions
@ -10,14 +11,10 @@ const {
toggleServiceCollapsed
} = actions;
const {
toggleCollapsed
} = common;
module.exports = handleActions({
[toggleServiceCollapsed.toString()]: (state, action) => ({
...state,
ui: {
...state.ui,
collapsed: state.ui.collapsed.indexOf(action.payload) >= 0
? state.ui.collapsed.filter((uuid) => uuid !== action.payload)
: [...state.ui.collapsed, action.payload]
}
})
[toggleServiceCollapsed.toString()]: toggleCollapsed
}, {});

View File

@ -16,8 +16,10 @@ const orgs = (state) => get(state, 'orgs.data', []);
const projects = (state) => get(state, 'projects.data', []);
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 metrics = (state) => get(state, 'metrics.data', []);
const metricTypes = (state) => get(state, 'metrics.data.types', []);
const metricDatasets = (state) => get(state, 'metrics.data.datasets', []);
const projectById = (projectId) => createSelector(
projects,
@ -46,9 +48,16 @@ const orgSections = (orgId) => createSelector(
)
);
const isCollapsed = (collapsed, uuid) => collapsed.indexOf(uuid) >= 0;
const datasets = (metrics, uuids) => uuids.map((uuid) => find(metrics, [
'uuid',
uuid
]));
const servicesByProjectId = (projectId) => createSelector(
[services, projectById(projectId), collapsedServices],
(services, project, collapsed) =>
[services, projectById(projectId), collapsedServices, metricDatasets],
(services, project, collapsed, metrics) =>
services.filter((s) => s.project === project.uuid)
.map((service) => ({
...service,
@ -57,24 +66,31 @@ const servicesByProjectId = (projectId) => createSelector(
.filter((s) => !s.parent)
.map((service) => ({
...service,
collapsed: collapsed.indexOf(service.uuid) >= 0,
metrics: datasets(metrics, service.metrics),
collapsed: isCollapsed(collapsed, service.uuid),
services: service.services.map((service) => ({
...service,
collapsed: collapsed.indexOf(service.uuid) >= 0
metrics: datasets(metrics, service.metrics),
collapsed: isCollapsed(collapsed, service.uuid)
}))
}))
);
const instancesByServiceId = (serviceId) => createSelector(
[instances, serviceById(serviceId)],
(instances, service) =>
[instances, serviceById(serviceId), collapsedInstances, metricDatasets],
(instances, service, collapsed, metrics) =>
instances.filter((i) => i.service === service.uuid)
.map((instance) => ({
...instance,
metrics: datasets(metrics, instance.metrics),
collapsed: isCollapsed(collapsed, instance.uuid)
}))
);
const metricsByServiceId = (serviceId) => createSelector(
[metrics, serviceById(serviceId)],
(metrics, service) =>
metrics.filter((i) => i.service === service.uuid)
[metricTypes, serviceById(serviceId)],
(metricTypes, service) =>
metricTypes.filter((i) => i.service === service.uuid)
);

View File

@ -3,7 +3,13 @@ const { configure } = require('@kadira/storybook');
const req = require.context('../src/components', true, /story.js$/)
function loadStories() {
req.keys().forEach((filename) => req(filename));
let stories = req.keys();
stories = stories.sort();
stories.forEach( story => req(story));
// Fallback to stories/index.js file for anything that
// hasn't been moved
require('../stories');
}

View File

@ -20,8 +20,10 @@ const StyledButton = styled(Button)`
const AddMetricButton = ({
children,
disabled,
metric,
onClick
}) => {
const onButtonClick = (e) => onClick(metric);
return disabled ?
(
<StyledButton
@ -33,7 +35,7 @@ const AddMetricButton = ({
) : (
<StyledButton
name='add-metric-button'
onClick={onClick}
onClick={onButtonClick}
secondary
>
{children}
@ -44,6 +46,7 @@ const AddMetricButton = ({
AddMetricButton.propTypes = {
children: React.PropTypes.node,
disabled: React.PropTypes.bool,
metric: React.PropTypes.string,
onClick: React.PropTypes.func,
};

View File

@ -0,0 +1,18 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Checkbox = require('./');
storiesOf('Checkbox', module)
.add('Default', () => (
<Checkbox />
))
.add('Checked', () => (
<Checkbox checked onChange={function noop() {}} />
))
.add('Disabled', () => (
<Checkbox disabled />
));

View File

@ -0,0 +1,20 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Base = require('../base');
const Close = require('./');
storiesOf('Close', module)
.add('Default', () => (
<Base
style={{
position: 'relative',
width: 60
}}
>
<Close onClick={function noop() {}} />
</Base>
));

View File

@ -31,12 +31,11 @@ const InputField = styled.input`
color: ${props => props.error ? colors.alert : colors.fonts.semibold}
display: block;
font-size: 16px;
height: ${remcalc(50)};
padding: ${remcalc(16)};
padding: ${remcalc('15 18')};
visibility: visible;
width: 100%;
${baseBox()};
border-color: ${props => props.error ? colors.alert : 'auto'};
border-color: ${props => props.error ? colors.alert : ''};
&:focus {
border-color: ${boxes.border.checked};

View File

@ -0,0 +1,35 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Base= require('../base');
const Input = require('./');
storiesOf('Input', module)
.add('Default', () => (
<Base>
<Input placeholder="I am the placeholder" />
</Base>
))
.add('type=email', () => (
<Base>
<Input
label='Email Address'
placeholder='Enter email'
type='email'
>
<small>We&apos;ll never share your email with anyone else.</small>
</Input>
</Base>
))
.add('Error', () => (
<Base>
<Input
error="Somethings missing"
placeholder="There was an error"
value="alexw/makeusproud.com"
/>
</Base>
));

View File

@ -0,0 +1,103 @@
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,
}];

View File

@ -0,0 +1,320 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Base = require('../base');
const Row = require('../row');
const Column = require('../column');
const MiniMetricData = require('./mini-metric-data');
const {
MiniMetricGraph,
MiniMetricMeta,
MiniMetricTitle,
MiniMetricSubtitle,
MiniMetricView
} = require('../mini-metric');
const {
ListItemDescription,
ListItemHeader,
ListItem,
ListItemMeta,
ListItemOptions,
ListItemOutlet,
ListItemSubTitle,
ListItemTitle,
ListItemView,
ListItemGroupView
} = require('./');
storiesOf('List Item', module)
.add('default', () => (
<Base>
<ListItem>
<ListItemView>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
<ListItemOptions>
</ListItemOptions>
</ListItem>
</Base>
))
.add('collapsed', () => (
<Base>
<ListItem collapsed>
<ListItemView>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
<ListItemOptions>
</ListItemOptions>
</ListItem>
</Base>
))
.add('headed', () => (
<Base>
<ListItem headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions>
</ListItemOptions>
</ListItemHeader>
<ListItemView>
<ListItemMeta>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</Base>
))
.add('headed collapsed', () => (
<Base>
<ListItem collapsed headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions>
</ListItemOptions>
</ListItemHeader>
<ListItemView>
<ListItemMeta>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</Base>
))
.add('stacked', () => (
<Base>
<ListItem stacked>
<ListItemView>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
<ListItemOptions>
</ListItemOptions>
</ListItem>
</Base>
))
.add('view-group', () => (
<Base>
<ListItem headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Percona</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions></ListItemOptions>
</ListItemHeader>
<ListItemGroupView>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat stacked>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</ListItemGroupView>
</ListItem>
</Base>
))
.add('view-group with metrics', () => (
<Base>
<ListItem headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Percona</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions></ListItemOptions>
</ListItemHeader>
<ListItemGroupView>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
</ListItemMeta>
<ListItemOutlet>
<Row>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
</Row>
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
<Row>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
</Row>
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat stacked>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
</ListItemMeta>
<ListItemOutlet>
<Row>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
</Row>
</ListItemOutlet>
</ListItemView>
</ListItem>
</ListItemGroupView>
</ListItem>
</Base>
));

View File

@ -4,7 +4,7 @@ const React = require('react');
const transfer = (parentProps, props) => {
// eslint-disable-next-line react/prop-types
return React.Children.map(props.children, (c) => {
return React.cloneElement(c, {
return c && React.cloneElement(c, {
...c.props,
...parentProps.reduce((sum, name) => ({
...sum,

View File

@ -0,0 +1,17 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Base= require('../base');
const Modal = require('./');
storiesOf('Modal', module)
.add('Default', () => (
<Base>
<Modal>
<h2>This is the Modal</h2>
</Modal>
</Base>
));

View File

@ -0,0 +1,34 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Base= require('../base');
const Notificaton = require('./');
storiesOf('Notificaton', module)
.add('Default', () => (
<Base>
<Notificaton>
<span>This is the default content</span>
</Notificaton>
</Base>
))
.add('Success', () => (
<Base>
<Notificaton
close={function noop() {}}
type="success"
>
<span>This is a success notification that is closable</span>
</Notificaton>
</Base>
))
.add('Alert', () => (
<Base>
<Notificaton type="alert">
<span>This is the alert content</span>
</Notificaton>
</Base>
));

View File

@ -0,0 +1,20 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Pagination = require('./');
storiesOf('Pagination', module)
.add('Default', () => (
<Pagination>
<a>
<span>&laquo;</span>
<span>Previous</span>
</a>
<a>1</a>
<a active>2</a>
<a>3</a>
</Pagination>
));

View File

@ -0,0 +1,27 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Base= require('../base');
const RadioGroup = require('./');
const Radio = require('./item');
storiesOf('Radio Group', module)
.add('Default', () => (
<Base>
<RadioGroup>
<Radio name='hello' value='default'>
Video killed the radio star
</Radio>
<Radio name='hello' value='fancy'>
Video killed the radio star
</Radio>
<Radio name='hello' value='none'>
Video killed the radio star
</Radio>
</RadioGroup>
</Base>
));

View File

@ -0,0 +1,20 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Radio = require('./');
storiesOf('Radio', module)
.add('Default', () => (
<Radio>
Video killed the radio star
</Radio>
))
.add('Checked', () => (
<Radio checked onChange={function noop() {}} />
))
.add('Disabled', () => (
<Radio disabled />
));

View File

@ -0,0 +1,12 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const RangeSlider = require('./');
storiesOf('Range Slider', module)
.add('Default', () => (
<RangeSlider />
));

View File

@ -0,0 +1,28 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const {
selectData
} = require('../../shared/fake-data');
const SelectCustom = require('./');
storiesOf('Select Custom', module)
.add('Default', () => (
<SelectCustom
label="This is the label"
onChange={function noop() {}}
options={selectData}
/>
))
.add('Multiple', () => (
<SelectCustom
label="This is the label"
multi
onChange={function noop() {}}
options={selectData}
/>
));

View File

@ -0,0 +1,26 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Select = require('./');
storiesOf('Select', module)
.add('Default', () => (
<Select label='example select'>
<option>Apple</option>
<option>Banana</option>
<option>Pear</option>
<option>Orange</option>
</Select>
))
.add('multiple', () => (
<Select label='example multiple select' multiple>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Select>
));

View File

@ -0,0 +1,20 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Tabs = require('./');
const Tab = require('./tab');
storiesOf('Tabs', module)
.add('Default', () => (
<Tabs name='my-tab-group'>
<Tab title='Containers'>
<h1>Containers</h1>
</Tab>
<Tab title='Users'>
<h1>User</h1>
</Tab>
</Tabs>
));

View File

@ -0,0 +1,146 @@
const React = require('react');
const composers = require('../../shared/composers');
const constants = require('../../shared/constants');
const fns = require('../../shared/functions');
const Styled = require('styled-components');
const {
boxes,
colors
} = constants;
const {
remcalc
} = fns;
const {
baseBox
} = composers;
const {
default: styled
} = Styled;
const Label = styled.label`
color: ${props => props.error ? colors.alert : colors.fonts.regular}
`;
const InputField = styled.textarea`
background: ${colors.brandSecondary};
color: ${props => props.error ? colors.alert : colors.fonts.semibold}
display: block;
font-size: 16px;
padding: ${remcalc('15 18')};
visibility: visible;
width: 100%;
min-height: ${remcalc(96)};
${baseBox()};
border-color: ${props => props.error ? colors.alert : ''};
&:focus {
border-color: ${boxes.border.checked};
outline: none;
}
`;
const Error = styled.span`
float: right;
color: ${colors.alert};
font-size: ${remcalc(14)};
`;
const Textarea = ({
autoComplete,
autoFocus,
children,
className,
disabled = false,
error,
form,
id,
inputMode,
label,
labelledby,
list,
name,
onChange,
pattern,
placeholder,
readOnly,
required,
selectionDirection,
spellCheck,
style,
tabIndex,
type,
value
}) => {
const _label = label || children;
const _children = label && children ? children : null;
const _error = error ? (<Error>{error}</Error>) : null;
return (
<div>
<Label
error={error}
htmlFor={id}
>
{_label}
</Label>
{_error}
<InputField
aria-labelledby={labelledby}
autoComplete={autoComplete}
autoFocus={autoFocus}
disabled={disabled}
error={error}
form={form}
id={id}
inputMode={inputMode}
list={list}
name={name}
onChange={onChange}
pattern={pattern}
placeholder={placeholder}
readOnly={readOnly}
required={required}
selectionDirection={selectionDirection}
spellCheck={spellCheck}
tabIndex={tabIndex}
type={type}
value={value}
/>
{_children}
</div>
);
};
Textarea.propTypes = {
autoComplete: React.PropTypes.string,
autoFocus: React.PropTypes.bool,
children: React.PropTypes.node,
className: React.PropTypes.string,
disabled: React.PropTypes.bool,
error: React.PropTypes.string,
form: React.PropTypes.string,
id: React.PropTypes.string,
inputMode: React.PropTypes.string,
label: React.PropTypes.string,
labelledby: React.PropTypes.string,
list: React.PropTypes.string,
name: React.PropTypes.string,
onChange: React.PropTypes.func,
pattern: React.PropTypes.string,
placeholder: React.PropTypes.string,
readOnly: React.PropTypes.bool,
required: React.PropTypes.bool,
selectionDirection: React.PropTypes.string,
spellCheck: React.PropTypes.bool,
style: React.PropTypes.object,
tabIndex: React.PropTypes.string,
type: React.PropTypes.string,
value: React.PropTypes.string
};
module.exports = Textarea;

View File

@ -0,0 +1,60 @@
# Input
## demo
```embed
const React = require('react');
const ReactDOM = require('react-dom/server');
const Base = require('../base');
const Container = require('../container');
const Row = require('../row');
const Column = require('../column');
const Input = require('./index.js');
nmodule.exports = ReactDOM.renderToString(
<Base>
<Row>
<Column>
<Input
placeholder='Enter email'
label='Email Address'
type='email'
>
<small>We'll never share your email with anyone else.</small>
</Input>
</Column>
</Row>
<Row>
<Column>
<Input placeholder='Password' type='password'>
Password
</Input>
</Column>
</Row>
</Base>
);
```
## usage
```js
const React = require('react');
const Input = require('ui/input');
module.exports = () => {
return (
<div>
<Input
placeholder='Enter email'
label='Email Address'
type='email'
>
<small>We'll never share your email with anyone else.</small>
</Input>
<Input placeholder='Password' type='password'>
Password
</Input>
</div>
);
}
```

View File

@ -0,0 +1,24 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Base= require('../base');
const Textarea = require('./');
storiesOf('Textarea', module)
.add('Default', () => (
<Base>
<Textarea placeholder="I am the placeholder" />
</Base>
))
.add('Error', () => (
<Base>
<Textarea
error="Somethings missing"
placeholder="There was an error"
value="alexw/makeusproud.com"
/>
</Base>
));

View File

@ -0,0 +1,30 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Toggle = require('./');
storiesOf('Toggle', module)
.add('default', () => (
<Toggle checked />
))
.add('checked', () => (
<Toggle
defaultChecked
options={[
{
label: 'Topology',
checked: true
},
{
label: 'List',
checked: false
}
]}
/>
))
.add('no props', () => (
<Toggle />
));

View File

@ -0,0 +1,29 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Tooltip = require('./');
storiesOf('Tooltip', module)
.add('default', () => (
<Tooltip>
<li>One</li>
<li>Two</li>
<li>Three</li>
</Tooltip>
))
.add('custom position', () => {
const arrowPosition = {
left: '90%',
bottom: '100%'
};
return (
<Tooltip arrowPosition={arrowPosition}>
<li>One</li>
<li>Two</li>
<li>Three</li>
</Tooltip>
);
});

View File

@ -0,0 +1,24 @@
const React = require('react');
const {
storiesOf
} = require('@kadira/storybook');
const Widget = require('./');
storiesOf('Widget', module)
.add('single', () => (
<Widget
checked
name='flag'
selectable='single'
value='flag_1'
>
<img
alt='england flag'
// eslint-disable-next-line max-len
src='https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Union_flag_1606_(Kings_Colors).svg/2000px-Union_flag_1606_(Kings_Colors).svg.png'
/>
<p>Some text</p>
</Widget>
));

View File

@ -24,5 +24,6 @@ module.exports = {
Tabs: require('./components/tabs'),
Toggle: require('./components/toggle'),
Tooltip: require('./components/tooltip'),
Textarea: require('./components/textarea'),
Widget: require('./components/widget'),
};

View File

@ -8,23 +8,8 @@ const {
const {
Base,
Container,
Checkbox,
Row,
Column,
Close,
Input,
List: {
ListItemDescription,
ListItemHeader,
ListItem,
ListItemMeta,
ListItemOptions,
ListItemOutlet,
ListItemSubTitle,
ListItemTitle,
ListItemView,
ListItemGroupView
},
MiniMetric: {
MiniMetricGraph,
MiniMetricMeta,
@ -32,26 +17,9 @@ const {
MiniMetricSubtitle,
MiniMetricView
},
Modal,
Notificaton,
Pagination,
RangeSlider,
Select,
SelectCustom,
Tabs,
Tab,
Toggle,
Tooltip,
Widget,
Radio,
RadioGroup
} = require('../src/');
const fakeData = require('../src/shared/fake-data');
const {
selectData
} = fakeData;
const MiniMetricData = require('../src/components/list/mini-metric-data');
const styles = {
base: {
@ -107,349 +75,6 @@ storiesOf('Grid', module)
</Base>
));
storiesOf('Checkbox', module)
.add('Default', () => (
<Checkbox />
))
.add('Checked', () => (
<Checkbox checked onChange={function noop() {}} />
))
.add('Disabled', () => (
<Checkbox disabled />
));
storiesOf('Radio', module)
.add('Default', () => (
<Radio>
Video killed the radio star
</Radio>
))
.add('Checked', () => (
<Radio checked onChange={function noop() {}} />
))
.add('Disabled', () => (
<Radio disabled />
));
storiesOf('Input', module)
.add('Default', () => (
<Base>
<Input placeholder="I am the placeholder" />
</Base>
))
.add('type=email', () => (
<Base>
<Input
label='Email Address'
placeholder='Enter email'
type='email'
>
<small>We&apos;ll never share your email with anyone else.</small>
</Input>
</Base>
))
.add('Error', () => (
<Base>
<Input
error="Somethings missing"
placeholder="There was an error"
value="alexw/makeusproud.com"
/>
</Base>
));
storiesOf('Modal', module)
.add('Default', () => (
<Modal>
<h2>This is the Modal</h2>
</Modal>
));
storiesOf('Notificaton', module)
.add('Default', () => (
<Base>
<Notificaton>
<span>This is the default content</span>
</Notificaton>
</Base>
))
.add('Success', () => (
<Base>
<Notificaton
close={function noop() {}}
type="success"
>
<span>This is a success notification that is closable</span>
</Notificaton>
</Base>
))
.add('Alert', () => (
<Base>
<Notificaton type="alert">
<span>This is the alert content</span>
</Notificaton>
</Base>
));
storiesOf('Pagination', module)
.add('Default', () => (
<Pagination>
<a>
<span>&laquo;</span>
<span>Previous</span>
</a>
<a>1</a>
<a active>2</a>
<a>3</a>
</Pagination>
));
storiesOf('Radio Group', module)
.add('Default', () => (
<RadioGroup>
<Radio name='hello' value='default'>
Video killed the radio star
</Radio>
<Radio name='hello' value='fancy'>
Video killed the radio star
</Radio>
<Radio name='hello' value='none'>
Video killed the radio star
</Radio>
</RadioGroup>
));
storiesOf('RangeSlider', module)
.add('Default', () => (
<RangeSlider />
));
storiesOf('Select', module)
.add('Default', () => (
<Select label='example select'>
<option>Apple</option>
<option>Banana</option>
<option>Pear</option>
<option>Orange</option>
</Select>
))
.add('multiple', () => (
<Select label='example multiple select' multiple>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Select>
));
storiesOf('Select Custom', module)
.add('Default', () => (
<SelectCustom
label="This is the label"
onChange={function noop() {}}
options={selectData}
/>
))
.add('Multiple', () => (
<SelectCustom
label="This is the label"
multi
onChange={function noop() {}}
options={selectData}
/>
));
storiesOf('Tabs', module)
.add('Default', () => (
<Tabs name='my-tab-group'>
<Tab title='Containers'>
<h1>Containers</h1>
</Tab>
<Tab title='Users'>
<h1>User</h1>
</Tab>
</Tabs>
));
storiesOf('Close', module)
.add('Default', () => (
<Base
style={{
position: 'relative',
width: 60
}}
>
<Close onClick={function noop() {}} />
</Base>
));
storiesOf('Toggle', module)
.add('default', () => (
<Toggle checked />
))
.add('checked', () => (
<Toggle
defaultChecked
options={[
{
label: 'Topology',
checked: true
},
{
label: 'List',
checked: false
}
]}
/>
))
.add('no props', () => (
<Toggle />
));
storiesOf('Tooltip', module)
.add('default', () => (
<Tooltip>
<li>One</li>
<li>Two</li>
<li>Three</li>
</Tooltip>
))
.add('custom position', () => {
const arrowPosition = {
left: '90%',
bottom: '100%'
};
return (
<Tooltip arrowPosition={arrowPosition}>
<li>One</li>
<li>Two</li>
<li>Three</li>
</Tooltip>
);
});
storiesOf('Widget', module)
.add('single', () => (
<Widget
checked
name='flag'
selectable='single'
value='flag_1'
>
<img
alt='england flag'
// eslint-disable-next-line max-len
src='https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Union_flag_1606_(Kings_Colors).svg/2000px-Union_flag_1606_(Kings_Colors).svg.png'
/>
<p>Some text</p>
</Widget>
));
const minMetricData = [{
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,
}];
storiesOf('Metrics', module)
.add('Mini Metric', () => (
<Base>
@ -460,7 +85,7 @@ storiesOf('Metrics', module)
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={3}>
@ -469,7 +94,7 @@ storiesOf('Metrics', module)
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
<Column xs={3}>
@ -478,298 +103,9 @@ storiesOf('Metrics', module)
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
<MiniMetricGraph data={MiniMetricData} />
</MiniMetricView>
</Column>
</Row>
</Base>
));
storiesOf('ListItem', module)
.add('default', () => (
<Base>
<ListItem>
<ListItemView>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
<ListItemOptions>
</ListItemOptions>
</ListItem>
</Base>
))
.add('collapsed', () => (
<Base>
<ListItem collapsed>
<ListItemView>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
<ListItemOptions>
</ListItemOptions>
</ListItem>
</Base>
))
.add('headed', () => (
<Base>
<ListItem headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions>
</ListItemOptions>
</ListItemHeader>
<ListItemView>
<ListItemMeta>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</Base>
))
.add('headed collapsed', () => (
<Base>
<ListItem collapsed headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions>
</ListItemOptions>
</ListItemHeader>
<ListItemView>
<ListItemMeta>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</Base>
))
.add('stacked', () => (
<Base>
<ListItem stacked>
<ListItemView>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
<ListItemOptions>
</ListItemOptions>
</ListItem>
</Base>
))
.add('view-group', () => (
<Base>
<ListItem headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Percona</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions></ListItemOptions>
</ListItemHeader>
<ListItemGroupView>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat stacked>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</ListItemGroupView>
</ListItem>
</Base>
))
.add('view-group with metrics', () => (
<Base>
<ListItem headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Percona</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions></ListItemOptions>
</ListItemHeader>
<ListItemGroupView>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
</ListItemMeta>
<ListItemOutlet>
<Row>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
</Row>
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
<Row>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
</Row>
</ListItemOutlet>
</ListItemView>
</ListItem>
<ListItem flat stacked>
<ListItemView>
<ListItemMeta>
<ListItemTitle>percona_database</ListItemTitle>
<ListItemSubTitle>5 instances</ListItemSubTitle>
</ListItemMeta>
<ListItemOutlet>
<Row>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
<Column xs={4}>
<MiniMetricView borderless>
<MiniMetricMeta>
<MiniMetricTitle>Memory: 54%</MiniMetricTitle>
<MiniMetricSubtitle>(1280/3000 MB)</MiniMetricSubtitle>
</MiniMetricMeta>
<MiniMetricGraph data={minMetricData} />
</MiniMetricView>
</Column>
</Row>
</ListItemOutlet>
</ListItemView>
</ListItem>
</ListItemGroupView>
</ListItem>
</Base>
));