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 { MetadataIcon, Button, H3, Divider, KeyValue } from 'joyent-ui-toolkit'; import Editor from 'joyent-ui-toolkit/dist/es/editor'; import Title from '@components/create-instance/title'; import Description from '@components/description'; const FORM_NAME_CREATE = 'CREATE-INSTANCE-METADATA-ADD'; const FORM_NAME_EDIT = i => `CREATE-INSTANCE-METADATA-EDIT-${i}`; export const Metadata = ({ id, step, metadata = [], expanded, proceeded, addOpen, handleAddMetadata, handleRemoveMetadata, handleUpdateMetadata, handleToggleExpanded, handleCancelEdit, handleChangeAddOpen, handleNext, handleEdit, shouldAsyncValidate, asyncValidate }) => ( } > Metadata {expanded ? ( Metadata can be used to pass data to the instance. It can also be used to inject a custom boot script. Unlike tags, metadata is only viewable inside the instance.{' '} Read the docs ) : null} {proceeded || expanded ? (

{metadata.length} key—value pair{metadata.length === 1 ? '' : 's'}

) : null} {metadata.map(({ name, value, open }, index) => ( handleUpdateMetadata(index, newValue)} shouldAsyncValidate={shouldAsyncValidate} asyncValidate={asyncValidate} > {props => ( expanded ? handleToggleExpanded(index) : null } onCancel={() => handleCancelEdit(index)} onRemove={() => handleRemoveMetadata(index)} editor={Editor} /> )} ))} {props => expanded && addOpen ? ( handleChangeAddOpen(false)} editor={Editor} expanded /> ) : null } {expanded ? ( ) : proceeded ? ( ) : null}
); export default compose( connect(({ values }, ownProps) => { const proceeded = get(values, 'create-instance-metadata-proceeded', false); const addOpen = get(values, 'create-instance-metadata-add-open', false); const metadata = get(values, 'create-instance-metadata', []); return { proceeded: proceeded || metadata.length, addOpen, metadata }; }), connect(null, (dispatch, { metadata = [], history }) => ({ handleNext: () => { dispatch( set({ name: 'create-instance-metadata-proceeded', value: true }) ); return history.push(`/~create/user-script${history.location.search}`); }, handleEdit: () => { return history.push(`/~create/metadata${history.location.search}`); }, shouldAsyncValidate: ({ trigger }) => { return trigger === 'submit'; }, asyncValidate: async ({ name = '', value = '' }) => { const isNameInvalid = name.length === 0; const isValueInvalid = value.length === 0; if (!isNameInvalid && !isValueInvalid) { return; } throw { name: isNameInvalid, value: isValueInvalid }; }, handleAddMetadata: value => { const toggleToClosed = set({ name: `create-instance-metadata-add-open`, value: false }); const appendMetadata = set({ name: `create-instance-metadata`, value: metadata.concat([{ ...value, open: false }]) }); return dispatch([ destroy(FORM_NAME_CREATE), toggleToClosed, appendMetadata ]); }, handleUpdateMetadata: (index, newMetadata) => { metadata[index] = { ...newMetadata, open: false }; return dispatch([ destroy(FORM_NAME_EDIT(index)), set({ name: `create-instance-metadata`, value: metadata.slice() }) ]); }, handleChangeAddOpen: value => { return dispatch([ reset(FORM_NAME_CREATE), set({ name: `create-instance-metadata-add-open`, value }) ]); }, handleToggleExpanded: index => { metadata[index] = { ...metadata[index], open: !metadata[index].open }; return dispatch( set({ name: `create-instance-metadata`, value: metadata.slice() }) ); }, handleCancelEdit: index => { metadata[index] = { ...metadata[index], open: false }; return dispatch([ reset(FORM_NAME_EDIT(index)), set({ name: `create-instance-metadata`, value: metadata.slice() }) ]); }, handleRemoveMetadata: index => { metadata.splice(index, 1); return dispatch([ destroy(FORM_NAME_EDIT(index)), set({ name: `create-instance-metadata`, value: metadata.slice() }) ]); } })) )(Metadata);