Merge remote-tracking branch 'react/master' into react
This commit is contained in:
commit
ad479d8a94
@ -57,6 +57,7 @@ rules:
|
|||||||
no-mixed-spaces-and-tabs: 2
|
no-mixed-spaces-and-tabs: 2
|
||||||
no-multiple-empty-lines: [2, {max: 2}]
|
no-multiple-empty-lines: [2, {max: 2}]
|
||||||
no-trailing-spaces: 2
|
no-trailing-spaces: 2
|
||||||
|
object-curly-spacing: [1, "always"]
|
||||||
quotes: [2, "single", "avoid-escape"]
|
quotes: [2, "single", "avoid-escape"]
|
||||||
semi: 2
|
semi: 2
|
||||||
space-after-keywords: 2
|
space-after-keywords: 2
|
||||||
@ -84,6 +85,7 @@ rules:
|
|||||||
no-unused-vars: [2, {"args": "none"}]
|
no-unused-vars: [2, {"args": "none"}]
|
||||||
|
|
||||||
|
|
||||||
|
react/prop-types: 1
|
||||||
react/forbid-prop-types: 1
|
react/forbid-prop-types: 1
|
||||||
react/jsx-boolean-value: 1
|
react/jsx-boolean-value: 1
|
||||||
react/jsx-closing-bracket-location: 1
|
react/jsx-closing-bracket-location: 1
|
||||||
@ -109,6 +111,7 @@ rules:
|
|||||||
react/no-string-refs: 1
|
react/no-string-refs: 1
|
||||||
react/no-unknown-property: 1
|
react/no-unknown-property: 1
|
||||||
react/prefer-es6-class: 1
|
react/prefer-es6-class: 1
|
||||||
|
react/prefer-stateless-function: 1
|
||||||
react/react-in-jsx-scope: 1
|
react/react-in-jsx-scope: 1
|
||||||
react/require-extension: 1
|
react/require-extension: 1
|
||||||
react/self-closing-comp: 1
|
react/self-closing-comp: 1
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
"babel-runtime": "^6.5.0",
|
"babel-runtime": "^6.5.0",
|
||||||
"eslint": "^1.10.3",
|
"eslint": "^1.10.3",
|
||||||
"eslint-loader": "^1.2.1",
|
"eslint-loader": "^1.2.1",
|
||||||
"eslint-plugin-react": "^3.16.1",
|
"eslint-plugin-react": "^5.1.1",
|
||||||
"exports-loader": "^0.6.3",
|
"exports-loader": "^0.6.3",
|
||||||
"express": "^4.13.4",
|
"express": "^4.13.4",
|
||||||
"file-loader": "^0.8.5",
|
"file-loader": "^0.8.5",
|
||||||
@ -39,8 +39,8 @@
|
|||||||
"mocha": "^2.4.5",
|
"mocha": "^2.4.5",
|
||||||
"moment": "^2.11.2",
|
"moment": "^2.11.2",
|
||||||
"normalizr": "^2.0.0",
|
"normalizr": "^2.0.0",
|
||||||
"react": "^0.14.7",
|
"react": "^15.1.0",
|
||||||
"react-dom": "^0.14.7",
|
"react-dom": "^15.1.0",
|
||||||
"react-immutable-proptypes": "^1.6.0",
|
"react-immutable-proptypes": "^1.6.0",
|
||||||
"react-lazy-load": "^3.0.3",
|
"react-lazy-load": "^3.0.3",
|
||||||
"react-pure-render": "^1.0.2",
|
"react-pure-render": "^1.0.2",
|
||||||
@ -54,7 +54,7 @@
|
|||||||
"webpack": "^1.12.13",
|
"webpack": "^1.12.13",
|
||||||
"webpack-dev-server": "^1.14.1",
|
"webpack-dev-server": "^1.14.1",
|
||||||
"webpack-postcss-tools": "^1.1.1",
|
"webpack-postcss-tools": "^1.1.1",
|
||||||
"whatwg-fetch": "^0.11.0"
|
"whatwg-fetch": "^1.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commonmark": "^0.24.0",
|
"commonmark": "^0.24.0",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import TestRepoBackend from './test-repo/Implementation';
|
import TestRepoBackend from './test-repo/implementation';
|
||||||
import GitHubBackend from './github/Implementation';
|
import GitHubBackend from './github/implementation';
|
||||||
import { resolveFormat } from '../formats/formats';
|
import { resolveFormat } from '../formats/formats';
|
||||||
|
|
||||||
class LocalStorageAuthStore {
|
class LocalStorageAuthStore {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import Widgets from './Widgets';
|
import Widgets from './Widgets';
|
||||||
|
|
||||||
export default class ControlPane extends React.Component {
|
export default class ControlPane extends React.Component {
|
||||||
@ -6,7 +7,6 @@ export default class ControlPane extends React.Component {
|
|||||||
const { entry, getMedia, onChange, onAddMedia, onRemoveMedia } = this.props;
|
const { entry, getMedia, onChange, onAddMedia, onRemoveMedia } = this.props;
|
||||||
const widget = Widgets[field.get('widget')] || Widgets._unknown;
|
const widget = Widgets[field.get('widget')] || Widgets._unknown;
|
||||||
return React.createElement(widget.Control, {
|
return React.createElement(widget.Control, {
|
||||||
key: field.get('name'),
|
|
||||||
field: field,
|
field: field,
|
||||||
value: entry.getIn(['data', field.get('name')]),
|
value: entry.getIn(['data', field.get('name')]),
|
||||||
onChange: (value) => onChange(entry.setIn(['data', field.get('name')], value)),
|
onChange: (value) => onChange(entry.setIn(['data', field.get('name')], value)),
|
||||||
@ -19,9 +19,17 @@ export default class ControlPane extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const { collection } = this.props;
|
const { collection } = this.props;
|
||||||
if (!collection) { return null; }
|
if (!collection) { return null; }
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{collection.get('fields').map((field) => <div key={field.get('names ')}>{this.controlFor(field)}</div>)}
|
{collection.get('fields').map((field) => <div key={field.get('name')}>{this.controlFor(field)}</div>)}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ControlPane.propTypes = {
|
||||||
|
collection: ImmutablePropTypes.map.isRequired,
|
||||||
|
entry: ImmutablePropTypes.map.isRequired,
|
||||||
|
getMedia: PropTypes.func.isRequired,
|
||||||
|
onAddMedia: PropTypes.func.isRequired,
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
onRemoveMedia: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
@ -1,32 +1,29 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ControlPane from './ControlPane';
|
import ControlPane from './ControlPane';
|
||||||
import PreviewPane from './PreviewPane';
|
import PreviewPane from './PreviewPane';
|
||||||
|
|
||||||
export default class EntryEditor extends React.Component {
|
export default function EntryEditor({ collection, entry, getMedia, onChange, onAddMedia, onRemoveMedia, onPersist }) {
|
||||||
|
return <div>
|
||||||
render() {
|
<h1>Entry in {collection.get('label')}</h1>
|
||||||
const { collection, entry, getMedia, onChange, onAddMedia, onRemoveMedia, onPersist } = this.props;
|
<h2>{entry && entry.get('title')}</h2>
|
||||||
return <div>
|
<div className="cms-container" style={styles.container}>
|
||||||
<h1>Entry in {collection.get('label')}</h1>
|
<div className="cms-control-pane" style={styles.pane}>
|
||||||
<h2>{entry && entry.get('title')}</h2>
|
<ControlPane
|
||||||
<div className="cms-container" style={styles.container}>
|
collection={collection}
|
||||||
<div className="cms-control-pane" style={styles.pane}>
|
entry={entry}
|
||||||
<ControlPane
|
getMedia={getMedia}
|
||||||
collection={collection}
|
onChange={onChange}
|
||||||
entry={entry}
|
onAddMedia={onAddMedia}
|
||||||
getMedia={getMedia}
|
onRemoveMedia={onRemoveMedia}
|
||||||
onChange={onChange}
|
/>
|
||||||
onAddMedia={onAddMedia}
|
|
||||||
onRemoveMedia={onRemoveMedia}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="cms-preview-pane" style={styles.pane}>
|
|
||||||
<PreviewPane collection={collection} entry={entry} getMedia={getMedia} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<button onClick={onPersist}>Save</button>
|
<div className="cms-preview-pane" style={styles.pane}>
|
||||||
</div>;
|
<PreviewPane collection={collection} entry={entry} getMedia={getMedia} />
|
||||||
}
|
</div>
|
||||||
|
</div>
|
||||||
|
<button onClick={onPersist}>Save</button>
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
@ -37,3 +34,13 @@ const styles = {
|
|||||||
width: '50%'
|
width: '50%'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EntryEditor.propTypes = {
|
||||||
|
collection: ImmutablePropTypes.map.isRequired,
|
||||||
|
entry: ImmutablePropTypes.map.isRequired,
|
||||||
|
getMedia: PropTypes.func.isRequired,
|
||||||
|
onAddMedia: PropTypes.func.isRequired,
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
onPersist: PropTypes.func.isRequired,
|
||||||
|
onRemoveMedia: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
export default class EntryListing extends React.Component {
|
export default function EntryListing({ collection, entries }) {
|
||||||
render() {
|
const name = collection.get('name');
|
||||||
const { collection, entries } = this.props;
|
return <div>
|
||||||
const name = collection.get('name');
|
<h2>Listing entries!</h2>
|
||||||
|
{entries.map((entry) => {
|
||||||
return <div>
|
const path = `/collections/${name}/entries/${entry.get('slug')}`;
|
||||||
<h2>Listing entries!</h2>
|
return <Link key={entry.get('slug')} to={path}>
|
||||||
{entries.map((entry) => {
|
<h3>{entry.getIn(['data', 'title'])}</h3>
|
||||||
const path = `/collections/${name}/entries/${entry.get('slug')}`;
|
</Link>;
|
||||||
return <Link key={entry.get('slug')} to={path}>
|
})}
|
||||||
<h3>{entry.getIn(['data', 'title'])}</h3>
|
</div>;
|
||||||
</Link>;
|
|
||||||
})}
|
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntryListing.propTypes = {
|
||||||
|
collection: ImmutablePropTypes.map.isRequired,
|
||||||
|
entries: ImmutablePropTypes.list,
|
||||||
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import Widgets from './Widgets';
|
import Widgets from './Widgets';
|
||||||
|
|
||||||
export default class PreviewPane extends React.Component {
|
export default class PreviewPane extends React.Component {
|
||||||
@ -6,7 +7,6 @@ export default class PreviewPane extends React.Component {
|
|||||||
const { entry, getMedia } = this.props;
|
const { entry, getMedia } = this.props;
|
||||||
const widget = Widgets[field.get('widget')] || Widgets._unknown;
|
const widget = Widgets[field.get('widget')] || Widgets._unknown;
|
||||||
return React.createElement(widget.Preview, {
|
return React.createElement(widget.Preview, {
|
||||||
key: field.get('name'),
|
|
||||||
field: field,
|
field: field,
|
||||||
value: entry.getIn(['data', field.get('name')]),
|
value: entry.getIn(['data', field.get('name')]),
|
||||||
getMedia: getMedia,
|
getMedia: getMedia,
|
||||||
@ -17,8 +17,15 @@ export default class PreviewPane extends React.Component {
|
|||||||
const { collection } = this.props;
|
const { collection } = this.props;
|
||||||
if (!collection) { return null; }
|
if (!collection) { return null; }
|
||||||
|
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{collection.get('fields').map((field) => <div>{this.previewFor(field)}</div>)}
|
{collection.get('fields').map((field) => <div key={field.get('name')}>{this.previewFor(field)}</div>)}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreviewPane.propTypes = {
|
||||||
|
collection: ImmutablePropTypes.map.isRequired,
|
||||||
|
entry: ImmutablePropTypes.map.isRequired,
|
||||||
|
getMedia: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import { truncateMiddle } from '../../lib/textHelper';
|
import { truncateMiddle } from '../../lib/textHelper';
|
||||||
import MediaProxy from '../../valueObjects/MediaProxy';
|
import MediaProxy from '../../valueObjects/MediaProxy';
|
||||||
|
|
||||||
@ -98,3 +98,10 @@ const styles = {
|
|||||||
display: 'none'
|
display: 'none'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ImageControl.propTypes = {
|
||||||
|
onAddMedia: PropTypes.func.isRequired,
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
onRemoveMedia: PropTypes.func.isRequired,
|
||||||
|
value: PropTypes.node,
|
||||||
|
};
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
|
||||||
export default class ImagePreview extends React.Component {
|
export default function ImagePreview({ value, getMedia }) {
|
||||||
constructor(props) {
|
return <span>
|
||||||
super(props);
|
{value ? <img src={getMedia(value)}/> : null}
|
||||||
}
|
</span>;
|
||||||
|
|
||||||
render() {
|
|
||||||
const { value, getMedia } = this.props;
|
|
||||||
return value ? <img src={getMedia(value)}/> : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImagePreview.propTypes = {
|
||||||
|
getMedia: PropTypes.func.isRequired,
|
||||||
|
value: PropTypes.node,
|
||||||
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import {Editor, EditorState, RichUtils} from 'draft-js';
|
import { Editor, EditorState, RichUtils } from 'draft-js';
|
||||||
import {stateToMarkdown} from 'draft-js-export-markdown';
|
import { stateToMarkdown } from 'draft-js-export-markdown';
|
||||||
import {stateFromMarkdown} from 'draft-js-import-markdown';
|
import { stateFromMarkdown } from 'draft-js-import-markdown';
|
||||||
|
|
||||||
export default class MarkdownControl extends React.Component {
|
export default class MarkdownControl extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -15,7 +15,7 @@ export default class MarkdownControl extends React.Component {
|
|||||||
|
|
||||||
handleChange(editorState) {
|
handleChange(editorState) {
|
||||||
const content = editorState.getCurrentContent();
|
const content = editorState.getCurrentContent();
|
||||||
this.setState({editorState});
|
this.setState({ editorState });
|
||||||
this.props.onChange(stateToMarkdown(content));
|
this.props.onChange(stateToMarkdown(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ export default class MarkdownControl extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {editorState} = this.state;
|
const { editorState } = this.state;
|
||||||
return (
|
return (
|
||||||
<Editor
|
<Editor
|
||||||
editorState={editorState}
|
editorState={editorState}
|
||||||
@ -38,3 +38,8 @@ export default class MarkdownControl extends React.Component {
|
|||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MarkdownControl.propTypes = {
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
value: PropTypes.node,
|
||||||
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import CommonMark from 'commonmark';
|
import CommonMark from 'commonmark';
|
||||||
import ReactRenderer from 'commonmark-react-renderer';
|
import ReactRenderer from 'commonmark-react-renderer';
|
||||||
|
|
||||||
@ -14,3 +14,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
return React.createElement.apply(React, ['div', {}].concat(renderer.render(ast)));
|
return React.createElement.apply(React, ['div', {}].concat(renderer.render(ast)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MarkdownPreview.propTypes = {
|
||||||
|
value: PropTypes.node,
|
||||||
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
|
||||||
export default class StringControl extends React.Component {
|
export default class StringControl extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -14,3 +14,8 @@ export default class StringControl extends React.Component {
|
|||||||
return <input value={this.props.value} onChange={this.handleChange}/>;
|
return <input value={this.props.value} onChange={this.handleChange}/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringControl.propTypes = {
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
value: PropTypes.node,
|
||||||
|
};
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
|
||||||
export default class StringPreview extends React.Component {
|
export default function StringPreview({ value }) {
|
||||||
render() {
|
return <span>{value}</span>;
|
||||||
const { value } = this.props;
|
|
||||||
|
|
||||||
return <span>{value}</span>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringPreview.propTypes = {
|
||||||
|
value: PropTypes.node,
|
||||||
|
};
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
export default class UnknownControl extends React.Component {
|
export default function UnknownControl({ field }) {
|
||||||
render() {
|
return <div>No control for widget '{field.get('widget')}'.</div>;
|
||||||
const { field } = this.props;
|
|
||||||
|
|
||||||
return <div>No control for widget '{field.get('widget')}'.</div>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnknownControl.propTypes = {
|
||||||
|
field: ImmutablePropTypes.map,
|
||||||
|
};
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
|
|
||||||
export default class UnknownPreview extends React.Component {
|
export default function UnknownPreview({ field }) {
|
||||||
render() {
|
return <div>No preview for widget '{field.get('widget')}'.</div>;
|
||||||
const { field } = this.props;
|
|
||||||
|
|
||||||
return <div>No preview for widget '{field.widget}'.</div>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnknownPreview.propTypes = {
|
||||||
|
field: ImmutablePropTypes.map,
|
||||||
|
};
|
||||||
|
@ -76,7 +76,7 @@ function mapStateToProps(state) {
|
|||||||
const { auth, config } = state;
|
const { auth, config } = state;
|
||||||
const user = auth && auth.get('user');
|
const user = auth && auth.get('user');
|
||||||
|
|
||||||
return {auth, config, user};
|
return { auth, config, user };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(App);
|
export default connect(mapStateToProps)(App);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { loadEntries } from '../actions/entries';
|
import { loadEntries } from '../actions/entries';
|
||||||
@ -23,7 +24,6 @@ class DashboardPage extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { collections, collection, entries } = this.props;
|
const { collections, collection, entries } = this.props;
|
||||||
|
|
||||||
if (collections == null) {
|
if (collections == null) {
|
||||||
return <h1>No collections defined in your config.yml</h1>;
|
return <h1>No collections defined in your config.yml</h1>;
|
||||||
}
|
}
|
||||||
@ -44,13 +44,20 @@ class DashboardPage extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DashboardPage.propTypes = {
|
||||||
|
collection: ImmutablePropTypes.map.isRequired,
|
||||||
|
collections: ImmutablePropTypes.orderedMap.isRequired,
|
||||||
|
dispatch: PropTypes.func.isRequired,
|
||||||
|
entries: ImmutablePropTypes.list,
|
||||||
|
};
|
||||||
|
|
||||||
function mapStateToProps(state, ownProps) {
|
function mapStateToProps(state, ownProps) {
|
||||||
const { collections } = state;
|
const { collections } = state;
|
||||||
const { name, slug } = ownProps.params;
|
const { name, slug } = ownProps.params;
|
||||||
const collection = name ? collections.get(name) : collections.first();
|
const collection = name ? collections.get(name) : collections.first();
|
||||||
const entries = selectEntries(state, collection.get('name'));
|
const entries = selectEntries(state, collection.get('name'));
|
||||||
|
|
||||||
return {slug, collection, collections, entries};
|
return { slug, collection, collections, entries };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(DashboardPage);
|
export default connect(mapStateToProps)(DashboardPage);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
loadEntry,
|
loadEntry,
|
||||||
@ -39,6 +40,7 @@ class EntryPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
entry, entryDraft, boundGetMedia, collection, changeDraft, addMedia, removeMedia
|
entry, entryDraft, boundGetMedia, collection, changeDraft, addMedia, removeMedia
|
||||||
} = this.props;
|
} = this.props;
|
||||||
@ -60,13 +62,28 @@ class EntryPage extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntryPage.propTypes = {
|
||||||
|
addMedia: PropTypes.func.isRequired,
|
||||||
|
boundGetMedia: PropTypes.func.isRequired,
|
||||||
|
changeDraft: PropTypes.func.isRequired,
|
||||||
|
collection: ImmutablePropTypes.map.isRequired,
|
||||||
|
createDraft: PropTypes.func.isRequired,
|
||||||
|
discardDraft: PropTypes.func.isRequired,
|
||||||
|
entry: ImmutablePropTypes.map.isRequired,
|
||||||
|
entryDraft: ImmutablePropTypes.map.isRequired,
|
||||||
|
loadEntry: PropTypes.func.isRequired,
|
||||||
|
persist: PropTypes.func.isRequired,
|
||||||
|
removeMedia: PropTypes.func.isRequired,
|
||||||
|
slug: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
function mapStateToProps(state, ownProps) {
|
function mapStateToProps(state, ownProps) {
|
||||||
const { collections, entryDraft } = state;
|
const { collections, entryDraft } = state;
|
||||||
const collection = collections.get(ownProps.params.name);
|
const collection = collections.get(ownProps.params.name);
|
||||||
const slug = ownProps.params.slug;
|
const slug = ownProps.params.slug;
|
||||||
const entry = selectEntry(state, collection.get('name'), slug);
|
const entry = selectEntry(state, collection.get('name'), slug);
|
||||||
const boundGetMedia = getMedia.bind(null, state);
|
const boundGetMedia = getMedia.bind(null, state);
|
||||||
return {collection, collections, entryDraft, boundGetMedia, slug, entry};
|
return { collection, collections, entryDraft, boundGetMedia, slug, entry };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
@ -4,12 +4,12 @@ import { AUTH_REQUEST, AUTH_SUCCESS, AUTH_FAILURE } from '../actions/auth';
|
|||||||
const auth = (state = null, action) => {
|
const auth = (state = null, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case AUTH_REQUEST:
|
case AUTH_REQUEST:
|
||||||
return Immutable.Map({isFetching: true});
|
return Immutable.Map({ isFetching: true });
|
||||||
case AUTH_SUCCESS:
|
case AUTH_SUCCESS:
|
||||||
return Immutable.fromJS({user: action.payload});
|
return Immutable.fromJS({ user: action.payload });
|
||||||
case AUTH_FAILURE:
|
case AUTH_FAILURE:
|
||||||
console.error(action.payload);
|
console.error(action.payload);
|
||||||
return Immutable.Map({error: action.payload.toString()});
|
return Immutable.Map({ error: action.payload.toString() });
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE } from '../actions/confi
|
|||||||
const config = (state = null, action) => {
|
const config = (state = null, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case CONFIG_REQUEST:
|
case CONFIG_REQUEST:
|
||||||
return Immutable.Map({isFetching: true});
|
return Immutable.Map({ isFetching: true });
|
||||||
case CONFIG_SUCCESS:
|
case CONFIG_SUCCESS:
|
||||||
return Immutable.fromJS(action.payload);
|
return Immutable.fromJS(action.payload);
|
||||||
case CONFIG_FAILURE:
|
case CONFIG_FAILURE:
|
||||||
return Immutable.Map({error: action.payload.toString()});
|
return Immutable.Map({ error: action.payload.toString() });
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
ENTRY_REQUEST, ENTRY_SUCCESS, ENTRIES_REQUEST, ENTRIES_SUCCESS
|
ENTRY_REQUEST, ENTRY_SUCCESS, ENTRIES_REQUEST, ENTRIES_SUCCESS
|
||||||
} from '../actions/entries';
|
} from '../actions/entries';
|
||||||
|
|
||||||
const entries = (state = Map({entities: Map(), pages: Map()}), action) => {
|
const entries = (state = Map({ entities: Map(), pages: Map() }), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ENTRY_REQUEST:
|
case ENTRY_REQUEST:
|
||||||
return state.setIn(['entities', `${action.payload.collection}.${action.payload.slug}`, 'isFetching'], true);
|
return state.setIn(['entities', `${action.payload.collection}.${action.payload.slug}`, 'isFetching'], true);
|
||||||
|
@ -2,7 +2,7 @@ import { Map, List } from 'immutable';
|
|||||||
import { DRAFT_CREATE, DRAFT_DISCARD, DRAFT_CHANGE } from '../actions/entries';
|
import { DRAFT_CREATE, DRAFT_DISCARD, DRAFT_CHANGE } from '../actions/entries';
|
||||||
import { ADD_MEDIA, REMOVE_MEDIA } from '../actions/media';
|
import { ADD_MEDIA, REMOVE_MEDIA } from '../actions/media';
|
||||||
|
|
||||||
const initialState = Map({entry: Map(), mediaFiles: List()});
|
const initialState = Map({ entry: Map(), mediaFiles: List() });
|
||||||
|
|
||||||
const entryDraft = (state = Map(), action) => {
|
const entryDraft = (state = Map(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
@ -9,6 +9,6 @@ export default function MediaProxy(value, file, uploaded = false) {
|
|||||||
this.uploaded = uploaded;
|
this.uploaded = uploaded;
|
||||||
this.uri = config.media_folder && !uploaded ? config.media_folder + '/' + value : value;
|
this.uri = config.media_folder && !uploaded ? config.media_folder + '/' + value : value;
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
return this.uploaded ? this.uri : window.URL.createObjectURL(this.file, {oneTimeOnly: true});
|
return this.uploaded ? this.uri : window.URL.createObjectURL(this.file, { oneTimeOnly: true });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user