import React, { Fragment } from 'react'; import { set } from 'react-redux-values'; import { Margin } from 'styled-components-spacing'; import { compose } from 'react-apollo'; import { destroy, reset } from 'redux-form'; import ReduxForm from 'declarative-redux-form'; import { connect } from 'react-redux'; import get from 'lodash.get'; import remcalc from 'remcalc'; import { AffinityIcon, Button, Divider, KeyValue } from 'joyent-ui-toolkit'; import Title from '@components/create-instance/title'; import { Rule, Header } from '@components/create-instance/affinity'; import Description from '@components/description'; import { addAffinityRule as validateRule } from '@state/validators'; import { Forms, Values } from '@root/constants'; const { IC_AFF_F_ADD, IC_AFF_F_EDIT } = Forms; const { IC_AFF_V_ADD_OPEN, IC_AFF_V_EDIT_OPEN, IC_AFF_V_AFF } = Values; const RULE_DEFAULTS = { conditional: 'should', placement: 'same', type: 'name', pattern: 'equalling', name: '', value: '' }; export const Affinity = ({ step, expanded, addOpen, editOpen, editingRule, creatingRule, exitingRule, shouldAsyncValidate, handleAsyncValidate, handleCreateAffinityRules, handleRemoveAffinityRule, handleUpdateAffinityRule, handleToggleExpanded, handleCancelEdit, handleChangeAddOpen, handleEdit }) => ( } > Affinity {expanded ? ( Control placement of instances on the physical servers. Design applications to adapt at failure by distributing application components. Instances are only provisioned when the exact criteria is met.{' '} Read the docs ) : null} {formProps => exitingRule ? ( } method="edit" input={inputProps => ( )} type="an affinity rule" onToggleExpanded={() => handleToggleExpanded(!exitingRule.expanded) } onCancel={handleCancelEdit} onRemove={handleRemoveAffinityRule} /> ) : null } {formProps => expanded && addOpen ? ( ( )} type="an affinity rule" expanded noRemove onCancel={() => handleChangeAddOpen(false)} /> ) : null } {expanded ? ( {!addOpen && !exitingRule ? ( ) : null} ) : exitingRule ? ( ) : null} {expanded ? : null} ); export default compose( connect(({ values, form }, ownProps) => { const editingRule = get(form, `${IC_AFF_F_EDIT}.values`, null); const creatingRule = get(form, `${IC_AFF_F_ADD}.values`, null); const exitingRule = get(values, IC_AFF_V_AFF, null); const addOpen = get(values, IC_AFF_V_ADD_OPEN, false); const editOpen = get(values, IC_AFF_V_EDIT_OPEN, false); return { addOpen, editOpen, creatingRule, editingRule, exitingRule }; }), connect(null, (dispatch, { history }) => ({ shouldAsyncValidate: ({ trigger }) => { return trigger === 'submit'; }, handleAsyncValidate: ({ type, ...aff }) => { return type === 'name' ? validateRule({ ...aff, type, name: 'default' }) : validateRule({ ...aff, type }); }, handleEdit: () => { return history.push( `/instances/~create/affinity${history.location.search}` ); }, handleCreateAffinityRules: value => { return dispatch([ destroy(IC_AFF_F_ADD), set({ name: IC_AFF_V_ADD_OPEN, value: false }), set({ name: IC_AFF_V_AFF, value }) ]); }, handleUpdateAffinityRule: value => { return dispatch([ destroy(IC_AFF_F_EDIT), set({ name: IC_AFF_V_EDIT_OPEN, value: false }), set({ name: IC_AFF_V_AFF, value }) ]); }, handleChangeAddOpen: value => { return dispatch([ reset(IC_AFF_F_ADD), set({ name: IC_AFF_V_ADD_OPEN, value }) ]); }, handleToggleExpanded: value => { return dispatch(set({ name: IC_AFF_V_EDIT_OPEN, value })); }, handleCancelEdit: () => { return dispatch([set({ name: IC_AFF_V_EDIT_OPEN, value: false })]); }, handleRemoveAffinityRule: () => { return dispatch([ destroy(IC_AFF_F_EDIT), set({ name: IC_AFF_V_AFF, value: null }) ]); } })) )(Affinity);