Skip to content

Commit

Permalink
fix(i18n): data is not duplicated for default value setting (#4463)
Browse files Browse the repository at this point in the history
  • Loading branch information
blackb1rd authored Nov 2, 2020
1 parent 922c1a7 commit 1777665
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 10 deletions.
3 changes: 3 additions & 0 deletions packages/netlify-cms-core/src/__tests__/backend.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ describe('Backend', () => {
raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' },
meta: {},
i18n: {},
label: null,
isModification: null,
status: '',
Expand Down Expand Up @@ -244,6 +245,7 @@ describe('Backend', () => {
raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' },
meta: {},
i18n: {},
label: null,
isModification: null,
status: '',
Expand Down Expand Up @@ -391,6 +393,7 @@ describe('Backend', () => {
raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' },
meta: { path: 'src/posts/index.md' },
i18n: {},
label: null,
isModification: true,
mediaFiles: [{ id: '1', draft: true }],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ describe('entries', () => {
collection: undefined,
data: {},
meta: {},
i18n: {},
isModification: null,
label: null,
mediaFiles: [],
Expand Down Expand Up @@ -81,6 +82,7 @@ describe('entries', () => {
collection: undefined,
data: { title: 'title', boolean: true },
meta: {},
i18n: {},
isModification: null,
label: null,
mediaFiles: [],
Expand Down Expand Up @@ -115,6 +117,7 @@ describe('entries', () => {
collection: undefined,
data: { title: '<script>alert('hello')</script>' },
meta: {},
i18n: {},
isModification: null,
label: null,
mediaFiles: [],
Expand Down
52 changes: 42 additions & 10 deletions packages/netlify-cms-core/src/actions/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { selectIsFetching, selectEntriesSortFields, selectEntryByPath } from '..
import { selectCustomPath } from '../reducers/entryDraft';
import { navigateToEntry } from '../routing/history';
import { getProcessSegment } from '../lib/formatters';
import { hasI18n, serializeI18n } from '../lib/i18n';
import { hasI18n, duplicateDefaultI18nFields, serializeI18n, I18N, I18N_FIELD } from '../lib/i18n';

const { notifSend } = notifActions;

Expand Down Expand Up @@ -669,6 +669,9 @@ const processValue = (unsafe: string) => {
return escapeHtml(unsafe);
};

const getDataFields = (fields: EntryFields) => fields.filter(f => !f!.get('meta')).toList();
const getMetaFields = (fields: EntryFields) => fields.filter(f => f!.get('meta') === true).toList();

export function createEmptyDraft(collection: Collection, search: string) {
return async (dispatch: ThunkDispatch<State, {}, AnyAction>, getState: () => State) => {
const params = new URLSearchParams(search);
Expand All @@ -679,8 +682,12 @@ export function createEmptyDraft(collection: Collection, search: string) {
});

const fields = collection.get('fields', List());
const dataFields = createEmptyDraftData(fields.filter(f => !f!.get('meta')).toList());
const metaFields = createEmptyDraftData(fields.filter(f => f!.get('meta') === true).toList());

const dataFields = getDataFields(fields);
const data = createEmptyDraftData(dataFields);

const metaFields = getMetaFields(fields);
const meta = createEmptyDraftData(metaFields);

const state = getState();
const backend = currentBackend(state.config);
Expand All @@ -689,11 +696,14 @@ export function createEmptyDraft(collection: Collection, search: string) {
await waitForMediaLibraryToLoad(dispatch, getState());
}

const i18nFields = createEmptyDraftI18nData(collection, dataFields);

let newEntry = createEntry(collection.get('name'), '', '', {
data: dataFields,
data,
i18n: i18nFields,
mediaFiles: [],
// eslint-disable-next-line @typescript-eslint/no-explicit-any
meta: metaFields as any,
meta: meta as any,
});
newEntry = await backend.processEntry(state, collection, newEntry);
dispatch(emptyDraftCreated(newEntry));
Expand All @@ -711,14 +721,23 @@ interface DraftEntryData {
| (string | DraftEntryData | boolean | List<unknown>)[];
}

export function createEmptyDraftData(fields: EntryFields, withNameKey = true) {
export function createEmptyDraftData(
fields: EntryFields,
withNameKey = true,
skipField: (field: EntryField) => boolean = () => false,
) {
return fields.reduce(
(
reduction: DraftEntryData | string | undefined | boolean | List<unknown>,
value: EntryField | undefined | boolean,
) => {
const acc = reduction as DraftEntryData;
const item = value as EntryField;

if (skipField(item)) {
return acc;
}

const subfields = item.get('field') || item.get('fields');
const list = item.get('widget') == 'list';
const name = item.get('name');
Expand All @@ -727,8 +746,8 @@ export function createEmptyDraftData(fields: EntryFields, withNameKey = true) {

if (List.isList(subfields)) {
const subDefaultValue = list
? [createEmptyDraftData(subfields as EntryFields)]
: createEmptyDraftData(subfields as EntryFields);
? [createEmptyDraftData(subfields as EntryFields, withNameKey, skipField)]
: createEmptyDraftData(subfields as EntryFields, withNameKey, skipField);
if (!isEmptyDefaultValue(subDefaultValue)) {
acc[name] = subDefaultValue;
} else if (list && List.isList(defaultValue) && (defaultValue as List<unknown>).isEmpty()) {
Expand All @@ -740,8 +759,8 @@ export function createEmptyDraftData(fields: EntryFields, withNameKey = true) {

if (Map.isMap(subfields)) {
const subDefaultValue = list
? [createEmptyDraftData(List([subfields as EntryField]), false)]
: createEmptyDraftData(List([subfields as EntryField]));
? [createEmptyDraftData(List([subfields as EntryField]), false, skipField)]
: createEmptyDraftData(List([subfields as EntryField]), withNameKey, skipField);
if (!isEmptyDefaultValue(subDefaultValue)) {
acc[name] = subDefaultValue;
} else if (list && List.isList(defaultValue) && (defaultValue as List<unknown>).isEmpty()) {
Expand All @@ -764,6 +783,19 @@ export function createEmptyDraftData(fields: EntryFields, withNameKey = true) {
);
}

function createEmptyDraftI18nData(collection: Collection, dataFields: EntryFields) {
if (!hasI18n(collection)) {
return {};
}

const skipField = (field: EntryField) => {
return field.get(I18N) !== I18N_FIELD.DUPLICATE && field.get(I18N) !== I18N_FIELD.TRANSLATE;
};

const i18nData = createEmptyDraftData(dataFields, true, skipField);
return duplicateDefaultI18nFields(collection, i18nData);
}

export function getMediaAssets({ entry }: { entry: EntryMap }) {
const filesArray = entry.get('mediaFiles').toArray();
const assets = filesArray
Expand Down
13 changes: 13 additions & 0 deletions packages/netlify-cms-core/src/lib/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,19 @@ export const getI18nDataFiles = (
return dataFiles;
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const duplicateDefaultI18nFields = (collection: Collection, dataFields: any) => {
const { locales, defaultLocale } = getI18nInfo(collection) as I18nInfo;

const i18nFields = Object.fromEntries(
locales
.filter(locale => locale !== defaultLocale)
.map(locale => [locale, { data: dataFields }]),
);

return i18nFields;
};

export const duplicateI18nFields = (
entryDraft: EntryDraft,
field: EntryField,
Expand Down
5 changes: 5 additions & 0 deletions packages/netlify-cms-core/src/valueObjects/Entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ interface Options {
updatedOn?: string;
status?: string;
meta?: { path?: string };
i18n?: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[locale: string]: any;
};
}

export interface EntryValue {
Expand Down Expand Up @@ -51,6 +55,7 @@ export function createEntry(collection: string, slug = '', path = '', options: O
updatedOn: options.updatedOn || '',
status: options.status || '',
meta: options.meta || {},
i18n: options.i18n || {},
};

return returnObj;
Expand Down

0 comments on commit 1777665

Please sign in to comment.