2017-11-09 13:27:32 +02:00
|
|
|
import React, { PureComponent } from 'react';
|
2017-12-06 20:16:11 +02:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { withTheme } from 'styled-components';
|
2017-09-20 12:30:53 +03:00
|
|
|
import { Row, Col } from 'react-styled-flexboxgrid';
|
2017-09-27 17:24:40 +03:00
|
|
|
import { Field } from 'redux-form';
|
2017-11-09 13:27:32 +02:00
|
|
|
import styled from 'styled-components';
|
|
|
|
import remcalc from 'remcalc';
|
|
|
|
import titleCase from 'title-case';
|
2017-12-21 21:20:22 +02:00
|
|
|
import { Padding } from 'styled-components-spacing';
|
2017-12-06 20:16:11 +02:00
|
|
|
import Flex, { FlexItem } from 'styled-flex-component';
|
2017-11-23 14:18:38 +02:00
|
|
|
import Editor from 'joyent-ui-toolkit/dist/es/editor';
|
2017-09-20 12:30:53 +03:00
|
|
|
|
|
|
|
import {
|
2017-11-09 13:27:32 +02:00
|
|
|
Message,
|
|
|
|
MessageDescription,
|
2017-12-06 17:35:22 +02:00
|
|
|
H4,
|
2017-11-09 13:27:32 +02:00
|
|
|
MessageTitle,
|
|
|
|
Card,
|
|
|
|
CardHeader,
|
|
|
|
CardHeaderMeta,
|
|
|
|
CardOutlet,
|
2017-09-20 12:30:53 +03:00
|
|
|
FormGroup,
|
2017-12-06 17:35:22 +02:00
|
|
|
FormLabel,
|
2017-09-20 12:30:53 +03:00
|
|
|
Input,
|
2017-11-09 13:27:32 +02:00
|
|
|
FormMeta,
|
2017-09-20 12:30:53 +03:00
|
|
|
Button,
|
2017-11-09 13:27:32 +02:00
|
|
|
Textarea,
|
2017-12-06 20:16:11 +02:00
|
|
|
Divider,
|
|
|
|
DeleteIcon
|
2017-09-20 12:30:53 +03:00
|
|
|
} from 'joyent-ui-toolkit';
|
|
|
|
|
2018-01-04 17:52:56 +02:00
|
|
|
const CollapsedKeyValue = styled.div`
|
2017-11-09 13:27:32 +02:00
|
|
|
word-break: break-all;
|
|
|
|
line-height: 1.5;
|
|
|
|
white-space: nowrap;
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
display: block;
|
|
|
|
`;
|
2017-09-20 12:30:53 +03:00
|
|
|
|
2017-11-09 13:27:32 +02:00
|
|
|
class ValueTextareaField extends PureComponent {
|
|
|
|
render() {
|
2017-12-21 21:20:22 +02:00
|
|
|
const { input = {}, submitting } = this.props;
|
2017-09-27 17:24:40 +03:00
|
|
|
|
2017-11-09 13:27:32 +02:00
|
|
|
return input.value === 'user-script' ? (
|
|
|
|
<Field name="value" component={Editor} />
|
|
|
|
) : (
|
|
|
|
<Textarea resize="vertical" disabled={submitting} fluid />
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-06 20:16:11 +02:00
|
|
|
const TextareaKeyValue = ({ type, submitting }) => [
|
|
|
|
<Row key="key">
|
|
|
|
<Col xs={12}>
|
2017-12-21 21:20:22 +02:00
|
|
|
<FormGroup name="name" field={Field} fluid>
|
2017-12-06 20:16:11 +02:00
|
|
|
<FormLabel>{titleCase(type)} key</FormLabel>
|
|
|
|
<Input type="text" disabled={submitting} />
|
|
|
|
<FormMeta />
|
|
|
|
</FormGroup>
|
|
|
|
<Divider height={remcalc(12)} transparent />
|
|
|
|
</Col>
|
|
|
|
</Row>,
|
|
|
|
<Row key="value">
|
|
|
|
<Col xs={12}>
|
2017-12-21 21:20:22 +02:00
|
|
|
<FormGroup name="value" field={Field} fluid>
|
2017-12-06 20:16:11 +02:00
|
|
|
<FormLabel>{titleCase(type)} value</FormLabel>
|
|
|
|
<Field
|
|
|
|
name="name"
|
|
|
|
fluid
|
|
|
|
component={ValueTextareaField}
|
|
|
|
props={{ submitting }}
|
|
|
|
/>
|
|
|
|
<FormMeta />
|
|
|
|
</FormGroup>
|
|
|
|
<Divider height={remcalc(12)} transparent />
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
];
|
2017-11-09 13:27:32 +02:00
|
|
|
|
2017-12-06 20:16:11 +02:00
|
|
|
const InputKeyValue = ({ type, submitting }) => (
|
2017-12-22 16:37:57 +02:00
|
|
|
<Flex justifyStart contentStretch>
|
2017-12-06 20:16:11 +02:00
|
|
|
<FlexItem basis="auto">
|
2017-12-21 21:20:22 +02:00
|
|
|
<FormGroup name="name" field={Field} fluid>
|
2017-12-06 20:16:11 +02:00
|
|
|
<FormLabel>{titleCase(type)} key</FormLabel>
|
|
|
|
<Input type="text" disabled={submitting} />
|
|
|
|
<FormMeta />
|
|
|
|
</FormGroup>
|
|
|
|
</FlexItem>
|
2017-12-21 21:20:22 +02:00
|
|
|
<FlexItem basis={remcalc(12)} />
|
2017-12-06 20:16:11 +02:00
|
|
|
<FlexItem basis="auto">
|
2017-12-21 21:20:22 +02:00
|
|
|
<FormGroup name="value" field={Field} fluid>
|
2017-12-06 20:16:11 +02:00
|
|
|
<FormLabel>{titleCase(type)} value</FormLabel>
|
|
|
|
<Input disabled={submitting} />
|
|
|
|
<FormMeta />
|
|
|
|
</FormGroup>
|
|
|
|
</FlexItem>
|
|
|
|
</Flex>
|
|
|
|
);
|
2017-11-09 13:27:32 +02:00
|
|
|
|
2018-01-05 17:42:09 +02:00
|
|
|
const InputName = ({ type, submitting }) => (
|
|
|
|
<Flex justifyStart contentStretch>
|
|
|
|
<FlexItem basis="auto">
|
|
|
|
<FormGroup name="name" field={Field} fluid>
|
|
|
|
<FormLabel>{titleCase(type)} Name</FormLabel>
|
|
|
|
<Input type="text" disabled={submitting} />
|
|
|
|
<FormMeta />
|
|
|
|
</FormGroup>
|
|
|
|
</FlexItem>
|
|
|
|
</Flex>
|
|
|
|
);
|
|
|
|
|
2017-12-21 21:20:22 +02:00
|
|
|
export const KeyValue = ({
|
|
|
|
input = 'input',
|
|
|
|
type = 'metadata',
|
|
|
|
method = 'add',
|
2018-01-04 12:56:10 +02:00
|
|
|
initialValues = {},
|
2017-12-21 21:20:22 +02:00
|
|
|
error = null,
|
|
|
|
expanded = true,
|
|
|
|
submitting = false,
|
|
|
|
pristine = true,
|
|
|
|
removing = false,
|
|
|
|
handleSubmit,
|
|
|
|
onToggleExpanded = () => null,
|
|
|
|
onCancel = () => null,
|
|
|
|
onRemove = () => null,
|
2018-01-05 17:42:09 +02:00
|
|
|
theme = {},
|
|
|
|
onlyName = false,
|
|
|
|
noRemove = false
|
2017-12-21 21:20:22 +02:00
|
|
|
}) => {
|
|
|
|
const handleHeaderClick = method === 'edit' && onToggleExpanded;
|
2017-11-09 13:27:32 +02:00
|
|
|
|
2017-12-21 21:20:22 +02:00
|
|
|
return (
|
|
|
|
<Card collapsed={!expanded} actionable={!expanded} shadow>
|
|
|
|
<CardHeader
|
|
|
|
secondary={false}
|
|
|
|
transparent={false}
|
|
|
|
actionable={Boolean(handleHeaderClick)}
|
|
|
|
onClick={handleHeaderClick}
|
|
|
|
>
|
|
|
|
<CardHeaderMeta>
|
2018-01-05 17:42:09 +02:00
|
|
|
{method === 'add' || method === 'create' ? (
|
2017-12-21 21:20:22 +02:00
|
|
|
<H4>{`${titleCase(method)} ${type}`}</H4>
|
|
|
|
) : (
|
|
|
|
<CollapsedKeyValue>
|
2018-01-04 17:52:56 +02:00
|
|
|
{expanded ? (
|
|
|
|
<span>{`${initialValues.name}: `}</span>
|
|
|
|
) : (
|
|
|
|
<b>{`${initialValues.name}: `}</b>
|
|
|
|
)}
|
2018-01-04 12:56:10 +02:00
|
|
|
<span>{initialValues.value}</span>
|
2017-12-21 21:20:22 +02:00
|
|
|
</CollapsedKeyValue>
|
|
|
|
)}
|
|
|
|
</CardHeaderMeta>
|
|
|
|
</CardHeader>
|
2017-12-21 02:12:42 +02:00
|
|
|
{expanded ? (
|
|
|
|
<CardOutlet>
|
|
|
|
<Padding all={1}>
|
|
|
|
{error && !submitting ? (
|
|
|
|
<Row>
|
|
|
|
<Col xs={12}>
|
|
|
|
<Message error>
|
|
|
|
<MessageTitle>Ooops!</MessageTitle>
|
|
|
|
<MessageDescription>{error}</MessageDescription>
|
|
|
|
</Message>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
) : null}
|
|
|
|
{input === 'input' ? (
|
2018-01-05 17:42:09 +02:00
|
|
|
onlyName ? (
|
|
|
|
<InputName type={type} submitting={submitting} />
|
|
|
|
) : (
|
|
|
|
<InputKeyValue type={type} submitting={submitting} />
|
|
|
|
)
|
2017-12-21 02:12:42 +02:00
|
|
|
) : (
|
|
|
|
<TextareaKeyValue type={type} submitting={submitting} />
|
|
|
|
)}
|
|
|
|
<Row between="xs" middle="xs">
|
|
|
|
<Col xs={method === 'add' ? 12 : 7}>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
onClick={onCancel}
|
|
|
|
disabled={submitting}
|
|
|
|
secondary
|
|
|
|
marginless
|
|
|
|
>
|
|
|
|
<span>Cancel</span>
|
|
|
|
</Button>
|
|
|
|
<Button
|
|
|
|
type="submit"
|
|
|
|
disabled={pristine}
|
|
|
|
loading={submitting && !removing}
|
|
|
|
marginless
|
|
|
|
>
|
|
|
|
<span>{method === 'add' ? 'Create' : 'Save'}</span>
|
|
|
|
</Button>
|
2017-12-21 21:20:22 +02:00
|
|
|
</Col>
|
2018-01-05 17:42:09 +02:00
|
|
|
{!noRemove && (
|
|
|
|
<Col xs={method === 'add' ? false : 5}>
|
|
|
|
<Button
|
|
|
|
type="button"
|
|
|
|
onClick={onRemove}
|
2017-12-21 02:12:42 +02:00
|
|
|
disabled={submitting}
|
2018-01-05 17:42:09 +02:00
|
|
|
loading={removing}
|
|
|
|
secondary
|
|
|
|
right
|
|
|
|
icon
|
|
|
|
error
|
|
|
|
marginless
|
|
|
|
>
|
|
|
|
<DeleteIcon
|
|
|
|
disabled={submitting}
|
|
|
|
fill={submitting ? undefined : theme.red}
|
|
|
|
/>
|
|
|
|
<span>Delete</span>
|
|
|
|
</Button>
|
|
|
|
</Col>
|
|
|
|
)}
|
2017-12-21 02:12:42 +02:00
|
|
|
</Row>
|
|
|
|
</Padding>
|
|
|
|
</CardOutlet>
|
|
|
|
) : null}
|
2017-12-21 21:20:22 +02:00
|
|
|
</Card>
|
|
|
|
);
|
|
|
|
};
|
2017-11-09 13:27:32 +02:00
|
|
|
|
2017-12-06 20:16:11 +02:00
|
|
|
KeyValue.propTypes = {
|
|
|
|
input: PropTypes.oneOf(['input', 'textarea']).isRequired,
|
|
|
|
type: PropTypes.string.isRequired,
|
|
|
|
method: PropTypes.oneOf(['add', 'edit']).isRequired,
|
2018-01-04 12:56:10 +02:00
|
|
|
initialValues: PropTypes.shape({
|
|
|
|
name: PropTypes.string,
|
|
|
|
value: PropTypes.string
|
|
|
|
}).isRequired,
|
2017-12-06 20:16:11 +02:00
|
|
|
removing: PropTypes.bool.isRequired,
|
|
|
|
expanded: PropTypes.bool.isRequired,
|
|
|
|
onToggleExpanded: PropTypes.func,
|
|
|
|
onCancel: PropTypes.func,
|
|
|
|
onRemove: PropTypes.func
|
2017-11-09 13:27:32 +02:00
|
|
|
};
|
2017-09-27 17:24:40 +03:00
|
|
|
|
2017-12-21 21:20:22 +02:00
|
|
|
export default withTheme(({ handleSubmit, ...rest }) => (
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
|
|
<KeyValue {...rest} />
|
|
|
|
<Divider height={remcalc(13)} transparent />
|
|
|
|
</form>
|
|
|
|
));
|