summaryrefslogtreecommitdiff
path: root/frontend/views/page/components/tile.form.js
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-09-26 14:56:02 +0200
committerJules Laplace <julescarbon@gmail.com>2020-09-26 14:56:02 +0200
commita17b76ac75f506f5da6fe8adf9c36632b60d4226 (patch)
treeabb0af0c4409b830dea2ef808c146223ee973933 /frontend/views/page/components/tile.form.js
parent2231a6e1c05b07bb7ec5906716aedec93d02429c (diff)
refactor to use app-rooted js imports
Diffstat (limited to 'frontend/views/page/components/tile.form.js')
-rw-r--r--frontend/views/page/components/tile.form.js645
1 files changed, 0 insertions, 645 deletions
diff --git a/frontend/views/page/components/tile.form.js b/frontend/views/page/components/tile.form.js
deleted file mode 100644
index 6011b0a..0000000
--- a/frontend/views/page/components/tile.form.js
+++ /dev/null
@@ -1,645 +0,0 @@
-import React, { Component } from 'react'
-import { connect } from 'react-redux'
-import { bindActionCreators } from 'redux'
-import { Link } from 'react-router-dom'
-
-import actions from '../../../actions'
-import { session } from '../../../session'
-
-import {
- TextInput, NumberInput, ColorInput, Slider,
- Select, LabelDescription, TextArea, Checkbox,
- SubmitButton, Loader } from '../../../common'
-import { preloadImage } from '../../../util'
-
-import * as tileActions from '../../tile/tile.actions'
-
-const SELECT_TYPES = [
- "image", "text", "link"
-].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'],
- link: [],
-}
-
-const IMAGE_TILE_STYLES = [
- 'tile', 'cover', 'contain', 'contain no-repeat'
-].map(style => ({ name: style, label: style }))
-
-const TEXT_FONT_FAMILIES = [
- 'sans-serif', 'serif', 'fantasy', 'monospace', 'cursive',
-].map(style => ({ name: style, label: style }))
-
-const TEXT_FONT_STYLES = [
- 'normal', 'bold', 'italic', 'bold-italic',
-].map(style => ({ name: style, label: style }))
-
-const CURSORS = [
- { name: 'hand_up', label: 'Up', },
- { name: 'hand_down', label: 'Down', },
- { name: 'hand_left', label: 'Left', },
- { name: 'hand_right', label: 'Right', },
-]
-
-const NO_LINK = 0
-const EXTERNAL_LINK = -1
-const PAGE_LIST_TOP_OPTIONS = [
- { name: NO_LINK, label: 'No link' },
- { name: EXTERNAL_LINK, label: 'External link' },
- { name: -2, label: '──────────', disabled: true },
-]
-
-// target_page_id = Column(Integer, ForeignKey('page.id'), nullable=True)
-// https://s3.amazonaws.com/i.asdf.us/im/1c/gradient_gold1-SpringGreen1_1321159749.jpg
-
-const newImage = (data) => ({
- settings: {
- ...newPosition(),
- is_tiled: false,
- tile_style: 'tile',
- url: "",
- external_link_url: "",
- cursor: 'hand_up',
- },
- type: 'image',
- target_page_id: null,
- ...data,
-})
-
-const newText = (data) => ({
- settings: {
- ...newPosition(),
- content: "",
- font_family: 'sans-serif',
- font_size: 16,
- font_style: 'normal',
- font_color: '#dddddd',
- background_color: 'transparent',
- width: 0,
- height: 0,
- external_link_url: "",
- cursor: 'hand_up',
- },
- type: 'text',
- target_page_id: null,
- ...data,
-})
-
-const newLink = (data) => ({
- settings: {
- ...newPosition({ width: 100, height: 100, }),
- external_link_url: "",
- cursor: 'hand_up',
- },
- type: 'link',
- target_page_id: null,
- ...data,
-})
-
-const newPosition = (data) => ({
- x: 0, y: 0,
- width: 0, height: 0,
- rotation: 0, scale: 1,
- opacity: 1,
- align: "center_center",
- ...data,
-})
-
-const TYPE_CONSTRUCTORS = {
- image: newImage,
- text: newText,
- link: newLink,
-}
-
-class TileForm extends Component {
- state = {
- title: "",
- submitTitle: "",
- errorFields: new Set([]),
- modified: false,
- pageList: [],
- }
-
- componentDidMount() {
- const { graph, page, isNew, initialData, sortOrder } = this.props
- const title = isNew ? 'new tile' : 'editing tile'
- const submitTitle = isNew ? "Create Tile" : "Save Changes"
- this.setState({
- title,
- submitTitle,
- errorFields: new Set([]),
- })
- const { pages } = graph.show.res
- const linkPages = initialData ? pages.filter(page => page.id !== initialData.id) : pages
- let pageList = [
- ...PAGE_LIST_TOP_OPTIONS,
- ...linkPages.map(page => ({ name: page.id, label: page.path }))
- ]
- this.setState({ pageList })
- if (isNew) {
- const newTile = newImage({
- id: "new",
- graph_id: graph.show.res.id,
- page_id: page.show.res.id,
- sort_order: sortOrder,
- })
- this.props.tileActions.updateTemporaryTile(newTile)
- } else {
- this.props.tileActions.updateTemporaryTile({ ...initialData })
- }
- }
-
- componentDidUpdate(prevProps) {
- if (!this.props.isNew && this.props.initialData !== prevProps.initialData) {
- this.handleSubmit()
- this.props.tileActions.updateTemporaryTile({ ...this.props.initialData })
- this.setState({
- errorFields: new Set([]),
- })
- }
- }
-
- componentWillUnmount() {
- // if the item has changed, save before we close the form!
- if (!this.props.isNew && this.state.modified) {
- this.handleSubmit()
- }
- }
-
- handleChange(e) {
- const { name, value } = e.target
- this.clearErrorField(name)
- this.props.tileActions.updateTemporaryTile({
- ...this.props.temporaryTile,
- [name]: value,
- })
- }
-
- handleTypeChange(type) {
- const { graph, page, temporaryTile } = this.props
- let newTile = TYPE_CONSTRUCTORS[type]({
- id: temporaryTile.id,
- graph_id: temporaryTile.graph_id,
- page_id: temporaryTile.page_id,
- })
- newTile.settings.align = temporaryTile.settings.align
- this.clearErrorField('type')
- this.props.tileActions.updateTemporaryTile(newTile)
- }
-
- handleSettingsChange(e) {
- const { name, value } = e.target
- this.clearErrorField(name)
- this.props.tileActions.updateTemporaryTile({
- ...this.props.temporaryTile,
- settings: {
- ...this.props.temporaryTile.settings,
- [name]: value,
- }
- })
- }
-
- handleSelect(name, value) {
- this.clearErrorField(name)
- if (name === 'type') {
- return this.handleTypeChange(value)
- }
- if (name === 'target_page_id') {
- value = parseInt(value)
- }
- this.props.tileActions.updateTemporaryTile({
- ...this.props.temporaryTile,
- [name]: value,
- })
- }
-
- handleSettingsSelect(name, value) {
- this.clearErrorField(name)
- this.props.tileActions.updateTemporaryTile({
- ...this.props.temporaryTile,
- settings: {
- ...this.props.temporaryTile.settings,
- [name]: value,
- }
- })
- }
-
- handleAlignment(name, value) {
- this.clearErrorField(name)
- this.props.tileActions.updateTemporaryTile({
- ...this.props.temporaryTile,
- settings: {
- ...this.props.temporaryTile.settings,
- [name]: value,
- x: 0, y: 0,
- }
- })
- }
-
- handleImageChange(e) {
- const { name, value } = e.target
- this.handleSettingsSelect(name, value)
- preloadImage(value).then(img => {
- // console.log(img)
- this.props.tileActions.updateTemporaryTile({
- ...this.props.temporaryTile,
- settings: {
- ...this.props.temporaryTile.settings,
- [name]: value,
- width: img.naturalWidth,
- height: img.naturalHeight,
- x: 0, y: 0,
- }
- })
- })
- }
-
- clearErrorField(name) {
- const { errorFields } = this.state
- if (errorFields.has(name)) {
- errorFields.delete(name)
- this.setState({
- errorFields,
- modified: true,
- })
- } else if (!this.state.modified) {
- this.setState({
- errorFields,
- modified: true,
- })
- }
- }
-
- handleSubmit(e) {
- if (e) e.preventDefault()
- const { isNew, temporaryTile, onSubmit, onClose } = this.props
- const requiredSettings = REQUIRED_KEYS[temporaryTile.type]
- const validKeys = "id graph_id page_id target_page_id type settings".split(" ")
- const validData = validKeys.reduce((a,b) => { a[b] = temporaryTile[b]; return a }, {})
- const errorFields = requiredSettings.filter(key => !validData.settings[key])
- if (errorFields.length) {
- console.log('error', errorFields, validData)
- if (e) {
- this.setState({ errorFields: new Set(errorFields) })
- }
- } else {
- if (isNew) {
- // side effect: set username if we're creating a new tile
- // session.set('username', data.username)
- delete validData.id
- } else {
- validData.id = temporaryTile.id
- }
- this.setState({ modified: false })
- console.log('submit', validData)
- onSubmit(validData)
- // if submitting after switching elements, don't close the form
- if (e && onClose) {
- onClose()
- }
- }
- }
-
- handleDelete() {
- const { temporaryTile, isNew, onClose } = this.props
- if (confirm('Really delete this tile?')) {
- actions.tile.destroy(temporaryTile)
- .then(() => {
- onClose()
- })
- }
- }
-
- render() {
- const { temporaryTile, isNew } = this.props
- const { title, submitTitle, errorFields } = this.state
- if (!temporaryTile || !temporaryTile.settings) return <div className='box' />
- return (
- <div className='box'>
- <h1>{title}</h1>
- <form onSubmit={this.handleSubmit.bind(this)}>
- <div className="row selects">
- <Select
- name='type'
- selected={temporaryTile.type}
- options={SELECT_TYPES}
- title=''
- onChange={this.handleSelect.bind(this)}
- />
- <Select
- name='align'
- selected={temporaryTile.settings.align}
- options={ALIGNMENTS}
- title=''
- onChange={this.handleAlignment.bind(this)}
- />
- </div>
-
- {this.renderPositionInfo()}
-
- {temporaryTile.type === 'image'
- ? this.renderImageForm()
- : temporaryTile.type === 'text'
- ? this.renderTextForm()
- : temporaryTile.type === 'link'
- ? this.renderLinkForm()
- : ""}
-
- {this.renderHyperlinkForm()}
- {this.renderMiscForm()}
-
- <div className='row buttons'>
- <SubmitButton
- title={submitTitle}
- onClick={this.handleSubmit.bind(this)}
- />
- {!isNew &&
- <SubmitButton
- title={'Delete'}
- className='destroy'
- onClick={this.handleDelete.bind(this)}
- />
- }
- </div>
- {!!errorFields.size &&
- <label>
- <span></span>
- <span>Please add the required fields =)</span>
- </label>
- }
- </form>
- </div>
- )
- }
-
- renderPositionInfo() {
- const { temporaryTile } = this.props
- const { x, y, width, height, rotation, scale } = temporaryTile.settings
- return (
- <div className='position'>
- {parseInt(x)}{', '}
- {parseInt(y)}{' '}
- {parseInt(width)}{'x'}{parseInt(height)}{' '}
- {rotation === 0 || <span>{parseInt(rotation)}{'\u00B0 '}</span>}
- {scale === 1 || <span>{'x'}{scale.toFixed(2)}</span>}
- </div>
- )
- }
-
- renderImageForm() {
- // const { isNew } = this.props
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- // console.log(temporaryTile.settings)
- return (
- <div>
- <div className='row imageUrl'>
- {temporaryTile.settings.url && <div className='thumb'><img src={temporaryTile.settings.url} /></div>}
- <TextInput
- title=""
- placeholder='http://'
- name="url"
- required
- data={temporaryTile.settings}
- error={errorFields.has('url')}
- onChange={this.handleImageChange.bind(this)}
- autoComplete="off"
- />
- </div>
- <div className='row pair'>
- <Checkbox
- label="Tiled"
- name="is_tiled"
- checked={temporaryTile.settings.is_tiled}
- onChange={this.handleSettingsSelect.bind(this)}
- autoComplete="off"
- />
- {temporaryTile.settings.is_tiled &&
- <Select
- name='tile_style'
- selected={temporaryTile.settings.tile_style || 'tile'}
- options={IMAGE_TILE_STYLES}
- title=''
- onChange={this.handleSettingsSelect.bind(this)}
- />
- }
- </div>
- </div>
- )
- }
-
- renderTextForm() {
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- return (
- <div>
- <TextArea
- title=""
- name="content"
- required
- data={temporaryTile.settings}
- error={errorFields.has('content')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- <div className='row font'>
- <Select
- title="Font"
- name='font_family'
- selected={temporaryTile.settings.font_family || 'sans-serif'}
- options={TEXT_FONT_FAMILIES}
- title=''
- onChange={this.handleSettingsSelect.bind(this)}
- />
- <NumberInput
- title=''
- name='font_size'
- data={temporaryTile.settings}
- min={1}
- max={1200}
- error={errorFields.has('font_size')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- <Select
- name='font_style'
- selected={temporaryTile.settings.font_style || 'normal'}
- options={TEXT_FONT_STYLES}
- title=''
- onChange={this.handleSettingsSelect.bind(this)}
- />
- </div>
- <ColorInput
- title='Text'
- name='font_color'
- data={temporaryTile.settings}
- error={errorFields.has('font_color')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- <ColorInput
- title='BG'
- name='background_color'
- data={temporaryTile.settings}
- error={errorFields.has('background_color')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- <div className='row pair'>
- <NumberInput
- title="Width"
- name="width"
- data={temporaryTile.settings}
- min={0}
- max={1200}
- error={errorFields.has('width')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- <NumberInput
- title="Height"
- name="height"
- data={temporaryTile.settings}
- min={0}
- max={1200}
- error={errorFields.has('height')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- </div>
- </div>
- )
- }
-
- renderLinkForm() {
- const { temporaryTile } = this.props
- const { errorFields } = this.state
- return (
- <div>
- <div className='row pair'>
- <NumberInput
- title="Width"
- name="width"
- data={temporaryTile.settings}
- min={0}
- max={1200}
- error={errorFields.has('width')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- <NumberInput
- title="Height"
- name="height"
- data={temporaryTile.settings}
- min={0}
- max={1200}
- error={errorFields.has('height')}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- </div>
- </div>
- )
- }
-
- renderHyperlinkForm() {
- const { temporaryTile } = this.props
- const { pageList } = this.state
- const isExternalLink = temporaryTile.target_page_id === EXTERNAL_LINK
- return (
- <div>
- <div className={'row selects'}>
- <Select
- title=''
- name='target_page_id'
- selected={temporaryTile.target_page_id || NO_LINK}
- options={pageList}
- onChange={this.handleSelect.bind(this)}
- />
- <Select
- title=''
- name='cursor'
- selected={temporaryTile.settings.cursor}
- options={CURSORS}
- defaultOption="Cursor"
- onChange={this.handleSettingsSelect.bind(this)}
- />
- </div>
- <div>
- {isExternalLink &&
- <TextInput
- title=""
- placeholder='http://'
- name="external_link_url"
- data={temporaryTile.settings}
- onChange={this.handleSettingsChange.bind(this)}
- autoComplete="off"
- />
- }
- </div>
- </div>
- )
- }
-
- renderMiscForm() {
- const { temporaryTile } = this.props
- return (
- <div>
- <Slider
- title='Opacity'
- name='opacity'
- value={temporaryTile.settings.opacity}
- onChange={this.handleSettingsSelect.bind(this)}
- min={0.0}
- max={1.0}
- step={0.01}
- />
- <Slider
- title='Scale'
- name='scale'
- value={temporaryTile.settings.scale}
- onChange={this.handleSettingsSelect.bind(this)}
- min={0.01}
- max={10.0}
- step={0.01}
- />
- <Slider
- title='Rotation'
- name='rotation'
- value={temporaryTile.settings.rotation}
- onChange={this.handleSettingsSelect.bind(this)}
- min={-180.0}
- max={180.0}
- step={1}
- type='int'
- />
- </div>
- )
- }
-}
-
-const mapStateToProps = state => ({
- graph: state.graph,
- page: state.page,
- tile: state.tile,
- temporaryTile: state.tile.temporaryTile,
-})
-
-const mapDispatchToProps = dispatch => ({
- tileActions: bindActionCreators({ ...tileActions }, dispatch),
-})
-
-export default connect(mapStateToProps, mapDispatchToProps)(TileForm)