Commit f541041d authored by Roman's avatar Roman

BRCD-1683 feta(RangeField) - added new field type 'Range' can be multi

parent 5d9eb722
......@@ -97,6 +97,7 @@ class CustomField extends Component {
};
getFieldType = field => (field.get('type', '') === '' ? 'text' : field.get('type', ''));
isBoolean = field => this.getFieldType(field) === 'boolean';
getPlayOptions = () => (this.props.availablePlays.map(play => ({
......@@ -114,10 +115,10 @@ class CustomField extends Component {
const showPlays = ['subscriber'].includes(entity) && playsOptions.length > 1;
const plays = field.get('plays', []).join(',');
const disableUnique = isBoolean || !this.hasEditableField('unique');
const disableUnique = ['boolean', 'ranges'].includes(this.getFieldType(field)) || !this.hasEditableField('unique');
const disableMandatory = isBoolean || field.get('unique', false) || !this.hasEditableField('mandatory');
const disableBoolean = field.get('select_list', false) || field.get('unique', false);
const disableMultiple = this.getFieldType(field) !== 'text' || !this.hasEditableField('multiple');
const disableMultiple = ['boolean', 'textarea'].includes(this.getFieldType(field)) || !this.hasEditableField('multiple');
const disableSearchable = isBoolean || !this.hasEditableField('searchable');
const disableSelectList = this.getFieldType(field) !== 'text' || !this.hasEditableField('select_list');
const disableSelectOptions = !field.get('select_list', false) || !this.hasEditableField('select_options');
......@@ -125,6 +126,7 @@ class CustomField extends Component {
{ value: 'text', label: 'Text' }, // must be first because text is default option
{ value: 'boolean', label: 'Boolean' },
{ value: 'textarea', label: 'Text Area' },
{ value: 'ranges', label: 'Range' },
];
return (
<ModalWrapper show={showAdvancedEdit} onOk={this.onCloseModal} title={modalTitle}>
......@@ -155,7 +157,7 @@ class CustomField extends Component {
className="inline mr10"
/>
{disableUnique && (
<small style={{ color: '#626262' }}>Unique field can not be boolean</small>
<small style={{ color: '#626262' }}>Unique field can not be boolean or of type range</small>
)}
</Col>
</FormGroup>
......
......@@ -26,6 +26,7 @@ class EntityField extends Component {
isFieldTags: this.props.field.get('multiple', false) && !this.props.field.get('select_list', false),
isFieldSelect: this.props.field.get('select_list', false),
isFieldBoolean: this.props.field.get('type', '') === 'boolean',
isFieldRanges: this.props.field.get('type', '') === 'ranges',
fieldPath: this.props.field.get('field_name', '').split('.'),
isRemoveField: ['params'].includes(this.props.field.get('field_name', '').split('.')[0]),
}
......@@ -41,17 +42,22 @@ class EntityField extends Component {
const noDefaultValueVal = this.getNoDefaultValueVal();
const defaultValue = field.get('default_value', noDefaultValueVal);
if (defaultValue !== null) {
this.props.onChange(fieldPath, defaultValue);
this.props.onChange(fieldPath, defaultValue);
}
}
}
}
getNoDefaultValueVal = (byConfig = true) => {
const { field } = this.props;
const { isFieldBoolean, isFieldTags, isFieldSelect } = this.state;
const { isFieldBoolean, isFieldTags, isFieldSelect, isFieldRanges } = this.state;
if (isFieldBoolean) {
return false;
}
if (isFieldRanges) {
// const defaultRangValue = Immutable.Map({ from: '', to: '' });
// return Immutable.List([defaultRangValue]);
return Immutable.List();
}
if (!byConfig) {
return null;
}
......@@ -86,22 +92,32 @@ class EntityField extends Component {
const { fieldPath } = this.state;
const multi = field.get('multiple', false);
if (multi) {
this.props.onChange(fieldPath, val.split(','));
this.props.onChange(fieldPath, val.split(','));
} else {
this.props.onChange(fieldPath, val);
}
}
onChangeRange = (val) => {
const { fieldPath } = this.state;
this.props.onChange(fieldPath, val);
}
onChangeTags = (val) => {
const { fieldPath } = this.state;
this.props.onChange(fieldPath, val);
}
getFieldValue = () => {
const { fieldPath, isFieldTags, isFieldBoolean } = this.state;
const { fieldPath, isFieldTags, isFieldBoolean, isFieldRanges } = this.state;
const { entity, editable } = this.props;
if (isFieldRanges) {
return entity.getIn(fieldPath, undefined);
// return entity.getIn(fieldPath, { from: '', to: '' });
}
if (isFieldBoolean) {
return entity.getIn(fieldPath, '');
const booleanValue = entity.getIn(fieldPath, '');
return (booleanValue === '') ? booleanValue : [true, 1, 'true'].includes(booleanValue);
}
const fieldVal = entity.getIn(fieldPath, []);
if (isFieldTags && editable) {
......@@ -133,8 +149,21 @@ class EntityField extends Component {
renderField = () => {
const { editable, field } = this.props;
const { isFieldTags, isFieldSelect, isFieldBoolean } = this.state;
const { isFieldTags, isFieldSelect, isFieldBoolean, isFieldRanges } = this.state;
const value = this.getFieldValue();
if (isFieldRanges) {
const multi = field.get('multiple', false);
return (
<Field
fieldType="ranges"
onChange={this.onChangeRange}
value={value}
multi={multi}
editable={editable}
label={field.get('title', field.get('field_name', ''))}
/>
);
}
if (isFieldBoolean) {
const checkboxStyle = { height: 29, marginTop: 8 };
return (
......
......@@ -14,6 +14,7 @@ import Radio from './types/Radio';
import Salutation from './types/Salutation';
import ToggeledInput from './types/ToggeledInput';
import TextEditor from './types/TextEditor';
import Ranges from './types/Ranges';
class Field extends PureComponent {
......@@ -47,7 +48,7 @@ class Field extends PureComponent {
}
createInput = () => {
const { fieldType, required, label, style, className, ...inputProps } = this.props;
const { fieldType, style, className, ...inputProps } = this.props;
switch (fieldType) {
case 'number':
return (<Number {...inputProps} />);
......@@ -64,19 +65,21 @@ class Field extends PureComponent {
case 'unlimited':
return (<Unlimitd {...inputProps} />);
case 'toggeledInput':
return (<ToggeledInput {...inputProps} label={label} />);
return (<ToggeledInput {...inputProps} />);
case 'checkbox':
return (<Checkbox {...inputProps} label={label} />);
return (<Checkbox {...inputProps} />);
case 'radio':
return (<Radio {...inputProps} label={label} />);
return (<Radio {...inputProps} />);
case 'salutation':
return (<Salutation {...inputProps} />);
case 'textEditor':
return (<TextEditor {...inputProps} />);
case 'select':
return (<Select {...inputProps} />);
case 'ranges':
return (<Ranges {...inputProps} />);
default:
return (<Text {...inputProps} required={required} />);
return (<Text {...inputProps} />);
}
}
......
import React, { PureComponent, PropTypes } from 'react';
import Immutable from 'immutable';
import { InputGroup } from 'react-bootstrap';
import Field from '../';
class Range extends PureComponent {
static propTypes = {
value: PropTypes.instanceOf(Immutable.Map),
// value: PropTypes.shape({
// from: PropTypes.oneOfType([
// PropTypes.string,
// PropTypes.number,
// ]),
// to: PropTypes.oneOfType([
// PropTypes.string,
// PropTypes.number,
// ]),
// }),
inputProps: PropTypes.object,
editable: PropTypes.bool,
placeholder: PropTypes.oneOfType([
PropTypes.string,
PropTypes.shape({
from: PropTypes.string,
to: PropTypes.string,
}),
]),
onChange: PropTypes.func,
};
static defaultProps = {
value: Immutable.Map({ from: '', to: '' }),
placeholder: { from: '', to: '' },
inputProps: {},
editable: true,
onChange: () => {},
};
onChangeFrom = (e) => {
const { value } = this.props;
const from = this.getValue(e);
this.props.onChange(value.set('from', from));
}
onChangeTo = (e) => {
const { value } = this.props;
const to = this.getValue(e);
this.props.onChange(value.set('to', to));
}
getValue = (e) => {
const { inputProps: { fieldType = 'text' } } = this.props;
switch (fieldType) {
case 'date':
case 'select':
return e;
default:
return e.target.value;
}
}
render() {
const {
onChange,
value,
placeholder,
editable,
inputProps: { fieldType = 'text' },
...otherProps
} = this.props;
const valueFrom = Immutable.Map.isMap(value) ? value.get('from', '') : '';
const valueTo = Immutable.Map.isMap(value) ? value.get('to', '') : '';
const placeholderFrom = typeof placeholder['from'] !== 'undefined' ? placeholder.from : '';
const placeholderTo = typeof placeholder['to'] !== 'undefined' ? placeholder.to : '';
if (editable) {
return (
<InputGroup style={{ width: '100%' }}>
<InputGroup.Addon><small>From</small></InputGroup.Addon>
<Field
{...otherProps}
fieldType={fieldType}
value={valueFrom}
onChange={this.onChangeFrom}
placeholder={placeholderFrom}
/>
<InputGroup.Addon><small>To</small></InputGroup.Addon>
<Field
{...otherProps}
fieldType={fieldType}
value={valueTo}
onChange={this.onChangeTo}
placeholder={placeholderTo}
/>
</InputGroup>
);
}
return (
<div className="non-editable-field">{ `${valueFrom} - ${valueTo}` }</div>
);
}
}
export default Range;
import React, { PureComponent, PropTypes } from 'react';
import Immutable from 'immutable';
import uuid from 'uuid';
import { FormGroup, InputGroup, Button } from 'react-bootstrap';
import CreateButton from '../../Elements/CreateButton';
import Range from './Range';
class Ranges extends PureComponent {
static propTypes = {
id: PropTypes.string,
value: PropTypes.instanceOf(Immutable.List),
label: PropTypes.string,
multi: PropTypes.bool,
editable: PropTypes.bool,
disabled: PropTypes.bool,
onChange: PropTypes.func,
};
static defaultProps = {
id: undefined,
value: Immutable.List([]),
label: '',
inputProps: {},
multi: false,
editable: true,
disabled: true,
onChange: () => {},
};
constructor(props) {
super(props);
this.state = {
id: props.id || uuid.v4(),
};
}
onChange = (rangeValue, index) => {
const { value } = this.props;
this.props.onChange(value.set(index, rangeValue));
}
onAdd = () => {
const { value } = this.props;
this.props.onChange(value.push(Immutable.Map({ from: '', to: '' })));
}
onRemove = (index) => {
const { value } = this.props;
this.props.onChange(value.delete(index));
}
render() {
const {
onChange,
value,
editable,
disabled,
label,
multi,
...otherProps
} = this.props;
const { id } = this.state;
if (!editable) {
return (
<span>
{value.map((rangeValue, index) => (
<Range key={`range_${id}_${index}`} value={rangeValue} editable={false} />
))}
</span>
);
}
const ranges = value.map((rangeValue, index) => {
const onChangeRange = (v) => {
this.onChange(v, index);
};
const onRemoveRange = () => {
this.onRemove(index);
};
return (
<FormGroup key={`range_${id}_${index}`} className="rangesField form-inner-edit-row">
<InputGroup>
<Range
{...otherProps}
value={rangeValue}
onChange={onChangeRange}
editable={editable}
disabled={disabled}
/>
{ editable && (
<InputGroup.Button>
<Button onClick={onRemoveRange} disabled={disabled} >
<i className="fa fa-fw fa-trash-o danger-red" />
</Button>
</InputGroup.Button>
) }
</InputGroup>
</FormGroup>
);
});
const hasEmptyValue = value.size > 0 && value.some(range => range.get('from', '') === '' || range.get('to', '') === '');
return (
<div>
{ranges}
{editable && (multi || (!multi && value.size === 0)) && (
<CreateButton
buttonStyle={{ marginTop: 5, marginBottom: 10 }}
onClick={this.onAdd}
action="Add"
label=""
type={label}
disabled={disabled || hasEmptyValue}
/>
)}
</div>
);
}
}
export default Ranges;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment