fix(i18n): data is not duplicated for default value setting (#4463)

This commit is contained in:
Prachya Saechua 2020-11-02 22:15:29 +07:00 committed by GitHub
parent 922c1a7658
commit 1777665943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 10 deletions

View File

@ -203,6 +203,7 @@ describe('Backend', () => {
raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' },
meta: {},
i18n: {},
label: null,
isModification: null,
status: '',
@ -244,6 +245,7 @@ describe('Backend', () => {
raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' },
meta: {},
i18n: {},
label: null,
isModification: null,
status: '',
@ -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 }],

View File

@ -49,6 +49,7 @@ describe('entries', () => {
collection: undefined,
data: {},
meta: {},
i18n: {},
isModification: null,
label: null,
mediaFiles: [],
@ -81,6 +82,7 @@ describe('entries', () => {
collection: undefined,
data: { title: 'title', boolean: true },
meta: {},
i18n: {},
isModification: null,
label: null,
mediaFiles: [],
@ -115,6 +117,7 @@ describe('entries', () => {
collection: undefined,
data: { title: '<script>alert('hello')</script>' },
meta: {},
i18n: {},
isModification: null,
label: null,
mediaFiles: [],

View File

@ -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;
@ -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);
@ -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);
@ -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));
@ -711,7 +721,11 @@ 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>,
@ -719,6 +733,11 @@ export function createEmptyDraftData(fields: EntryFields, withNameKey = true) {
) => {
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');
@ -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()) {
@ -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()) {
@ -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

View File

@ -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,

View File

@ -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 {
@ -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;