fix(my-joy-beta): create instance - affinity ui fixes

fixes #1014
This commit is contained in:
Sara Vieira 2018-01-16 11:23:00 +00:00 committed by Sérgio Ramos
parent 2e3dfb3444
commit 5266b5d485
13 changed files with 67 additions and 50 deletions

View File

@ -10,9 +10,11 @@ Array [
" ", " ",
" node as the instance(s) identified by the instance ", " node as the instance(s) identified by the instance ",
" ", " ",
"key ", "key “",
" “",
"\\" and the instance tag value", "\\" and the instance tag value",
" ",
" ",
"\\"",
"”", "”",
] ]
`; `;
@ -27,9 +29,11 @@ Array [
" ", " ",
" node as the instance(s) identified by the instance ", " node as the instance(s) identified by the instance ",
" ", " ",
"key ", "key “",
" “",
"\\" and the instance tag value", "\\" and the instance tag value",
" ",
" ",
"\\"",
"”", "”",
] ]
`; `;
@ -198,7 +202,7 @@ exports[`renders <Rule/> without throwing 1`] = `
} }
.c4:after { .c4:after {
right: 0rem; right: 0.375rem;
} }
.c7 { .c7 {
@ -231,7 +235,7 @@ exports[`renders <Rule/> without throwing 1`] = `
} }
.c7:after { .c7:after {
right: 0rem; right: 0.375rem;
} }
.c6 { .c6 {
@ -664,7 +668,7 @@ exports[`renders <Rule/> without throwing 2`] = `
} }
.c4:after { .c4:after {
right: 0rem; right: 0.375rem;
} }
.c7 { .c7 {
@ -697,7 +701,7 @@ exports[`renders <Rule/> without throwing 2`] = `
} }
.c7:after { .c7:after {
right: 0rem; right: 0.375rem;
} }
.c6 { .c6 {

View File

@ -27,7 +27,6 @@ it('renders <Rule/> without throwing', () => {
'rule-instance-name': 'test', 'rule-instance-name': 'test',
'rule-instance-conditional': 'must', 'rule-instance-conditional': 'must',
'rule-instance-placement': 'same', 'rule-instance-placement': 'same',
'rule-instance-tag-key-pattern': 'equalling',
'rule-instance-tag-value-pattern': 'equalling', 'rule-instance-tag-value-pattern': 'equalling',
'rule-instance-name-pattern': 'equalling', 'rule-instance-name-pattern': 'equalling',
'rule-instance-tag-value': '', 'rule-instance-tag-value': '',
@ -51,7 +50,6 @@ it('renders <Header /> without throwing', () => {
'rule-instance-name': 'test', 'rule-instance-name': 'test',
'rule-instance-conditional': 'must', 'rule-instance-conditional': 'must',
'rule-instance-placement': 'same', 'rule-instance-placement': 'same',
'rule-instance-tag-key-pattern': 'equalling',
'rule-instance-tag-value-pattern': 'equalling', 'rule-instance-tag-value-pattern': 'equalling',
'rule-instance-name-pattern': 'equalling', 'rule-instance-name-pattern': 'equalling',
'rule-instance-tag-value': '', 'rule-instance-tag-value': '',
@ -75,7 +73,6 @@ it('renders <Header tag/> without throwing', () => {
'rule-instance-name': 'test', 'rule-instance-name': 'test',
'rule-instance-conditional': 'must', 'rule-instance-conditional': 'must',
'rule-instance-placement': 'same', 'rule-instance-placement': 'same',
'rule-instance-tag-key-pattern': 'equalling',
'rule-instance-tag-value-pattern': 'equalling', 'rule-instance-tag-value-pattern': 'equalling',
'rule-instance-name-pattern': 'equalling', 'rule-instance-name-pattern': 'equalling',
'rule-instance-tag-value': 'one', 'rule-instance-tag-value': 'one',

View File

@ -1,3 +1,5 @@
/* eslint-disable camelcase */
import React from 'react'; import React from 'react';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
import 'jest-styled-components'; import 'jest-styled-components';

View File

@ -7,9 +7,9 @@ import titleCase from 'title-case';
import { H5, Select, Input, FormGroup } from 'joyent-ui-toolkit'; import { H5, Select, Input, FormGroup } from 'joyent-ui-toolkit';
const Values = ( const Values = touched => (
<Margin right={1}> <Margin right={1}>
<Select embedded> <Select embedded touched={touched}>
<option value="equalling">equalling</option> <option value="equalling">equalling</option>
<option value="not-equalling">not equalling</option> <option value="not-equalling">not equalling</option>
<option value="containing">containing</option> <option value="containing">containing</option>
@ -26,7 +26,7 @@ export const Rule = rule => (
The instance The instance
</H5> </H5>
<FormGroup name="rule-instance-conditional" field={Field}> <FormGroup name="rule-instance-conditional" field={Field}>
<Select embedded> <Select embedded touched={rule['rule-instance-conditional']}>
<option value="must">must</option> <option value="must">must</option>
<option value="should">should</option> <option value="should">should</option>
</Select> </Select>
@ -35,7 +35,7 @@ export const Rule = rule => (
be on be on
</H5> </H5>
<FormGroup name="rule-instance-placement" field={Field}> <FormGroup name="rule-instance-placement" field={Field}>
<Select embedded> <Select embedded touched={rule['rule-instance-placement']}>
<option value="same">the same</option> <option value="same">the same</option>
<option value="different">a different</option> <option value="different">a different</option>
</Select> </Select>
@ -44,7 +44,7 @@ export const Rule = rule => (
node as the instance(s) identified by the node as the instance(s) identified by the
</H5> </H5>
<FormGroup name="rule-type" field={Field}> <FormGroup name="rule-type" field={Field}>
<Select embedded left> <Select embedded left touched={rule['rule-type']}>
<option value="name">instance name</option> <option value="name">instance name</option>
<option value="tag">tag</option> <option value="tag">tag</option>
</Select> </Select>
@ -58,7 +58,7 @@ export const Rule = rule => (
and value{' '} and value{' '}
</H5> </H5>
<FormGroup name="rule-instance-tag-value-pattern" field={Field}> <FormGroup name="rule-instance-tag-value-pattern" field={Field}>
{Values} {Values(rule['rule-instance-tag-value-pattern'])}
</FormGroup> </FormGroup>
<FormGroup name="rule-instance-tag-value" field={Field}> <FormGroup name="rule-instance-tag-value" field={Field}>
<Input small embedded type="text" required placeholder="value" /> <Input small embedded type="text" required placeholder="value" />
@ -67,7 +67,7 @@ export const Rule = rule => (
) : ( ) : (
<Fragment> <Fragment>
<FormGroup name="rule-instance-name-pattern" field={Field}> <FormGroup name="rule-instance-name-pattern" field={Field}>
{Values} {Values(rule['rule-instance-name-pattern'])}
</FormGroup> </FormGroup>
<FormGroup name="rule-instance-name" field={Field}> <FormGroup name="rule-instance-name" field={Field}>
<Input <Input
@ -96,9 +96,10 @@ export const Header = rule => (
) : ( ) : (
<Fragment> <Fragment>
{' '} {' '}
key {rule['rule-instance-tag-key-pattern']} {rule['rule-instance-tag-key']}" key {rule['rule-instance-tag-key']}" and the instance tag value{' '}
and the instance tag value {rule['rule-instance-tag-value-pattern']} {rule['rule-instance-tag-value-pattern'] &&
{rule['rule-instance-tag-value']} rule['rule-instance-tag-value-pattern'].split('-').join(' ')}{' '}
"{rule['rule-instance-tag-value']}
</Fragment> </Fragment>
)} )}
</Fragment> </Fragment>

View File

@ -1,3 +1,5 @@
/* eslint-disable camelcase */
import React from 'react'; import React from 'react';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
import 'jest-styled-components'; import 'jest-styled-components';

View File

@ -8,7 +8,7 @@ import { connect } from 'react-redux';
import get from 'lodash.get'; import get from 'lodash.get';
import remcalc from 'remcalc'; import remcalc from 'remcalc';
import { AffinityIcon, P, Button, H3, Divider } from 'joyent-ui-toolkit'; import { AffinityIcon, Button, H3, Divider } from 'joyent-ui-toolkit';
import Title from '@components/create-instance/title'; import Title from '@components/create-instance/title';
import { Rule, Header } from '@components/create-instance/affinity'; import { Rule, Header } from '@components/create-instance/affinity';
@ -49,12 +49,12 @@ export const Affinity = ({
<Title icon={<AffinityIcon />}>Affinity</Title> <Title icon={<AffinityIcon />}>Affinity</Title>
{expanded ? ( {expanded ? (
<Description> <Description>
Affinity rules control the location of instances, to help reduce traffic Control placement of instances on the physical servers. Design
across networks and keep the workload balanced. With strict rules, applications to adapt at failure by distributing application components.
instances are only provisioned when the criteria is met.{' '} Instances are only provisioned when the exact criteria is met.{' '}
<a <a
target="__blank" target="__blank"
href="https://apidocs.joyent.com/docker/features/placement" href="https://docs.joyent.com/public-cloud/instances/docker/how/start-containers#controlling-container-placement"
> >
Read the docs Read the docs
</a> </a>
@ -62,9 +62,7 @@ export const Affinity = ({
) : null} ) : null}
{proceeded ? ( {proceeded ? (
<Margin bottom={4}> <Margin bottom={4}>
<H3> <H3>{affinityRules.length} Affinity Rule</H3>
{affinityRules.length} Affinity Rule{affinityRules.length === 1 ? '' : 's'}
</H3>
</Margin> </Margin>
) : null} ) : null}
{affinityRules.map((rule, index) => ( {affinityRules.map((rule, index) => (
@ -114,6 +112,7 @@ export const Affinity = ({
<div> <div>
{expanded ? ( {expanded ? (
<Fragment> <Fragment>
{affinityRules.length === 0 ? (
<Button <Button
type="button" type="button"
onClick={() => handleChangeAddOpen(true)} onClick={() => handleChangeAddOpen(true)}
@ -121,6 +120,7 @@ export const Affinity = ({
> >
Create affinity rule Create affinity rule
</Button> </Button>
) : null}
<Margin top={2} bottom={4}> <Margin top={2} bottom={4}>
<Button type="submit" onClick={handleNext}> <Button type="submit" onClick={handleNext}>
Next Next

View File

@ -1,3 +1,5 @@
/* eslint-disable camelcase */
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { compose, graphql } from 'react-apollo'; import { compose, graphql } from 'react-apollo';
import { Margin } from 'styled-components-spacing'; import { Margin } from 'styled-components-spacing';
@ -108,7 +110,7 @@ export default compose(
} }
}), }),
props: ({ ownProps, data }) => { props: ({ ownProps, data }) => {
const { enabled, showInactive, tags = [] } = ownProps; const { enabled, showInactive } = ownProps;
const { const {
firewall_rules_create_machine = [], firewall_rules_create_machine = [],

View File

@ -1,3 +1,5 @@
/* eslint-disable camelcase */
import React from 'react'; import React from 'react';
import { Margin } from 'styled-components-spacing'; import { Margin } from 'styled-components-spacing';
import ReduxForm from 'declarative-redux-form'; import ReduxForm from 'declarative-redux-form';
@ -24,6 +26,8 @@ import Affinity from '@containers/create-instance/affinity';
import CreateInstanceMutation from '@graphql/create-instance.gql'; import CreateInstanceMutation from '@graphql/create-instance.gql';
import parseError from '@state/parse-error'; import parseError from '@state/parse-error';
const CREATE_FORM = 'CREATE-INSTANCE';
const CreateInstance = ({ step, handleSubmit, ...props }) => ( const CreateInstance = ({ step, handleSubmit, ...props }) => (
<ViewContainer> <ViewContainer>
<Margin top={4} bottom={4}> <Margin top={4} bottom={4}>
@ -57,7 +61,7 @@ const CreateInstance = ({ step, handleSubmit, ...props }) => (
<Affinity {...props} expanded={step === 'affinity'} /> <Affinity {...props} expanded={step === 'affinity'} />
</Margin> </Margin>
<Margin top={7} bottom={10}> <Margin top={7} bottom={10}>
<ReduxForm form="create-instance" onSubmit={handleSubmit}> <ReduxForm form={CREATE_FORM} onSubmit={handleSubmit}>
{({ handleSubmit, submitting }) => ( {({ handleSubmit, submitting }) => (
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<Button disabled={step !== 'summary'} loading={submitting}> <Button disabled={step !== 'summary'} loading={submitting}>
@ -134,12 +138,13 @@ export default compose(
`${conditional}_${placement === 'same' ? 'equal' : 'not_equal'}` `${conditional}_${placement === 'same' ? 'equal' : 'not_equal'}`
); );
console.log(pattern);
const patterns = { const patterns = {
equalling: value => value, equalling: value => value,
'not-equalling': `/^!${value}$/`, 'not-equalling': value => `/^!${value}$/`,
containing: `/${value}/`, containing: value => `/${value}/`,
starting: `/^${value}/`, starting: value => `/^${value}/`,
ending: `/${value}$/` ending: value => `/${value}$/`
}; };
const _key = identity === 'name' ? 'instance' : key; const _key = identity === 'name' ? 'instance' : key;
@ -198,7 +203,7 @@ export default compose(
if (err) { if (err) {
return dispatch( return dispatch(
stopSubmit(TABLE_FORM_NAME, { stopSubmit(CREATE_FORM, {
_error: parseError(err) _error: parseError(err)
}) })
); );

View File

@ -7,7 +7,7 @@ import ReduxForm from 'declarative-redux-form';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import get from 'lodash.get'; import get from 'lodash.get';
import { MetadataIcon, P, Button, H3 } from 'joyent-ui-toolkit'; import { MetadataIcon, Button, H3 } from 'joyent-ui-toolkit';
import Title from '@components/create-instance/title'; import Title from '@components/create-instance/title';
import Description from '@components/create-instance/description'; import Description from '@components/create-instance/description';

View File

@ -6,7 +6,7 @@ import { connect } from 'react-redux';
import get from 'lodash.get'; import get from 'lodash.get';
import forceArray from 'force-array'; import forceArray from 'force-array';
import { NetworkIcon, P, Button, H3, StatusLoader } from 'joyent-ui-toolkit'; import { NetworkIcon, Button, H3, StatusLoader } from 'joyent-ui-toolkit';
import Description from '@components/create-instance/description'; import Description from '@components/create-instance/description';
import Title from '@components/create-instance/title'; import Title from '@components/create-instance/title';

View File

@ -9,7 +9,7 @@ import sortBy from 'lodash.sortby';
import find from 'lodash.find'; import find from 'lodash.find';
import constantCase from 'constant-case'; import constantCase from 'constant-case';
import { PackageIcon, StatusLoader, P } from 'joyent-ui-toolkit'; import { PackageIcon, StatusLoader } from 'joyent-ui-toolkit';
import { import {
Filters, Filters,
Packages, Packages,

View File

@ -7,7 +7,7 @@ import ReduxForm from 'declarative-redux-form';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import get from 'lodash.get'; import get from 'lodash.get';
import { TagsIcon, P, Button, H3, TagList } from 'joyent-ui-toolkit'; import { TagsIcon, Button, H3, TagList } from 'joyent-ui-toolkit';
import Title from '@components/create-instance/title'; import Title from '@components/create-instance/title';
import Tag from '@components/instances/tags'; import Tag from '@components/instances/tags';

View File

@ -41,7 +41,7 @@ const SelectWrapper = styled.div`
margin: 0 ${remcalc(6)}; margin: 0 ${remcalc(6)};
min-width: 0; min-width: 0;
&:after { &:after {
right: ${remcalc(0)}; right: ${remcalc(6)};
} }
`}; `};
@ -83,6 +83,10 @@ const StyledSelect = select.extend`
margin: 0 ${remcalc(6)}; margin: 0 ${remcalc(6)};
`}; `};
${is('embedded', 'touched')`
color: ${props => props.theme.text};
`}
${is('wrapped')` ${is('wrapped')`
margin: 0; margin: 0;
border: none; border: none;