editorial workflow HoC
This commit is contained in:
parent
90d4b39fc1
commit
04c50d8def
@ -3,6 +3,7 @@ import { EDITORIAL_WORKFLOW } from '../constants/publishModes';
|
||||
/*
|
||||
* Contant Declarations
|
||||
*/
|
||||
export const INIT = 'init';
|
||||
export const UNPUBLISHED_ENTRIES_REQUEST = 'UNPUBLISHED_ENTRIES_REQUEST';
|
||||
export const UNPUBLISHED_ENTRIES_SUCCESS = 'UNPUBLISHED_ENTRIES_SUCCESS';
|
||||
export const UNPUBLISHED_ENTRIES_FAILURE = 'UNPUBLISHED_ENTRIES_FAILURE';
|
||||
@ -35,6 +36,16 @@ function unpublishedEntriesFailed(error) {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Exported simple Action Creators
|
||||
*/
|
||||
export function init() {
|
||||
return {
|
||||
type: INIT
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exported Thunk Action Creators
|
||||
*/
|
||||
|
@ -1,11 +1,13 @@
|
||||
import LocalForage from 'localforage';
|
||||
import MediaProxy from '../../valueObjects/MediaProxy';
|
||||
import { Base64 } from 'js-base64';
|
||||
import { EDITORIAL_WORKFLOW } from '../../constants/publishModes';
|
||||
import { EDITORIAL_WORKFLOW, status } from '../../constants/publishModes';
|
||||
|
||||
const API_ROOT = 'https://api.github.com';
|
||||
|
||||
export default class API {
|
||||
|
||||
|
||||
constructor(token, repo, branch) {
|
||||
this.token = token;
|
||||
this.repo = repo;
|
||||
@ -192,7 +194,7 @@ export default class API {
|
||||
return this.createBranch(branchName, response.sha)
|
||||
.then(this.storeMetadata(contentKey, {
|
||||
type: 'PR',
|
||||
status: 'draft',
|
||||
status: status.DRAFT,
|
||||
branch: branchName,
|
||||
collection: options.collectionName,
|
||||
title: options.parsedData.title,
|
||||
|
@ -1,3 +1,18 @@
|
||||
// Create/edit workflows
|
||||
import { Map } from 'immutable';
|
||||
|
||||
// Create/edit workflow modes
|
||||
export const SIMPLE = 'simple';
|
||||
export const EDITORIAL_WORKFLOW = 'editorial_workflow';
|
||||
|
||||
// Available status
|
||||
export const status = {
|
||||
DRAFT: 'draft',
|
||||
PENDING_REVIEW: 'pending_review',
|
||||
PENDING_PUBLISH: 'pending_publish',
|
||||
};
|
||||
|
||||
export const statusDescriptions = Map({
|
||||
[status.DRAFT]: 'Draft',
|
||||
[status.PENDING_REVIEW]: 'Waiting for Review',
|
||||
[status.PENDING_PUBLISH]: 'Waiting to go live',
|
||||
});
|
||||
|
@ -2,15 +2,14 @@ import React, { PropTypes } from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { connect } from 'react-redux';
|
||||
import { loadEntries } from '../actions/entries';
|
||||
import { loadUnpublishedEntries } from '../actions/editorialWorkflow';
|
||||
import { selectEntries } from '../reducers';
|
||||
import { Loader } from '../components/UI';
|
||||
import EntryListing from '../components/EntryListing';
|
||||
import EditorialWorkflow from './EditorialWorkflowHoC';
|
||||
|
||||
class DashboardPage extends React.Component {
|
||||
componentDidMount() {
|
||||
const { collection, dispatch } = this.props;
|
||||
dispatch(loadUnpublishedEntries());
|
||||
if (collection) {
|
||||
dispatch(loadEntries(collection));
|
||||
}
|
||||
@ -38,7 +37,6 @@ class DashboardPage extends React.Component {
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
DashboardPage.propTypes = {
|
||||
collection: ImmutablePropTypes.map.isRequired,
|
||||
collections: ImmutablePropTypes.orderedMap.isRequired,
|
||||
@ -46,6 +44,13 @@ DashboardPage.propTypes = {
|
||||
entries: ImmutablePropTypes.list,
|
||||
};
|
||||
|
||||
/*
|
||||
* Instead of checking the publish mode everywhere to dispatch & render the additional editorial workflow stuff,
|
||||
* We delegate it to a Higher Order Component
|
||||
*/
|
||||
DashboardPage = EditorialWorkflow(DashboardPage);
|
||||
|
||||
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const { collections } = state;
|
||||
const { name, slug } = ownProps.params;
|
||||
|
52
src/containers/EditorialWorkflowHoC.js
Normal file
52
src/containers/EditorialWorkflowHoC.js
Normal file
@ -0,0 +1,52 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { init, loadUnpublishedEntries } from '../actions/editorialWorkflow';
|
||||
import { selectUnpublishedEntries } from '../reducers';
|
||||
import { EDITORIAL_WORKFLOW } from '../constants/publishModes';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
export default function EditorialWorkflow(WrappedComponent) {
|
||||
class EditorialWorkflow extends WrappedComponent {
|
||||
|
||||
componentDidMount() {
|
||||
const { dispatch, isEditorialWorkflow } = this.props;
|
||||
if (isEditorialWorkflow) {
|
||||
dispatch(init());
|
||||
dispatch(loadUnpublishedEntries());
|
||||
}
|
||||
super.componentDidMount();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isEditorialWorkflow } = this.props;
|
||||
if (!isEditorialWorkflow) return super.render();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>HOC</h2>
|
||||
{super.render()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EditorialWorkflow.propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
isEditorialWorkflow: PropTypes.bool.isRequired,
|
||||
unpublishedEntries: ImmutablePropTypes.list,
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const publish_mode = state.config.get('publish_mode');
|
||||
const isEditorialWorkflow = (publish_mode === EDITORIAL_WORKFLOW);
|
||||
const returnObj = { isEditorialWorkflow };
|
||||
|
||||
if (isEditorialWorkflow) {
|
||||
returnObj.unpublishedEntries = selectUnpublishedEntries(state, 'draft');
|
||||
}
|
||||
|
||||
return returnObj;
|
||||
}
|
||||
|
||||
return connect(mapStateToProps)(EditorialWorkflow);
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
import { Map, List, fromJS } from 'immutable';
|
||||
import {
|
||||
UNPUBLISHED_ENTRIES_REQUEST, UNPUBLISHED_ENTRIES_SUCCESS
|
||||
INIT, UNPUBLISHED_ENTRIES_REQUEST, UNPUBLISHED_ENTRIES_SUCCESS
|
||||
} from '../actions/editorialWorkflow';
|
||||
|
||||
const unpublishedEntries = (state = Map({ entities: Map(), pages: Map() }), action) => {
|
||||
const unpublishedEntries = (state = null, action) => {
|
||||
switch (action.type) {
|
||||
case INIT:
|
||||
// Editorial workflow must be explicitly initiated.
|
||||
return Map({ entities: Map(), pages: Map() });
|
||||
case UNPUBLISHED_ENTRIES_REQUEST:
|
||||
return state.setIn(['pages', 'isFetching'], true);
|
||||
|
||||
@ -29,9 +32,9 @@ export const selectUnpublishedEntry = (state, status, slug) => (
|
||||
);
|
||||
|
||||
export const selectUnpublishedEntries = (state, status) => {
|
||||
if (!state) return;
|
||||
const slugs = state.getIn(['pages', 'ids']);
|
||||
return slugs && slugs.map((slug) => selectUnpublishedEntry(state, status, slug));
|
||||
};
|
||||
|
||||
|
||||
export default unpublishedEntries;
|
||||
|
Loading…
x
Reference in New Issue
Block a user