feat(joyent-cp-frontend): create dg initial implementation
This commit is contained in:
parent
b5a8a8e23d
commit
1cc2330b22
@ -34,8 +34,6 @@ Gruntfile.js
|
||||
.flowconfig
|
||||
.documentup.json
|
||||
.yarn-metadata.json
|
||||
.*.yml
|
||||
*.yml
|
||||
|
||||
# misc
|
||||
*.gz
|
||||
|
@ -2,6 +2,8 @@
|
||||
"lerna": "2.0.0-rc.4",
|
||||
"version": "independent",
|
||||
"npmClient": "yarn",
|
||||
"hoist": true,
|
||||
"nohoist": ["graphi"],
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
|
10
package.json
10
package.json
@ -46,7 +46,7 @@
|
||||
"conventional-changelog-lint": "^1.1.9",
|
||||
"conventional-changelog-lint-config-angular": "^0.4.1",
|
||||
"conventional-changelog-lint-config-lerna-scopes": "^1.0.0",
|
||||
"cross-env": "^5.0.0",
|
||||
"cross-env": "^5.0.1",
|
||||
"dotenv": "^4.0.0",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-prettier": "^2.1.1",
|
||||
@ -58,11 +58,11 @@
|
||||
"eslint-plugin-prettier": "^2.1.1",
|
||||
"eslint-plugin-react": "^7.0.1",
|
||||
"eslint-tap": "^2.0.1",
|
||||
"execa": "^0.6.3",
|
||||
"execa": "^0.7.0",
|
||||
"figures": "^2.0.0",
|
||||
"force-array": "^3.1.0",
|
||||
"husky": "^0.13.4",
|
||||
"inquirer": "^3.0.6",
|
||||
"inquirer": "^3.1.0",
|
||||
"lerna": "^2.0.0-rc.5",
|
||||
"lerna-wizard": "ramitos/lerna-wizard#7bcdc11",
|
||||
"license-to-fail": "^2.2.0",
|
||||
@ -71,9 +71,7 @@
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.uniq": "^4.5.0",
|
||||
"lodash.uniqby": "^4.7.0",
|
||||
"npm-check-updates": "^2.11.2",
|
||||
"per-env": "^1.0.2",
|
||||
"prettier": "1.3.1",
|
||||
"prettier": "1.4.4",
|
||||
"quality-docs": "^3.3.0",
|
||||
"read-pkg": "^2.0.0",
|
||||
"redrun": "^5.9.14",
|
||||
|
@ -15,11 +15,11 @@
|
||||
"dependencies": {
|
||||
"bunyan": "^1.8.10",
|
||||
"dotenv": "^4.0.0",
|
||||
"express": "^4.15.2",
|
||||
"express-graphql": "^0.6.4",
|
||||
"got": "^6.7.1",
|
||||
"graphql": "^0.9.3",
|
||||
"smartdc-auth": "^2.5.2",
|
||||
"express": "^4.15.3",
|
||||
"express-graphql": "^0.6.6",
|
||||
"got": "^7.0.0",
|
||||
"graphql": "^0.10.1",
|
||||
"smartdc-auth": "^2.5.5",
|
||||
"triton": "^5.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -20,37 +20,44 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo": "^0.2.2",
|
||||
"apr-intercept": "^1.0.4",
|
||||
"constant-case": "^2.0.0",
|
||||
"graphql-tag": "^2.0.0",
|
||||
"graphql-tag": "^2.2.2",
|
||||
"joyent-manifest-editor": "^1.0.0",
|
||||
"joyent-ui-toolkit": "^1.1.0",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"normalized-styled-components": "^1.0.5",
|
||||
"normalized-styled-components": "^1.0.8",
|
||||
"param-case": "^2.1.1",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^15.5.4",
|
||||
"react-apollo": "^1.2.0",
|
||||
"react-apollo": "^1.4.2",
|
||||
"react-bundle": "^1.0.3",
|
||||
"react-codemirror": "^1.0.0",
|
||||
"react-dom": "^15.5.4",
|
||||
"react-redux": "^5.0.4",
|
||||
"react-redux": "^5.0.5",
|
||||
"react-router": "^4.1.1",
|
||||
"react-router-dom": "^4.1.1",
|
||||
"react-styled-flexboxgrid": "^1.1.2",
|
||||
"react-styled-flexboxgrid": "^2.0.0",
|
||||
"redux": "^3.6.0",
|
||||
"redux-actions": "^2.0.3",
|
||||
"redux-batched-actions": "^0.2.0",
|
||||
"redux-form": "^6.7.0",
|
||||
"remcalc": "^1.0.5",
|
||||
"redux-form": "^6.8.0",
|
||||
"remcalc": "^1.0.8",
|
||||
"reselect": "^3.0.1",
|
||||
"simple-statistics": "^4.1.0",
|
||||
"styled-components": "^2.0.0",
|
||||
"styled-is": "^1.0.7",
|
||||
"unitcalc": "^1.0.5"
|
||||
"styled-components": "^2.0.1",
|
||||
"styled-is": "^1.0.11",
|
||||
"styled-text-spinners": "^1.0.1",
|
||||
"unitcalc": "^1.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"apr-find": "^1.0.5",
|
||||
"apr-for-each": "^1.0.6",
|
||||
"apr-main": "^1.0.7",
|
||||
"babel-plugin-inline-react-svg": "^0.4.0",
|
||||
"babel-plugin-styled-components": "^1.1.4",
|
||||
"babel-preset-joyent-portal": "^1.0.0",
|
||||
"cross-env": "^5.0.0",
|
||||
"babel-preset-joyent-portal": "^1.0.3",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"jest": "^20.0.4",
|
||||
@ -62,12 +69,12 @@
|
||||
"jest-snapshot": "^20.0.3",
|
||||
"jest-styled-components": "^3.0.0-2",
|
||||
"mz": "^2.6.0",
|
||||
"react-scripts": "^1.0.0",
|
||||
"react-scripts": "^1.0.7",
|
||||
"react-test-renderer": "^15.5.4",
|
||||
"redrun": "^5.9.14",
|
||||
"stylelint": "^7.10.1",
|
||||
"stylelint": "^7.11.0",
|
||||
"stylelint-config-primer": "^1.4.0",
|
||||
"stylelint-config-standard": "^16.0.0",
|
||||
"stylelint-processor-styled-components": "^0.1.0"
|
||||
"stylelint-processor-styled-components": "styled-components/stylelint-processor-styled-components#68b4c4f"
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,16 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<title>React App</title>
|
||||
<style>
|
||||
.CodeMirror, .ReactCodeMirror {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
border: solid 1px #d8d8d8;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
@ -1,10 +1,9 @@
|
||||
const { readFile, writeFile, exists } = require('mz/fs');
|
||||
const main = require('apr-main');
|
||||
const forEach = require('apr-for-each');
|
||||
const find = require('apr-find');
|
||||
const path = require('path');
|
||||
|
||||
const ROOT = path.join(__dirname, '../node_modules/react-scripts/config');
|
||||
|
||||
const configs = ['webpack.config.dev', 'webpack.config.prod'];
|
||||
|
||||
const toCopy = [
|
||||
@ -13,6 +12,8 @@ const toCopy = [
|
||||
'webpack.config.prod'
|
||||
];
|
||||
|
||||
let ROOT;
|
||||
|
||||
const backup = async file => {
|
||||
const backupPath = path.join(ROOT, `${file}.original.js`);
|
||||
const backupExists = await exists(backupPath);
|
||||
@ -36,6 +37,15 @@ const copy = async file => {
|
||||
|
||||
main(
|
||||
(async () => {
|
||||
ROOT = await find([
|
||||
path.join(__dirname, '../node_modules/react-scripts/config'),
|
||||
path.join(__dirname, '../../../node_modules/react-scripts/config')
|
||||
], exists);
|
||||
|
||||
if (!ROOT) {
|
||||
throw new Error('react-scripts not found');
|
||||
}
|
||||
|
||||
await forEach(configs, backup);
|
||||
await forEach(toCopy, copy);
|
||||
})()
|
||||
|
@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
import { FormGroup, FormMeta, Input, Button } from 'joyent-ui-toolkit';
|
||||
import { Field } from 'redux-form';
|
||||
import { Row, Col } from 'react-styled-flexboxgrid';
|
||||
import { Dots2 } from 'styled-text-spinners';
|
||||
import Bundle from 'react-bundle';
|
||||
|
||||
const Editor = ManifestEditor => ({ input }) =>
|
||||
<ManifestEditor mode="yaml" {...input} />;
|
||||
|
||||
export const Name = ({ handleSubmit, onCancel, dirty }) =>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Row>
|
||||
<Col xs={12} md={3} lg={3}>
|
||||
<FormGroup name="name" reduxForm>
|
||||
<FormMeta left />
|
||||
<Input type="text" />
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Button onClick={onCancel} secondary>Cancel</Button>
|
||||
<Button type="submit" disabled={!dirty}>Next</Button>
|
||||
</Row>
|
||||
</form>;
|
||||
|
||||
export const Manifest = ({ handleSubmit, onCancel, dirty, mode }) =>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Bundle load={() => import('joyent-manifest-editor')}>
|
||||
{ManifestEditor =>
|
||||
ManifestEditor
|
||||
? <Field name="manifest" component={Editor(ManifestEditor)} />
|
||||
: <Dots2 />}
|
||||
</Bundle>
|
||||
<Row>
|
||||
<Button onClick={onCancel} secondary>Cancel</Button>
|
||||
<Button type="submit" disabled={!dirty}>Review</Button>
|
||||
</Row>
|
||||
</form>;
|
||||
|
||||
export const Review = ({ handleSubmit, onCancel, dirty, ...state }) =>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<pre>{state.deploymentGroupName}</pre>
|
||||
<pre>{state.manifest}</pre>
|
||||
<Row>
|
||||
<Button onClick={onCancel} disabled={state.loading} secondary>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button disabled={state.loading} type="submit">
|
||||
{state.loading ? <Dots2 /> : 'Provision'}
|
||||
</Button>
|
||||
</Row>
|
||||
</form>;
|
@ -2,10 +2,9 @@ import React from 'react';
|
||||
|
||||
import { Col, Row } from 'react-styled-flexboxgrid';
|
||||
|
||||
export default () => (
|
||||
export default () =>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<p>you don't have any deployment groups</p>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
</Row>;
|
||||
|
@ -3,10 +3,9 @@ import React from 'react';
|
||||
import { Col, Row } from 'react-styled-flexboxgrid';
|
||||
import { P } from 'joyent-ui-toolkit';
|
||||
|
||||
export default () => (
|
||||
export default () =>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
<P>You don't have any instances</P>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
</Row>;
|
||||
|
@ -13,7 +13,7 @@ const InstanceCard = ({
|
||||
instance = {},
|
||||
onOptionsClick = () => null,
|
||||
toggleCollapsed = () => null
|
||||
}) => (
|
||||
}) =>
|
||||
<Card collapsed={true} key={instance.uuid}>
|
||||
<CardView>
|
||||
<CardMeta onClick={toggleCollapsed}>
|
||||
@ -21,8 +21,7 @@ const InstanceCard = ({
|
||||
</CardMeta>
|
||||
</CardView>
|
||||
<CardOptions onClick={onOptionsClick} />
|
||||
</Card>
|
||||
);
|
||||
</Card>;
|
||||
|
||||
InstanceCard.propTypes = {
|
||||
instance: PropTypes.object,
|
||||
|
@ -47,7 +47,7 @@ function getBreadcrumbLinks(links) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const Breadcrumb = ({ links = [] }) => (
|
||||
const Breadcrumb = ({ links = [] }) =>
|
||||
<Grid>
|
||||
<Row>
|
||||
<Col xs={12}>
|
||||
@ -58,8 +58,7 @@ const Breadcrumb = ({ links = [] }) => (
|
||||
</StyledDiv>
|
||||
</Col>
|
||||
</Row>
|
||||
</Grid>
|
||||
);
|
||||
</Grid>;
|
||||
|
||||
Breadcrumb.propTypes = {
|
||||
links: PropTypes.arrayOf(
|
||||
|
@ -15,7 +15,7 @@ const StyledLogo = Img.extend`
|
||||
height: ${remcalc(25)};
|
||||
`;
|
||||
|
||||
const NavHeader = ({ datacenter, username }) => (
|
||||
const NavHeader = ({ datacenter, username }) =>
|
||||
<Header>
|
||||
<HeaderBrand>
|
||||
<Link to="/">
|
||||
@ -24,8 +24,7 @@ const NavHeader = ({ datacenter, username }) => (
|
||||
</HeaderBrand>
|
||||
<HeaderItem>{datacenter}</HeaderItem>
|
||||
<HeaderItem>{username}</HeaderItem>
|
||||
</Header>
|
||||
);
|
||||
</Header>;
|
||||
|
||||
NavHeader.propTypes = {
|
||||
datacenter: PropTypes.string,
|
||||
|
@ -16,7 +16,7 @@ const StyledBox = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
export default () =>
|
||||
<LayoutContainer>
|
||||
<Row>
|
||||
<Col>
|
||||
@ -28,7 +28,8 @@ export default () => (
|
||||
<Col md={10}>
|
||||
<H3>Import your services</H3>
|
||||
<P>
|
||||
You can import your services from a Git repository hosting service. Learn more.
|
||||
You can import your services from a Git repository hosting
|
||||
service. Learn more.
|
||||
</P>
|
||||
<Button secondary>from GitHub</Button>
|
||||
<Button secondary>from GitLab</Button>
|
||||
@ -42,7 +43,9 @@ export default () => (
|
||||
<Col md={9}>
|
||||
<H3>Alternatively, you can upload or edit manifest file.</H3>
|
||||
<P>
|
||||
Manifest is a file describing your services. It is similar to Docker Compose file. You can upload a file from you local machine or edit it manually. Learn more.
|
||||
Manifest is a file describing your services. It is similar
|
||||
to Docker Compose file. You can upload a file from you local
|
||||
machine or edit it manually. Learn more.
|
||||
</P>
|
||||
<Button secondary>Upload manifest</Button>
|
||||
<Button secondary>Edit manifest</Button>
|
||||
@ -53,5 +56,4 @@ export default () => (
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</LayoutContainer>
|
||||
);
|
||||
</LayoutContainer>;
|
||||
|
@ -44,13 +44,13 @@ const ServiceListItem = ({
|
||||
const isChild = Boolean(service.parent);
|
||||
|
||||
const children = service.children
|
||||
? service.children.map(service => (
|
||||
? service.children.map(service =>
|
||||
<ServiceListItem
|
||||
key={service.id}
|
||||
deploymentGroup={deploymentGroup}
|
||||
service={service}
|
||||
/>
|
||||
))
|
||||
)
|
||||
: null;
|
||||
|
||||
const to = `/deployment-groups/${deploymentGroup}/services/${service.slug}`;
|
||||
|
231
packages/cp-frontend/src/containers/deployment-groups/create.js
Normal file
231
packages/cp-frontend/src/containers/deployment-groups/create.js
Normal file
@ -0,0 +1,231 @@
|
||||
import React, { Component } from 'react';
|
||||
import { reduxForm } from 'redux-form';
|
||||
import { compose, graphql } from 'react-apollo';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import intercept from 'apr-intercept';
|
||||
import PropTypes from 'prop-types';
|
||||
import paramCase from 'param-case';
|
||||
|
||||
import DeploymentGroupBySlug from '@graphql/DeploymentGroupBySlug.gql';
|
||||
import DeploymentGroupCreateMutation from '@graphql/DeploymentGroupCreate.gql';
|
||||
import DeploymentGroupProvisionMutation from '@graphql/DeploymentGroupProvision.gql';
|
||||
|
||||
import { client } from '@state/store';
|
||||
import { LayoutContainer } from '@components/layout';
|
||||
import { Name, Manifest, Review } from '@components/deployment-groups/create';
|
||||
import { H2 } from 'joyent-ui-toolkit';
|
||||
|
||||
const Title = H2.extend`
|
||||
margin-top: 0;
|
||||
`;
|
||||
|
||||
const validateName = async ({ name = '' }) => {
|
||||
const { data } = await client.query({
|
||||
fetchPolicy: 'network-only',
|
||||
query: DeploymentGroupBySlug,
|
||||
variables: {
|
||||
slug: paramCase(name.trim())
|
||||
}
|
||||
});
|
||||
|
||||
if (data.deploymentGroups.length) {
|
||||
throw { name: `"${name}" already exists!` };
|
||||
}
|
||||
};
|
||||
|
||||
const NameForm = reduxForm({
|
||||
form: 'create-deployment-group',
|
||||
destroyOnUnmount: true,
|
||||
forceUnregisterOnUnmount: true,
|
||||
asyncValidate: validateName
|
||||
})(Name);
|
||||
|
||||
const ManifestForm = reduxForm({
|
||||
form: 'create-deployment-group',
|
||||
destroyOnUnmount: true,
|
||||
forceUnregisterOnUnmount: true
|
||||
})(Manifest);
|
||||
|
||||
const ReviewForm = reduxForm({
|
||||
form: 'create-deployment-group',
|
||||
destroyOnUnmount: true,
|
||||
forceUnregisterOnUnmount: true
|
||||
})(Review);
|
||||
|
||||
// TODO: move state to redux. why: because in redux we can cache transactional
|
||||
// state between refreshes
|
||||
class DeploymentGroupCreate extends Component {
|
||||
state = {
|
||||
deploymentGroupName: '',
|
||||
manifest: '',
|
||||
loading: false,
|
||||
error: null
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.stages = {
|
||||
name: this.renderNameForm.bind(this),
|
||||
manifest: this.renderManifestEditor.bind(this),
|
||||
review: this.renderReview.bind(this)
|
||||
};
|
||||
|
||||
this.handleNameSubmit = this.handleNameSubmit.bind(this);
|
||||
this.handleManifestSubmit = this.handleManifestSubmit.bind(this);
|
||||
this.handleReviewSubmit = this.handleReviewSubmit.bind(this);
|
||||
this.handleCancel = this.handleCancel.bind(this);
|
||||
}
|
||||
|
||||
handleNameSubmit({ name = '' }) {
|
||||
this.setState({ deploymentGroupName: name }, () =>
|
||||
this.redirect({ stage: 'manifest', prog: true })
|
||||
);
|
||||
}
|
||||
|
||||
handleManifestSubmit({ manifest = '' }) {
|
||||
this.setState({ manifest }, () =>
|
||||
this.redirect({ stage: 'review', prog: true })
|
||||
);
|
||||
}
|
||||
|
||||
handleReviewSubmit() {
|
||||
const { history } = this.props;
|
||||
|
||||
const submit = async () => {
|
||||
const { id, slug } = await this.createDeploymentGroup();
|
||||
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const manifest = await this.provision(id);
|
||||
|
||||
if (!manifest) {
|
||||
return;
|
||||
}
|
||||
|
||||
history.push(`/deployment-groups/${slug}`);
|
||||
};
|
||||
|
||||
this.setState({ loading: true }, submit);
|
||||
}
|
||||
|
||||
createDeploymentGroup = async () => {
|
||||
const { deploymentGroupName } = this.state;
|
||||
const { createDeploymentGroup } = this.props;
|
||||
|
||||
const [err, res] = await intercept(
|
||||
createDeploymentGroup({ name: deploymentGroupName })
|
||||
);
|
||||
|
||||
if (err) {
|
||||
this.setState({
|
||||
error: err.message
|
||||
});
|
||||
}
|
||||
|
||||
return err ? null : res.data.createDeploymentGroup;
|
||||
};
|
||||
|
||||
provision = async deploymentGroupId => {
|
||||
const { manifest } = this.state;
|
||||
const { provisionManifest } = this.props;
|
||||
|
||||
const [err, { data }] = await intercept(
|
||||
provisionManifest({
|
||||
deploymentGroupId,
|
||||
type: 'COMPOSE',
|
||||
format: 'YAML',
|
||||
raw: manifest
|
||||
})
|
||||
);
|
||||
|
||||
if (err) {
|
||||
this.setState({
|
||||
error: err.message
|
||||
});
|
||||
}
|
||||
|
||||
return err ? null : true;
|
||||
};
|
||||
|
||||
renderNameForm() {
|
||||
return (
|
||||
<NameForm onSubmit={this.handleNameSubmit} onCancel={this.handleCancel} />
|
||||
);
|
||||
}
|
||||
|
||||
renderManifestEditor() {
|
||||
return (
|
||||
<ManifestForm
|
||||
onSubmit={this.handleManifestSubmit}
|
||||
onCancel={this.handleCancel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderReview() {
|
||||
return (
|
||||
<ReviewForm
|
||||
onSubmit={this.handleReviewSubmit}
|
||||
onCancel={this.handleCancel}
|
||||
{...this.state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
const { history } = this.props;
|
||||
|
||||
history.push('/');
|
||||
}
|
||||
|
||||
redirect({ stage = 'name', prog = false }) {
|
||||
const { match, history } = this.props;
|
||||
|
||||
const pathname = match.url.replace(/~create(.*)/, '~create');
|
||||
const to = `${pathname}/${stage}`;
|
||||
|
||||
if (!prog) {
|
||||
return <Redirect to={to} />;
|
||||
}
|
||||
|
||||
history.push(to);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { match } = this.props;
|
||||
const stage = match.params.stage;
|
||||
|
||||
if (!stage) {
|
||||
return this.redirect({ stage: 'name' });
|
||||
}
|
||||
|
||||
if (!this.stages[stage]) {
|
||||
return this.redirect({ stage: 'name' });
|
||||
}
|
||||
|
||||
const view = this.stages[stage]();
|
||||
|
||||
return (
|
||||
<LayoutContainer>
|
||||
<Title>Creating deployment group</Title>
|
||||
{view}
|
||||
</LayoutContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
graphql(DeploymentGroupCreateMutation, {
|
||||
props: ({ mutate }) => ({
|
||||
createDeploymentGroup: variables => mutate({ variables })
|
||||
})
|
||||
}),
|
||||
graphql(DeploymentGroupProvisionMutation, {
|
||||
props: ({ mutate }) => ({
|
||||
provisionManifest: variables => mutate({ variables })
|
||||
})
|
||||
})
|
||||
)(DeploymentGroupCreate);
|
@ -1 +1,2 @@
|
||||
export { default as DeploymentGroupList } from './list';
|
||||
export { default as DeploymentGroupCreate } from './create';
|
||||
|
@ -28,13 +28,13 @@ class InstanceList extends Component {
|
||||
}
|
||||
|
||||
const instanceList = instances
|
||||
? instances.map((instance, index) => (
|
||||
? instances.map((instance, index) =>
|
||||
<InstanceListItem
|
||||
instance={instance}
|
||||
key={instance.id}
|
||||
toggleCollapsed={() => null}
|
||||
/>
|
||||
))
|
||||
)
|
||||
: <EmptyInstances />;
|
||||
|
||||
return (
|
||||
|
@ -14,12 +14,11 @@ const Header = ({
|
||||
},
|
||||
loading,
|
||||
error
|
||||
}) => (
|
||||
}) =>
|
||||
<HeaderComponent
|
||||
datacenter={portal.datacenter.region}
|
||||
username={portal.user.firstName}
|
||||
/>
|
||||
);
|
||||
/>;
|
||||
|
||||
const HeaderWithData = graphql(PortalQuery, {
|
||||
props: ({ data: { portal, loading, error } }) => ({
|
||||
|
@ -2,24 +2,25 @@ import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Menu as MenuComponent } from '@components/navigation';
|
||||
|
||||
const Menu = ({ sections, matchUrl }) => {
|
||||
return <MenuComponent links={sections} />;
|
||||
};
|
||||
const Menu = ({ sections }) =>
|
||||
sections && sections.length ? <MenuComponent links={sections} /> : null;
|
||||
|
||||
const ConnectedMenu = connect(
|
||||
(state, ownProps) => {
|
||||
const params = ownProps.match.params;
|
||||
const matchUrl = ownProps.match.url;
|
||||
const deploymentGroupSlug = params.deploymentGroup;
|
||||
const serviceSlug = params.service;
|
||||
|
||||
if ((deploymentGroupSlug || '').match(/^\~/)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const sections = serviceSlug
|
||||
? state.ui.sections.services
|
||||
: deploymentGroupSlug ? state.ui.sections.deploymentGroups : null;
|
||||
|
||||
return {
|
||||
sections,
|
||||
matchUrl
|
||||
sections
|
||||
};
|
||||
},
|
||||
dispatch => ({})
|
||||
|
@ -48,7 +48,7 @@ class ServiceList extends Component {
|
||||
toggleServicesQuickActions(o);
|
||||
};
|
||||
|
||||
const serviceList = services.map(service => (
|
||||
const serviceList = services.map(service =>
|
||||
<ServiceListItem
|
||||
key={service.id}
|
||||
deploymentGroup={deploymentGroup.slug}
|
||||
@ -60,7 +60,7 @@ class ServiceList extends Component {
|
||||
onQuickActionsClick={handleQuickActionsClick}
|
||||
onQuickActionsBlur={handleQuickActionsBlur}
|
||||
/>
|
||||
));
|
||||
);
|
||||
|
||||
return (
|
||||
<LayoutContainer>
|
||||
|
@ -0,0 +1,5 @@
|
||||
query DeploymentGroupBySlug($slug: String!) {
|
||||
deploymentGroups(slug: $slug) {
|
||||
id
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
#import "./DeploymentGroupInfo.gql"
|
||||
|
||||
mutation createDeploymentGroup($name: String!) {
|
||||
createDeploymentGroup(name: $name) {
|
||||
...DeploymentGroupInfo
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
mutation provisionManifest($deploymentGroupId: ID!, $type: ManifestType!, $format: ManifestFormat!, $raw: String!) {
|
||||
provisionManifest(deploymentGroupId: $deploymentGroupId, type: $type, format: $format, raw: $raw) {
|
||||
id
|
||||
created
|
||||
type
|
||||
format
|
||||
obj
|
||||
}
|
||||
}
|
@ -2,28 +2,31 @@ import React from 'react';
|
||||
import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { Header, Breadcrumb, Menu } from '@containers/navigation';
|
||||
import { InstanceList } from '@containers/instances';
|
||||
|
||||
import {
|
||||
DeploymentGroupList,
|
||||
DeploymentGroupCreate
|
||||
} from '@containers/deployment-groups';
|
||||
|
||||
import { DeploymentGroupList } from '@containers/deployment-groups';
|
||||
import {
|
||||
ServiceList,
|
||||
ServicesTopology,
|
||||
ServicesMenu
|
||||
} from '@containers/services';
|
||||
import { InstanceList } from '@containers/instances';
|
||||
|
||||
const rootRedirect = p => <Redirect to="/deployment-groups" />;
|
||||
|
||||
const deploymentGroupRedirect = p => (
|
||||
const deploymentGroupRedirect = p =>
|
||||
<Redirect
|
||||
to={`/deployment-groups/${p.match.params.deploymentGroup}/services-list`}
|
||||
/>
|
||||
);
|
||||
/>;
|
||||
|
||||
const serviceRedirect = p => (
|
||||
const serviceRedirect = p =>
|
||||
<Redirect
|
||||
to={`/deployment-groups/${p.match.params.deploymentGroup}/services/${p.match.params.service}/instances`}
|
||||
/>
|
||||
);
|
||||
to={`/deployment-groups/${p.match.params.deploymentGroup}/services/${p.match
|
||||
.params.service}/instances`}
|
||||
/>;
|
||||
|
||||
const Router = (
|
||||
<BrowserRouter>
|
||||
@ -53,6 +56,12 @@ const Router = (
|
||||
<Route path="/" exact component={rootRedirect} />
|
||||
<Route path="/deployment-groups" exact component={DeploymentGroupList} />
|
||||
|
||||
<Switch>
|
||||
<Route
|
||||
path="/deployment-groups/~create/:stage?"
|
||||
exact
|
||||
component={DeploymentGroupCreate}
|
||||
/>
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup"
|
||||
exact
|
||||
@ -63,6 +72,8 @@ const Router = (
|
||||
exact
|
||||
component={deploymentGroupRedirect}
|
||||
/>
|
||||
</Switch>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/instances"
|
||||
exact
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
|
||||
import { reducer as formReducer } from 'redux-form';
|
||||
// import { enableBatching } from 'redux-batched-actions';
|
||||
import { ApolloClient, createNetworkInterface } from 'react-apollo';
|
||||
import state from './state';
|
||||
@ -36,7 +37,8 @@ export const client = new ApolloClient({
|
||||
export const store = createStore(
|
||||
combineReducers({
|
||||
ui,
|
||||
apollo: client.reducer()
|
||||
apollo: client.reducer(),
|
||||
form: formReducer
|
||||
}),
|
||||
state, // Initial state
|
||||
compose(
|
||||
|
@ -2390,10 +2390,6 @@ eslint-plugin-import@2.2.0:
|
||||
minimatch "^3.0.3"
|
||||
pkg-up "^1.0.0"
|
||||
|
||||
eslint-plugin-jest@^20.0.3:
|
||||
version "20.0.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-20.0.3.tgz#ec15eba6ac0ab44a67ebf6e02672ca9d7e7cba29"
|
||||
|
||||
eslint-plugin-jsx-a11y@5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.0.3.tgz#4a939f76ec125010528823331bf948cc573380b6"
|
||||
@ -3886,9 +3882,9 @@ jest-snapshot@^20.0.3:
|
||||
natural-compare "^1.4.0"
|
||||
pretty-format "^20.0.3"
|
||||
|
||||
jest-styled-components@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-styled-components/-/jest-styled-components-2.2.0.tgz#7c0748c07979b090ede10220ffa67ab9057b4e8e"
|
||||
jest-styled-components@^3.0.0-2:
|
||||
version "3.0.0-2"
|
||||
resolved "https://registry.yarnpkg.com/jest-styled-components/-/jest-styled-components-3.0.0-2.tgz#147fd618f3642d0fd7724285bdc08a8b3a91361b"
|
||||
dependencies:
|
||||
css "^2.2.1"
|
||||
|
||||
@ -4607,6 +4603,10 @@ npmlog@^4.0.2:
|
||||
gauge "~2.7.3"
|
||||
set-blocking "~2.0.0"
|
||||
|
||||
nprogress@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1"
|
||||
|
||||
nth-check@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
|
||||
|
@ -14,13 +14,17 @@
|
||||
"dev": "nodemon src/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"camel-case": "^3.0.0",
|
||||
"good": "^7.2.0",
|
||||
"good-console": "^6.4.0",
|
||||
"good-squeeze": "^5.0.2",
|
||||
"graphi": "^2.0.0",
|
||||
"hapi": "^16.1.1",
|
||||
"joi": "^10.5.0",
|
||||
"joyent-cp-gql-schema": "^1.0.4"
|
||||
"graphi": "^2.2.1",
|
||||
"hapi": "^16.4.3",
|
||||
"joi": "^10.5.2",
|
||||
"joyent-cp-gql-schema": "^1.0.4",
|
||||
"js-yaml": "^3.8.4",
|
||||
"param-case": "^2.1.1",
|
||||
"uuid": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^3.19.0",
|
||||
|
@ -15,7 +15,7 @@
|
||||
"deploymentGroups": [
|
||||
{
|
||||
"id": "e0ea0c02-55cc-45fe-8064-3e5176a59401",
|
||||
"slug": "forest-foundation-dev",
|
||||
"slug": "warp-records-blog",
|
||||
"name": "WarpRecords Blog"
|
||||
},
|
||||
{
|
||||
|
@ -1,3 +1,8 @@
|
||||
const { v4: uuid } = require('uuid');
|
||||
const paramCase = require('param-case');
|
||||
const camelCase = require('camel-case');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
const {
|
||||
datacenter,
|
||||
portal,
|
||||
@ -58,6 +63,43 @@ const getPortal = () =>
|
||||
})
|
||||
);
|
||||
|
||||
const createDeploymentGroup = ({ name }) => {
|
||||
const dg = {
|
||||
id: uuid(),
|
||||
slug: paramCase(name),
|
||||
name
|
||||
};
|
||||
|
||||
deploymentGroups.push(dg);
|
||||
|
||||
return Promise.resolve(dg);
|
||||
};
|
||||
|
||||
const createServicesFromManifest = ({ deploymentGroupId, raw }) => {
|
||||
const manifest = yaml.safeLoad(raw);
|
||||
|
||||
Object.keys(manifest).forEach(name => {
|
||||
const service = {
|
||||
id: uuid(),
|
||||
deploymentGroup: deploymentGroupId,
|
||||
slug: paramCase(name),
|
||||
name
|
||||
};
|
||||
|
||||
const instance = {
|
||||
id: uuid(),
|
||||
name: camelCase(`${service.slug}_01`),
|
||||
service: service.id,
|
||||
deploymentGroup: deploymentGroupId
|
||||
};
|
||||
|
||||
services.push(service);
|
||||
instances.push(instance);
|
||||
});
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
portal: getPortal,
|
||||
deploymentGroups: getDeploymentGroups,
|
||||
@ -65,5 +107,12 @@ module.exports = {
|
||||
services: getServices,
|
||||
service: query => getServices(query).then(services => services.shift()),
|
||||
instances: getInstances,
|
||||
instance: query => getInstances(query).then(instances => instances.shift())
|
||||
instance: query => getInstances(query).then(instances => instances.shift()),
|
||||
createDeploymentGroup,
|
||||
provisionManifest: options =>
|
||||
createServicesFromManifest(options).then(() => ({
|
||||
id: uuid(),
|
||||
type: options.type,
|
||||
format: options.format
|
||||
}))
|
||||
};
|
||||
|
@ -14,7 +14,7 @@
|
||||
"zerorpc": "^0.9.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"code": "^4.0.0",
|
||||
"code": "^4.1.0",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"js-yaml": "^3.8.4",
|
||||
|
@ -13,13 +13,13 @@
|
||||
"peerDependencies": {
|
||||
"babel-eslint": "^7.2.3",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-prettier": "^2.1.0",
|
||||
"eslint-config-prettier": "^2.1.1",
|
||||
"eslint-config-react-app": "^0.6.2",
|
||||
"eslint-config-xo-space": "^0.16.0",
|
||||
"eslint-plugin-flowtype": "^2.33.0",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-jsx-a11y": "^5.0.3",
|
||||
"eslint-plugin-prettier": "^2.0.1",
|
||||
"eslint-plugin-prettier": "^2.1.1",
|
||||
"eslint-plugin-react": "^7.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -23,21 +23,21 @@
|
||||
"prepublish": "redrun build"
|
||||
},
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.10"
|
||||
"prop-types": "^15.5.10",
|
||||
"react-codemirror": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-react-app": "^3.0.0",
|
||||
"bup": "^1.0.9",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.3",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"jest": "^20.0.4",
|
||||
"react": "^15.5.4",
|
||||
"react-test-renderer": "^15.5.4",
|
||||
"redrun": "^5.9.14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-codemirror": "*"
|
||||
"react": "*"
|
||||
},
|
||||
"jest": {
|
||||
"testEnvironment": "jsdom",
|
||||
|
@ -1,3 +1,20 @@
|
||||
import 'codemirror/lib/codemirror.css';
|
||||
import 'codemirror/theme/eclipse.css';
|
||||
import 'codemirror/addon/fold/foldgutter.css';
|
||||
import 'codemirror/addon/lint/lint.css';
|
||||
import 'codemirror/mode/yaml/yaml';
|
||||
import 'codemirror/mode/javascript/javascript';
|
||||
import 'codemirror/addon/edit/closebrackets';
|
||||
import 'codemirror/addon/edit/matchbrackets';
|
||||
import 'codemirror/addon/fold/foldcode';
|
||||
import 'codemirror/addon/fold/foldgutter';
|
||||
import 'codemirror/addon/fold/brace-fold';
|
||||
import 'codemirror/addon/fold/indent-fold';
|
||||
import 'codemirror/addon/fold/comment-fold';
|
||||
import 'codemirror/addon/hint/show-hint';
|
||||
import 'codemirror/addon/selection/active-line';
|
||||
import 'codemirror/addon/edit/closetag';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import ReactCodeMirror from 'react-codemirror';
|
||||
import PropTypes from 'prop-types';
|
||||
@ -11,7 +28,6 @@ const options = {
|
||||
electricChars: true,
|
||||
lineNumbers: true,
|
||||
inputStyle: 'contenteditable',
|
||||
readOnly: false,
|
||||
lint: true,
|
||||
autoCloseBrackets: true,
|
||||
styleActiveLine: true,
|
||||
@ -38,7 +54,7 @@ class ManifestEditor extends Component {
|
||||
this._refs[name] = ref;
|
||||
};
|
||||
}
|
||||
options({ mode }) {
|
||||
options({ mode, readOnly }) {
|
||||
const modes = {
|
||||
json: {
|
||||
name: 'javascript',
|
||||
@ -48,7 +64,8 @@ class ManifestEditor extends Component {
|
||||
};
|
||||
|
||||
return Object.assign({}, options, {
|
||||
mode: modes[mode.toLowerCase()]
|
||||
mode: modes[mode.toLowerCase()],
|
||||
readOnly
|
||||
});
|
||||
}
|
||||
render() {
|
||||
@ -72,7 +89,8 @@ ManifestEditor.defaultProps = {
|
||||
onChange: () => null,
|
||||
onFocusChange: () => null,
|
||||
autoSave: true,
|
||||
preserveScrollPosition: true
|
||||
preserveScrollPosition: true,
|
||||
readOnly: false
|
||||
};
|
||||
|
||||
ManifestEditor.propTypes = {
|
||||
@ -81,7 +99,8 @@ ManifestEditor.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
onFocusChange: PropTypes.func,
|
||||
autoSave: PropTypes.bool,
|
||||
preserveScrollPosition: PropTypes.bool
|
||||
preserveScrollPosition: PropTypes.bool,
|
||||
readOnly: PropTypes.bool
|
||||
};
|
||||
|
||||
export default ManifestEditor;
|
||||
|
@ -30,12 +30,12 @@
|
||||
"prepublish": "redrun build"
|
||||
},
|
||||
"dependencies": {
|
||||
"remcalc": "^1.0.5"
|
||||
"remcalc": "^1.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-styled-components": "^1.1.4",
|
||||
"babel-preset-react-app": "^3.0.0",
|
||||
"bup": "^1.0.7",
|
||||
"bup": "^1.0.9",
|
||||
"chalk": "^1.1.3",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
@ -44,13 +44,13 @@
|
||||
"jest-junit": "^1.5.1",
|
||||
"jest-matcher-utils": "^20.0.3",
|
||||
"jest-snapshot": "^20.0.3",
|
||||
"jest-styled-components": "^3.0.0-1",
|
||||
"jest-styled-components": "^3.0.0-2",
|
||||
"react": "^15.5.4",
|
||||
"react-test-renderer": "^15.5.4",
|
||||
"redrun": "^5.9.14",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"styled-components": "^2.0.0",
|
||||
"stylelint": "^7.10.1",
|
||||
"styled-components": "^2.0.1",
|
||||
"stylelint": "^7.11.0",
|
||||
"stylelint-config-primer": "^1.4.0",
|
||||
"stylelint-config-standard": "^16.0.0",
|
||||
"stylelint-processor-styled-components": "styled-components/stylelint-processor-styled-components#68b4c4f"
|
||||
|
@ -18,19 +18,19 @@
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"belly-button": "^3.1.0",
|
||||
"code": "^4.0.0",
|
||||
"hapi": "^16.1.1",
|
||||
"code": "^4.1.0",
|
||||
"hapi": "^16.4.3",
|
||||
"hapi-swagger": "^7.7.0",
|
||||
"inert": "^4.2.0",
|
||||
"lab": "^13.0.2",
|
||||
"lab": "^13.1.0",
|
||||
"vision": "^4.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"boom": "^4.3.1",
|
||||
"graphi": "^2.0.0",
|
||||
"boom": "^5.1.0",
|
||||
"graphi": "^2.2.1",
|
||||
"hoek": "^4.1.1",
|
||||
"joi": "^10.4.1",
|
||||
"joi": "^10.5.2",
|
||||
"joyent-cp-gql-schema": "^1.0.4",
|
||||
"portal-data": "^1.0.0"
|
||||
"portal-data": "^1.1.0"
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,13 @@
|
||||
"docker-compose-client": "^1.0.7",
|
||||
"dockerode": "^2.4.3",
|
||||
"hoek": "^4.1.1",
|
||||
"penseur": "^7.8.1",
|
||||
"penseur": "^7.12.3",
|
||||
"vasync": "^1.6.4",
|
||||
"yamljs": "^0.2.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"belly-button": "^3.1.0",
|
||||
"code": "^4.0.0",
|
||||
"lab": "^13.0.4"
|
||||
"code": "^4.1.0",
|
||||
"lab": "^13.1.0"
|
||||
}
|
||||
}
|
||||
|
@ -39,15 +39,14 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "0.19.1",
|
||||
"babel-plugin-istanbul": "^4.1.3",
|
||||
"babel-preset-env": "^1.5.1",
|
||||
"babel-plugin-istanbul": "^4.1.4",
|
||||
"babel-preset-env": "^1.5.2",
|
||||
"babel-register": "^6.24.1",
|
||||
"bup": "^1.0.7",
|
||||
"cross-env": "^5.0.0",
|
||||
"bup": "^1.0.9",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"nyc": "^10.3.2",
|
||||
"prettier": "^1.3.1",
|
||||
"nyc": "^11.0.2",
|
||||
"redrun": "^5.9.14",
|
||||
"tap-xunit": "^1.7.0"
|
||||
},
|
||||
|
@ -37,19 +37,18 @@
|
||||
"has-own-prop": "^1.0.0",
|
||||
"lodash.isnull": "^3.0.0",
|
||||
"lodash.isundefined": "^3.0.1",
|
||||
"yaml-ast-parser": "0.0.32"
|
||||
"yaml-ast-parser": "0.0.33"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "0.19.1",
|
||||
"babel-plugin-istanbul": "^4.1.3",
|
||||
"babel-preset-env": "^1.5.1",
|
||||
"babel-plugin-istanbul": "^4.1.4",
|
||||
"babel-preset-env": "^1.5.2",
|
||||
"babel-register": "^6.24.1",
|
||||
"bup": "^1.0.7",
|
||||
"cross-env": "^5.0.0",
|
||||
"bup": "^1.0.9",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"nyc": "^10.3.2",
|
||||
"prettier": "^1.3.1",
|
||||
"nyc": "^11.0.2",
|
||||
"redrun": "^5.9.14",
|
||||
"tap-xunit": "^1.7.0"
|
||||
},
|
||||
|
@ -29,17 +29,17 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "0.19.1",
|
||||
"babel-plugin-istanbul": "^4.1.3",
|
||||
"babel-plugin-istanbul": "^4.1.4",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-parameters": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
"babel-register": "^6.24.1",
|
||||
"bup": "^1.0.8",
|
||||
"cross-env": "^5.0.0",
|
||||
"bup": "^1.0.9",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"nyc": "^10.3.2",
|
||||
"nyc": "^11.0.2",
|
||||
"tap-xunit": "^1.7.0"
|
||||
},
|
||||
"nyc": {
|
||||
|
@ -25,16 +25,16 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "0.19.1",
|
||||
"babel-plugin-istanbul": "^4.1.3",
|
||||
"babel-plugin-istanbul": "^4.1.4",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
"babel-register": "^6.24.1",
|
||||
"bup": "^1.0.8",
|
||||
"cross-env": "^5.0.0",
|
||||
"bup": "^1.0.9",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"lodash.uniq": "^4.5.0",
|
||||
"nyc": "^10.3.2",
|
||||
"nyc": "^11.0.2",
|
||||
"tap-xunit": "^1.7.0"
|
||||
},
|
||||
"nyc": {
|
||||
|
@ -28,20 +28,20 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "0.19.1",
|
||||
"babel-plugin-istanbul": "^4.1.3",
|
||||
"babel-plugin-istanbul": "^4.1.4",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-parameters": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-template-literals": "^6.22.0",
|
||||
"babel-register": "^6.24.1",
|
||||
"bup": "^1.0.7",
|
||||
"cross-env": "^5.0.0",
|
||||
"bup": "^1.0.9",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"nyc": "^10.3.2",
|
||||
"nyc": "^11.0.2",
|
||||
"react": "^15.5.4",
|
||||
"redrun": "^5.9.14",
|
||||
"styled-components": "^2.0.0",
|
||||
"styled-components": "^2.0.1",
|
||||
"tap-xunit": "^1.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -32,48 +32,54 @@
|
||||
"d3": "^4.9.1",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"normalized-styled-components": "^1.0.5",
|
||||
"polished": "^1.1.2",
|
||||
"polished": "^1.1.3",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^15.5.4",
|
||||
"react-broadcast": "^0.1.2",
|
||||
"react-dom": "^15.5.4",
|
||||
"react-router-dom": "^4.1.1",
|
||||
"react-styled-flexboxgrid": "^1.1.2",
|
||||
"redux-form": "^6.7.0",
|
||||
"remcalc": "^1.0.5",
|
||||
"rnd-id": "^1.0.5",
|
||||
"styled-components": "^2.0.0",
|
||||
"styled-is": "^1.0.7",
|
||||
"unitcalc": "^1.0.5"
|
||||
"react-styled-flexboxgrid": "^2.0.0",
|
||||
"remcalc": "^1.0.8",
|
||||
"rnd-id": "^1.0.8",
|
||||
"styled-components": "^2.0.1",
|
||||
"styled-is": "^1.0.11",
|
||||
"unitcalc": "^1.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.24.1",
|
||||
"babel-plugin-inline-react-svg": "^0.4.0",
|
||||
"babel-plugin-styled-components": "^1.1.4",
|
||||
"babel-preset-joyent-portal": "^1.0.0",
|
||||
"cross-env": "^5.0.0",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"jest": "^20.0.3",
|
||||
"jest": "^20.0.4",
|
||||
"jest-diff": "^20.0.3",
|
||||
"jest-matcher-utils": "^20.0.3",
|
||||
"jest-snapshot": "^20.0.3",
|
||||
"jest-styled-components": "^2.0.0",
|
||||
"jest-styled-components": "^3.0.0-2",
|
||||
"react": "^15.5.4",
|
||||
"react-docgen": "^2.15.0",
|
||||
"react-docgen-displayname-handler": "^1.0.0",
|
||||
"react-dom": "^15.5.4",
|
||||
"react-redux": "^5.0.5",
|
||||
"react-scripts": "^1.0.0",
|
||||
"react-styleguidist": "^5.2.1",
|
||||
"react-router-dom": "^4.1.1",
|
||||
"react-scripts": "^1.0.7",
|
||||
"react-styleguidist": "^5.4.2",
|
||||
"react-test-renderer": "^15.5.4",
|
||||
"redrun": "^5.9.14",
|
||||
"redux": "^3.6.0",
|
||||
"redux-form": "^6.8.0",
|
||||
"snapguidist": "^1.1.2",
|
||||
"stylelint": "^7.10.1",
|
||||
"stylelint": "^7.11.0",
|
||||
"stylelint-config-primer": "^1.4.0",
|
||||
"stylelint-config-standard": "^16.0.0",
|
||||
"stylelint-processor-styled-components": "ramitos/stylelint-processor-styled-components#e81e1d0",
|
||||
"stylelint-processor-styled-components": "styled-components/stylelint-processor-styled-components#68b4c4f",
|
||||
"tinycolor2": "^1.4.1",
|
||||
"title-case": "^2.1.1",
|
||||
"webpack": "^2.5.1"
|
||||
"webpack": "^2.6.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.5.4",
|
||||
"react-dom": "^15.5.4",
|
||||
"react-router-dom": "^4.1.1",
|
||||
"redux-form": "^6.8.0"
|
||||
}
|
||||
}
|
||||
|
@ -36,9 +36,8 @@ class FormGroup extends Component {
|
||||
render() {
|
||||
const {
|
||||
name = rndId(),
|
||||
defaultValue,
|
||||
normalize,
|
||||
reduxForm = false
|
||||
reduxForm = false,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
if (!reduxForm) {
|
||||
@ -48,9 +47,8 @@ class FormGroup extends Component {
|
||||
return (
|
||||
<Field
|
||||
name={name}
|
||||
defaultValue={defaultValue}
|
||||
component={this.renderGroup}
|
||||
normalize={normalize}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -28,20 +28,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"remcalc": "^1.0.5"
|
||||
"remcalc": "^1.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "0.19.1",
|
||||
"babel-plugin-istanbul": "^4.1.3",
|
||||
"babel-plugin-istanbul": "^4.1.4",
|
||||
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
|
||||
"babel-plugin-transform-es2015-parameters": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-spread": "^6.22.0",
|
||||
"babel-register": "^6.24.1",
|
||||
"bup": "^1.0.8",
|
||||
"cross-env": "^5.0.0",
|
||||
"bup": "^1.0.9",
|
||||
"cross-env": "^5.0.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-joyent-portal": "1.0.0",
|
||||
"nyc": "^10.3.2",
|
||||
"nyc": "^11.0.2",
|
||||
"tap-xunit": "^1.7.0"
|
||||
},
|
||||
"nyc": {
|
||||
|
Loading…
Reference in New Issue
Block a user