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);