From f67323fc164eb8fe05e9964477d341c6b503c29e Mon Sep 17 00:00:00 2001 From: Maciej Ziarkowski Date: Mon, 6 Jan 2020 16:21:44 +0000 Subject: [PATCH] Reuse single data entry in multi --- .../data-components/data-entry-input.tsx | 30 ++++++ .../building/data-components/data-entry.tsx | 27 ++---- .../data-components/multi-data-entry.tsx | 95 ++++++++++++------- 3 files changed, 99 insertions(+), 53 deletions(-) create mode 100644 app/src/frontend/building/data-components/data-entry-input.tsx diff --git a/app/src/frontend/building/data-components/data-entry-input.tsx b/app/src/frontend/building/data-components/data-entry-input.tsx new file mode 100644 index 00000000..09c02b90 --- /dev/null +++ b/app/src/frontend/building/data-components/data-entry-input.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +export interface TextDataEntryInputProps { + slug: string; + maxLength?: number; + disabled?: boolean; + placeholder?: string; + valueTransform?: (val: string) => string; + onChange?: (key: string, val: any) => void; +} + +export const TextDataEntryInput: React.FC = props => { + return ( + { + const transform = props.valueTransform || (x => x); + const val = e.target.value === '' ? + null : + transform(e.target.value); + props.onChange(props.slug, val); + }} + /> + ); +}; diff --git a/app/src/frontend/building/data-components/data-entry.tsx b/app/src/frontend/building/data-components/data-entry.tsx index 1e1bfca0..071d17c6 100644 --- a/app/src/frontend/building/data-components/data-entry.tsx +++ b/app/src/frontend/building/data-components/data-entry.tsx @@ -2,6 +2,7 @@ import React, { Fragment } from 'react'; import { CopyProps } from '../data-containers/category-view-props'; +import { TextDataEntryInput, TextDataEntryInputProps } from './data-entry-input'; import { DataTitleCopyable } from './data-title'; interface BaseDataEntryProps { @@ -14,14 +15,11 @@ interface BaseDataEntryProps { onChange?: (key: string, value: any) => void; } -interface DataEntryProps extends BaseDataEntryProps { +interface DataEntryProps extends BaseDataEntryProps, TextDataEntryInputProps { value?: string; - maxLength?: number; - placeholder?: string; - valueTransform?: (string) => string; } -const DataEntry: React.FunctionComponent = (props) => { +const DataEntry: React.FC = (props) => { return ( = (props) => { disabled={props.disabled || props.value == undefined || props.value == ''} copy={props.copy} /> - { - const transform = props.valueTransform || (x => x); - const val = e.target.value === '' ? - null : - transform(e.target.value); - props.onChange(props.slug, val); - }} + valueTransform={props.valueTransform} /> ); diff --git a/app/src/frontend/building/data-components/multi-data-entry.tsx b/app/src/frontend/building/data-components/multi-data-entry.tsx index e51e7d8c..ce4e0644 100644 --- a/app/src/frontend/building/data-components/multi-data-entry.tsx +++ b/app/src/frontend/building/data-components/multi-data-entry.tsx @@ -3,49 +3,57 @@ import React, { Component, Fragment } from 'react'; import { sanitiseURL } from '../../helpers'; import { BaseDataEntryProps } from './data-entry'; +import { TextDataEntryInput, TextDataEntryInputProps } from './data-entry-input'; import { DataTitleCopyable } from './data-title'; -interface MultiDataEntryProps extends BaseDataEntryProps { +interface MultiDataEntryProps extends BaseDataEntryProps, TextDataEntryInputProps { value: string[]; - placeholder: string; } -class MultiDataEntry extends Component { +interface MultiDataEntryState { + newValue: string; +} + +class MultiDataEntry extends Component { constructor(props) { super(props); + this.state = { + newValue: '' + }; + + this.setNewValue = this.setNewValue.bind(this); this.edit = this.edit.bind(this); - this.add = this.add.bind(this); + this.addNew = this.addNew.bind(this); this.remove = this.remove.bind(this); this.getValues = this.getValues.bind(this); } getValues() { - return (this.props.value && this.props.value.length)? this.props.value : [null]; + return this.props.value == undefined ? [] : this.props.value; } - edit(event) { - const editIndex = +event.target.dataset.index; - const editItem = event.target.value; - const oldValues = this.getValues(); - const values = oldValues.map((item, i) => { - return i === editIndex ? editItem : item; - }); + setNewValue(value: string) { + this.setState({newValue: value}); + } + + edit(index: number, value: string) { + let values = this.getValues(); + values.splice(index, 1, value); this.props.onChange(this.props.slug, values); } - - add(event) { + addNew(event) { event.preventDefault(); - const values = this.getValues().concat(''); + const values = this.getValues().concat(this.state.newValue); + this.setState({newValue: ''}); this.props.onChange(this.props.slug, values); } remove(event){ const removeIndex = +event.target.dataset.index; - const values = this.getValues().filter((_, i) => { - return i !== removeIndex; - }); + const values = this.getValues(); + values.splice(removeIndex, 1); this.props.onChange(this.props.slug, values); } @@ -74,30 +82,45 @@ class MultiDataEntry extends Component { } :'\u00A0' - : values.map((item, i) => ( -
- + {values.map((val, i) => ( +
+ this.edit(i, val)} + + maxLength={props.maxLength} + placeholder={props.placeholder} + valueTransform={props.valueTransform} + /> +
+ +
+
+ ))} +
+ this.setNewValue(val)} + + maxLength={props.maxLength} + placeholder={props.placeholder} + valueTransform={props.valueTransform} />
- +
- )) + } - ; } }