diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-06-03 19:27:29 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-06-03 19:27:29 +0200 |
| commit | e52dcc61ed433980d760a050ff14852a05676b96 (patch) | |
| tree | 8af65e8261971bfba5130aae20df557b7bb1c54e /frontend/views/page/components/tile.form.js | |
| parent | 3e9de575501fd1945b8341f7a4e3a89b73e3cb03 (diff) | |
image/text form
Diffstat (limited to 'frontend/views/page/components/tile.form.js')
| -rw-r--r-- | frontend/views/page/components/tile.form.js | 255 |
1 files changed, 212 insertions, 43 deletions
diff --git a/frontend/views/page/components/tile.form.js b/frontend/views/page/components/tile.form.js index 6b9d0a7..9bd8f14 100644 --- a/frontend/views/page/components/tile.form.js +++ b/frontend/views/page/components/tile.form.js @@ -3,38 +3,79 @@ import { Link } from 'react-router-dom' import { session } from '../../../session' -import { TextInput, LabelDescription, TextArea, Checkbox, SubmitButton, Loader } from '../../../common' +import { TextInput, NumberInput, Select, LabelDescription, TextArea, Checkbox, SubmitButton, Loader } from '../../../common' -const newTile = (data) => ({ - path: '', - title: '', - username: session('username'), - description: '', +const SELECT_TYPES = [ + "image", "text" +].map(s => ({ name: s, label: s })) + +const ALIGNMENTS = [ + "top_left", "top center", "top_right", + "center_left", "center_center", "center_right", + "bottom_left", "bottom_center", "bottom_right", +].map(align => ({ + name: align, + label: align === 'center_center' + ? 'center' + : align.replace('_', ' ') + })) + +const REQUIRED_KEYS = { + image: ['url'], + text: ['content', 'width', 'height'], +} + +// target_page_id = Column(Integer, ForeignKey('page.id'), nullable=True) + +const newImage = (data) => ({ settings: { - x: 0.05, y: 0.05, + ...newPosition(), + tile: false, + url: "", }, + type: 'image', ...data, }) +const newText = (data) => ({ + settings: { + ...newPosition(), + tile: false, + url: "", + width: 200, + height: 200, + }, + type: 'text', + ...data, +}) + +const newPosition = () => ({ + x: 0, y: 0, + width: 0, height: 0, + rotation: 0, scale: 1, + align: "center_center", +}) + export default class TileForm extends Component { state = { title: "", submitTitle: "", - data: { ...newTile() }, + data: { ...newText() }, errorFields: new Set([]), } componentDidMount() { - const { graph, page, data, isNew } = this.props - const title = isNew ? 'new tile' : 'editing ' + data.title + const { graph, page, isNew } = this.props + const title = isNew ? 'new tile' : 'editing tile' const submitTitle = isNew ? "Create Tile" : "Save Changes" this.setState({ title, submitTitle, errorFields: new Set([]), data: { - ...newTile({ graph_id: graph.id, page_id: page.id }), - ...data, + ...(this.props.data || this.state.data), + graph_id: graph.id, + page_id: page.id, }, }) } @@ -45,15 +86,45 @@ export default class TileForm extends Component { if (errorFields.has(name)) { errorFields.delete(name) } - let sanitizedValue = value - if (name === 'path') { - sanitizedValue = sanitizedValue.toLowerCase().replace(/ /, '-').replace(/[!@#$%^&*()[\]{}]/, '-').replace(/-+/, '-') + if (name === 'type') { + const { graph, page } = this.props + let newData; + switch(type) { + case 'image': + newData = newImage({ graph_id: graph.id, page_id: page.id }) + break + case 'text': + newData = newText({ graph_id: graph.id, page_id: page.id }) + break + } + this.setState({ + errorFields, + data: newData, + }) + } + this.setState({ + errorFields, + data: { + ...this.state.data, + [name]: value, + } + }) + } + + handleSettingsChange(e) { + const { errorFields } = this.state + const { name, value } = e.target + if (errorFields.has(name)) { + errorFields.delete(name) } this.setState({ errorFields, data: { ...this.state.data, - [name]: sanitizedValue, + settings: { + ...this.state.settings, + [name]: value, + } } }) } @@ -72,12 +143,29 @@ export default class TileForm extends Component { }) } + handleSettingsSelect(name, value) { + const { errorFields } = this.state + if (errorFields.has(name)) { + errorFields.delete(name) + } + this.setState({ + errorFields, + data: { + ...this.state.data, + settings: { + ...this.state.data.settings, + [name]: value, + } + } + }) + } + handleSubmit(e) { e.preventDefault() const { isNew, onSubmit } = this.props const { data } = this.state - const requiredKeys = "path title".split(" ") - const validKeys = "graph_id path title username description settings".split(" ") + const requiredKeys = REQUIRED_KEYS[data.type] + const validKeys = "graph_id username settings".split(" ") const validData = validKeys.reduce((a,b) => { a[b] = data[b]; return a }, {}) const errorFields = requiredKeys.filter(key => !validData[key]) if (errorFields.length) { @@ -96,36 +184,38 @@ export default class TileForm extends Component { } render() { - const { graph, isNew } = this.props + const { isNew } = this.props const { title, submitTitle, errorFields, data } = this.state + if (!data) return return ( <div className='box'> <h1>{title}</h1> <form onSubmit={this.handleSubmit.bind(this)}> - <TextInput - title="Path" - name="path" - required - data={data} - error={errorFields.has('path')} - onChange={this.handleChange.bind(this)} - autoComplete="off" - /> - <TextInput - title="Title" - name="title" - required - data={data} - error={errorFields.has('title')} - onChange={this.handleChange.bind(this)} - autoComplete="off" - /> - <TextArea - title="Description" - name="description" - data={data} - onChange={this.handleChange.bind(this)} - /> + <div className="row selects"> + <Select + name='type' + selected={data.type} + options={SELECT_TYPES} + title='' + onChange={this.handleSelect.bind(this)} + /> + <Select + name='align' + selected={data.settings.align} + options={ALIGNMENTS} + title='' + onChange={this.handleSettingsSelect.bind(this)} + /> + </div> + + {this.renderPositionInfo()} + + {data.type === 'image' + ? this.renderImageForm() + : data.type === 'text' + ? this.renderTextForm() + : ""} + <SubmitButton title={submitTitle} onClick={this.handleSubmit.bind(this)} @@ -140,4 +230,83 @@ export default class TileForm extends Component { </div> ) } + + renderPositionInfo() { + const { x, y, width, height, rotation, scale } = this.state.data.settings + return ( + <div className='position'> + {''}{parseInt(x)}{', '} + {''}{parseInt(y)}{' '} + {parseInt(width)}{'x'}{parseInt(height)}{' '} + {parseInt(rotation * 180 / Math.PI)}{'\u00B0 '} + {'x'}{scale.toFixed(0.2)} + </div> + ) + } + + renderImageForm() { + // const { isNew } = this.props + const { data } = this.state + return ( + <div> + <TextInput + title="" + placeholder='http://' + name="url" + required + data={data.settings} + error={errorFields.has('url')} + onChange={this.handleSettingsChange.bind(this)} + autoComplete="off" + /> + <Checkbox + label="Tiled" + name="tile" + data={data.settings} + onChange={this.handleSettingsSelect.bind(this)} + autoComplete="off" + /> + </div> + ) + + } + + renderTextForm() { + const { data } = this.state + return ( + <div> + <TextArea + title="" + name="content" + required + data={data.settings} + error={errorFields.has('content')} + onChange={this.handleChange.bind(this)} + autoComplete="off" + /> + <div className='row pair'> + <NumberInput + title="Width" + name="width" + data={data.settings} + min={10} + max={1200} + error={errorFields.has('width')} + onChange={this.handleSettingsChange.bind(this)} + autoComplete="off" + /> + <NumberInput + title="Height" + name="height" + data={data.settings} + min={10} + max={1200} + error={errorFields.has('height')} + onChange={this.handleSettingsChange.bind(this)} + autoComplete="off" + /> + </div> + </div> + ) + } } |
