2016-10-18 12:32:39 -02:00
|
|
|
import uuid from 'uuid';
|
2016-10-31 18:19:51 -02:00
|
|
|
import { actions as notifActions } from 'redux-notifications';
|
2017-01-11 20:58:15 -02:00
|
|
|
import { closeEntry } from './editor';
|
2016-10-18 12:32:39 -02:00
|
|
|
import { BEGIN, COMMIT, REVERT } from 'redux-optimist';
|
2016-09-06 13:04:17 -03:00
|
|
|
import { currentBackend } from '../backends/backend';
|
2017-01-10 22:23:22 -02:00
|
|
|
import { getAsset } from '../reducers';
|
2017-01-11 20:58:15 -02:00
|
|
|
import { loadEntry } from './entries';
|
2016-10-31 18:19:51 -02:00
|
|
|
import { status, EDITORIAL_WORKFLOW } from '../constants/publishModes';
|
2017-01-11 20:58:15 -02:00
|
|
|
import { EditorialWorkflowError } from "../valueObjects/errors";
|
2016-10-31 18:19:51 -02:00
|
|
|
|
|
|
|
const { notifSend } = notifActions;
|
|
|
|
|
2016-09-06 13:04:17 -03:00
|
|
|
/*
|
|
|
|
* Contant Declarations
|
|
|
|
*/
|
2016-09-13 03:59:48 -03:00
|
|
|
export const UNPUBLISHED_ENTRY_REQUEST = 'UNPUBLISHED_ENTRY_REQUEST';
|
|
|
|
export const UNPUBLISHED_ENTRY_SUCCESS = 'UNPUBLISHED_ENTRY_SUCCESS';
|
2017-01-11 20:58:15 -02:00
|
|
|
export const UNPUBLISHED_ENTRY_REDIRECT = 'UNPUBLISHED_ENTRY_REDIRECT';
|
2016-09-13 03:59:48 -03:00
|
|
|
|
2016-09-06 13:04:17 -03:00
|
|
|
export const UNPUBLISHED_ENTRIES_REQUEST = 'UNPUBLISHED_ENTRIES_REQUEST';
|
|
|
|
export const UNPUBLISHED_ENTRIES_SUCCESS = 'UNPUBLISHED_ENTRIES_SUCCESS';
|
|
|
|
export const UNPUBLISHED_ENTRIES_FAILURE = 'UNPUBLISHED_ENTRIES_FAILURE';
|
|
|
|
|
2016-09-13 14:31:18 -03:00
|
|
|
export const UNPUBLISHED_ENTRY_PERSIST_REQUEST = 'UNPUBLISHED_ENTRY_PERSIST_REQUEST';
|
|
|
|
export const UNPUBLISHED_ENTRY_PERSIST_SUCCESS = 'UNPUBLISHED_ENTRY_PERSIST_SUCCESS';
|
2016-10-31 18:19:51 -02:00
|
|
|
export const UNPUBLISHED_ENTRY_PERSIST_FAILURE = 'UNPUBLISHED_ENTRY_PERSIST_FAILURE';
|
2016-09-06 13:04:17 -03:00
|
|
|
|
2016-09-13 16:00:24 -03:00
|
|
|
export const UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST = 'UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST';
|
|
|
|
export const UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS = 'UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS';
|
2016-10-18 12:32:39 -02:00
|
|
|
export const UNPUBLISHED_ENTRY_STATUS_CHANGE_FAILURE = 'UNPUBLISHED_ENTRY_STATUS_CHANGE_FAILURE';
|
|
|
|
|
2016-09-14 18:25:45 -03:00
|
|
|
export const UNPUBLISHED_ENTRY_PUBLISH_REQUEST = 'UNPUBLISHED_ENTRY_PUBLISH_REQUEST';
|
|
|
|
export const UNPUBLISHED_ENTRY_PUBLISH_SUCCESS = 'UNPUBLISHED_ENTRY_PUBLISH_SUCCESS';
|
2016-10-18 12:32:39 -02:00
|
|
|
export const UNPUBLISHED_ENTRY_PUBLISH_FAILURE = 'UNPUBLISHED_ENTRY_PUBLISH_FAILURE';
|
2016-09-14 18:25:45 -03:00
|
|
|
|
2016-09-06 13:04:17 -03:00
|
|
|
/*
|
|
|
|
* Simple Action Creators (Internal)
|
|
|
|
*/
|
2016-09-13 03:59:48 -03:00
|
|
|
|
2017-01-11 20:58:15 -02:00
|
|
|
function unpublishedEntryLoading(collection, slug) {
|
2016-09-13 03:59:48 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_REQUEST,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: {
|
|
|
|
collection: collection.get('name'),
|
|
|
|
slug,
|
|
|
|
},
|
2016-09-13 03:59:48 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-01-11 20:58:15 -02:00
|
|
|
function unpublishedEntryLoaded(collection, entry) {
|
2016-09-13 03:59:48 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_SUCCESS,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: {
|
|
|
|
collection: collection.get('name'),
|
|
|
|
entry,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function unpublishedEntryRedirected(collection, slug) {
|
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_REDIRECT,
|
|
|
|
payload: {
|
|
|
|
collection: collection.get('name'),
|
|
|
|
slug,
|
|
|
|
},
|
2016-09-13 03:59:48 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-09-06 13:04:17 -03:00
|
|
|
function unpublishedEntriesLoading() {
|
|
|
|
return {
|
2016-10-18 12:32:39 -02:00
|
|
|
type: UNPUBLISHED_ENTRIES_REQUEST,
|
2016-09-06 13:04:17 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function unpublishedEntriesLoaded(entries, pagination) {
|
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRIES_SUCCESS,
|
|
|
|
payload: {
|
2016-10-18 12:32:39 -02:00
|
|
|
entries,
|
|
|
|
pages: pagination,
|
|
|
|
},
|
2016-09-06 13:04:17 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function unpublishedEntriesFailed(error) {
|
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRIES_FAILURE,
|
|
|
|
error: 'Failed to load entries',
|
2016-12-01 19:59:29 -02:00
|
|
|
payload: error,
|
2016-09-06 13:04:17 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-09-13 14:31:18 -03:00
|
|
|
|
2016-10-31 18:19:51 -02:00
|
|
|
function unpublishedEntryPersisting(collection, entry, transactionID) {
|
2016-09-13 14:31:18 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_PERSIST_REQUEST,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: {
|
|
|
|
collection: collection.get('name'),
|
|
|
|
entry,
|
|
|
|
},
|
2016-10-31 18:19:51 -02:00
|
|
|
optimist: { type: BEGIN, id: transactionID },
|
2016-09-13 14:31:18 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-31 18:19:51 -02:00
|
|
|
function unpublishedEntryPersisted(collection, entry, transactionID) {
|
2016-09-13 14:31:18 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_PERSIST_SUCCESS,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: {
|
|
|
|
collection: collection.get('name'),
|
|
|
|
entry,
|
|
|
|
},
|
2016-10-31 18:19:51 -02:00
|
|
|
optimist: { type: COMMIT, id: transactionID },
|
2016-09-13 14:31:18 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-31 18:19:51 -02:00
|
|
|
function unpublishedEntryPersistedFail(error, transactionID) {
|
2016-09-13 14:31:18 -03:00
|
|
|
return {
|
2016-10-31 18:19:51 -02:00
|
|
|
type: UNPUBLISHED_ENTRY_PERSIST_FAILURE,
|
2016-10-18 12:32:39 -02:00
|
|
|
payload: { error },
|
2016-10-31 18:19:51 -02:00
|
|
|
optimist: { type: REVERT, id: transactionID },
|
2016-09-13 16:00:24 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-18 12:32:39 -02:00
|
|
|
function unpublishedEntryStatusChangeRequest(collection, slug, oldStatus, newStatus, transactionID) {
|
2016-09-13 16:00:24 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: {
|
|
|
|
collection,
|
|
|
|
slug,
|
|
|
|
oldStatus,
|
|
|
|
newStatus,
|
|
|
|
},
|
2016-10-18 12:32:39 -02:00
|
|
|
optimist: { type: BEGIN, id: transactionID },
|
2016-09-13 16:00:24 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-18 12:32:39 -02:00
|
|
|
function unpublishedEntryStatusChangePersisted(collection, slug, oldStatus, newStatus, transactionID) {
|
2016-09-13 16:00:24 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: {
|
|
|
|
collection,
|
|
|
|
slug,
|
|
|
|
oldStatus,
|
|
|
|
newStatus,
|
|
|
|
},
|
2016-10-18 12:32:39 -02:00
|
|
|
optimist: { type: COMMIT, id: transactionID },
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function unpublishedEntryStatusChangeError(collection, slug, transactionID) {
|
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_STATUS_CHANGE_FAILURE,
|
|
|
|
payload: { collection, slug },
|
|
|
|
optimist: { type: REVERT, id: transactionID },
|
2016-09-13 14:31:18 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-01-11 20:58:15 -02:00
|
|
|
function unpublishedEntryPublishRequest(collection, slug, transactionID) {
|
2016-09-14 18:25:45 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_PUBLISH_REQUEST,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: { collection, slug },
|
2016-10-18 12:32:39 -02:00
|
|
|
optimist: { type: BEGIN, id: transactionID },
|
2016-09-14 18:25:45 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-01-11 20:58:15 -02:00
|
|
|
function unpublishedEntryPublished(collection, slug, transactionID) {
|
2016-09-14 18:25:45 -03:00
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_PUBLISH_SUCCESS,
|
2017-01-11 20:58:15 -02:00
|
|
|
payload: { collection, slug },
|
2016-10-18 12:32:39 -02:00
|
|
|
optimist: { type: COMMIT, id: transactionID },
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function unpublishedEntryPublishError(collection, slug, transactionID) {
|
|
|
|
return {
|
|
|
|
type: UNPUBLISHED_ENTRY_PUBLISH_FAILURE,
|
|
|
|
payload: { collection, slug },
|
|
|
|
optimist: { type: REVERT, id: transactionID },
|
2016-09-14 18:25:45 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-09-06 13:04:17 -03:00
|
|
|
/*
|
|
|
|
* Exported Thunk Action Creators
|
|
|
|
*/
|
2016-09-13 03:59:48 -03:00
|
|
|
|
2017-01-11 20:58:15 -02:00
|
|
|
export function loadUnpublishedEntry(collection, slug) {
|
2016-09-13 03:59:48 -03:00
|
|
|
return (dispatch, getState) => {
|
|
|
|
const state = getState();
|
|
|
|
const backend = currentBackend(state.config);
|
2017-01-11 20:58:15 -02:00
|
|
|
dispatch(unpublishedEntryLoading(collection, slug));
|
2016-09-13 03:59:48 -03:00
|
|
|
backend.unpublishedEntry(collection, slug)
|
2017-01-11 20:58:15 -02:00
|
|
|
.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,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
});
|
2016-09-13 03:59:48 -03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-09-06 13:04:17 -03:00
|
|
|
export function loadUnpublishedEntries() {
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
const state = getState();
|
2016-09-06 17:18:27 -03:00
|
|
|
if (state.config.get('publish_mode') !== EDITORIAL_WORKFLOW) return;
|
2016-09-06 13:04:17 -03:00
|
|
|
const backend = currentBackend(state.config);
|
|
|
|
dispatch(unpublishedEntriesLoading());
|
|
|
|
backend.unpublishedEntries().then(
|
2016-10-18 12:32:39 -02:00
|
|
|
response => dispatch(unpublishedEntriesLoaded(response.entries, response.pagination)),
|
|
|
|
error => dispatch(unpublishedEntriesFailed(error))
|
2016-09-06 13:04:17 -03:00
|
|
|
);
|
|
|
|
};
|
|
|
|
}
|
2016-09-13 14:31:18 -03:00
|
|
|
|
2017-01-13 19:30:40 -02:00
|
|
|
export function persistUnpublishedEntry(collection, existingUnpublishedEntry) {
|
2016-09-13 14:31:18 -03:00
|
|
|
return (dispatch, getState) => {
|
|
|
|
const state = getState();
|
2017-01-13 19:30:40 -02:00
|
|
|
const entryDraft = state.entryDraft;
|
|
|
|
|
|
|
|
// Early return if draft contains validation errors
|
2017-08-01 19:44:33 -07:00
|
|
|
if (!entryDraft.get('fieldsErrors').isEmpty()) return Promise.resolve();
|
2017-01-13 19:30:40 -02:00
|
|
|
|
2016-09-13 14:31:18 -03:00
|
|
|
const backend = currentBackend(state.config);
|
2017-07-18 19:14:40 -04:00
|
|
|
const transactionID = uuid.v4();
|
2017-01-10 22:23:22 -02:00
|
|
|
const assetProxies = entryDraft.get('mediaFiles').map(path => getAsset(state, path));
|
2016-10-31 18:19:51 -02:00
|
|
|
const entry = entryDraft.get('entry');
|
|
|
|
|
2017-08-02 13:11:43 -04:00
|
|
|
/**
|
|
|
|
* 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));
|
2016-10-31 18:19:51 -02:00
|
|
|
const persistAction = existingUnpublishedEntry ? backend.persistUnpublishedEntry : backend.persistEntry;
|
2017-08-02 13:11:43 -04:00
|
|
|
return persistAction.call(backend, state.config, collection, serializedEntryDraft, assetProxies.toJS())
|
2016-10-31 18:19:51 -02:00
|
|
|
.then(() => {
|
|
|
|
dispatch(notifSend({
|
|
|
|
message: 'Entry saved',
|
|
|
|
kind: 'success',
|
|
|
|
dismissAfter: 4000,
|
|
|
|
}));
|
2017-08-02 13:11:43 -04:00
|
|
|
return dispatch(unpublishedEntryPersisted(collection, serializedEntry, transactionID));
|
2016-10-31 18:19:51 -02:00
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
dispatch(notifSend({
|
2017-01-11 20:58:15 -02:00
|
|
|
message: `Failed to persist entry: ${ error }`,
|
2016-10-31 18:19:51 -02:00
|
|
|
kind: 'danger',
|
2017-01-11 20:58:15 -02:00
|
|
|
dismissAfter: 8000,
|
2016-10-31 18:19:51 -02:00
|
|
|
}));
|
2017-08-01 19:44:33 -07:00
|
|
|
return dispatch(unpublishedEntryPersistedFail(error, transactionID));
|
2016-10-31 18:19:51 -02:00
|
|
|
});
|
2016-09-13 14:31:18 -03:00
|
|
|
};
|
|
|
|
}
|
2016-09-13 16:00:24 -03:00
|
|
|
|
|
|
|
export function updateUnpublishedEntryStatus(collection, slug, oldStatus, newStatus) {
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
const state = getState();
|
|
|
|
const backend = currentBackend(state.config);
|
2016-10-18 12:32:39 -02:00
|
|
|
const transactionID = uuid.v4();
|
|
|
|
dispatch(unpublishedEntryStatusChangeRequest(collection, slug, oldStatus, newStatus, transactionID));
|
2016-09-13 16:00:24 -03:00
|
|
|
backend.updateUnpublishedEntryStatus(collection, slug, newStatus)
|
|
|
|
.then(() => {
|
2016-10-18 12:32:39 -02:00
|
|
|
dispatch(unpublishedEntryStatusChangePersisted(collection, slug, oldStatus, newStatus, transactionID));
|
|
|
|
})
|
|
|
|
.catch(() => {
|
|
|
|
dispatch(unpublishedEntryStatusChangeError(collection, slug, transactionID));
|
2016-09-13 16:00:24 -03:00
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
2016-09-14 18:25:45 -03:00
|
|
|
|
2017-03-11 13:47:36 -05:00
|
|
|
export function deleteUnpublishedEntry(collection, slug) {
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
const state = getState();
|
|
|
|
const backend = currentBackend(state.config);
|
|
|
|
const transactionID = uuid.v4();
|
|
|
|
dispatch(unpublishedEntryPublishRequest(collection, slug, transactionID));
|
|
|
|
backend.deleteUnpublishedEntry(collection, slug)
|
|
|
|
.then(() => {
|
|
|
|
dispatch(unpublishedEntryPublished(collection, slug, transactionID));
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
dispatch(notifSend({
|
|
|
|
message: `Failed to close PR: ${ error }`,
|
|
|
|
kind: 'danger',
|
|
|
|
dismissAfter: 8000,
|
|
|
|
}));
|
|
|
|
dispatch(unpublishedEntryPublishError(collection, slug, transactionID));
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-01-11 20:58:15 -02:00
|
|
|
export function publishUnpublishedEntry(collection, slug) {
|
2016-09-14 18:25:45 -03:00
|
|
|
return (dispatch, getState) => {
|
|
|
|
const state = getState();
|
|
|
|
const backend = currentBackend(state.config);
|
2016-10-18 12:32:39 -02:00
|
|
|
const transactionID = uuid.v4();
|
2017-01-11 20:58:15 -02:00
|
|
|
dispatch(unpublishedEntryPublishRequest(collection, slug, transactionID));
|
|
|
|
backend.publishUnpublishedEntry(collection, slug)
|
2016-09-14 18:25:45 -03:00
|
|
|
.then(() => {
|
2017-01-11 20:58:15 -02:00
|
|
|
dispatch(unpublishedEntryPublished(collection, slug, transactionID));
|
2016-10-18 12:32:39 -02:00
|
|
|
})
|
2017-01-11 20:58:15 -02:00
|
|
|
.catch((error) => {
|
|
|
|
dispatch(notifSend({
|
|
|
|
message: `Failed to merge: ${ error }`,
|
|
|
|
kind: 'danger',
|
|
|
|
dismissAfter: 8000,
|
|
|
|
}));
|
2016-10-18 12:32:39 -02:00
|
|
|
dispatch(unpublishedEntryPublishError(collection, slug, transactionID));
|
2016-09-14 18:25:45 -03:00
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|