fix small code issues in RTE implementation
This commit is contained in:
parent
3d83325afc
commit
9c0b7262ef
@ -231,20 +231,25 @@ export function persistUnpublishedEntry(collection, existingUnpublishedEntry) {
|
||||
const transactionID = uuid.v4();
|
||||
const assetProxies = entryDraft.get('mediaFiles').map(path => getAsset(state, path));
|
||||
const entry = entryDraft.get('entry');
|
||||
const transformedData = serializeValues(entryDraft.getIn(['entry', 'data']), collection.get('fields'));
|
||||
const transformedEntry = entry.set('data', transformedData);
|
||||
const transformedEntryDraft = entryDraft.set('entry', transformedEntry);
|
||||
|
||||
dispatch(unpublishedEntryPersisting(collection, transformedEntry, transactionID));
|
||||
/**
|
||||
* Serialize the values of any fields with registered serializers, and
|
||||
* update the entry and entryDraft with the serialized values.
|
||||
*/
|
||||
const serializedData = serializeValues(entryDraft.getIn(['entry', 'data']), collection.get('fields'));
|
||||
const serializedEntry = entry.set('data', serializedData);
|
||||
const serializedEntryDraft = entryDraft.set('entry', serializedEntry);
|
||||
|
||||
dispatch(unpublishedEntryPersisting(collection, serializedEntry, transactionID));
|
||||
const persistAction = existingUnpublishedEntry ? backend.persistUnpublishedEntry : backend.persistEntry;
|
||||
return persistAction.call(backend, state.config, collection, transformedEntryDraft, assetProxies.toJS())
|
||||
return persistAction.call(backend, state.config, collection, serializedEntryDraft, assetProxies.toJS())
|
||||
.then(() => {
|
||||
dispatch(notifSend({
|
||||
message: 'Entry saved',
|
||||
kind: 'success',
|
||||
dismissAfter: 4000,
|
||||
}));
|
||||
return dispatch(unpublishedEntryPersisted(collection, transformedEntry, transactionID));
|
||||
return dispatch(unpublishedEntryPersisted(collection, serializedEntry, transactionID));
|
||||
})
|
||||
.catch((error) => {
|
||||
dispatch(notifSend({
|
||||
|
@ -271,19 +271,24 @@ export function persistEntry(collection) {
|
||||
const backend = currentBackend(state.config);
|
||||
const assetProxies = entryDraft.get('mediaFiles').map(path => getAsset(state, path));
|
||||
const entry = entryDraft.get('entry');
|
||||
const transformedData = serializeValues(entryDraft.getIn(['entry', 'data']), collection.get('fields'));
|
||||
const transformedEntry = entry.set('data', transformedData);
|
||||
const transformedEntryDraft = entryDraft.set('entry', transformedEntry);
|
||||
dispatch(entryPersisting(collection, transformedEntry));
|
||||
|
||||
/**
|
||||
* Serialize the values of any fields with registered serializers, and
|
||||
* update the entry and entryDraft with the serialized values.
|
||||
*/
|
||||
const serializedData = serializeValues(entryDraft.getIn(['entry', 'data']), collection.get('fields'));
|
||||
const serializedEntry = entry.set('data', serializedData);
|
||||
const serializedEntryDraft = entryDraft.set('entry', serializedEntry);
|
||||
dispatch(entryPersisting(collection, serializedEntry));
|
||||
return backend
|
||||
.persistEntry(state.config, collection, transformedEntryDraft, assetProxies.toJS())
|
||||
.persistEntry(state.config, collection, serializedEntryDraft, assetProxies.toJS())
|
||||
.then(() => {
|
||||
dispatch(notifSend({
|
||||
message: 'Entry saved',
|
||||
kind: 'success',
|
||||
dismissAfter: 4000,
|
||||
}));
|
||||
return dispatch(entryPersisted(collection, transformedEntry));
|
||||
return dispatch(entryPersisted(collection, serializedEntry));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
@ -292,7 +297,7 @@ export function persistEntry(collection) {
|
||||
kind: 'danger',
|
||||
dismissAfter: 8000,
|
||||
}));
|
||||
return dispatch(entryPersistFail(collection, transformedEntry, error));
|
||||
return dispatch(entryPersistFail(collection, serializedEntry, error));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -9,6 +9,10 @@ const style = {
|
||||
fontFamily: 'Roboto, "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif',
|
||||
};
|
||||
|
||||
/**
|
||||
* Use a stateful component so that child components can effectively utilize
|
||||
* `shouldComponentUpdate`.
|
||||
*/
|
||||
export default class Preview extends React.Component {
|
||||
render() {
|
||||
const { collection, fields, widgetFor } = this.props;
|
||||
|
@ -1,9 +1,11 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import { ScrollSyncPane } from '../ScrollSync';
|
||||
|
||||
// We need to create a lightweight component here so that we can
|
||||
// access the context within the Frame. This allows us to attach
|
||||
// the ScrollSyncPane to the body.
|
||||
/**
|
||||
* We need to create a lightweight component here so that we can access the
|
||||
* context within the Frame. This allows us to attach the ScrollSyncPane to the
|
||||
* body.
|
||||
*/
|
||||
class PreviewContent extends React.Component {
|
||||
render() {
|
||||
const { previewComponent, previewProps } = this.props;
|
||||
|
@ -17,6 +17,9 @@ export default class PreviewPane extends React.Component {
|
||||
const { fieldsMetaData, getAsset, entry } = props;
|
||||
const widget = resolveWidget(field.get('widget'));
|
||||
|
||||
/**
|
||||
* Use an HOC to provide conditional updates for all previews.
|
||||
*/
|
||||
return !widget.preview ? null : (
|
||||
<PreviewHOC
|
||||
previewComponent={widget.preview}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import ImmutablePropTypes from "react-immutable-proptypes";
|
||||
import isEqual from 'lodash/isEqual';
|
||||
|
||||
const truthy = () => ({ error: false });
|
||||
|
||||
|
@ -19,7 +19,7 @@ import mdastDefinitions from 'mdast-util-definitions';
|
||||
* Yields:
|
||||
*
|
||||
* ```
|
||||
* ![alpha][http://example.com/example.jpg]
|
||||
* ![alpha](http://example.com/example.jpg)
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
@ -1,10 +1,13 @@
|
||||
import React from 'react';
|
||||
|
||||
class PreviewHOC extends React.Component {
|
||||
|
||||
/**
|
||||
* Only re-render on value change, but always re-render objects and lists.
|
||||
* Their child widgets will each also be wrapped with this component, and
|
||||
* will only be updated on value change.
|
||||
*/
|
||||
shouldComponentUpdate(nextProps) {
|
||||
// Only re-render on value change, but always re-render objects and lists.
|
||||
// Their child widgets will each also be wrapped with this component, and
|
||||
// will only be updated on value change.
|
||||
const isWidgetContainer = ['object', 'list'].includes(nextProps.field.get('widget'));
|
||||
return isWidgetContainer || this.props.value !== nextProps.value;
|
||||
}
|
||||
|
@ -68,6 +68,11 @@ class EntryPage extends React.Component {
|
||||
const { entry, newEntry, fields, collection } = nextProps;
|
||||
|
||||
if (entry && !entry.get('isFetching') && !entry.get('error')) {
|
||||
|
||||
/**
|
||||
* Deserialize entry values for widgets with registered serializers before
|
||||
* creating the entry draft.
|
||||
*/
|
||||
const values = deserializeValues(entry.get('data'), fields);
|
||||
const deserializedEntry = entry.set('data', values);
|
||||
this.createDraft(deserializedEntry);
|
||||
|
@ -20,22 +20,40 @@ import registry from './registry';
|
||||
* registered deserialization handlers run on entry load, and serialization
|
||||
* handlers run on persist.
|
||||
*/
|
||||
|
||||
const runSerializer = (values, fields, method) => {
|
||||
|
||||
/**
|
||||
* Reduce the list of fields to a map where keys are field names and values
|
||||
* are field values, serializing the values of fields whose widgets have
|
||||
* registered serializers. If the field is a list or object, call recursively
|
||||
* for nested fields.
|
||||
*/
|
||||
return fields.reduce((acc, field) => {
|
||||
const fieldName = field.get('name');
|
||||
const value = values.get(fieldName);
|
||||
const serializer = registry.getWidgetValueSerializer(field.get('widget'));
|
||||
const nestedFields = field.get('fields');
|
||||
|
||||
// Call recursively for fields within lists
|
||||
if (nestedFields && List.isList(value)) {
|
||||
return acc.set(fieldName, value.map(val => runSerializer(val, nestedFields, method)));
|
||||
} else if (nestedFields && Map.isMap(value)) {
|
||||
}
|
||||
|
||||
// Call recursively for fields within objects
|
||||
if (nestedFields && Map.isMap(value)) {
|
||||
return acc.set(fieldName, runSerializer(value, nestedFields, method));
|
||||
} else if (serializer && !isNil(value)) {
|
||||
}
|
||||
|
||||
// Run serialization method on value if not null or undefined
|
||||
if (serializer && !isNil(value)) {
|
||||
return acc.set(fieldName, serializer[method](value));
|
||||
} else if (!isNil(value)) {
|
||||
}
|
||||
|
||||
// If no serializer is registered for the field's widget, use the field as is
|
||||
if (!isNil(value)) {
|
||||
return acc.set(fieldName, value);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, Map());
|
||||
};
|
||||
|
@ -21,11 +21,10 @@ const entries = (state = Map({ entities: Map(), pages: Map() }), action) => {
|
||||
return state.setIn(['entities', `${ action.payload.collection }.${ action.payload.slug }`, 'isFetching'], true);
|
||||
|
||||
case ENTRY_SUCCESS:
|
||||
const result = state.setIn(
|
||||
return state.setIn(
|
||||
['entities', `${ action.payload.collection }.${ action.payload.entry.slug }`],
|
||||
fromJS(action.payload.entry)
|
||||
);
|
||||
return result;
|
||||
|
||||
case ENTRIES_REQUEST:
|
||||
return state.setIn(['pages', action.payload.collection, 'isFetching'], true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user