Support for object widget
This commit is contained in:
parent
442a02f009
commit
6b73c39ba8
@ -37,6 +37,13 @@ collections: # A list of collections the CMS should be able to edit
|
||||
description: "General Site Settings"
|
||||
fields:
|
||||
- {label: "Global title", name: "site_title", widget: "string"}
|
||||
- label: "Post Settings"
|
||||
name: posts
|
||||
widget: "object"
|
||||
fields:
|
||||
- {label: "Number of posts on frontpage", name: front_limit, widget: number}
|
||||
- {label: "Default Author", name: author, widget: string}
|
||||
- {label: "Default Thumbnail", name: thumb, widget: image, class: "thumb"}
|
||||
|
||||
- name: "authors"
|
||||
label: "Authors"
|
||||
|
@ -154,16 +154,18 @@ class Backend {
|
||||
throw (new Error('Not allowed to create new entries in this collection'));
|
||||
}
|
||||
const slug = slugFormatter(collection.get('slug'), entryDraft.getIn(['entry', 'data']));
|
||||
const path = collectionModel.entryPath(slug);
|
||||
entryObj = {
|
||||
path: collectionModel.entryPath(slug),
|
||||
path,
|
||||
slug,
|
||||
raw: this.entryToRaw(collection, entryData),
|
||||
raw: this.entryToRaw(collection, Object.assign({ path }, entryData)),
|
||||
};
|
||||
} else {
|
||||
const path = entryDraft.getIn(['entry', 'path']);
|
||||
entryObj = {
|
||||
path: entryDraft.getIn(['entry', 'path']),
|
||||
path,
|
||||
slug: entryDraft.getIn(['entry', 'slug']),
|
||||
raw: this.entryToRaw(collection, entryData),
|
||||
raw: this.entryToRaw(collection, Object.assign({ path }, entryData)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ import UnknownControl from './Widgets/UnknownControl';
|
||||
import UnknownPreview from './Widgets/UnknownPreview';
|
||||
import StringControl from './Widgets/StringControl';
|
||||
import StringPreview from './Widgets/StringPreview';
|
||||
import NumberControl from './Widgets/NumberControl';
|
||||
import NumberPreview from './Widgets/NumberPreview';
|
||||
import ListControl from './Widgets/ListControl';
|
||||
import ListPreview from './Widgets/ListPreview';
|
||||
import TextControl from './Widgets/TextControl';
|
||||
@ -13,13 +15,17 @@ import ImageControl from './Widgets/ImageControl';
|
||||
import ImagePreview from './Widgets/ImagePreview';
|
||||
import DateTimeControl from './Widgets/DateTimeControl';
|
||||
import DateTimePreview from './Widgets/DateTimePreview';
|
||||
import ObjectControl from './Widgets/ObjectControl';
|
||||
import ObjectPreview from './Widgets/ObjectPreview';
|
||||
|
||||
registry.registerWidget('string', StringControl, StringPreview);
|
||||
registry.registerWidget('text', TextControl, TextPreview);
|
||||
registry.registerWidget('number', NumberControl, NumberPreview);
|
||||
registry.registerWidget('list', ListControl, ListPreview);
|
||||
registry.registerWidget('markdown', MarkdownControl, MarkdownPreview);
|
||||
registry.registerWidget('image', ImageControl, ImagePreview);
|
||||
registry.registerWidget('datetime', DateTimeControl, DateTimePreview);
|
||||
registry.registerWidget('object', ObjectControl, ObjectPreview);
|
||||
registry.registerWidget('unknown', UnknownControl, UnknownPreview);
|
||||
|
||||
export function resolveWidget(name) {
|
||||
|
16
src/components/Widgets/NumberControl.js
Normal file
16
src/components/Widgets/NumberControl.js
Normal file
@ -0,0 +1,16 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
export default class StringControl extends React.Component {
|
||||
handleChange = e => {
|
||||
this.props.onChange(e.target.value);
|
||||
};
|
||||
|
||||
render() {
|
||||
return <input type="number" value={this.props.value || ''} onChange={this.handleChange}/>;
|
||||
}
|
||||
}
|
||||
|
||||
StringControl.propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
value: PropTypes.node,
|
||||
};
|
9
src/components/Widgets/NumberPreview.js
Normal file
9
src/components/Widgets/NumberPreview.js
Normal file
@ -0,0 +1,9 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
|
||||
export default function StringPreview({ value }) {
|
||||
return <span>{value}</span>;
|
||||
}
|
||||
|
||||
StringPreview.propTypes = {
|
||||
value: PropTypes.node,
|
||||
};
|
51
src/components/Widgets/ObjectControl.js
Normal file
51
src/components/Widgets/ObjectControl.js
Normal file
@ -0,0 +1,51 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { Map } from 'immutable';
|
||||
import { resolveWidget } from '../Widgets';
|
||||
import styles from '../ControlPanel/ControlPane.css';
|
||||
|
||||
export default class ObjectControl extends Component {
|
||||
static propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onAddMedia: PropTypes.func.isRequired,
|
||||
getMedia: PropTypes.func.isRequired,
|
||||
value: PropTypes.node,
|
||||
field: PropTypes.node,
|
||||
};
|
||||
|
||||
controlFor(field) {
|
||||
const { onAddMedia, onRemoveMedia, getMedia, value, onChange } = this.props;
|
||||
const widget = resolveWidget(field.get('widget') || 'string');
|
||||
const fieldValue = value && value.get(field.get('name'));
|
||||
|
||||
return (
|
||||
<div className={styles.control} key={field.get('name')}>
|
||||
<label className={styles.label}>{field.get('label')}</label>
|
||||
{
|
||||
React.createElement(widget.control, {
|
||||
field,
|
||||
value: fieldValue,
|
||||
onChange: (val) => {
|
||||
onChange((value || Map()).set(field.get('name'), val));
|
||||
},
|
||||
onAddMedia,
|
||||
onRemoveMedia,
|
||||
getMedia,
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { field } = this.props;
|
||||
const fields = field.get('fields');
|
||||
|
||||
if (!fields) {
|
||||
return <h3>No fields defined for this widget</h3>;
|
||||
}
|
||||
|
||||
return (<div>
|
||||
{field.get('fields').map(field => this.controlFor(field))}
|
||||
</div>);
|
||||
}
|
||||
}
|
28
src/components/Widgets/ObjectPreview.js
Normal file
28
src/components/Widgets/ObjectPreview.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import { resolveWidget } from '../Widgets';
|
||||
|
||||
export default class ObjectPreview extends Component {
|
||||
widgetFor = (field) => {
|
||||
const { value, getMedia } = this.props;
|
||||
const widget = resolveWidget(field.get('widget'));
|
||||
return (<div key={field.get('name')}>{React.createElement(widget.preview, {
|
||||
key: field.get('name'),
|
||||
value: value && value.get(field.get('name')),
|
||||
field,
|
||||
getMedia,
|
||||
})}</div>);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { field } = this.props;
|
||||
const fields = field && field.get('fields');
|
||||
|
||||
return <div>{fields && fields.map(f => this.widgetFor(f))}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectPreview.propTypes = {
|
||||
value: PropTypes.node,
|
||||
field: PropTypes.node,
|
||||
getMedia: PropTypes.func.isRequired,
|
||||
};
|
@ -33,6 +33,7 @@ export function resolveFormat(collectionOrEntity, entry) {
|
||||
if (typeof collectionOrEntity === 'string') {
|
||||
return formatByType(collectionOrEntity);
|
||||
}
|
||||
console.log('entry: %o', entry);
|
||||
const path = entry && entry.path;
|
||||
if (path) {
|
||||
return formatByExtension(path.split('.').pop());
|
||||
|
@ -4,6 +4,6 @@ export default class JSONFormatter {
|
||||
}
|
||||
|
||||
toFile(data) {
|
||||
return JSON.generate(data);
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user