Skip to content

Commit

Permalink
reactive-render now a action, handle clicking into rerendered inline …
Browse files Browse the repository at this point in the history
…component forms
  • Loading branch information
nelsonpecora committed Jun 20, 2017
1 parent e52cf9b commit 9b10722
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 49 deletions.
22 changes: 9 additions & 13 deletions lib/component-data/actions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash';
import { removeElement, find } from '@nymag/dom';
import { UPDATE_COMPONENT, REVERT_COMPONENT, RENDER_COMPONENT, REMOVE_COMPONENT } from './mutationTypes';
import { UPDATE_COMPONENT, REVERT_COMPONENT, REMOVE_COMPONENT } from './mutationTypes';
import { getData, getModel, getTemplate, getSchema } from '../core-data/components';
import { getComponentName, refProp, refAttr, layoutAttr, editAttr, componentListProp, componentProp } from '../utils/references';
import { save as modelSave, render as modelRender } from './model';
Expand All @@ -22,7 +22,6 @@ function logSaveError(uri, e, store) {
console.error(`Error saving component (${getComponentName(uri)}):`, e);
store.dispatch('finishProgress', 'error');
store.dispatch('showStatus', { type: 'error', message: `Changes made to ${label(getComponentName(uri))} were not saved!` });
throw e; // prevent anything after this from running
}

/**
Expand All @@ -42,26 +41,25 @@ function clientSave(uri, data, oldData, store, {eventID, snapshot, paths}) { //
.catch((e) => {
// if model.js errors (or times out), re-render component with old data
// and show the end user an error message
store.commit(RENDER_COMPONENT, { uri, data: oldData, snapshot, paths });
logSaveError(uri, e, store);
return store.dispatch('render', { uri, data: oldData, snapshot, paths });
})
.then((savedData) => {
// kick api call off in the background
addToQueue(save, [uri, savedData, false], 'save') // add hooks=false to prevent models from re-running on server
// note: we don't care about the data we got back from the api
.catch((e) => {
store.commit(REVERT_COMPONENT, {uri, oldData});
store.commit(RENDER_COMPONENT, { uri, data: oldData, snapshot, paths });
logSaveError(uri, e, store);
store.commit(REVERT_COMPONENT, {uri, oldData});
return store.dispatch('render', { uri, data: oldData, snapshot, paths });
});

return savedData;
})
.then((savedData) => modelRender(uri, savedData))
.then((renderableData) => {
store.commit(UPDATE_COMPONENT, {uri, data: renderableData});
store.commit(RENDER_COMPONENT, { uri, data: renderableData, snapshot, paths });
return renderableData;
return store.dispatch('render', { uri, data: renderableData, snapshot, paths });
});
}

Expand All @@ -80,13 +78,12 @@ function serverSave(uri, data, oldData, store, {snapshot, paths}) { // eslint-di
return addToQueue(save, [uri, data], 'save')
.then((res) => {
store.commit(UPDATE_COMPONENT, {uri, data: res});
store.commit(RENDER_COMPONENT, { uri, data: res, snapshot, paths });
return res;
return store.dispatch('render', { uri, data: res, snapshot, paths });
})
.catch((e) => {
store.commit(REVERT_COMPONENT, {uri, oldData});
store.commit(RENDER_COMPONENT, { uri, data: oldData, snapshot, paths });
logSaveError(uri, e, store);
return store.dispatch('render', { uri, data: oldData, snapshot, paths });
});
}

Expand Down Expand Up @@ -140,14 +137,13 @@ function serverSaveAndRerender(uri, data, oldData, store, {snapshot, paths}) { /
return addToQueue(getObject, [uri], 'save')
.then((res) => {
store.commit(UPDATE_COMPONENT, {uri, data: res});
store.commit(RENDER_COMPONENT, { uri, html, snapshot, paths });
return res;
return store.dispatch('render', { uri, html, snapshot, paths });
})
// otherwise revert the data
.catch((e) => {
store.commit(REVERT_COMPONENT, {uri, oldData});
store.commit(RENDER_COMPONENT, { uri, html: oldHTML, snapshot, paths });
logSaveError(uri, e, store);
return store.dispatch('render', { uri, html: oldHTML, snapshot, paths });
});
});
}
Expand Down
2 changes: 1 addition & 1 deletion lib/component-data/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default {
_.set(state, `schemas['${name}']`, data);
return state;
},
[RENDER_COMPONENT]: (state) => state,
[RENDER_COMPONENT]: (state) => state, // mutation for snapshots, plugins to listen for
[REMOVE_COMPONENT]: (state, {uri}) => {
_.set(state, `components['${uri}']`, {});
// set to empty obj rather than null so decorators and such don't fail hard
Expand Down
51 changes: 27 additions & 24 deletions lib/component-data/reactive-render.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { RENDER_COMPONENT } from './mutationTypes';
import { RENDER_PAGE } from '../page-data/mutationTypes';
import { render as renderTemplate } from './template';
import { decorate } from '../decorators';
import { refAttr, editAttr } from '../utils/references';
import { refAttr, editAttr, isComponent } from '../utils/references';
import addPlaceholder from '../decorators/placeholders';
import addComponentList from '../decorators/component-list';
import { getComponentFragment, getComponentListFragment, replaceHeadComponent, replaceHeadList } from '../utils/head-components';
Expand Down Expand Up @@ -136,47 +136,50 @@ export function updateDOM(uri, newEl, paths) {
* @param {string} uri
* @param {Element} html
* @param {array} paths that have changed
* @returns {Promise}
*/
function renderServerHTML(uri, html, paths) {
updateDOM(uri, html, paths);
return Promise.resolve(updateDOM(uri, html, paths));
}

/**
* render a component client-side based on data
* @param {string} uri
* @param {object} data
* @param {array} paths that have changed
* @returns {Promise}
*/
function renderClientData(uri, data, paths) {
renderTemplate(uri, data).then((html) => updateDOM(uri, html, paths));
return renderTemplate(uri, data).then((html) => updateDOM(uri, html, paths));
}

/**
* reactive render plugin
* listens to render events and updates the dom
* @param {object} store
* @param {string} uri
* @param {object} [data]
* @param {Element} [html]
* @param {string} snapshot
* @param {array} paths
* @returns {Promise}
*/
export default function reactiveRender(store) {
store.subscribe((mutation) => {
if (mutation.type === RENDER_COMPONENT) {
const uri = mutation.payload.uri,
data = mutation.payload.data,
html = mutation.payload.html,
paths = mutation.payload.paths;

if (html) {
// server-side legacy html (or new layout html)
renderServerHTML(uri, html, paths);
} else if (data) {
renderClientData(uri, data, paths);
}
} else if (mutation.type === RENDER_PAGE) {
const uri = mutation.payload.uri,
html = mutation.payload.html,
paths = mutation.payload.paths;

// render new page html
renderServerHTML(uri, html, paths);
export function render(store, {uri, data, html, snapshot, paths}) {
let promise;

if (html) {
// server-side legacy html (or new layout html)
promise = renderServerHTML(uri, html, paths);
} else {
// client-side html, passing through handlebars template
promise = renderClientData(uri, data, paths);
}

return promise.then(() => {
if (isComponent(uri)) {
store.commit(RENDER_COMPONENT, { uri, data, html, snapshot, paths });
} else {
store.commit(RENDER_PAGE, { uri, data, html, snapshot, paths });
}
});
}
3 changes: 2 additions & 1 deletion lib/core-data/actions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import _ from 'lodash';
import preloader from '../preloader/actions';
import * as reactiveRender from '../component-data/reactive-render';
import * as decorators from '../decorators/actions';
import * as forms from '../forms/actions';
import * as components from '../component-data/actions';
Expand All @@ -12,6 +13,6 @@ import * as validators from '../validators/actions';
import * as undo from '../undo/actions';
import * as lists from '../lists/actions';

const actions = _.assign({}, decorators, forms, { preload: preloader }, components, pages, pageState, toolbar, panes, deepLinking, validators, undo, lists);
const actions = _.assign({}, decorators, forms, { preload: preloader }, reactiveRender, components, pages, pageState, toolbar, panes, deepLinking, validators, undo, lists);

export default actions;
3 changes: 1 addition & 2 deletions lib/core-data/plugins.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import reactiveRender from '../component-data/reactive-render';
import pubsub from '../component-data/pubsub';
import undo from '../undo/plugin';

// note: external plugins might be added after DOMContentLoaded,
// so we manually add them in edit.js
const plugins = [reactiveRender, pubsub, undo];
const plugins = [pubsub, undo];

export default plugins;
9 changes: 7 additions & 2 deletions lib/decorators/actions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash';
import { SELECT, UN_SELECT, FOCUS, UN_FOCUS } from './mutationTypes';
import { getPrevVisible, getNextVisible, getParentComponent } from '../utils/component-elements';
import { getPrevVisible, getNextVisible, getParentComponent, getFieldEl } from '../utils/component-elements';
import { refAttr, layoutAttr } from '../utils/references';
import { scrollToY } from '../utils/scroll';
import { checkValidity } from '../forms/native-validation';
Expand Down Expand Up @@ -103,9 +103,14 @@ export function focus(store, { uri, path, el, offset, appendText }) { // love to
offset = offset || 0; // if no offset is passed in, set it to zero

return unfocus(store).then(() => {
// use the original el if it's in the doc,
// but if we're closing, rerendering, and opening a different form in the same component
// the original el may have been detached
const fieldEl = document.body.contains(el) ? el : getFieldEl(uri, path);

// note: we don't select components automatically when we focus,
// because you cannot 'select' head components
store.commit(FOCUS, uri, path);
store.dispatch('openForm', { uri, path, el, offset, appendText });
store.dispatch('openForm', { uri, path, el: fieldEl, offset, appendText });
}).catch(_.noop);
}
9 changes: 4 additions & 5 deletions lib/page-data/actions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'lodash';
import { UPDATE_PAGE, REVERT_PAGE, RENDER_PAGE, PAGE_PUBLISH, PAGE_SCHEDULE, PAGE_UNPUBLISH, PAGE_UNSCHEDULE } from './mutationTypes';
import { UPDATE_PAGE, REVERT_PAGE, PAGE_PUBLISH, PAGE_SCHEDULE, PAGE_UNPUBLISH, PAGE_UNSCHEDULE } from './mutationTypes';
import { save, create, getObject, removeText, remove, getHTML } from '../core-data/api';
import { add as addToQueue } from '../core-data/queue';
import { replaceVersion, pagesRoute, refProp, htmlExt, editExt, urisRoute, scheduleRoute } from '../utils/references';
Expand Down Expand Up @@ -36,16 +36,15 @@ function queuePageSave(uri, data, oldData, store, {snapshot, paths}) { // eslint
// note: we don't care about the data we got back from the api
store.commit(UPDATE_PAGE, data);
if (shouldRender(paths)) {
store.commit(RENDER_PAGE, {html, snapshot, paths});
return store.dispatch('render', { uri, html, snapshot, paths });
}
return data;
})
.catch((e) => {
store.commit(REVERT_PAGE, oldData);
logSaveError(uri, e);
if (shouldRender(paths)) {
store.commit(RENDER_PAGE, {html: document, snapshot, paths});
return store.dispatch('render', { uri, html: document, snapshot, paths });
}
logSaveError(uri, e);
});
}

Expand Down
2 changes: 1 addition & 1 deletion lib/page-data/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default {
// todo: set something that shows the error
return state;
},
[RENDER_PAGE]: (state) => state,
[RENDER_PAGE]: (state) => state, // mutation for snapshots, plugins to listen for
[PAGE_PUBLISH]: (state, { url, date }) => {
_.set(state, 'page.state.published', true);
_.set(state, 'page.state.publishedUrl', url);
Expand Down

0 comments on commit 9b10722

Please sign in to comment.