diff --git a/src/actions/config.js b/src/actions/config.js index 51f743cd..f506d705 100644 --- a/src/actions/config.js +++ b/src/actions/config.js @@ -1,6 +1,7 @@ import yaml from 'js-yaml'; import { currentBackend } from '../backends/backend'; import { authenticate } from '../actions/auth'; +import * as ImageProxy from '../valueObjects/ImageProxy'; export const CONFIG_REQUEST = 'CONFIG_REQUEST'; export const CONFIG_SUCCESS = 'CONFIG_SUCCESS'; @@ -27,9 +28,17 @@ export function configFailed(err) { }; } +export function configDidLoad(config) { + return (dispatch) => { + ImageProxy.setConfig(config); + dispatch(configLoaded(config)); + }; +} + + export function loadConfig(config) { if (window.CMS_CONFIG) { - return configLoaded(window.CMS_CONFIG); + return configDidLoad(window.CMS_CONFIG); } return (dispatch, getState) => { dispatch(configLoading()); @@ -40,7 +49,7 @@ export function loadConfig(config) { } response.text().then(parseConfig).then((config) => { - dispatch(configLoaded(config)); + dispatch(configDidLoad(config)); const backend = currentBackend(config); const user = backend && backend.currentUser(); user && dispatch(authenticate(user)); diff --git a/src/actions/entries.js b/src/actions/entries.js index dffcecc8..a20d13d8 100644 --- a/src/actions/entries.js +++ b/src/actions/entries.js @@ -4,6 +4,10 @@ export const ENTRY_REQUEST = 'ENTRY_REQUEST'; export const ENTRY_SUCCESS = 'ENTRY_SUCCESS'; export const ENTRY_FAILURE = 'ENTRY_FAILURE'; +export const ENTRY_PERSIST_REQUEST = 'ENTRY_PERSIST_REQUEST'; +export const ENTRY_PERSIST_SUCCESS = 'ENTRY_PERSIST_SUCCESS'; +export const ENTRY_PERSIST_FAILURE = 'ENTRY_PERSIST_FAILURE'; + export const ENTRIES_REQUEST = 'ENTRIES_REQUEST'; export const ENTRIES_SUCCESS = 'ENTRIES_SUCCESS'; export const ENTRIES_FAILURE = 'ENTRIES_FAILURE'; @@ -28,17 +32,34 @@ export function entryLoaded(collection, entry) { }; } -export function entriesLoaded(collection, entries, pagination) { +export function entryPersisting(collection, entry) { return { - type: ENTRIES_SUCCESS, + type: ENTRY_PERSIST_REQUEST, payload: { - collection: collection.get('name'), - entries: entries, - pages: pagination + collection: collection, + entry: entry } }; } +export function entryPersisted(collection, entry) { + return { + type: ENTRY_PERSIST_SUCCESS, + payload: { + collection: collection, + entry: entry + } + }; +} + +export function entryPersistFail(collection, entry, error) { + return { + type: ENTRIES_FAILURE, + error: 'Failed to persist entry', + payload: error.toString() + }; +} + export function entriesLoading(collection) { return { type: ENTRIES_REQUEST, @@ -48,6 +69,17 @@ export function entriesLoading(collection) { }; } +export function entriesLoaded(collection, entries, pagination) { + return { + type: ENTRIES_SUCCESS, + payload: { + collection: collection.get('name'), + entries: entries, + pages: pagination + } + }; +} + export function entriesFailed(collection, error) { return { type: ENTRIES_FAILURE, @@ -76,6 +108,18 @@ export function loadEntries(collection) { dispatch(entriesLoading(collection)); backend.entries(collection) - .then((response) => dispatch(entriesLoaded(collection, response.entries, response.pagination))) + .then((response) => dispatch(entriesLoaded(collection, response.entries, response.pagination))); + }; +} + +export function persist(collection, entry, mediaFiles) { + return (dispatch, getState) => { + const state = getState(); + const backend = currentBackend(state.config); + dispatch(entryPersisting(collection, entry)); + backend.persist(collection, entry, mediaFiles).then( + (entry) => dispatch(entryPersisted(collection, entry)), + (error) => dispatch(entryPersistFail(collection, entry, error)) + ); }; } diff --git a/src/backends/backend.js b/src/backends/backend.js index 72dba0c6..8bb51aa4 100644 --- a/src/backends/backend.js +++ b/src/backends/backend.js @@ -66,6 +66,22 @@ class Backend { return entry; }; } + + persist(collection, entry, mediaFiles) { + const entryData = entry.get('data').toJS(); + const entryObj = { + path: entry.get('path'), + slug: entry.get('slug'), + raw: this.entryToRaw(collection, entryData) + }; + + return this.implementation.persist(collection, entryObj, mediaFiles.toJS()); + } + + entryToRaw(collection, entry) { + const format = resolveFormat(collection, entry); + return format && format.toFile(entry); + } } export function resolveBackend(config) { diff --git a/src/backends/test-repo/implementation.js b/src/backends/test-repo/implementation.js index 3f4ed4bd..c14bfe31 100644 --- a/src/backends/test-repo/implementation.js +++ b/src/backends/test-repo/implementation.js @@ -47,4 +47,9 @@ export default class TestRepo { response.entries.filter((entry) => entry.slug === slug)[0] )); } + + persist(collection, entry, mediaFiles) { + alert('This will be the persisted data:\n' + entry.raw); + return Promise.resolve({collection, entry}); + } } diff --git a/src/components/ControlPane.js b/src/components/ControlPane.js index 203bc581..c5225a55 100644 --- a/src/components/ControlPane.js +++ b/src/components/ControlPane.js @@ -9,7 +9,8 @@ export default class ControlPane extends React.Component { key: field.get('name'), field: field, value: entry.getIn(['data', field.get('name')]), - onChange: (value) => this.props.onChange(entry.setIn(['data', field.get('name')], value)) + onChange: (value) => this.props.onChange(entry.setIn(['data', field.get('name')], value)), + onAddMedia: (mediaFile) => this.props.onAddMedia(mediaFile) }); } diff --git a/src/components/EntryEditor.js b/src/components/EntryEditor.js index 488b5cb3..163f13e1 100644 --- a/src/components/EntryEditor.js +++ b/src/components/EntryEditor.js @@ -1,18 +1,32 @@ import React from 'react'; +import Immutable from 'immutable'; import ControlPane from './ControlPane'; import PreviewPane from './PreviewPane'; export default class EntryEditor extends React.Component { constructor(props) { super(props); - this.state = {entry: props.entry}; + this.state = { + entry: props.entry, + mediaFiles: Immutable.List() + }; this.handleChange = this.handleChange.bind(this); + this.handleAddMedia = this.handleAddMedia.bind(this); + this.handleSave = this.handleSave.bind(this); } handleChange(entry) { this.setState({entry: entry}); } + handleAddMedia(mediaFile) { + this.setState({mediaFiles: this.state.mediaFiles.push(mediaFile)}); + } + + handleSave() { + this.props.onPersist(this.state.entry, this.state.mediaFiles); + } + render() { const { collection, entry } = this.props; @@ -21,12 +35,18 @@ export default class EntryEditor extends React.Component {