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"
|
description: "General Site Settings"
|
||||||
fields:
|
fields:
|
||||||
- {label: "Global title", name: "site_title", widget: "string"}
|
- {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"
|
- name: "authors"
|
||||||
label: "Authors"
|
label: "Authors"
|
||||||
|
@ -154,16 +154,18 @@ class Backend {
|
|||||||
throw (new Error('Not allowed to create new entries in this collection'));
|
throw (new Error('Not allowed to create new entries in this collection'));
|
||||||
}
|
}
|
||||||
const slug = slugFormatter(collection.get('slug'), entryDraft.getIn(['entry', 'data']));
|
const slug = slugFormatter(collection.get('slug'), entryDraft.getIn(['entry', 'data']));
|
||||||
|
const path = collectionModel.entryPath(slug);
|
||||||
entryObj = {
|
entryObj = {
|
||||||
path: collectionModel.entryPath(slug),
|
path,
|
||||||
slug,
|
slug,
|
||||||
raw: this.entryToRaw(collection, entryData),
|
raw: this.entryToRaw(collection, Object.assign({ path }, entryData)),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
const path = entryDraft.getIn(['entry', 'path']);
|
||||||
entryObj = {
|
entryObj = {
|
||||||
path: entryDraft.getIn(['entry', 'path']),
|
path,
|
||||||
slug: entryDraft.getIn(['entry', 'slug']),
|
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 UnknownPreview from './Widgets/UnknownPreview';
|
||||||
import StringControl from './Widgets/StringControl';
|
import StringControl from './Widgets/StringControl';
|
||||||
import StringPreview from './Widgets/StringPreview';
|
import StringPreview from './Widgets/StringPreview';
|
||||||
|
import NumberControl from './Widgets/NumberControl';
|
||||||
|
import NumberPreview from './Widgets/NumberPreview';
|
||||||
import ListControl from './Widgets/ListControl';
|
import ListControl from './Widgets/ListControl';
|
||||||
import ListPreview from './Widgets/ListPreview';
|
import ListPreview from './Widgets/ListPreview';
|
||||||
import TextControl from './Widgets/TextControl';
|
import TextControl from './Widgets/TextControl';
|
||||||
@ -13,13 +15,17 @@ import ImageControl from './Widgets/ImageControl';
|
|||||||
import ImagePreview from './Widgets/ImagePreview';
|
import ImagePreview from './Widgets/ImagePreview';
|
||||||
import DateTimeControl from './Widgets/DateTimeControl';
|
import DateTimeControl from './Widgets/DateTimeControl';
|
||||||
import DateTimePreview from './Widgets/DateTimePreview';
|
import DateTimePreview from './Widgets/DateTimePreview';
|
||||||
|
import ObjectControl from './Widgets/ObjectControl';
|
||||||
|
import ObjectPreview from './Widgets/ObjectPreview';
|
||||||
|
|
||||||
registry.registerWidget('string', StringControl, StringPreview);
|
registry.registerWidget('string', StringControl, StringPreview);
|
||||||
registry.registerWidget('text', TextControl, TextPreview);
|
registry.registerWidget('text', TextControl, TextPreview);
|
||||||
|
registry.registerWidget('number', NumberControl, NumberPreview);
|
||||||
registry.registerWidget('list', ListControl, ListPreview);
|
registry.registerWidget('list', ListControl, ListPreview);
|
||||||
registry.registerWidget('markdown', MarkdownControl, MarkdownPreview);
|
registry.registerWidget('markdown', MarkdownControl, MarkdownPreview);
|
||||||
registry.registerWidget('image', ImageControl, ImagePreview);
|
registry.registerWidget('image', ImageControl, ImagePreview);
|
||||||
registry.registerWidget('datetime', DateTimeControl, DateTimePreview);
|
registry.registerWidget('datetime', DateTimeControl, DateTimePreview);
|
||||||
|
registry.registerWidget('object', ObjectControl, ObjectPreview);
|
||||||
registry.registerWidget('unknown', UnknownControl, UnknownPreview);
|
registry.registerWidget('unknown', UnknownControl, UnknownPreview);
|
||||||
|
|
||||||
export function resolveWidget(name) {
|
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') {
|
if (typeof collectionOrEntity === 'string') {
|
||||||
return formatByType(collectionOrEntity);
|
return formatByType(collectionOrEntity);
|
||||||
}
|
}
|
||||||
|
console.log('entry: %o', entry);
|
||||||
const path = entry && entry.path;
|
const path = entry && entry.path;
|
||||||
if (path) {
|
if (path) {
|
||||||
return formatByExtension(path.split('.').pop());
|
return formatByExtension(path.split('.').pop());
|
||||||
|
@ -4,6 +4,6 @@ export default class JSONFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toFile(data) {
|
toFile(data) {
|
||||||
return JSON.generate(data);
|
return JSON.stringify(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user