Editorial workflow Improvements (#212)

* Merge conflicts automatically. Closes #208
* removed unpublished entry route
All entries (either under editorial workflow or not) go through the same edit route.
This commit is contained in:
Cássio Souza
2017-01-11 20:58:15 -02:00
committed by GitHub
parent c40171820f
commit 48d8077ff0
19 changed files with 279 additions and 155 deletions

View File

@ -1,6 +1,7 @@
import history from '../routing/history';
export const SWITCH_VISUAL_MODE = 'SWITCH_VISUAL_MODE';
export const CLOSED_ENTRY = 'CLOSED_ENTRY';
export function switchVisualMode(useVisualMode) {
return {
@ -9,8 +10,13 @@ export function switchVisualMode(useVisualMode) {
};
}
export function cancelEdit() {
return () => {
history.goBack();
export function closeEntry(collection) {
return (dispatch) => {
if (collection && collection.get('name', false)) {
history.push(`collections/${ collection.get('name') }`);
} else {
history.goBack();
}
dispatch({ type: CLOSED_ENTRY });
};
}

View File

@ -1,9 +1,12 @@
import uuid from 'uuid';
import { actions as notifActions } from 'redux-notifications';
import { closeEntry } from './editor';
import { BEGIN, COMMIT, REVERT } from 'redux-optimist';
import { currentBackend } from '../backends/backend';
import { getAsset } from '../reducers';
import { loadEntry } from './entries';
import { status, EDITORIAL_WORKFLOW } from '../constants/publishModes';
import { EditorialWorkflowError } from "../valueObjects/errors";
const { notifSend } = notifActions;
@ -12,6 +15,7 @@ const { notifSend } = notifActions;
*/
export const UNPUBLISHED_ENTRY_REQUEST = 'UNPUBLISHED_ENTRY_REQUEST';
export const UNPUBLISHED_ENTRY_SUCCESS = 'UNPUBLISHED_ENTRY_SUCCESS';
export const UNPUBLISHED_ENTRY_REDIRECT = 'UNPUBLISHED_ENTRY_REDIRECT';
export const UNPUBLISHED_ENTRIES_REQUEST = 'UNPUBLISHED_ENTRIES_REQUEST';
export const UNPUBLISHED_ENTRIES_SUCCESS = 'UNPUBLISHED_ENTRIES_SUCCESS';
@ -33,17 +37,33 @@ export const UNPUBLISHED_ENTRY_PUBLISH_FAILURE = 'UNPUBLISHED_ENTRY_PUBLISH_FAIL
* Simple Action Creators (Internal)
*/
function unpublishedEntryLoading(status, slug) {
function unpublishedEntryLoading(collection, slug) {
return {
type: UNPUBLISHED_ENTRY_REQUEST,
payload: { status, slug },
payload: {
collection: collection.get('name'),
slug,
},
};
}
function unpublishedEntryLoaded(status, entry) {
function unpublishedEntryLoaded(collection, entry) {
return {
type: UNPUBLISHED_ENTRY_SUCCESS,
payload: { status, entry },
payload: {
collection: collection.get('name'),
entry,
},
};
}
function unpublishedEntryRedirected(collection, slug) {
return {
type: UNPUBLISHED_ENTRY_REDIRECT,
payload: {
collection: collection.get('name'),
slug,
},
};
}
@ -75,7 +95,10 @@ function unpublishedEntriesFailed(error) {
function unpublishedEntryPersisting(collection, entry, transactionID) {
return {
type: UNPUBLISHED_ENTRY_PERSIST_REQUEST,
payload: { collection, entry },
payload: {
collection: collection.get('name'),
entry,
},
optimist: { type: BEGIN, id: transactionID },
};
}
@ -83,7 +106,10 @@ function unpublishedEntryPersisting(collection, entry, transactionID) {
function unpublishedEntryPersisted(collection, entry, transactionID) {
return {
type: UNPUBLISHED_ENTRY_PERSIST_SUCCESS,
payload: { collection, entry },
payload: {
collection: collection.get('name'),
entry,
},
optimist: { type: COMMIT, id: transactionID },
};
}
@ -99,7 +125,12 @@ function unpublishedEntryPersistedFail(error, transactionID) {
function unpublishedEntryStatusChangeRequest(collection, slug, oldStatus, newStatus, transactionID) {
return {
type: UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST,
payload: { collection, slug, oldStatus, newStatus },
payload: {
collection,
slug,
oldStatus,
newStatus,
},
optimist: { type: BEGIN, id: transactionID },
};
}
@ -107,7 +138,12 @@ function unpublishedEntryStatusChangeRequest(collection, slug, oldStatus, newSta
function unpublishedEntryStatusChangePersisted(collection, slug, oldStatus, newStatus, transactionID) {
return {
type: UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS,
payload: { collection, slug, oldStatus, newStatus },
payload: {
collection,
slug,
oldStatus,
newStatus,
},
optimist: { type: COMMIT, id: transactionID },
};
}
@ -120,18 +156,18 @@ function unpublishedEntryStatusChangeError(collection, slug, transactionID) {
};
}
function unpublishedEntryPublishRequest(collection, slug, status, transactionID) {
function unpublishedEntryPublishRequest(collection, slug, transactionID) {
return {
type: UNPUBLISHED_ENTRY_PUBLISH_REQUEST,
payload: { collection, slug, status },
payload: { collection, slug },
optimist: { type: BEGIN, id: transactionID },
};
}
function unpublishedEntryPublished(collection, slug, status, transactionID) {
function unpublishedEntryPublished(collection, slug, transactionID) {
return {
type: UNPUBLISHED_ENTRY_PUBLISH_SUCCESS,
payload: { collection, slug, status },
payload: { collection, slug },
optimist: { type: COMMIT, id: transactionID },
};
}
@ -148,13 +184,25 @@ function unpublishedEntryPublishError(collection, slug, transactionID) {
* Exported Thunk Action Creators
*/
export function loadUnpublishedEntry(collection, status, slug) {
export function loadUnpublishedEntry(collection, slug) {
return (dispatch, getState) => {
const state = getState();
const backend = currentBackend(state.config);
dispatch(unpublishedEntryLoading(status, slug));
dispatch(unpublishedEntryLoading(collection, slug));
backend.unpublishedEntry(collection, slug)
.then(entry => dispatch(unpublishedEntryLoaded(status, entry)));
.then(entry => dispatch(unpublishedEntryLoaded(collection, entry)))
.catch((error) => {
if (error instanceof EditorialWorkflowError && error.notUnderEditorialWorkflow) {
dispatch(unpublishedEntryRedirected(collection, slug));
dispatch(loadEntry(collection, slug));
} else {
dispatch(notifSend({
message: `Error loading entry: ${ error }`,
kind: 'danger',
dismissAfter: 8000,
}));
}
});
};
}
@ -188,13 +236,14 @@ export function persistUnpublishedEntry(collection, entryDraft, existingUnpublis
kind: 'success',
dismissAfter: 4000,
}));
dispatch(closeEntry());
dispatch(unpublishedEntryPersisted(collection, entry, transactionID));
})
.catch((error) => {
dispatch(notifSend({
message: 'Failed to persist entry',
message: `Failed to persist entry: ${ error }`,
kind: 'danger',
dismissAfter: 4000,
dismissAfter: 8000,
}));
dispatch(unpublishedEntryPersistedFail(error, transactionID));
});
@ -217,17 +266,22 @@ export function updateUnpublishedEntryStatus(collection, slug, oldStatus, newSta
};
}
export function publishUnpublishedEntry(collection, slug, status) {
export function publishUnpublishedEntry(collection, slug) {
return (dispatch, getState) => {
const state = getState();
const backend = currentBackend(state.config);
const transactionID = uuid.v4();
dispatch(unpublishedEntryPublishRequest(collection, slug, status, transactionID));
backend.publishUnpublishedEntry(collection, slug, status)
dispatch(unpublishedEntryPublishRequest(collection, slug, transactionID));
backend.publishUnpublishedEntry(collection, slug)
.then(() => {
dispatch(unpublishedEntryPublished(collection, slug, status, transactionID));
dispatch(unpublishedEntryPublished(collection, slug, transactionID));
})
.catch(() => {
.catch((error) => {
dispatch(notifSend({
message: `Failed to merge: ${ error }`,
kind: 'danger',
dismissAfter: 8000,
}));
dispatch(unpublishedEntryPublishError(collection, slug, transactionID));
});
};

View File

@ -1,5 +1,6 @@
import { List } from 'immutable';
import { actions as notifActions } from 'redux-notifications';
import { closeEntry } from './editor';
import { currentBackend } from '../backends/backend';
import { getIntegrationProvider } from '../integrations';
import { getAsset, selectIntegration } from '../reducers';
@ -164,7 +165,7 @@ export function changeDraftField(field, value, metadata) {
* Exported Thunk Action Creators
*/
export function loadEntry(entry, collection, slug) {
export function loadEntry(collection, slug) {
return (dispatch, getState) => {
const state = getState();
const backend = currentBackend(state.config);
@ -177,7 +178,7 @@ export function loadEntry(entry, collection, slug) {
dispatch(notifSend({
message: `Failed to load entry: ${ error.message }`,
kind: 'danger',
dismissAfter: 4000,
dismissAfter: 8000,
}));
dispatch(entryLoadError(error, collection, slug));
});
@ -227,13 +228,14 @@ export function persistEntry(collection, entryDraft) {
kind: 'success',
dismissAfter: 4000,
}));
dispatch(closeEntry(collection));
dispatch(entryPersisted(collection, entry));
})
.catch((error) => {
dispatch(notifSend({
message: 'Failed to persist entry',
message: `Failed to persist entry: ${ error }`,
kind: 'danger',
dismissAfter: 4000,
dismissAfter: 8000,
}));
dispatch(entryPersistFail(collection, entry, error));
});