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', raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' }, data: { title: 'Hello World' },
meta: {}, meta: {},
i18n: {},
label: null, label: null,
isModification: null, isModification: null,
status: '', status: '',
@ -244,6 +245,7 @@ describe('Backend', () => {
raw: '---\ntitle: "Hello World"\n---\n', raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' }, data: { title: 'Hello World' },
meta: {}, meta: {},
i18n: {},
label: null, label: null,
isModification: null, isModification: null,
status: '', status: '',
@ -391,6 +393,7 @@ describe('Backend', () => {
raw: '---\ntitle: "Hello World"\n---\n', raw: '---\ntitle: "Hello World"\n---\n',
data: { title: 'Hello World' }, data: { title: 'Hello World' },
meta: { path: 'src/posts/index.md' }, meta: { path: 'src/posts/index.md' },
i18n: {},
label: null, label: null,
isModification: true, isModification: true,
mediaFiles: [{ id: '1', draft: true }], mediaFiles: [{ id: '1', draft: true }],

View File

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

View File

@ -31,7 +31,7 @@ import { selectIsFetching, selectEntriesSortFields, selectEntryByPath } from '..
import { selectCustomPath } from '../reducers/entryDraft'; import { selectCustomPath } from '../reducers/entryDraft';
import { navigateToEntry } from '../routing/history'; import { navigateToEntry } from '../routing/history';
import { getProcessSegment } from '../lib/formatters'; import { getProcessSegment } from '../lib/formatters';
import { hasI18n, serializeI18n } from '../lib/i18n'; import { hasI18n, duplicateDefaultI18nFields, serializeI18n, I18N, I18N_FIELD } from '../lib/i18n';
const { notifSend } = notifActions; const { notifSend } = notifActions;
@ -669,6 +669,9 @@ const processValue = (unsafe: string) => {
return escapeHtml(unsafe); 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) { export function createEmptyDraft(collection: Collection, search: string) {
return async (dispatch: ThunkDispatch<State, {}, AnyAction>, getState: () => State) => { return async (dispatch: ThunkDispatch<State, {}, AnyAction>, getState: () => State) => {
const params = new URLSearchParams(search); const params = new URLSearchParams(search);
@ -679,8 +682,12 @@ export function createEmptyDraft(collection: Collection, search: string) {
}); });
const fields = collection.get('fields', List()); 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 state = getState();
const backend = currentBackend(state.config); const backend = currentBackend(state.config);
@ -689,11 +696,14 @@ export function createEmptyDraft(collection: Collection, search: string) {
await waitForMediaLibraryToLoad(dispatch, getState()); await waitForMediaLibraryToLoad(dispatch, getState());
} }
const i18nFields = createEmptyDraftI18nData(collection, dataFields);
let newEntry = createEntry(collection.get('name'), '', '', { let newEntry = createEntry(collection.get('name'), '', '', {
data: dataFields, data,
i18n: i18nFields,
mediaFiles: [], mediaFiles: [],
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
meta: metaFields as any, meta: meta as any,
}); });
newEntry = await backend.processEntry(state, collection, newEntry); newEntry = await backend.processEntry(state, collection, newEntry);
dispatch(emptyDraftCreated(newEntry)); dispatch(emptyDraftCreated(newEntry));
@ -711,7 +721,11 @@ interface DraftEntryData {
| (string | DraftEntryData | boolean | List<unknown>)[]; | (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( return fields.reduce(
( (
reduction: DraftEntryData | string | undefined | boolean | List<unknown>, reduction: DraftEntryData | string | undefined | boolean | List<unknown>,
@ -719,6 +733,11 @@ export function createEmptyDraftData(fields: EntryFields, withNameKey = true) {
) => { ) => {
const acc = reduction as DraftEntryData; const acc = reduction as DraftEntryData;
const item = value as EntryField; const item = value as EntryField;
if (skipField(item)) {
return acc;
}
const subfields = item.get('field') || item.get('fields'); const subfields = item.get('field') || item.get('fields');
const list = item.get('widget') == 'list'; const list = item.get('widget') == 'list';
const name = item.get('name'); const name = item.get('name');
@ -727,8 +746,8 @@ export function createEmptyDraftData(fields: EntryFields, withNameKey = true) {
if (List.isList(subfields)) { if (List.isList(subfields)) {
const subDefaultValue = list const subDefaultValue = list
? [createEmptyDraftData(subfields as EntryFields)] ? [createEmptyDraftData(subfields as EntryFields, withNameKey, skipField)]
: createEmptyDraftData(subfields as EntryFields); : createEmptyDraftData(subfields as EntryFields, withNameKey, skipField);
if (!isEmptyDefaultValue(subDefaultValue)) { if (!isEmptyDefaultValue(subDefaultValue)) {
acc[name] = subDefaultValue; acc[name] = subDefaultValue;
} else if (list && List.isList(defaultValue) && (defaultValue as List<unknown>).isEmpty()) { } 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)) { if (Map.isMap(subfields)) {
const subDefaultValue = list const subDefaultValue = list
? [createEmptyDraftData(List([subfields as EntryField]), false)] ? [createEmptyDraftData(List([subfields as EntryField]), false, skipField)]
: createEmptyDraftData(List([subfields as EntryField])); : createEmptyDraftData(List([subfields as EntryField]), withNameKey, skipField);
if (!isEmptyDefaultValue(subDefaultValue)) { if (!isEmptyDefaultValue(subDefaultValue)) {
acc[name] = subDefaultValue; acc[name] = subDefaultValue;
} else if (list && List.isList(defaultValue) && (defaultValue as List<unknown>).isEmpty()) { } 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 }) { export function getMediaAssets({ entry }: { entry: EntryMap }) {
const filesArray = entry.get('mediaFiles').toArray(); const filesArray = entry.get('mediaFiles').toArray();
const assets = filesArray const assets = filesArray

View File

@ -341,6 +341,19 @@ export const getI18nDataFiles = (
return dataFiles; 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 = ( export const duplicateI18nFields = (
entryDraft: EntryDraft, entryDraft: EntryDraft,
field: EntryField, field: EntryField,

View File

@ -13,6 +13,10 @@ interface Options {
updatedOn?: string; updatedOn?: string;
status?: string; status?: string;
meta?: { path?: string }; meta?: { path?: string };
i18n?: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[locale: string]: any;
};
} }
export interface EntryValue { export interface EntryValue {
@ -51,6 +55,7 @@ export function createEntry(collection: string, slug = '', path = '', options: O
updatedOn: options.updatedOn || '', updatedOn: options.updatedOn || '',
status: options.status || '', status: options.status || '',
meta: options.meta || {}, meta: options.meta || {},
i18n: options.i18n || {},
}; };
return returnObj; return returnObj;