Resolving conflict

This commit is contained in:
JUDIT GRESKOVITS 2017-01-23 15:14:06 +00:00
commit 390adddd30
47 changed files with 3152 additions and 1788 deletions

View File

@ -21,6 +21,7 @@
"dependencies": { "dependencies": {
"@tomgco/joyent-portal-ui": "alpha", "@tomgco/joyent-portal-ui": "alpha",
"constant-case": "^2.0.0", "constant-case": "^2.0.0",
"css-loader": "^0.26.1",
"force-array": "^3.1.0", "force-array": "^3.1.0",
"hapi": "^16.1.0", "hapi": "^16.1.0",
"inert": "^4.1.0", "inert": "^4.1.0",

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` const StyledName = styled.span`
color: #646464;
font-size: ${remcalc(16)}
position: relative; position: relative;
top: ${remcalc(-12)}; top: ${remcalc(-12)};
`; `;

View File

@ -42,6 +42,7 @@ const StyledNav = styled.div`
// TODO: refactor colours into constants in UI // TODO: refactor colours into constants in UI
const NavigationLinkContainer = styled.div` const NavigationLinkContainer = styled.div`
position: relative;
padding: ${remcalc(11)} ${remcalc(12)} ${remcalc(12)}; padding: ${remcalc(11)} ${remcalc(12)} ${remcalc(12)};
color: #646464; color: #646464;
border: solid ${remcalc(1)} #d8d8d8; 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 = ({ const OrgNavigation = ({
orgs = [] orgs = []
}) => { }) => {
@ -98,6 +110,7 @@ const OrgNavigation = ({
}) => }) =>
<a href={href} onClick={onClick}> <a href={href} onClick={onClick}>
<NavigationLinkContainer className={isActive ? 'active' : ''}> <NavigationLinkContainer className={isActive ? 'active' : ''}>
{ !isActive && <Shadow />}
<OrgImage> <OrgImage>
<OrgAvatar <OrgAvatar
height={remcalc(26)} height={remcalc(26)}

View File

@ -1,31 +0,0 @@
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

@ -1,39 +1,53 @@
const React = require('react'); const React = require('react');
const PersonItem = require('@components/people-item');
const PropTypes = require('@root/prop-types'); const PropTypes = require('@root/prop-types');
const Row = require('@ui/components/row');
const Column = require('@ui/components/column');
const Button = require('@ui/components/button');
const PeopleList = ({ const PeopleTable = require('./table');
people = []
}) => {
const peopleList = people.map((person) => ( const buttonStyle = {
<PersonItem float: 'right'
key={person.uuid} };
person={person}
/> const People = (props) => {
));
const {
people = [],
orgUI = {},
handleToggle
} = props;
return ( return (
<div> <div>
<table> <Row>
<thead> <Column smOffset={9} xs={2}>
<tr> <Button
<th>Member</th> disabled={orgUI.invite_toggled}
<th>Status</th> onClick={handleToggle}
<th>Role</th> style={buttonStyle}
</tr> >
</thead> Invite
<tbody> </Button>
{peopleList} </Column>
</tbody> </Row>
</table>
<Row>
<Column xs={12}>
<PeopleTable
people={people}
/>
</Column>
</Row>
</div> </div>
); );
}; };
PeopleList.propTypes = { People.propTypes = {
handleToggle: React.PropTypes.func,
orgUI: React.PropTypes.obj,
people: React.PropTypes.arrayOf(PropTypes.person), people: React.PropTypes.arrayOf(PropTypes.person),
}; };
module.exports = PeopleList; module.exports = People;

View File

@ -0,0 +1,47 @@
const React = require('react');
const PropTypes = require('@root/prop-types');
const Table = require('@ui/components/table-data-table');
const Checkbox = require('@ui/components/checkbox');
const PeopleTable = ({
people = []
}) => {
const columns = [{
title: <Checkbox />,
width: '5%'
}, {
title: 'Member',
width: '35%'
}, {
title: 'Status',
width: '25%'
}, {
title: 'Role',
width: '25%'
}, {
title: '',
width: '10%' // Empty title for delete
}];
const data = people.map( (person) => ({
checkbox: <Checkbox />,
name: person.name,
status: person.status,
role: person.role,
bin: ''
}));
return (
<Table
columns={columns}
data={data}
/>
);
};
PeopleTable.propTypes = {
people: React.PropTypes.arrayOf(PropTypes.person)
};
module.exports = PeopleTable;

View File

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

View File

@ -1,70 +1,42 @@
const React = require('react'); const React = require('react');
// const ReactIntl = require('react-intl');
const ReactRedux = require('react-redux'); const ReactRedux = require('react-redux');
// const ReactRouter = require('react-router'); const PeopleSection = require('@components/people-list');
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 selectors = require('@state/selectors');
const Section = require('./section'); const Section = require('./section');
const actions = require('@state/actions');
// const {
// FormattedMessage
// } = ReactIntl;
const { const {
connect connect
} = ReactRedux; } = ReactRedux;
const { const {
peopleByOrgIdSelector peopleByOrgIdSelector,
orgUISelector
} = selectors; } = selectors;
const buttonStyle = { const {
float: 'right' handleInviteToggle
}; } = actions;
const People = (props) => { const People = (props) => {
const {
people = []
} = props;
return ( return (
<Section {...props}> <Section {...props}>
<Row> <PeopleSection {...props} />
<Column smOffset={9} xs={2}>
<Button style={buttonStyle}>Invite</Button>
</Column>
</Row>
<Row>
<Column>
<PeopleList
people={people}
/>
</Column>
</Row>
</Section> </Section>
); );
}; };
People.propTypes = {
people: React.PropTypes.arrayOf(PropTypes.person)
// toggleCollapsed: React.PropTypes.func
};
const mapStateToProps = (state, { const mapStateToProps = (state, {
params = {} params = {}
}) => ({ }) => ({
people: peopleByOrgIdSelector(params.org)(state) people: peopleByOrgIdSelector(params.org)(state),
orgUI: orgUISelector(state)
}); });
const mapDispatchToProps = (dispatch) => ({}); const mapDispatchToProps = (dispatch) => ({
handleToggle: () => dispatch(handleInviteToggle())
});
module.exports = connect( module.exports = connect(
mapStateToProps, mapStateToProps,

View File

@ -203,6 +203,7 @@
}, },
"orgs": { "orgs": {
"ui": { "ui": {
"invite_toggled": false,
"sections": [ "sections": [
"projects", "projects",
"people", "people",
@ -223,9 +224,18 @@
"uuid": "e12ad7db-91b2-4154-83dd-40dcfc700dcc", "uuid": "e12ad7db-91b2-4154-83dd-40dcfc700dcc",
"id": "biz-tech", "id": "biz-tech",
"name": "BizTech", "name": "BizTech",
"members": [{ "members": [
"uuid": "fd853d8f-e1dd-49b5-b7b3-ae9adfea1e2f" {
}] "uuid": "fd853d8f-e1dd-49b5-b7b3-ae9adfea1e2f",
"role": "Owner",
"status": "Active"
},
{
"uuid": "6deddbaa-3b94-4373-8cf7-97129507a872",
"role": "Unassigned",
"status": "Sent invitation"
}
]
}, { }, {
"owner": "b94033c1-3665-4c36-afab-d9c3d0b51c01", "owner": "b94033c1-3665-4c36-afab-d9c3d0b51c01",
"uuid": "551f316d-e414-480f-9787-b4c408db3edd", "uuid": "551f316d-e414-480f-9787-b4c408db3edd",

View File

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

View File

@ -15,5 +15,6 @@ module.exports = {
addMetric: createAction(`${APP}/ADD_METRIC`), addMetric: createAction(`${APP}/ADD_METRIC`),
toggleInstanceCollapsed: createAction(`${APP}/TOGGLE_INSTANCE_COLLAPSED`), toggleInstanceCollapsed: createAction(`${APP}/TOGGLE_INSTANCE_COLLAPSED`),
toggleMonitorView: createAction(`${APP}/TOGGLE_MONITOR_VIEW`), toggleMonitorView: createAction(`${APP}/TOGGLE_MONITOR_VIEW`),
switchMonitorViewPage: createAction(`${APP}/SWITCH_MONITOR_VIEW_PAGE`) switchMonitorViewPage: createAction(`${APP}/SWITCH_MONITOR_VIEW_PAGE`),
handleInviteToggle: createAction(`${APP}/HANDLE_INVITE_MEMBER_TOGGLE`)
}; };

View File

@ -14,6 +14,7 @@ module.exports = () => {
monitors: require('@state/reducers/monitors'), monitors: require('@state/reducers/monitors'),
orgs: require('@state/reducers/orgs'), orgs: require('@state/reducers/orgs'),
projects: require('@state/reducers/projects'), projects: require('@state/reducers/projects'),
services: require('@state/reducers/services') services: require('@state/reducers/services'),
members: require('@state/reducers/members'),
}); });
}; };

View File

@ -0,0 +1,9 @@
const ReduxActions = require('redux-actions');
const {
handleActions
} = ReduxActions;
module.exports = handleActions({
'x': (state) => state // somehow handleActions needs at least one reducer
}, {});

View File

@ -13,6 +13,7 @@ const orgUiSections = (state) => get(state, 'orgs.ui.sections', []);
const projectUiSections = (state) => get(state, 'projects.ui.sections', []); const projectUiSections = (state) => get(state, 'projects.ui.sections', []);
const serviceUiSections = (state) => get(state, 'services.ui.sections', []); const serviceUiSections = (state) => get(state, 'services.ui.sections', []);
const orgs = (state) => get(state, 'orgs.data', []); const orgs = (state) => get(state, 'orgs.data', []);
const orgUI = (state) => get(state, 'orgs.ui', []);
const projects = (state) => get(state, 'projects.data', []); const projects = (state) => get(state, 'projects.data', []);
const services = (state) => get(state, 'services.data', []); const services = (state) => get(state, 'services.data', []);
const collapsedServices = (state) => get(state, 'services.ui.collapsed', []); const collapsedServices = (state) => get(state, 'services.ui.collapsed', []);
@ -114,9 +115,16 @@ const instancesByProjectId = (projectId) => createSelector(
); );
const peopleByOrgId = (orgId) => createSelector( const peopleByOrgId = (orgId) => createSelector(
// [members, orgById(orgId)], (members, org) => org.members [members, orgById(orgId)], (members, org) => {
const matched = [];
[members, orgById(orgId)], (members, org) => org.members org.members.filter((m) => {
matched.push({
...find(members, ['uuid', m.uuid]),
...m
});
});
return matched;
}
); );
module.exports = { module.exports = {
@ -124,6 +132,7 @@ module.exports = {
accountUISelector: accountUi, accountUISelector: accountUi,
orgByIdSelector: orgById, orgByIdSelector: orgById,
orgsSelector: orgs, orgsSelector: orgs,
orgUISelector: orgUI,
servicesSelector: services, servicesSelector: services,
serviceByIdSelector: serviceById, serviceByIdSelector: serviceById,
orgSectionsSelector: orgSections, orgSectionsSelector: orgSections,

View File

@ -2,6 +2,7 @@
<html lang='en-US'> <html lang='en-US'>
<head> <head>
<title>Joyent Frontend</title> <title>Joyent Frontend</title>
<link rel="stylesheet" href="../../ui/src/vendor/normalize.css">
</head> </head>
<body> <body>
<div id='root'></div> <div id='root'></div>

View File

@ -50,7 +50,7 @@ module.exports = {
], ],
loaders: [ loaders: [
'babel-loader' 'babel-loader'
], ]
}, { }, {
test: /\.json?$/, test: /\.json?$/,
exclude: /node_modules/, exclude: /node_modules/,
@ -60,7 +60,7 @@ module.exports = {
], ],
loaders: [ loaders: [
'json-loader' 'json-loader'
], ]
}, { }, {
test: /\.png/, test: /\.png/,
exclude: /node_modules/, exclude: /node_modules/,
@ -68,19 +68,30 @@ module.exports = {
FRONTEND, FRONTEND,
UI UI
], ],
loaders: [ loader: [
'url-loader' 'url-loader'
], ]
}, },
{ {
test: /\.(eot|svg|ttf|woff|woff2)$/, test: /\.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader',
// XXX: By commenting this out, production "BUILD=production make compile"
// will break.
//
// exclude: /node_modules/,
include: [ include: [
FRONTEND, FRONTEND,
UI UI
], ],
loaders: [ },
'file-loader' {
], test: /\.css$/,
exclude: /node_modules/,
loaders: [ 'style-loader', 'css-loader' ],
include: [
FRONTEND,
UI
]
}] }]
} }
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,600" rel="stylesheet"> <link href="./normalize.css" rel="stylesheet">

View File

@ -11,7 +11,7 @@
"lint": "make lint", "lint": "make lint",
"test": "make test", "test": "make test",
"build": "make compile", "build": "make compile",
"storybook": "start-storybook -s ./src/shared/assets -p 6006", "storybook": "start-storybook -s ./src/assets,./src/vendor -p 6006",
"build-storybook": "build-storybook" "build-storybook": "build-storybook"
}, },
"dependencies": { "dependencies": {

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,12 +1,8 @@
const constants = require('../../shared/constants'); const constants = require('../../shared/constants');
const fncs = require('../../shared/functions');
const Styled = require('styled-components'); const Styled = require('styled-components');
const { const {
forms,
tables,
typography,
colors colors
} = constants; } = constants;
@ -14,469 +10,12 @@ const {
default: styled, default: styled,
} = Styled; } = Styled;
const {
remcalc
} = fncs;
module.exports = styled.div` module.exports = styled.div`
font-family: 'LibreFranklin', sans-serif; font-family: 'LibreFranklin', sans-serif;
font-size: 1rem; font-size: 1rem;
line-height: 1.5; line-height: 1.5;
color: ${colors.fonts.regular}; color: ${colors.fonts.regular};
background-color: #FFFFFF; background-color: #FFFFFF;
/**************************************************************************
* NORMALIZE.CSS *
**************************************************************************/
& article,
& aside,
& details,
& figcaption,
& figure,
& footer,
& header,
& main,
& menu,
& nav,
& section,
& summary {
display: block;
}
& audio,
& canvas,
& progress,
& video {
display: inline-block;
}
& audio:not([controls]) {
display: none;
height: 0;
}
& progress {
vertical-align: baseline;
}
& template,
& [hidden] {
display: none;
}
& a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
& a:active,
& a:hover {
outline-width: 0;
}
& abbr[title] {
border-bottom: none;
text-decoration: underline;
text-decoration: underline dotted;
}
& b,
& strong {
font-weight: inherit;
}
& b,
& strong {
font-weight: bolder;
}
& dfn {
font-style: italic;
}
& h1 {
margin: 0.67em 0;
}
& mark {
background-color: #ff0;
color: #000;
}
& small {
font-size: 80%;
}
& sub,
& sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
& sub {
bottom: -0.25em;
}
& sup {
top: -0.5em;
}
& img {
border-style: none;
}
& svg:not(:root) {
overflow: hidden;
}
& code,
& kbd,
& pre,
& samp {
font-family: monospace, monospace;
font-size: 1em;
}
& figure {
margin: 1em ${remcalc(40)};
}
& hr {
-webkit-box-sizing: content-box;
box-sizing: content-box;
height: 0;
overflow: visible;
}
& button,
& input,
& optgroup,
& select,
& textarea {
font: inherit;
margin: 0;
}
& optgroup {
font-weight: bold;
}
& button,
& input {
overflow: visible;
}
& button,
& select {
text-transform: none;
}
& button,
& [type="button"],
& [type="reset"],
& [type="submit"] {
-webkit-appearance: button;
}
& button::-moz-focus-inner,
& [type="button"]::-moz-focus-inner,
& [type="reset"]::-moz-focus-inner,
& [type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
& button:-moz-focusring,
& [type="button"]:-moz-focusring,
& [type="reset"]:-moz-focusring,
& [type="submit"]:-moz-focusring {
outline: ${remcalc(1)} dotted ButtonText;
}
& fieldset {
border: ${remcalc(1)} solid #c0c0c0;
margin: 0 ${remcalc(2)};
padding: 0.35em 0.625em 0.75em;
}
& legend {
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal;
}
& textarea {
overflow: auto;
}
& [type="checkbox"],
& [type="radio"] {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
}
& [type="number"]::-webkit-inner-spin-button,
& [type="number"]::-webkit-outer-spin-button {
height: auto;
}
& [type="search"] {
-webkit-appearance: textfield;
outline-offset: ${remcalc(-2)};
}
& [type="search"]::-webkit-search-cancel-button,
& [type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
& ::-webkit-input-placeholder {
color: inherit;
opacity: 0.54;
}
& ::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
/**************************************************************************
* BOOTSTRAP REBOOT *
**************************************************************************/
& *,
& *::before,
& *::after {
box-sizing: inherit;
}
& @-ms-viewport {
width: device-width;
}
& [tabindex="-1"]:focus {
outline: none !important;
}
/**
* Typography
*/
& h1,
& h2,
& h3,
& h4,
& h5,
& h6 {
margin-top: 0;
margin-bottom: .5rem;
}
& p {
margin-top: 0;
margin-bottom: 1rem;
}
& abbr[title],
& abbr[data-original-title] {
cursor: help;
border-bottom: ${remcalc(1)} dotted ${typography.abbrBorderColor};
}
& address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
& ol,
& ul,
& dl {
margin-top: 0;
margin-bottom: 1rem;
}
& ol ol,
& ul ul,
& ol ul,
& ul ol {
margin-bottom: 0;
}
& dt {
font-weight: ${typography.dtFontWeight};
}
& dd {
margin-bottom: .5rem;
margin-left: 0; /* Undo browser default */
}
& blockquote {
margin: 0 0 1rem;
}
/**
* Links
*/
& a {
color: ${colors.brandPrimaryLink};
text-decoration: underline;
&:focus,
&:hover {
text-decoration: none;
}
&:focus {
outline: ${remcalc(5)} auto -webkit-focus-ring-color;
outline-offset: ${remcalc(-2)};
}
}
& a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
&:focus,
&:hover {
text-decoration: none;
}
&:focus {
outline: none;
}
}
/**
* Code
*/
& pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
/**
* Figures
*/
& figure {
margin: 0 0 1rem;
}
/**
* Images
*/
& img {
vertical-align: middle;
}
& [role="button"] {
cursor: pointer;
}
& a,
& area,
& button,
& [role="button"],
& input,
& label,
& select,
& summary,
& textarea {
touch-action: manipulation;
}
/**
* Tables
*/
& table {
border-collapse: collapse;
background-color: ${tables.bg};
}
& caption {
padding-top: ${tables.cellPadding};
padding-bottom: ${tables.cellPadding};
color: ${typography.textMuted};
text-align: left;
caption-side: bottom;
}
& th {
text-align: left;
}
/**
* Forms
*/
& label {
display: inline-block;
margin-bottom: .5rem;
}
& button:focus {
outline: ${remcalc(1)} dotted;
outline: ${remcalc(5)} auto -webkit-focus-ring-color;
}
& input,
& button,
& select,
& textarea {
line-height: inherit;
}
& input[type="radio"],
& input[type="checkbox"] {
&:disabled {
cursor: ${forms.cursorDisabled};
}
}
& input[type="date"],
& input[type="time"],
& input[type="datetime-local"],
& input[type="month"] {
-webkit-appearance: listbox;
}
& textarea {
resize: vertical;
}
& fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
& legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
}
& input[type="search"] {
-webkit-appearance: none;
}
`; `;
module.exports.global = require('./global'); module.exports.global = require('./global');

View File

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

View File

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

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

@ -0,0 +1,46 @@
const React = require('react');
const Styled = require('styled-components');
const TableContent = require('./table-content');
const {
default: styled
} = Styled;
const StyledTitle = styled.h3`
text-align: center
`;
const StyledTableWrapper = styled.section`
font-family: 'LibreFranklin', sans-serif;
font-style: normal;
`;
const Table = ({
children,
columns = [],
data = [],
title,
}) => {
return (
<StyledTableWrapper>
<StyledTitle>{title}</StyledTitle>
<TableContent
columns={columns}
data={data}
/>
</StyledTableWrapper>
);
};
Table.propTypes = {
children: React.PropTypes.node,
columns: React.PropTypes.array,
data: React.PropTypes.array,
title: React.PropTypes.string,
};
module.exports = Table;

View File

@ -0,0 +1,76 @@
# `<Avatar>`
## 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 Table = require('./index.js');
nmodule.exports = ReactDOM.renderToString(
<Base>
<Table
columns={columns}
data={data}
title="This is the table title"
/>
</Base>
);
```
## usage
```js
const React = require('react');
const Avatar = require('ui/table');
const columns = [{
title: 'Memeber',
dataID: 'member',
dataKey: 'member',
width: ''
}, {
title: 'Status',
dataID: 'status',
dataKey: 'status',
width: ''
}, {
title: 'Role',
dataID: 'role',
dataKey: 'role',
width: ''
}, {
title: '',
dataID: 'delete',
dataKey: 'delete',
width: ''
}];
const data = [{
name: 'Nicola',
status: 'Active',
role: 'Owner',
key: 1
}, {
name: 'Alex',
status: 'Inactive',
role: 'Read Only',
key: 2
}];
module.exports = () => {
return (
<Base>
<Table
columns={columns}
data={data}
title="This is the table title"
/>
</Base>
);
}
```

View File

@ -0,0 +1,54 @@
const React = require('react');
const Base = require('../base');
const {
storiesOf
} = require('@kadira/storybook');
const Table = require('./');
const memberDetail = (name) => {
return (
<div>
<h4>{name}</h4>
<small>{name}@biztech.com</small>
</div>
);
};
const columns = [{
title: 'Memeber',
width: '50%'
}, {
title: 'Status',
width: '10%'
}, {
title: 'Role',
width: '20%'
}, {
title: '',
width: '20%'
}];
const data = [{
name: memberDetail('Nicola'),
status: 'Active',
role: 'Owner',
key: 1
}, {
name: memberDetail('Alex'),
status: 'Inactive',
role: 'Read Only',
key: 2
}];
storiesOf('Table - Data Table', module)
.add('Default', () => (
<Base>
<Table
columns={columns}
data={data}
title="This is the table title"
/>
</Base>
));

View File

@ -0,0 +1,25 @@
const React = require('react');
const Row = require('./table-row');
const TableBody = ({
columns,
data
}) => {
const rows = columns.map( (column, index) => {
return <Row dataItem={data[index]} key={index} />;
});
return (
<tbody>
{rows}
</tbody>
);
};
TableBody.propTypes = {
columns: React.PropTypes.array,
data: React.PropTypes.array
};
module.exports = TableBody;

View File

@ -0,0 +1,39 @@
const React = require('react');
const Styled = require('styled-components');
const TableBody = require('./table-body');
const TableHeader = require('./table-head');
const {
default: styled
} = Styled;
const StyledTable = styled.table`
width: 100%;
`;
const TableContent = ({
columns,
data,
hasHeader = columns.length >= 1,
hasBody = data.length >= 1,
width = '100%'
}) => {
return (
<StyledTable>
{hasHeader ? <TableHeader columns={columns} /> : null}
{hasBody ? <TableBody columns={columns} data={data} /> : null}
</StyledTable>
);
};
TableContent.propTypes = {
columns: React.PropTypes.array,
data: React.PropTypes.array,
hasBody: React.PropTypes.bool,
hasHeader: React.PropTypes.bool,
width: React.PropTypes.string,
};
module.exports = TableContent;

View File

@ -0,0 +1,57 @@
const React = require('react');
const Styled = require('styled-components');
const fns = require('../../shared/functions');
const {
remcalc
} = fns;
const {
default: styled
} = Styled;
const StyledTableHeadItem = styled.td`
${props => `width: ${props.width}`}
border-bottom: none;
padding: ${remcalc(24)};
`;
const StyledTableHead = styled.thead`
background: #fafafa;
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.05);
border: solid ${remcalc(1)} #d8d8d8;
`;
const TableHeader = ({
columns
}) => {
const fallBackWidth = `${100 / parseInt(columns.length)}%`;
const titles = columns.map( (column, i) => {
return (
<StyledTableHeadItem
key={i}
width={column.width || fallBackWidth}
>
{column.title}
</StyledTableHeadItem>
);
});
return (
<StyledTableHead>
<tr>
{titles}
</tr>
</StyledTableHead>
);
};
TableHeader.propTypes = {
columns: React.PropTypes.array
};
module.exports = TableHeader;

View File

@ -0,0 +1,44 @@
const React = require('react');
const Styled = require('styled-components');
const fns = require('../../shared/functions');
const {
remcalc
} = fns;
const {
default: styled
} = Styled;
const StyledRow = styled.tr`
border: solid ${remcalc(1)} #d8d8d8;
`;
const StyledTableItem = styled.td`
padding: ${remcalc(24)};
`;
const Row = ({
dataItem = {}
}) => {
const _dataItem = dataItem;
const rowItems = Object.keys(_dataItem).map( (item, i) => {
const value = _dataItem[item];
return <StyledTableItem key={i}>{value}</StyledTableItem>;
});
return (
<StyledRow>
{rowItems}
</StyledRow>
);
};
Row.propTypes = {
dataItem: React.PropTypes.object
};
module.exports = Row;

View File

@ -0,0 +1,8 @@
module.exports = {
Table: require('./table'),
TableHead: require('./table-head'),
TableBody: require('./table-body'),
TableCell: require('./table-cell'),
TableRow: require('./table-row'),
TableItem: require('./table-item'),
};

View File

@ -0,0 +1,41 @@
# `<Avatar>`
## 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 Avatar = require('./index.js');
const styles = require('./style.css');
nmodule.exports = ReactDOM.renderToString(
<Base>
<Row>
<Column>
<Avatar color='#35a8c0' name='Alex' />
</Column>
<Column>
<Avatar color='#ef6176' name='Alex' src='https://openclipart.org/image/2400px/svg_to_png/177482/ProfilePlaceholderSuit.png' />
</Column>
</Row>
</Base>
);
```
## usage
```js
const React = require('react');
const Avatar = require('ui/avatar');
module.exports = () => {
return (
<Avatar color='#35a8c0' name='Alex' />
<Avatar color='#ef6176' name='Alex' src='path/to/image.png' />
);
}
```

View File

@ -0,0 +1,51 @@
const React = require('react');
const Base = require('../base');
const {
storiesOf
} = require('@kadira/storybook');
const _table = require('./');
const {
Table,
TableHead,
TableItem,
TableBody,
TableRow
} = _table;
storiesOf('Table - Simple', module)
.add('Default', () => (
<Base>
<Table>
<TableHead>
<TableItem>Member</TableItem>
<TableItem>Status</TableItem>
<TableItem>Role</TableItem>
<TableItem>{/*Empty last Column*/}</TableItem>
</TableHead>
<TableBody>
<TableRow>
<TableItem>
<h4>Nicola (You)</h4>
<p>nicola@biztech.com</p>
</TableItem>
<TableItem>Active</TableItem>
<TableItem>Owner</TableItem>
<TableItem>🗑</TableItem>
</TableRow>
<TableRow>
<TableItem>
<h4>Nicola (You)</h4>
<p>nicola@biztech.com</p>
</TableItem>
<TableItem>Active</TableItem>
<TableItem>Owner</TableItem>
<TableItem>🗑</TableItem>
</TableRow>
</TableBody>
</Table>
</Base>
));

View File

@ -0,0 +1,39 @@
const composers = require('../../shared/composers');
const React = require('react');
const Styled = require('styled-components');
const {
default: styled,
} = Styled;
const {
clearfix
} = composers;
const StyledTableBody = styled.article`
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.05);
${clearfix}
`;
const TableBody = ({
children
}) => {
const itemCount = children.length;
if (itemCount <= 1) return;
return (
<StyledTableBody itemCount={itemCount}>
{children}
</StyledTableBody>
);
};
TableBody.propTypes = {
children: React.PropTypes.node
};
module.exports = StyledTableBody;

View File

@ -0,0 +1,58 @@
const fns = require('../../shared/functions');
const composers = require('../../shared/composers');
const React = require('react');
const Styled = require('styled-components');
const {
remcalc
} = fns;
const {
default: styled,
css
} = Styled;
const {
clearfix
} = composers;
const StyledTableHead = styled.header`
background: #fafafa;
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.05);
padding: ${remcalc(24)} 0;
${clearfix}
& > .table-item {
text-align: center;
${props => {
const width = 100 / props.itemCount;
return css`
width: ${width}%;
`;
}}
}
`;
const TableHead = ({
children
}) => {
const itemCount = children.length;
if (itemCount <= 1) return;
return (
<StyledTableHead itemCount={itemCount}>
{children}
</StyledTableHead>
);
};
TableHead.propTypes = {
children: React.PropTypes.node
};
module.exports = TableHead;

View File

@ -0,0 +1,28 @@
const React = require('react');
const Styled = require('styled-components');
const {
default: styled
} = Styled;
const Item = styled.div`
display: inline-block;
float: left;
`;
const TableItem = ({
children
}) => {
return (
<Item className="table-item">
{children}
</Item>
);
};
TableItem.propTypes = {
children: React.PropTypes.node
};
module.exports = TableItem;

View File

@ -0,0 +1,54 @@
const fns = require('../../shared/functions');
const composers = require('../../shared/composers');
const React = require('react');
const Styled = require('styled-components');
const {
default: styled,
css
} = Styled;
const {
clearfix
} = composers;
const {
remcalc
} = fns;
const StyledTableRow = styled.div`
${clearfix}
padding: ${remcalc(24)} 0;
border-bottom: solid 1px #d8d8d8;
& > .table-item {
text-align: center;
${props => {
const width = 100 / props.itemCount;
return css`
width: ${width}%;
`;
}}
}
`;
const TableRow = ({
children
}) => {
const itemCount = children.length;
return (
<StyledTableRow itemCount={itemCount}>
{children}
</StyledTableRow>
);
};
TableRow.propTypes = {
children: React.PropTypes.node
};
module.exports = TableRow;

View File

@ -0,0 +1,49 @@
const React = require('react');
const Styled = require('styled-components');
const {
default: styled
} = Styled;
const StyledTableWrapper = styled.section`
border: solid 1px #d8d8d8
font-family: 'LibreFranklin', sans-serif;
font-style: normal;
`;
// const StyledTableHead = styled.thead``;
// const StyledTableBody = styled.tbody``;
// const renderTable = ({
// hasHeader = false,
// hasBody = true,
// width = '100%'
// }) => {
//
// const tableBody = () => {
//
// return (
// <StyledTableBody />
// )
// }
//
// }
const Table = ({
children,
title,
}) => {
return (
<StyledTableWrapper>
{children}
</StyledTableWrapper>
);
};
Table.propTypes = {
children: React.PropTypes.node,
title: React.PropTypes.string,
};
module.exports = Table;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

View File

@ -47,5 +47,16 @@ module.exports = {
right: ${positions.right || 'auto'}; right: ${positions.right || 'auto'};
bottom: ${positions.bottom || 'auto'}; bottom: ${positions.bottom || 'auto'};
left: ${positions.left || 'auto'}; left: ${positions.left || 'auto'};
` `,
clearfix: css`
&:before,
&:after {
content:"";
display:table;
}
&:after {
clear:both;
}
`,
}; };

454
ui/src/vendor/normalize.css vendored Normal file
View File

@ -0,0 +1,454 @@
/**************************************************************************
* NORMALIZE.CSS *
**************************************************************************/
article,
aside,
details,
figcaption,
figure,
footer,
header,
main,
menu,
nav,
section,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block;
}
audio:not([controls]) {
display: none;
height: 0;
}
progress {
vertical-align: baseline;
}
template,
[hidden] {
display: none;
}
a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:active,
a:hover {
outline-width: 0;
}
abbr[title] {
border-bottom: none;
text-decoration: underline;
text-decoration: underline dotted;
}
b,
strong {
font-weight: inherit;
}
b,
strong {
font-weight: bolder;
}
dfn {
font-style: italic;
}
h1 {
margin: 0.67em 0;
}
mark {
background-color: #ff0;
color: #000;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
img {
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
figure {
margin: 1em calc( (40 / 16) * 1rem);
}
hr {
-webkit-box-sizing: content-box;
box-sizing: content-box;
height: 0;
overflow: visible;
}
button,
input,
optgroup,
select,
textarea {
font: inherit;
margin: 0;
}
optgroup {
font-weight: bold;
}
button,
input {
overflow: visible ;
}
button,
select {
text-transform: none;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal;
}
textarea {
overflow: auto;
}
[type="checkbox"],
[type="radio"] {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-input-placeholder {
color: inherit;
opacity: 0.54;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
/**************************************************************************
* BOOTSTRAP REBOOT *
**************************************************************************/
*,
*::before,
*::after {
box-sizing: inherit;
}
@-ms-viewport {
width: device-width;
}
[tabindex="-1"]:focus {
outline: none !important;
}
/**
* Typography
*/
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 0;
margin-bottom: .5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
cursor: help;
border-bottom: 1px dotted #FFFFFF;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: bold;
}
dd {
margin-bottom: .5rem;
margin-left: 0; /* Undo browser default */
}
blockquote {
margin: 0 0 1rem;
}
/**
* Links
*/
a {
color: #364ACD;
text-decoration: underline;
&:focus,
&:hover {
text-decoration: none;
}
&:focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: 2px;
}
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
&:focus,
&:hover {
text-decoration: none;
}
&:focus {
outline: none;
}
}
/**
* Code
*/
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
/**
* Figures
*/
figure {
margin: 0 0 1rem;
}
/**
* Images
*/
img {
vertical-align: middle;
}
[role="button"] {
cursor: pointer;
}
a,
area,
button,
[role="button"],
input,
label,
select,
summary,
textarea {
touch-action: manipulation;
}
/**
* Tables
*/
table {
border-collapse: collapse;
background-color: transparent;
}
caption {
padding-top: .75rem;
padding-bottom: .75rem;
color: #FFFFFF;
text-align: left;
caption-side: bottom;
}
th {
text-align: left;
}
/**
* Forms
*/
label {
display: inline-block;
margin-bottom: .5rem;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
textarea {
line-height: inherit;
}
input[type="radio"],
input[type="checkbox"] {
&:disabled {
cursor: disabled;
}
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
}
input[type="search"] {
-webkit-appearance: none;
}

File diff suppressed because it is too large Load Diff