UNPKG

meteor-interface

Version:

Simple Content Management System to generate your administration interface for Meteor and React.

270 lines (240 loc) 10.1 kB
import React, { Fragment, Component, PureComponent } from 'react'; import { withTracker } from 'meteor/react-meteor-data'; import slugify from 'slugify'; import { Transition, Spring } from 'react-spring' import DynamicImporter from "../../../utils/DynamicImporter"; import { WidgetFormConsumer } from '../../../utils/contexts/WidgetFormContext' const TinyMCE = DynamicImporter(() => import('react-tinymce')); // Packages import { Segment, Header, List, Label, Form, Button, Checkbox, Image, Message, Icon, } from 'semantic-ui-react'; import ModalImageSelector from '../../MediaManager/components/ModalImageSelector'; const tinyConfig = { height: 300, menubar: false, plugins: [ 'advlist autolink lists link image charmap print preview anchor textcolor colorpicker', 'searchreplace visualblocks code fullscreen', 'insertdatetime media table contextmenu paste code emoticons', ], toolbar: 'undo redo | insert | fontsizeselect | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link | forecolor backcolor emoticons | image', }; const WidgetSelector = WidgetFormConsumer((props) => { let { collection, collection2, item2 } = props if(item2 && collection2){ collection = collection2 item = item2 } return collection.fields.map((field, i) => <SingleWidget key={i} field={field} {...props }/> ) }) class SingleWidget extends Component { state = { id: Random.id() } updateNestedValue = (e, { name, value, checked }) => { const { nested, index, collection2, item2, parent, context = {}, field } = this.props let { updateValue, item, collection, ready } = context; if(item2 && collection2){ collection = collection2 item = item2 } parent[index][name] = value || checked updateValue(e, { name: collection.name , value: parent, }) } updateNormalValue = (e, { name, value, checked }) => { const { nested, index, collection2, item2, parent, context = {}, field } = this.props let { updateValue, item, collection, ready } = context; updateValue(e, { name, value, checked }) } incrementeList = (e) => { const { nested, index, collection2, item2, parent, context = {}, field } = this.props let { updateValue, item, collection, ready } = context; if(nested){ parent[index][name] && parent[index][name].length ? parent[index][name].push({}) : parent[index][name] = [{}] updateValue(e, { name: collection.name , value: parent, }) } else { item[field.name] && item[field.name].length ? item[field.name].push({}) : item[field.name] = [{}] updateValue(e, { name: [field.name], value: item[field.name] }) } } decrementeList = (e, index) => { const { nested, collection2, item2, parent, context, field } = this.props; let { updateValue, item, collection, ready } = context; if(nested){ parent[index][name].splice(index, 1) updateValue(e, { name: collection.name , value: parent, }) } else { item[field.name].splice(index, 1) updateValue(e, { name: [field.name], value: item[field.name] }) } } render() { const { id } = this.state const { nested, index, collection2, item2, parent, context = {}, field } = this.props; let { updateValue, item, collection, ready } = context; if(item2 && collection2){ collection = collection2 item = item2 } switch (field.widget){ case 'string': return ( <Form.Input value={item[field.name]} label={field.label} key={id} onChange={ nested ? this.updateNestedValue : this.updateNormalValue} name={field.name} /> ) case 'multiline': return ( <Form.TextArea value={item[field.name]} label={field.label} key={id} onChange={ nested ? this.updateNestedValue : this.updateNormalValue} name={field.name} /> ) case 'html': if(typeof tinymce !== 'undefined'){ return ( <Form.Field className="tinymce-selector"> <label>{field.label}</label> <div className="wrapper" > <TinyMCE content={item[field.name]} config={tinyConfig} onChange={e => { const updateFunction = nested ? this.updateNestedValue : this.updateNormalValue updateFunction(e, { name: field.name, value: e.target.getContent() }) }} /> </div> </Form.Field> ) } return <div key={id}>Loading TinyMCE Editor ... </div> case 'image': return ( <Form.Field className="image-selector" key={id} > <label>{field.label}</label> <div className="wrapper" > <Image rounded src={item[field.name]} size="tiny" /> <div className="choice" > <p>{item[field.name]}</p> <ModalImageSelector selectPicture={nested ? this.updateNestedValue : this.updateNormalValue} currentPicture={item[field.name]} name={field.name} /> {item[field.name] && <Button onClick={ nested ? this.updateNestedValue : this.updateNormalValue} value={null} name={field.name} size='mini' color="red">remove the picture</Button> } </div> </div> </Form.Field> ) case 'boolean': return ( <Form.Field key={id}> <label>{field.label}</label> <Checkbox checked={item[field.name]} toggle key={id} onChange={ nested ? this.updateNestedValue : this.updateNormalValue} name={field.name} /> </Form.Field> ) case 'list': if(field.fields){ return ( <Segment key={id} > <Label as='a' color='green' ribbon size="small"> {field.name} </Label> {item[field.name] ? item[field.name].map((mark, i2) => ( <Message key={id + i2}> <Segment.Group> <WidgetSelector collection2={field} item2={mark} nested={true} index={i2} parent={item[field.name]} /> </Segment.Group> <a className="decrementation" onClick={(e) => this.decrementeList(e, i2)}>Remove</a> </Message> )): null } <a className="incrementation" onClick={this.incrementeList}>Add entry</a> </Segment> ) } else { const options = item[field.name] && item[field.name].length > 0 ? item[field.name].map((mark, i) => ({ key: `${JSON.stringify(mark)}_${i}`, text: mark, value: mark })) : [] return ( <Form.Dropdown key={id} name={field.name} fluid multiple label={field.label} search selection allowAdditions options={options} onChange={ nested ? this.updateNestedValue : this.updateNormalValue} value={ item[field.name] || []} /> ) } } } } export default WidgetSelector;