import React, { Fragment } from 'react'; import { Margin } from 'styled-components-spacing'; import { compose } from 'react-apollo'; import { Link } from 'react-router-dom'; import ReduxForm from 'declarative-redux-form'; import { connect } from 'react-redux'; import { set } from 'react-redux-values'; import { reset } from 'redux-form'; import { destroy } from 'redux-form'; import get from 'lodash.get'; import Step, { Header as StepHeader, Description as StepDescription, Preview as StepPreview, Outlet as StepOutlet } from 'joyent-ui-resource-step'; import { AffinityIcon, Button } from 'joyent-ui-toolkit'; import { KeyValue } from 'joyent-ui-resource-widgets'; import { Rule, Header } from './components'; import { addAffinityRule as validateRule } from '../validators'; import { Forms, Values } from '../constants'; const { IR_AFF_F_ADD, IR_AFF_F_EDIT } = Forms; const { IR_AFF_V_ADD_OPEN, IR_AFF_V_EDIT_OPEN, IR_AFF_V_AFF } = Values; const RULE_DEFAULTS = { conditional: 'should', placement: 'same', type: 'name', pattern: 'equalling', name: '', value: '' }; const Preview = ({ handleAsyncValidate, shouldAsyncValidate, handleCancelEdit, handleRemoveAffinityRule, handleUpdateAffinityRule, handleToggleExpanded, editOpen = true, editingRule, exitingRule, disabled = false }) => ( {formProps => exitingRule ? ( } method="edit" input={inputProps => ( )} type="an affinity rule" onCancel={handleCancelEdit} onRemove={handleRemoveAffinityRule} onToggleExpanded={ handleToggleExpanded && (() => handleToggleExpanded(!editOpen)) } disabled={disabled} /> ) : null } ); const Affinity = ({ handleGetValue, handleAsyncValidate, shouldAsyncValidate, handleCancelEdit, handleChangeAddOpen, handleCreateAffinityRules, handleRemoveAffinityRule, handleToggleExpanded, handleUpdateAffinityRule, preview = [], addOpen = true, editOpen = true, creatingRule, editingRule, exitingRule, ...props }) => ( }>Affinity rules Affinity rules control the location of instances, to help reduce traffic across networks and keep the workload balanced. With strict rules, instances are only provisioned when the criteria is met. {({ next }) => ( {formProps => addOpen ? ( ( )} type="an affinity rule" noRemove borderless headless id="affinity" onCancel={() => handleChangeAddOpen(false)} /> ) : null } {!addOpen && !exitingRule ? ( ) : null} {!addOpen && exitingRule ? ( ) : null} )} ); export default compose( connect(({ values, form }, ownProps) => { const editingRule = get(form, `${IR_AFF_F_EDIT}.values`, null); const creatingRule = get(form, `${IR_AFF_F_ADD}.values`, null); const exitingRule = get(values, IR_AFF_V_AFF, null); const addOpen = get(values, IR_AFF_V_ADD_OPEN, true); const editOpen = get(values, IR_AFF_V_EDIT_OPEN, false); return { addOpen, editOpen, creatingRule, editingRule, exitingRule, handleGetValue: () => exitingRule }; }), connect(null, (dispatch, { history }) => ({ shouldAsyncValidate: ({ trigger }) => { return trigger === 'submit'; }, handleAsyncValidate: ({ type, ...aff }) => { return type === 'name' ? validateRule({ ...aff, type, name: 'default' }) : validateRule({ ...aff, type }); }, handleCreateAffinityRules: value => { return dispatch([ destroy(IR_AFF_F_ADD), set({ name: IR_AFF_V_ADD_OPEN, value: false }), set({ name: IR_AFF_V_AFF, value }) ]); }, handleUpdateAffinityRule: value => { return dispatch([ destroy(IR_AFF_F_EDIT), set({ name: IR_AFF_V_EDIT_OPEN, value: false }), set({ name: IR_AFF_V_AFF, value }) ]); }, handleChangeAddOpen: value => { return dispatch([ reset(IR_AFF_F_ADD), set({ name: IR_AFF_V_ADD_OPEN, value }) ]); }, handleToggleExpanded: value => { return dispatch(set({ name: IR_AFF_V_EDIT_OPEN, value })); }, handleCancelEdit: () => { return dispatch([set({ name: IR_AFF_V_EDIT_OPEN, value: false })]); }, handleRemoveAffinityRule: () => { return dispatch([ destroy(IR_AFF_F_EDIT), set({ name: IR_AFF_V_AFF, value: null }) ]); } })) )(Affinity);