Skip to content

Commit

Permalink
fix: call createDraftFromEntry after entry is loaded instead in Editor (
Browse files Browse the repository at this point in the history
#3418)

* fix: call createDraftFromEntry after entry is loaded instead in Editor
  • Loading branch information
erezrokah committed Mar 16, 2020
1 parent c9b8255 commit 2409323
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('editorialWorkflow actions', () => {

return store.dispatch(actions.loadUnpublishedEntry(collection, slug)).then(() => {
const actions = store.getActions();
expect(actions).toHaveLength(3);
expect(actions).toHaveLength(4);
expect(actions[0]).toEqual({
type: 'UNPUBLISHED_ENTRY_REQUEST',
payload: {
Expand All @@ -80,6 +80,12 @@ describe('editorialWorkflow actions', () => {
entry: { ...entry, mediaFiles: [{ file: { name: 'name' }, id: '1', draft: true }] },
},
});
expect(actions[3]).toEqual({
type: 'DRAFT_CREATE_FROM_ENTRY',
payload: {
entry,
},
});
});
});
});
Expand Down Expand Up @@ -111,7 +117,7 @@ describe('editorialWorkflow actions', () => {

return store.dispatch(actions.publishUnpublishedEntry('posts', slug)).then(() => {
const actions = store.getActions();
expect(actions).toHaveLength(6);
expect(actions).toHaveLength(7);

expect(actions[0]).toEqual({
type: 'UNPUBLISHED_ENTRY_PUBLISH_REQUEST',
Expand Down Expand Up @@ -155,6 +161,12 @@ describe('editorialWorkflow actions', () => {
collection: 'posts',
},
});
expect(actions[6]).toEqual({
type: 'DRAFT_CREATE_FROM_ENTRY',
payload: {
entry,
},
});
});
});

Expand Down
3 changes: 2 additions & 1 deletion packages/netlify-cms-core/src/actions/editorialWorkflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { selectFields } from '../reducers/collections';
import { EDITORIAL_WORKFLOW, status, Status } from '../constants/publishModes';
import { EDITORIAL_WORKFLOW_ERROR } from 'netlify-cms-lib-util';
import { loadEntry, entryDeleted, getMediaAssets } from './entries';
import { loadEntry, entryDeleted, getMediaAssets, createDraftFromEntry } from './entries';
import { createAssetProxy } from '../valueObjects/AssetProxy';
import { addAssets } from './media';
import { loadMedia } from './mediaLibrary';
Expand Down Expand Up @@ -290,6 +290,7 @@ export function loadUnpublishedEntry(collection: Collection, slug: string) {
}

dispatch(unpublishedEntryLoaded(collection, { ...entry, mediaFiles }));
dispatch(createDraftFromEntry(entry));
} catch (error) {
if (error.name === EDITORIAL_WORKFLOW_ERROR && error.notUnderEditorialWorkflow) {
dispatch(unpublishedEntryRedirected(collection, slug));
Expand Down
42 changes: 21 additions & 21 deletions packages/netlify-cms-core/src/actions/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,10 @@ export function emptyDraftCreated(entry: EntryValue) {
/*
* Exported simple Action Creators
*/
export function createDraftFromEntry(entry: EntryMap, metadata?: Map<string, unknown>) {
export function createDraftFromEntry(entry: EntryValue) {
return {
type: DRAFT_CREATE_FROM_ENTRY,
payload: { entry, metadata },
payload: { entry },
};
}

Expand Down Expand Up @@ -339,25 +339,25 @@ export function loadEntry(collection: Collection, slug: string) {
const backend = currentBackend(state.config);
await waitForMediaLibraryToLoad(dispatch, getState());
dispatch(entryLoading(collection, slug));
return backend
.getEntry(getState(), collection, slug)
.then((loadedEntry: EntryValue) => {
return dispatch(entryLoaded(collection, loadedEntry));
})
.catch((error: Error) => {
console.error(error);
dispatch(
notifSend({
message: {
details: error.message,
key: 'ui.toast.onFailToLoadEntries',
},
kind: 'danger',
dismissAfter: 8000,
}),
);
dispatch(entryLoadError(error, collection, slug));
});

try {
const loadedEntry = await backend.getEntry(getState(), collection, slug);
dispatch(entryLoaded(collection, loadedEntry));
dispatch(createDraftFromEntry(loadedEntry));
} catch (error) {
console.error(error);
dispatch(
notifSend({
message: {
details: error.message,
key: 'ui.toast.onFailToLoadEntries',
},
kind: 'danger',
dismissAfter: 8000,
}),
);
dispatch(entryLoadError(error, collection, slug));
}
};
}

Expand Down
21 changes: 2 additions & 19 deletions packages/netlify-cms-core/src/components/Editor/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { logoutUser } from 'Actions/auth';
import {
loadEntry,
loadEntries,
createDraftFromEntry,
createDraftDuplicateFromEntry,
createEmptyDraft,
discardDraft,
Expand All @@ -30,7 +29,6 @@ import {
deleteUnpublishedEntry,
} from 'Actions/editorialWorkflow';
import { loadDeployPreview } from 'Actions/deploys';
import { deserializeValues } from 'Lib/serializeEntryValues';
import { selectEntry, selectUnpublishedEntry, selectDeployPreview } from 'Reducers';
import { selectFields } from 'Reducers/collections';
import { status, EDITORIAL_WORKFLOW } from 'Constants/publishModes';
Expand All @@ -48,7 +46,6 @@ export class Editor extends React.Component {
changeDraftField: PropTypes.func.isRequired,
changeDraftFieldValidation: PropTypes.func.isRequired,
collection: ImmutablePropTypes.map.isRequired,
createDraftFromEntry: PropTypes.func.isRequired,
createDraftDuplicateFromEntry: PropTypes.func.isRequired,
createEmptyDraft: PropTypes.func.isRequired,
discardDraft: PropTypes.func.isRequired,
Expand Down Expand Up @@ -198,18 +195,9 @@ export class Editor extends React.Component {

if (prevProps.entry === this.props.entry) return;

const { entry, newEntry, fields, collection } = this.props;
const { newEntry, collection } = this.props;

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);
const fieldsMetaData = this.props.entryDraft && this.props.entryDraft.get('fieldsMetaData');
this.createDraft(deserializedEntry, fieldsMetaData);
} else if (newEntry) {
if (newEntry) {
prevProps.createEmptyDraft(collection, this.props.location.search);
}
}
Expand All @@ -224,10 +212,6 @@ export class Editor extends React.Component {
this.props.persistLocalBackup(entry, collection);
}, 2000);

createDraft = (entry, metadata) => {
if (entry) this.props.createDraftFromEntry(entry, metadata);
};

handleChangeDraftField = (field, value, metadata) => {
const entries = [this.props.unPublishedEntry, this.props.publishedEntry].filter(Boolean);
this.props.changeDraftField(field, value, metadata, entries);
Expand Down Expand Up @@ -509,7 +493,6 @@ const mapDispatchToProps = {
retrieveLocalBackup,
persistLocalBackup,
deleteLocalBackup,
createDraftFromEntry,
createDraftDuplicateFromEntry,
createEmptyDraft,
discardDraft,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ describe('Editor', () => {
changeDraftField: jest.fn(),
changeDraftFieldValidation: jest.fn(),
collection: fromJS({ name: 'posts' }),
createDraftFromEntry: jest.fn(),
createDraftDuplicateFromEntry: jest.fn(),
createEmptyDraft: jest.fn(),
discardDraft: jest.fn(),
Expand Down Expand Up @@ -215,32 +214,4 @@ describe('Editor', () => {
props.collection,
);
});

it('should create draft from entry when done fetching', () => {
const { rerender } = render(
<Editor
{...props}
entryDraft={fromJS({ entry: {} })}
entry={fromJS({ isFetching: false, mediaFiles: [] })}
/>,
);

jest.clearAllMocks();
rerender(
<Editor
{...props}
entryDraft={fromJS({
entry: {},
fieldsMetaData: {},
})}
entry={fromJS({ isFetching: false, mediaFiles: [{ id: '1' }], data: {} })}
/>,
);

expect(props.createDraftFromEntry).toHaveBeenCalledTimes(1);
expect(props.createDraftFromEntry).toHaveBeenCalledWith(
fromJS({ isFetching: false, data: {}, mediaFiles: [{ id: '1' }] }),
fromJS({}),
);
});
});
7 changes: 2 additions & 5 deletions packages/netlify-cms-core/src/reducers/entryDraft.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ const entryDraftReducer = (state = Map(), action) => {
case DRAFT_CREATE_FROM_ENTRY:
// Existing Entry
return state.withMutations(state => {
state.set('entry', action.payload.entry);
state.set('entry', fromJS(action.payload.entry));
state.setIn(['entry', 'newRecord'], false);
// An existing entry may already have metadata. If we surfed away and back to its
// editor page, the metadata will have been fetched already, so we shouldn't
// clear it as to not break relation lists.
state.set('fieldsMetaData', action.payload.metadata || Map());
state.set('fieldsMetaData', Map());
state.set('fieldsErrors', Map());
state.set('hasChanged', false);
state.set('key', uuid());
Expand Down

0 comments on commit 2409323

Please sign in to comment.