feat: make non default locales optional (#1109)
This commit is contained in:
parent
69fc27ab6b
commit
1d0141fcc8
@ -19,6 +19,10 @@ i18n:
|
|||||||
# Optional, defaults to the first item in locales.
|
# Optional, defaults to the first item in locales.
|
||||||
# The locale to be used for fields validation and as a baseline for the entry.
|
# The locale to be used for fields validation and as a baseline for the entry.
|
||||||
default_locale: en
|
default_locale: en
|
||||||
|
|
||||||
|
# Optional, defaults to true.
|
||||||
|
# Enforce required fields in non-default locales
|
||||||
|
enforce_required_non_default: true
|
||||||
collections:
|
collections:
|
||||||
- name: posts
|
- name: posts
|
||||||
label: Posts
|
label: Posts
|
||||||
|
@ -697,7 +697,12 @@ describe('config', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}).collections[0].i18n,
|
}).collections[0].i18n,
|
||||||
).toEqual({ structure: 'multiple_folders', locales: ['en', 'de'], default_locale: 'en' });
|
).toEqual({
|
||||||
|
structure: 'multiple_folders',
|
||||||
|
locales: ['en', 'de'],
|
||||||
|
default_locale: 'en',
|
||||||
|
enforce_required_non_default: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not set root i18n on collection when collection i18n is not set', () => {
|
it('should not set root i18n on collection when collection i18n is not set', () => {
|
||||||
@ -757,7 +762,12 @@ describe('config', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}).collections[0].i18n,
|
}).collections[0].i18n,
|
||||||
).toEqual({ structure: 'multiple_folders', locales: ['en', 'fr'], default_locale: 'fr' });
|
).toEqual({
|
||||||
|
structure: 'multiple_folders',
|
||||||
|
locales: ['en', 'fr'],
|
||||||
|
default_locale: 'fr',
|
||||||
|
enforce_required_non_default: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when i18n structure is not single_file on files collection', () => {
|
it('should throw when i18n structure is not single_file on files collection', () => {
|
||||||
|
@ -92,17 +92,24 @@ function setI18nField<T extends BaseField = UnknownField>(field: T) {
|
|||||||
|
|
||||||
function getI18nDefaults(
|
function getI18nDefaults(
|
||||||
collectionOrFileI18n: boolean | Partial<I18nInfo>,
|
collectionOrFileI18n: boolean | Partial<I18nInfo>,
|
||||||
{ default_locale, locales = ['en'], structure = I18N_STRUCTURE_SINGLE_FILE }: Partial<I18nInfo>,
|
{
|
||||||
|
default_locale,
|
||||||
|
locales = ['en'],
|
||||||
|
structure = I18N_STRUCTURE_SINGLE_FILE,
|
||||||
|
enforce_required_non_default = true,
|
||||||
|
}: Partial<I18nInfo>,
|
||||||
): I18nInfo {
|
): I18nInfo {
|
||||||
if (typeof collectionOrFileI18n === 'boolean') {
|
if (typeof collectionOrFileI18n === 'boolean') {
|
||||||
return { default_locale, locales, structure };
|
return { default_locale, locales, structure, enforce_required_non_default };
|
||||||
} else {
|
} else {
|
||||||
const mergedI18n: I18nInfo = deepmerge(
|
const mergedI18n: I18nInfo = deepmerge(
|
||||||
{ default_locale, locales, structure },
|
{ default_locale, locales, structure, enforce_required_non_default },
|
||||||
collectionOrFileI18n,
|
collectionOrFileI18n,
|
||||||
);
|
);
|
||||||
mergedI18n.locales = collectionOrFileI18n.locales ?? locales;
|
mergedI18n.locales = collectionOrFileI18n.locales ?? locales;
|
||||||
mergedI18n.default_locale = collectionOrFileI18n.default_locale || locales?.[0];
|
mergedI18n.default_locale = collectionOrFileI18n.default_locale || locales?.[0];
|
||||||
|
mergedI18n.enforce_required_non_default =
|
||||||
|
collectionOrFileI18n.enforce_required_non_default || true;
|
||||||
throwOnMissingDefaultLocale(mergedI18n);
|
throwOnMissingDefaultLocale(mergedI18n);
|
||||||
return mergedI18n;
|
return mergedI18n;
|
||||||
}
|
}
|
||||||
@ -202,6 +209,7 @@ function applyCollectionFileDefaults(
|
|||||||
locales: collectionI18n.locales,
|
locales: collectionI18n.locales,
|
||||||
default_locale: collectionI18n.default_locale,
|
default_locale: collectionI18n.default_locale,
|
||||||
structure: collectionI18n.structure,
|
structure: collectionI18n.structure,
|
||||||
|
enforce_required_non_default: collectionI18n.enforce_required_non_default,
|
||||||
});
|
});
|
||||||
file.i18n = fileI18n;
|
file.i18n = fileI18n;
|
||||||
} else {
|
} else {
|
||||||
@ -315,6 +323,7 @@ export function applyDefaults<EF extends BaseField = UnknownField>(
|
|||||||
|
|
||||||
if (i18n) {
|
if (i18n) {
|
||||||
i18n.default_locale = i18n.default_locale ?? i18n.locales[0];
|
i18n.default_locale = i18n.default_locale ?? i18n.locales[0];
|
||||||
|
i18n.enforce_required_non_default = i18n.enforce_required_non_default ?? true;
|
||||||
}
|
}
|
||||||
|
|
||||||
throwOnMissingDefaultLocale(i18n);
|
throwOnMissingDefaultLocale(i18n);
|
||||||
|
@ -124,7 +124,8 @@ const EditorControl: FC<EditorControlProps> = ({
|
|||||||
(!dirty && !submitted) ||
|
(!dirty && !submitted) ||
|
||||||
disabled ||
|
disabled ||
|
||||||
i18nDisabled ||
|
i18nDisabled ||
|
||||||
(forList && field.widget === 'object' && field.fields.length === 1)
|
(forList && field.widget === 'object' && field.fields.length === 1) ||
|
||||||
|
(i18n?.enforceRequiredNonDefault === false && i18n?.currentLocale !== i18n?.defaultLocale)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,12 @@ const EditorControlPane: FC<EditorControlPaneProps> = ({
|
|||||||
|
|
||||||
const i18n = useMemo(() => {
|
const i18n = useMemo(() => {
|
||||||
if (hasI18n(collection)) {
|
if (hasI18n(collection)) {
|
||||||
const { locales, default_locale } = getI18nInfo(collection);
|
const { locales, default_locale, enforce_required_non_default } = getI18nInfo(collection);
|
||||||
return {
|
return {
|
||||||
currentLocale: locale ?? locales?.[0],
|
currentLocale: locale ?? locales?.[0],
|
||||||
locales,
|
locales,
|
||||||
defaultLocale: default_locale,
|
defaultLocale: default_locale,
|
||||||
|
enforceRequiredNonDefault: enforce_required_non_default,
|
||||||
} as I18nSettings;
|
} as I18nSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ const i18n = {
|
|||||||
uniqueItems: true,
|
uniqueItems: true,
|
||||||
},
|
},
|
||||||
default_locale: localeType,
|
default_locale: localeType,
|
||||||
|
enforce_required_non_default: { type: 'boolean' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -267,6 +267,7 @@ export interface I18nSettings {
|
|||||||
currentLocale: string;
|
currentLocale: string;
|
||||||
defaultLocale: string;
|
defaultLocale: string;
|
||||||
locales: string[];
|
locales: string[];
|
||||||
|
enforceRequiredNonDefault?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Format = keyof typeof formatExtensions;
|
export type Format = keyof typeof formatExtensions;
|
||||||
@ -1306,6 +1307,7 @@ export interface I18nInfo {
|
|||||||
locales: string[];
|
locales: string[];
|
||||||
default_locale?: string;
|
default_locale?: string;
|
||||||
structure: I18nStructure;
|
structure: I18nStructure;
|
||||||
|
enforce_required_non_default?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProcessedCodeLanguage {
|
export interface ProcessedCodeLanguage {
|
||||||
|
@ -343,6 +343,7 @@ export async function getI18nEntry<EF extends BaseField>(
|
|||||||
i18nInfo = {
|
i18nInfo = {
|
||||||
structure: I18N_STRUCTURE_SINGLE_FILE,
|
structure: I18N_STRUCTURE_SINGLE_FILE,
|
||||||
locales: [],
|
locales: [],
|
||||||
|
enforce_required_non_default: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ describe('entryDraft', () => {
|
|||||||
locales: ['en', 'fr', 'es'],
|
locales: ['en', 'fr', 'es'],
|
||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
currentLocale: 'en',
|
currentLocale: 'en',
|
||||||
|
enforceRequiredNonDefault: true,
|
||||||
},
|
},
|
||||||
isMeta: false,
|
isMeta: false,
|
||||||
},
|
},
|
||||||
@ -155,6 +156,7 @@ describe('entryDraft', () => {
|
|||||||
locales: ['en', 'fr', 'es'],
|
locales: ['en', 'fr', 'es'],
|
||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
currentLocale: 'en',
|
currentLocale: 'en',
|
||||||
|
enforceRequiredNonDefault: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let state = entryDraftReducer(startState, {
|
let state = entryDraftReducer(startState, {
|
||||||
|
@ -25,6 +25,10 @@ i18n:
|
|||||||
# Optional, defaults to the first item in locales.
|
# Optional, defaults to the first item in locales.
|
||||||
# The locale to be used for fields validation and as a baseline for the entry.
|
# The locale to be used for fields validation and as a baseline for the entry.
|
||||||
default_locale: en
|
default_locale: en
|
||||||
|
|
||||||
|
# Optional, defaults to true.
|
||||||
|
# Enforce required fields in non-default locales
|
||||||
|
enforce_required_non_default: false
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@ -44,7 +48,13 @@ i18n: {
|
|||||||
* Optional, defaults to the first item in locales.
|
* Optional, defaults to the first item in locales.
|
||||||
* The locale to be used for fields validation and as a baseline for the entry.
|
* The locale to be used for fields validation and as a baseline for the entry.
|
||||||
*/
|
*/
|
||||||
default_locale: 'en'
|
default_locale: 'en',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional, defaults to true.
|
||||||
|
* Enforce required fields in non-default locales
|
||||||
|
*/
|
||||||
|
enforce_required_non_default: false
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user