feat(cp-frontend): DeploymentGroup reprovision flow
This commit is contained in:
parent
3aa7ec54bb
commit
4e241191bf
@ -28,6 +28,7 @@
|
||||
"jest-cli": "^20.0.4",
|
||||
"joyent-manifest-editor": "^1.0.0",
|
||||
"joyent-ui-toolkit": "^1.1.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"normalized-styled-components": "^1.0.8",
|
||||
"param-case": "^2.1.1",
|
||||
|
@ -45,8 +45,8 @@ const ButtonsRow = Row.extend`
|
||||
margin-bottom: ${remcalc(60)};
|
||||
`;
|
||||
|
||||
const Editor = ManifestEditor => ({ input }) =>
|
||||
<ManifestEditor mode="yaml" {...input} />;
|
||||
const Editor = ManifestEditor => ({ input, defaultValue }) =>
|
||||
<ManifestEditor mode="yaml" {...input} value={input.value || defaultValue} />;
|
||||
|
||||
export const Name = ({ handleSubmit, onCancel, dirty }) =>
|
||||
<form onSubmit={handleSubmit}>
|
||||
@ -64,12 +64,23 @@ export const Name = ({ handleSubmit, onCancel, dirty }) =>
|
||||
</ButtonsRow>
|
||||
</form>;
|
||||
|
||||
export const Manifest = ({ handleSubmit, onCancel, dirty, mode, loading }) =>
|
||||
export const Manifest = ({
|
||||
handleSubmit,
|
||||
onCancel,
|
||||
dirty,
|
||||
defaultValue,
|
||||
mode,
|
||||
loading
|
||||
}) =>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Bundle load={() => import('joyent-manifest-editor')}>
|
||||
{ManifestEditor =>
|
||||
ManifestEditor
|
||||
? <Field name="manifest" component={Editor(ManifestEditor)} />
|
||||
? <Field
|
||||
name="manifest"
|
||||
defaultValue={defaultValue}
|
||||
component={Editor(ManifestEditor)}
|
||||
/>
|
||||
: <Dots2 />}
|
||||
</Bundle>
|
||||
<ButtonsRow>
|
||||
@ -82,7 +93,7 @@ export const Manifest = ({ handleSubmit, onCancel, dirty, mode, loading }) =>
|
||||
|
||||
export const Review = ({ handleSubmit, onCancel, dirty, ...state }) => {
|
||||
const serviceList = forceArray(state.services).map(({ name, image }) =>
|
||||
<ServiceCard>
|
||||
<ServiceCard key={name}>
|
||||
<Dl>
|
||||
<dt><ServiceName>{name}</ServiceName></dt>
|
||||
<dt><ImageTitle>Image:</ImageTitle> <Image>{image}</Image></dt>
|
||||
|
@ -18,11 +18,14 @@ import {
|
||||
const STATUSES = [
|
||||
'CREATED',
|
||||
'RESTARTING',
|
||||
'PROVISIONING',
|
||||
'READY',
|
||||
'RUNNING',
|
||||
'PAUSED',
|
||||
'EXITED',
|
||||
'DELETED',
|
||||
'STOPPED',
|
||||
'STOPPING',
|
||||
'FAILED'
|
||||
];
|
||||
|
||||
@ -46,6 +49,14 @@ const Dot = styled.div`
|
||||
background-color: yellow;
|
||||
`};
|
||||
|
||||
${is('provisioning')`
|
||||
background-color: yellow;
|
||||
`};
|
||||
|
||||
${is('ready')`
|
||||
background-color: yellow;
|
||||
`};
|
||||
|
||||
${is('running')`
|
||||
background-color: ${props => props.theme.green};
|
||||
`};
|
||||
@ -62,6 +73,10 @@ const Dot = styled.div`
|
||||
background-color: ${props => props.theme.secondaryActive};
|
||||
`};
|
||||
|
||||
${is('stopping')`
|
||||
background-color: orange;
|
||||
`};
|
||||
|
||||
${is('stopped')`
|
||||
background-color: ${props => props.theme.red};
|
||||
`};
|
||||
|
@ -1,270 +1,18 @@
|
||||
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 paramCase from 'param-case';
|
||||
import React from 'react';
|
||||
|
||||
import DeploymentGroupBySlug from '@graphql/DeploymentGroupBySlug.gql';
|
||||
import DeploymentGroupCreateMutation from '@graphql/DeploymentGroupCreate.gql';
|
||||
import DeploymentGroupProvisionMutation from '@graphql/DeploymentGroupProvision.gql';
|
||||
import DeploymentGroupConfigQuery from '@graphql/DeploymentGroupConfig.gql';
|
||||
|
||||
import { client } from '@state/store';
|
||||
import DeploymentGroupEditOrCreate from './edit-or-create';
|
||||
import { LayoutContainer } from '@components/layout';
|
||||
import { Name, Manifest, Review } from '@components/deployment-groups/create';
|
||||
import { DeploymentGroupsLoading } from '@components/deployment-groups';
|
||||
import { H2 } from 'joyent-ui-toolkit';
|
||||
|
||||
const validateName = async ({ name = '' }) => {
|
||||
const { data } = await client.query({
|
||||
fetchPolicy: 'network-only',
|
||||
query: DeploymentGroupBySlug,
|
||||
variables: {
|
||||
slug: paramCase(name.trim())
|
||||
}
|
||||
});
|
||||
|
||||
if (data.deploymentGroups.length) {
|
||||
// eslint-disable-next-line no-throw-literal
|
||||
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 = {
|
||||
name: '',
|
||||
manifest: '',
|
||||
services: [],
|
||||
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({ name }, () =>
|
||||
this.redirect({ stage: 'manifest', prog: true })
|
||||
);
|
||||
}
|
||||
|
||||
handleManifestSubmit({ manifest = '' }) {
|
||||
const { config } = this.props;
|
||||
const { name } = this.state;
|
||||
|
||||
const getConfig = async () => {
|
||||
const [err, conf] = await intercept(
|
||||
config({
|
||||
deploymentGroupName: name,
|
||||
type: 'COMPOSE',
|
||||
format: 'YAML',
|
||||
raw: manifest
|
||||
})
|
||||
);
|
||||
|
||||
if (err) {
|
||||
return this.setState({
|
||||
error: err.message
|
||||
});
|
||||
}
|
||||
|
||||
const { data } = conf;
|
||||
const { config: services } = data;
|
||||
|
||||
this.setState({ loading: false, services }, () => {
|
||||
this.redirect({ stage: 'review', prog: true });
|
||||
});
|
||||
};
|
||||
|
||||
this.setState({ manifest, loading: true }, getConfig);
|
||||
}
|
||||
|
||||
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 { name } = this.state;
|
||||
const { createDeploymentGroup } = this.props;
|
||||
|
||||
const [err, res] = await intercept(createDeploymentGroup({ name }));
|
||||
|
||||
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] = 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}
|
||||
loading={this.state.loading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
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 { err } = this.state;
|
||||
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' });
|
||||
}
|
||||
|
||||
if (stage !== 'name' && !this.state.name) {
|
||||
return this.redirect({ stage: 'name' });
|
||||
}
|
||||
|
||||
if (stage === 'review' && !this.state.manifest) {
|
||||
return this.redirect({ stage: 'manifest' });
|
||||
}
|
||||
|
||||
const view = this.stages[stage]();
|
||||
|
||||
const error = err ? <span>{err}</span> : null;
|
||||
|
||||
return (
|
||||
<LayoutContainer>
|
||||
<H2>Creating deployment group</H2>
|
||||
{error}
|
||||
{view}
|
||||
</LayoutContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
graphql(DeploymentGroupCreateMutation, {
|
||||
props: ({ mutate }) => ({
|
||||
createDeploymentGroup: variables => mutate({ variables })
|
||||
})
|
||||
}),
|
||||
graphql(DeploymentGroupProvisionMutation, {
|
||||
props: ({ mutate }) => ({
|
||||
provisionManifest: variables => mutate({ variables })
|
||||
})
|
||||
}),
|
||||
graphql(DeploymentGroupConfigQuery, {
|
||||
props: ({ mutate }) => ({
|
||||
config: variables => mutate({ variables })
|
||||
})
|
||||
})
|
||||
)(DeploymentGroupCreate);
|
||||
export default ({ loading, error, manifest = '', deploymentGroup = null }) =>
|
||||
<LayoutContainer>
|
||||
<H2>Creating deployment group</H2>
|
||||
{loading && <DeploymentGroupsLoading />}
|
||||
{error && <span>{error.toString()}</span>}
|
||||
<DeploymentGroupEditOrCreate
|
||||
create
|
||||
manifest={manifest}
|
||||
deploymentGroup={deploymentGroup}
|
||||
/>
|
||||
</LayoutContainer>;
|
||||
|
@ -0,0 +1,298 @@
|
||||
import React, { Component } from 'react';
|
||||
import { reduxForm } from 'redux-form';
|
||||
import { compose, graphql } from 'react-apollo';
|
||||
import { withRouter } from 'react-router';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import intercept from 'apr-intercept';
|
||||
import paramCase from 'param-case';
|
||||
|
||||
import DeploymentGroupBySlugQuery from '@graphql/DeploymentGroupBySlug.gql';
|
||||
import DeploymentGroupCreateMutation from '@graphql/DeploymentGroupCreate.gql';
|
||||
import DeploymentGroupProvisionMutation from '@graphql/DeploymentGroupProvision.gql';
|
||||
import DeploymentGroupConfigQuery from '@graphql/DeploymentGroupConfig.gql';
|
||||
|
||||
import { client } from '@state/store';
|
||||
import { Name, Manifest, Review } from '@components/deployment-groups/create';
|
||||
|
||||
// TODO: move state to redux. why: because in redux we can cache transactional
|
||||
// state between refreshes
|
||||
class DeploymentGroupEditOrCreate extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const { create, edit } = props;
|
||||
const type = create ? 'create' : 'edit';
|
||||
|
||||
const NameForm =
|
||||
create &&
|
||||
reduxForm({
|
||||
form: `${type}-deployment-group`,
|
||||
destroyOnUnmount: true,
|
||||
forceUnregisterOnUnmount: true,
|
||||
asyncValidate: async ({ name = '' }) => {
|
||||
const { data } = await client.query({
|
||||
fetchPolicy: 'network-only',
|
||||
query: DeploymentGroupBySlugQuery,
|
||||
variables: {
|
||||
slug: paramCase(name.trim())
|
||||
}
|
||||
});
|
||||
|
||||
if (data.deploymentGroups.length) {
|
||||
// eslint-disable-next-line no-throw-literal
|
||||
throw { name: `"${name}" already exists!` };
|
||||
}
|
||||
}
|
||||
})(Name);
|
||||
|
||||
const ManifestForm = reduxForm({
|
||||
form: `${type}-deployment-group`,
|
||||
destroyOnUnmount: true,
|
||||
forceUnregisterOnUnmount: true
|
||||
})(Manifest);
|
||||
|
||||
const ReviewForm = reduxForm({
|
||||
form: `${type}-deployment-group`,
|
||||
destroyOnUnmount: true,
|
||||
forceUnregisterOnUnmount: true
|
||||
})(Review);
|
||||
|
||||
this.state = {
|
||||
defaultStage: create ? 'name' : 'edit',
|
||||
manifestStage: create ? 'manifest' : 'edit',
|
||||
name: '',
|
||||
manifest: '',
|
||||
services: [],
|
||||
loading: false,
|
||||
error: null,
|
||||
NameForm,
|
||||
ManifestForm,
|
||||
ReviewForm
|
||||
};
|
||||
|
||||
this.stages = {
|
||||
name: create && this.renderNameForm.bind(this),
|
||||
[create ? 'manifest' : 'edit']: this.renderManifestEditor.bind(this),
|
||||
review: this.renderReview.bind(this)
|
||||
};
|
||||
|
||||
this.handleNameSubmit =
|
||||
type === 'create' && this.handleNameSubmit.bind(this);
|
||||
|
||||
this.handleManifestSubmit = this.handleManifestSubmit.bind(this);
|
||||
this.handleReviewSubmit = this.handleReviewSubmit.bind(this);
|
||||
this.handleCancel = this.handleCancel.bind(this);
|
||||
|
||||
if (edit) {
|
||||
setTimeout(this.getDeploymentGroup, 16);
|
||||
}
|
||||
}
|
||||
|
||||
createDeploymentGroup = async () => {
|
||||
const { createDeploymentGroup, deploymentGroup, edit } = this.props;
|
||||
|
||||
if (edit && (!deploymentGroup || !deploymentGroup.id)) {
|
||||
this.setState({
|
||||
error: 'Unexpected Error: Inexistent DeploymentGroup!'
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (deploymentGroup && deploymentGroup.id) {
|
||||
return deploymentGroup;
|
||||
}
|
||||
|
||||
const { name } = this.state;
|
||||
|
||||
const [err, res] = await intercept(createDeploymentGroup({ name }));
|
||||
|
||||
if (err) {
|
||||
this.setState({
|
||||
error: err.message
|
||||
});
|
||||
}
|
||||
|
||||
return err ? {} : res.data.createDeploymentGroup;
|
||||
};
|
||||
|
||||
provision = async deploymentGroupId => {
|
||||
const { manifest } = this.state;
|
||||
const { provisionManifest } = this.props;
|
||||
|
||||
const [err] = await intercept(
|
||||
provisionManifest({
|
||||
deploymentGroupId,
|
||||
type: 'COMPOSE',
|
||||
format: 'YAML',
|
||||
raw: manifest
|
||||
})
|
||||
);
|
||||
|
||||
if (err) {
|
||||
this.setState({
|
||||
error: err.message
|
||||
});
|
||||
}
|
||||
|
||||
return err ? null : true;
|
||||
};
|
||||
|
||||
handleNameSubmit({ name = '' }) {
|
||||
this.setState({ name }, () =>
|
||||
this.redirect({ stage: 'manifest', prog: true })
|
||||
);
|
||||
}
|
||||
|
||||
handleManifestSubmit({ manifest = '' }) {
|
||||
const { name } = this.state;
|
||||
|
||||
const getConfig = async () => {
|
||||
const [err, conf] = await intercept(
|
||||
client.query({
|
||||
query: DeploymentGroupConfigQuery,
|
||||
variables: {
|
||||
deploymentGroupName: name,
|
||||
type: 'COMPOSE',
|
||||
format: 'YAML',
|
||||
raw: manifest
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
if (err) {
|
||||
return this.setState({
|
||||
error: err.message
|
||||
});
|
||||
}
|
||||
|
||||
const { data } = conf;
|
||||
const { config: services } = data;
|
||||
|
||||
this.setState({ loading: false, services }, () => {
|
||||
this.redirect({ stage: 'review', prog: true });
|
||||
});
|
||||
};
|
||||
|
||||
this.setState({ manifest, loading: true }, getConfig);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
const { history, create, deploymentGroup } = this.props;
|
||||
|
||||
history.push(create ? '/' : `/deployment-groups/${deploymentGroup.slug}`);
|
||||
}
|
||||
|
||||
redirect({ stage = 'name', prog = false }) {
|
||||
const { match, history, create } = this.props;
|
||||
|
||||
const regex = create ? /\/~create(.*)/ : /\/manifest(.*)/;
|
||||
const to = match.url.replace(
|
||||
regex,
|
||||
create ? `/~create/${stage}` : `/manifest/${stage}`
|
||||
);
|
||||
|
||||
if (!prog) {
|
||||
return <Redirect to={to} />;
|
||||
}
|
||||
|
||||
history.push(to);
|
||||
}
|
||||
|
||||
renderNameForm() {
|
||||
const { NameForm } = this.state;
|
||||
|
||||
return (
|
||||
<NameForm onSubmit={this.handleNameSubmit} onCancel={this.handleCancel} />
|
||||
);
|
||||
}
|
||||
|
||||
renderManifestEditor() {
|
||||
const { ManifestForm } = this.state;
|
||||
|
||||
return (
|
||||
<ManifestForm
|
||||
defaultValue={this.props.manifest}
|
||||
onSubmit={this.handleManifestSubmit}
|
||||
onCancel={this.handleCancel}
|
||||
loading={this.state.loading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderReview() {
|
||||
const { ReviewForm } = this.state;
|
||||
|
||||
return (
|
||||
<ReviewForm
|
||||
onSubmit={this.handleReviewSubmit}
|
||||
onCancel={this.handleCancel}
|
||||
{...this.state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { error, defaultStage, manifestStage } = this.state;
|
||||
|
||||
if (error) {
|
||||
return <span>{error}</span>;
|
||||
}
|
||||
|
||||
const { match, create } = this.props;
|
||||
const stage = match.params.stage;
|
||||
|
||||
if (!stage) {
|
||||
return this.redirect({ stage: defaultStage });
|
||||
}
|
||||
|
||||
if (!this.stages[stage]) {
|
||||
return this.redirect({ stage: defaultStage });
|
||||
}
|
||||
|
||||
if (create && stage !== 'name' && !this.state.name) {
|
||||
return this.redirect({ stage: defaultStage });
|
||||
}
|
||||
|
||||
if (stage === 'review' && !this.state.manifest) {
|
||||
return this.redirect({ stage: manifestStage });
|
||||
}
|
||||
|
||||
return this.stages[stage]();
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
graphql(DeploymentGroupCreateMutation, {
|
||||
props: ({ mutate }) => ({
|
||||
createDeploymentGroup: variables => mutate({ variables })
|
||||
})
|
||||
}),
|
||||
graphql(DeploymentGroupProvisionMutation, {
|
||||
props: ({ mutate }) => ({
|
||||
provisionManifest: variables => mutate({ variables })
|
||||
})
|
||||
})
|
||||
)(withRouter(DeploymentGroupEditOrCreate));
|
@ -1,12 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
import { compose, graphql } from 'react-apollo';
|
||||
import { graphql } from 'react-apollo';
|
||||
import intercept from 'apr-intercept';
|
||||
|
||||
import DeploymentGroupImportMutation from '@graphql/DeploymentGroupImport.gql';
|
||||
|
||||
import { LayoutContainer } from '@components/layout';
|
||||
import { DeploymentGroupsLoading } from '@components/deployment-groups';
|
||||
import { Dots2 } from 'styled-text-spinners';
|
||||
import { H2 } from 'joyent-ui-toolkit';
|
||||
|
||||
class DeploymentGroupImport extends Component {
|
||||
|
@ -1,3 +1,4 @@
|
||||
export { default as DeploymentGroupList } from './list';
|
||||
export { default as DeploymentGroupCreate } from './create';
|
||||
export { default as DeploymentGroupImport } from './import';
|
||||
export { default as DeploymentGroupManifest } from './manifest';
|
||||
|
@ -8,11 +8,11 @@ import forceArray from 'force-array';
|
||||
import remcalc from 'remcalc';
|
||||
|
||||
import { LayoutContainer } from '@components/layout';
|
||||
import { Loader, ErrorMessage } from '@components/messaging';
|
||||
import { ErrorMessage } from '@components/messaging';
|
||||
import { DeploymentGroupsLoading } from '@components/deployment-groups';
|
||||
import DeploymentGroupsQuery from '@graphql/DeploymentGroups.gql';
|
||||
import DeploymentGroupsImportableQuery from '@graphql/DeploymentGroupsImportable.gql';
|
||||
import { Button, H2, H3, Small } from 'joyent-ui-toolkit';
|
||||
import { H2, H3, Small } from 'joyent-ui-toolkit';
|
||||
|
||||
const Title = H2.extend`
|
||||
margin-top: ${remcalc(2)};
|
||||
|
@ -0,0 +1,67 @@
|
||||
import React from 'react';
|
||||
import { compose, graphql } from 'react-apollo';
|
||||
import get from 'lodash.get';
|
||||
|
||||
import ManifestQuery from '@graphql/Manifest.gql';
|
||||
import DeploymentGroupBySlugQuery from '@graphql/DeploymentGroupBySlug.gql';
|
||||
|
||||
import DeploymentGroupEditOrCreate from './edit-or-create';
|
||||
import { LayoutContainer } from '@components/layout';
|
||||
import { DeploymentGroupsLoading } from '@components/deployment-groups';
|
||||
import { H2 } from 'joyent-ui-toolkit';
|
||||
|
||||
const Manifest = ({
|
||||
loading,
|
||||
error,
|
||||
manifest = '',
|
||||
deploymentGroup = null
|
||||
}) => {
|
||||
const _loading = !loading ? null : <DeploymentGroupsLoading />;
|
||||
const _error = !error ? null : <span>{error.toString()}</span>;
|
||||
|
||||
const _view = (loading || !deploymentGroup)
|
||||
? null
|
||||
: <DeploymentGroupEditOrCreate
|
||||
edit
|
||||
manifest={manifest}
|
||||
deploymentGroup={deploymentGroup}
|
||||
/>;
|
||||
|
||||
return (
|
||||
<LayoutContainer>
|
||||
<H2>Edit Manifest</H2>
|
||||
{_error}
|
||||
{_loading}
|
||||
{_view}
|
||||
</LayoutContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default compose(
|
||||
graphql(ManifestQuery, {
|
||||
options: props => ({
|
||||
variables: {
|
||||
deploymentGroupSlug: props.match.params.deploymentGroup
|
||||
}
|
||||
}),
|
||||
props: ({ data: { deploymentGroup, loading, error } }) => ({
|
||||
manifest: get(deploymentGroup, 'version.manifest.raw', ''),
|
||||
loading,
|
||||
error
|
||||
})
|
||||
}),
|
||||
graphql(DeploymentGroupBySlugQuery, {
|
||||
options: props => ({
|
||||
variables: {
|
||||
slug: props.match.params.deploymentGroup
|
||||
}
|
||||
}),
|
||||
props: ({ data: { deploymentGroups, loading, error } }) => ({
|
||||
deploymentGroup: deploymentGroups && deploymentGroups.length
|
||||
? deploymentGroups[0]
|
||||
: null,
|
||||
loading,
|
||||
error
|
||||
})
|
||||
})
|
||||
)(Manifest);
|
@ -6,7 +6,7 @@ import { Row } from 'react-styled-flexboxgrid';
|
||||
import remcalc from 'remcalc';
|
||||
|
||||
import { LayoutContainer } from '@components/layout';
|
||||
import { Loader, ErrorMessage } from '@components/messaging';
|
||||
import { ErrorMessage } from '@components/messaging';
|
||||
import { InstanceListItem, EmptyInstances } from '@components/instances';
|
||||
import { DeploymentGroupsLoading } from '@components/deployment-groups';
|
||||
import { H2 } from 'joyent-ui-toolkit';
|
||||
@ -40,6 +40,8 @@ class InstanceList extends Component {
|
||||
return (
|
||||
<LayoutContainer>
|
||||
<Title>Instances</Title>
|
||||
{_error}
|
||||
{_loading}
|
||||
{instanceList}
|
||||
</LayoutContainer>
|
||||
);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#import "./DeploymentGroupInfo.gql"
|
||||
|
||||
query DeploymentGroupBySlug($slug: String!) {
|
||||
deploymentGroups(slug: $slug) {
|
||||
id
|
||||
...DeploymentGroupInfo
|
||||
}
|
||||
}
|
||||
|
@ -2,4 +2,5 @@ fragment DeploymentGroupInfo on DeploymentGroup {
|
||||
id
|
||||
name
|
||||
slug
|
||||
imported
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
mutation provisionManifest($deploymentGroupId: ID!, $type: ManifestType!, $format: ManifestFormat!, $raw: String!) {
|
||||
provisionManifest(deploymentGroupId: $deploymentGroupId, type: $type, format: $format, raw: $raw) {
|
||||
manifestId
|
||||
scale {
|
||||
serviceName
|
||||
replicas
|
||||
|
12
packages/cp-frontend/src/graphql/Manifest.gql
Normal file
12
packages/cp-frontend/src/graphql/Manifest.gql
Normal file
@ -0,0 +1,12 @@
|
||||
query ManifestById($deploymentGroupSlug: String!) {
|
||||
deploymentGroup(slug: $deploymentGroupSlug) {
|
||||
version {
|
||||
manifest {
|
||||
id
|
||||
type
|
||||
format
|
||||
raw
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,8 @@ import { InstanceList } from '@containers/instances';
|
||||
import {
|
||||
DeploymentGroupList,
|
||||
DeploymentGroupCreate,
|
||||
DeploymentGroupImport
|
||||
DeploymentGroupImport,
|
||||
DeploymentGroupManifest
|
||||
} from '@containers/deployment-groups';
|
||||
|
||||
import {
|
||||
@ -66,6 +67,11 @@ const Router = (
|
||||
<Route path="/" exact component={rootRedirect} />
|
||||
<Route path="/deployment-groups" exact component={DeploymentGroupList} />
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-list"
|
||||
component={ServicesMenu}
|
||||
/>
|
||||
|
||||
<Switch>
|
||||
<Route
|
||||
path="/deployment-groups/~create/:stage?"
|
||||
@ -87,22 +93,36 @@ const Router = (
|
||||
exact
|
||||
component={deploymentGroupRedirect}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/instances"
|
||||
exact
|
||||
component={InstanceList}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/manifest/:stage?"
|
||||
exact
|
||||
component={DeploymentGroupManifest}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-list"
|
||||
component={ServiceList}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-topology"
|
||||
component={ServicesTopology}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services/:service/instances"
|
||||
exact
|
||||
component={InstanceList}
|
||||
/>
|
||||
</Switch>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/instances"
|
||||
exact
|
||||
component={InstanceList}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-list"
|
||||
component={ServicesMenu}
|
||||
/>
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-list"
|
||||
component={ServiceList}
|
||||
/>
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-list/:service/scale"
|
||||
exact
|
||||
@ -118,10 +138,7 @@ const Router = (
|
||||
path="/deployment-groups/:deploymentGroup/services-topology"
|
||||
component={ServicesMenu}
|
||||
/>
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-topology"
|
||||
component={ServicesTopology}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services-topology/:service/scale"
|
||||
exact
|
||||
@ -138,11 +155,6 @@ const Router = (
|
||||
exact
|
||||
component={serviceRedirect}
|
||||
/>
|
||||
<Route
|
||||
path="/deployment-groups/:deploymentGroup/services/:service/instances"
|
||||
exact
|
||||
component={InstanceList}
|
||||
/>
|
||||
|
||||
</Container>
|
||||
</BrowserRouter>
|
||||
|
111
yarn.lock
111
yarn.lock
@ -186,6 +186,10 @@ ansi-regex@^2.0.0, ansi-regex@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
|
||||
ansi-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
||||
|
||||
ansi-styles@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de"
|
||||
@ -216,8 +220,8 @@ anymatch@^1.3.0:
|
||||
micromatch "^2.1.5"
|
||||
|
||||
apollo-client@^1.4.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-1.5.0.tgz#c0ce752f2fe1945dca2eaaa62c7907fdde384563"
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-1.6.0.tgz#d2b831fd8e6e6c045ce91dc8b86a920d44fd77a9"
|
||||
dependencies:
|
||||
graphql "^0.10.0"
|
||||
graphql-anywhere "^3.0.1"
|
||||
@ -493,6 +497,10 @@ ast-types@0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.0.tgz#c8721c8747ae4d5b29b929e99c5317b4e8745623"
|
||||
|
||||
ast-types@0.9.6:
|
||||
version "0.9.6"
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
|
||||
|
||||
async-each@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
|
||||
@ -1757,12 +1765,12 @@ camelcase@^4.0.0, camelcase@^4.1.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
|
||||
|
||||
caniuse-db@^1.0.30000187, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
|
||||
version "1.0.30000694"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000694.tgz#02009f4f82d2f0126e4c691b7cd5adb351935c01"
|
||||
version "1.0.30000696"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000696.tgz#e71f5c61e1f96c7a3af4e791ac5db55e11737604"
|
||||
|
||||
caniuse-lite@^1.0.30000684:
|
||||
version "1.0.30000694"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000694.tgz#1492dab7c10c608c9d37a723e6e3e7873e0ce94f"
|
||||
version "1.0.30000696"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000696.tgz#30f2695d2a01a0dfd779a26ab83f4d134b3da5cc"
|
||||
|
||||
capture-stack-trace@^1.0.0:
|
||||
version "1.0.0"
|
||||
@ -3358,8 +3366,8 @@ eslint-plugin-import@^2.3.0:
|
||||
read-pkg-up "^2.0.0"
|
||||
|
||||
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"
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.1.0.tgz#4a829634344e7a90391a9fb0fbd19810737d79c5"
|
||||
dependencies:
|
||||
aria-query "^0.5.0"
|
||||
array-includes "^3.0.3"
|
||||
@ -3489,7 +3497,7 @@ esprima@^2.6.0, esprima@~2.7.1:
|
||||
version "2.7.3"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
|
||||
|
||||
esprima@^3.1.1:
|
||||
esprima@^3.1.1, esprima@~3.1.0:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
|
||||
|
||||
@ -4374,8 +4382,8 @@ hash-base@^2.0.0:
|
||||
inherits "^2.0.1"
|
||||
|
||||
hash.js@^1.0.0, hash.js@^1.0.3:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.1.tgz#5cb2e796499224e69fd0b00ed01d2d4a16e7a323"
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.2.tgz#bf5c887825cfe40b9efde7bf11bd2db26e6bf01b"
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
minimalistic-assert "^1.0.0"
|
||||
@ -4439,12 +4447,12 @@ home-or-tmp@^2.0.0:
|
||||
os-tmpdir "^1.0.1"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
|
||||
|
||||
html-tags@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-1.2.0.tgz#c78de65b5663aa597989dd2b7ab49200d7e4db98"
|
||||
html-tags@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b"
|
||||
|
||||
http-errors@^1.3.0, http-errors@~1.6.1:
|
||||
version "1.6.1"
|
||||
@ -4999,7 +5007,7 @@ istanbul-lib-hook@^1.0.7:
|
||||
dependencies:
|
||||
append-transform "^0.4.0"
|
||||
|
||||
istanbul-lib-instrument@^1.7.2:
|
||||
istanbul-lib-instrument@^1.7.2, istanbul-lib-instrument@^1.7.3:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.3.tgz#925b239163eabdd68cc4048f52c2fa4f899ecfa7"
|
||||
dependencies:
|
||||
@ -5712,7 +5720,7 @@ lodash.flattendeep@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
||||
|
||||
lodash.get@^4.1.2:
|
||||
lodash.get@^4.1.2, lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
|
||||
@ -6344,8 +6352,8 @@ nopt@~1.0.10:
|
||||
abbrev "1"
|
||||
|
||||
normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb"
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
|
||||
dependencies:
|
||||
hosted-git-info "^2.1.4"
|
||||
is-builtin-module "^1.0.0"
|
||||
@ -6387,8 +6395,8 @@ npm-run-path@^2.0.0:
|
||||
path-key "^2.0.0"
|
||||
|
||||
npmlog@^4.0.2, npmlog@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.0.tgz#dc59bee85f64f00ed424efb2af0783df25d1c0b5"
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
||||
dependencies:
|
||||
are-we-there-yet "~1.1.2"
|
||||
console-control-strings "~1.1.0"
|
||||
@ -6411,8 +6419,8 @@ number-is-nan@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
|
||||
nyc@^11.0.2:
|
||||
version "11.0.2"
|
||||
resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.0.2.tgz#9e592a697186028253b668516c38f079c39c08f3"
|
||||
version "11.0.3"
|
||||
resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.0.3.tgz#0c28bc669a851621709bf7a08503034bee3812b6"
|
||||
dependencies:
|
||||
archy "^1.0.0"
|
||||
arrify "^1.0.1"
|
||||
@ -6426,7 +6434,7 @@ nyc@^11.0.2:
|
||||
glob "^7.0.6"
|
||||
istanbul-lib-coverage "^1.1.1"
|
||||
istanbul-lib-hook "^1.0.7"
|
||||
istanbul-lib-instrument "^1.7.2"
|
||||
istanbul-lib-instrument "^1.7.3"
|
||||
istanbul-lib-report "^1.1.1"
|
||||
istanbul-lib-source-maps "^1.2.1"
|
||||
istanbul-reports "^1.1.1"
|
||||
@ -6437,7 +6445,7 @@ nyc@^11.0.2:
|
||||
resolve-from "^2.0.0"
|
||||
rimraf "^2.5.4"
|
||||
signal-exit "^3.0.1"
|
||||
spawn-wrap "^1.3.6"
|
||||
spawn-wrap "^1.3.7"
|
||||
test-exclude "^4.1.1"
|
||||
yargs "^8.0.1"
|
||||
yargs-parser "^5.0.0"
|
||||
@ -7399,8 +7407,8 @@ read-installed@~4.0.3:
|
||||
graceful-fs "^4.1.2"
|
||||
|
||||
read-package-json@^2.0.0:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.5.tgz#f93a64e641529df68a08c64de46389e8a3f88845"
|
||||
version "2.0.9"
|
||||
resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.9.tgz#fd3c21750d760a96c02abda60081e62133213a26"
|
||||
dependencies:
|
||||
glob "^7.1.1"
|
||||
json-parse-helpfulerror "^1.0.2"
|
||||
@ -7517,7 +7525,7 @@ readline2@^1.0.1:
|
||||
is-fullwidth-code-point "^1.0.0"
|
||||
mute-stream "0.0.5"
|
||||
|
||||
recast@0.11.12, recast@^0.11.5:
|
||||
recast@0.11.12:
|
||||
version "0.11.12"
|
||||
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.12.tgz#a79e4d3f82d5d72a82ee177aeaa791e793bbe5d6"
|
||||
dependencies:
|
||||
@ -7526,6 +7534,15 @@ recast@0.11.12, recast@^0.11.5:
|
||||
private "~0.1.5"
|
||||
source-map "~0.5.0"
|
||||
|
||||
recast@^0.11.5:
|
||||
version "0.11.23"
|
||||
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3"
|
||||
dependencies:
|
||||
ast-types "0.9.6"
|
||||
esprima "~3.1.0"
|
||||
private "~0.1.5"
|
||||
source-map "~0.5.0"
|
||||
|
||||
rechoir@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
|
||||
@ -8257,6 +8274,12 @@ sort-keys@^1.1.1, sort-keys@^1.1.2:
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
sort-keys@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128"
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
source-list-map@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1"
|
||||
@ -8304,7 +8327,7 @@ spache@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/spache/-/spache-1.1.0.tgz#8c68ba807630f0199429c2035c82ed96f5438cd5"
|
||||
|
||||
spawn-wrap@^1.3.6:
|
||||
spawn-wrap@^1.3.7:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.7.tgz#beb8bf4426d64b2b06871e0d7dee2643f1f8d1bc"
|
||||
dependencies:
|
||||
@ -8492,11 +8515,11 @@ string-width@^1.0.0, string-width@^1.0.1, string-width@^1.0.2:
|
||||
strip-ansi "^3.0.0"
|
||||
|
||||
string-width@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e"
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0"
|
||||
dependencies:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string_decoder@^0.10.25, string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
@ -8533,6 +8556,12 @@ strip-ansi@^0.3.0:
|
||||
dependencies:
|
||||
ansi-regex "^0.2.1"
|
||||
|
||||
strip-ansi@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
strip-ansi@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
|
||||
@ -8662,8 +8691,8 @@ stylelint-selector-no-utility@^1.5.0:
|
||||
stylelint "^7.0.0"
|
||||
|
||||
stylelint@^7.0.0, stylelint@^7.0.3, stylelint@^7.11.1:
|
||||
version "7.11.1"
|
||||
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-7.11.1.tgz#c816c658baf7d9e5d167d82273fead37c97ae49d"
|
||||
version "7.12.0"
|
||||
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-7.12.0.tgz#bf302c265d7c2d6fe79b154a9fd873a80f8b4aa4"
|
||||
dependencies:
|
||||
autoprefixer "^6.0.0"
|
||||
balanced-match "^0.4.0"
|
||||
@ -8677,7 +8706,7 @@ stylelint@^7.0.0, stylelint@^7.0.3, stylelint@^7.11.1:
|
||||
get-stdin "^5.0.0"
|
||||
globby "^6.0.0"
|
||||
globjoin "^0.1.4"
|
||||
html-tags "^1.1.1"
|
||||
html-tags "^2.0.0"
|
||||
ignore "^3.2.0"
|
||||
imurmurhash "^0.1.4"
|
||||
known-css-properties "^0.2.0"
|
||||
@ -9677,7 +9706,7 @@ write-file-stdout@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/write-file-stdout/-/write-file-stdout-0.0.2.tgz#c252d7c7c5b1b402897630e3453c7bfe690d9ca1"
|
||||
|
||||
write-json-file@^2.0.0, write-json-file@^2.1.0:
|
||||
write-json-file@^2.0.0, write-json-file@^2.1.0, write-json-file@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.2.0.tgz#51862506bbb3b619eefab7859f1fd6c6d0530876"
|
||||
dependencies:
|
||||
@ -9696,11 +9725,11 @@ write-pkg@^2.0.0:
|
||||
write-json-file "^2.0.0"
|
||||
|
||||
write-pkg@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.0.1.tgz#f95245805be6f6a4eb1d6c31c43b57226815e6e3"
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.1.0.tgz#030a9994cc9993d25b4e75a9f1a1923607291ce9"
|
||||
dependencies:
|
||||
sort-keys "^1.1.2"
|
||||
write-json-file "^2.0.0"
|
||||
sort-keys "^2.0.0"
|
||||
write-json-file "^2.2.0"
|
||||
|
||||
write@^0.2.1:
|
||||
version "0.2.1"
|
||||
|
Loading…
Reference in New Issue
Block a user