Skip to content
This repository has been archived by the owner on Sep 9, 2024. It is now read-only.

Commit

Permalink
feat: make non default locales optional (#1109)
Browse files Browse the repository at this point in the history
  • Loading branch information
KaneFreeman authored Apr 26, 2024
1 parent 69fc27a commit 1d0141f
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 8 deletions.
4 changes: 4 additions & 0 deletions packages/core/dev-test/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ i18n:
# Optional, defaults to the first item in locales.
# The locale to be used for fields validation and as a baseline for the entry.
default_locale: en

# Optional, defaults to true.
# Enforce required fields in non-default locales
enforce_required_non_default: true
collections:
- name: posts
label: Posts
Expand Down
14 changes: 12 additions & 2 deletions packages/core/src/actions/__tests__/config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,12 @@ describe('config', () => {
},
],
}).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', () => {
Expand Down Expand Up @@ -757,7 +762,12 @@ describe('config', () => {
},
],
}).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', () => {
Expand Down
15 changes: 12 additions & 3 deletions packages/core/src/actions/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,24 @@ function setI18nField<T extends BaseField = UnknownField>(field: T) {

function getI18nDefaults(
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 {
if (typeof collectionOrFileI18n === 'boolean') {
return { default_locale, locales, structure };
return { default_locale, locales, structure, enforce_required_non_default };
} else {
const mergedI18n: I18nInfo = deepmerge(
{ default_locale, locales, structure },
{ default_locale, locales, structure, enforce_required_non_default },
collectionOrFileI18n,
);
mergedI18n.locales = collectionOrFileI18n.locales ?? locales;
mergedI18n.default_locale = collectionOrFileI18n.default_locale || locales?.[0];
mergedI18n.enforce_required_non_default =
collectionOrFileI18n.enforce_required_non_default || true;
throwOnMissingDefaultLocale(mergedI18n);
return mergedI18n;
}
Expand Down Expand Up @@ -202,6 +209,7 @@ function applyCollectionFileDefaults(
locales: collectionI18n.locales,
default_locale: collectionI18n.default_locale,
structure: collectionI18n.structure,
enforce_required_non_default: collectionI18n.enforce_required_non_default,
});
file.i18n = fileI18n;
} else {
Expand Down Expand Up @@ -315,6 +323,7 @@ export function applyDefaults<EF extends BaseField = UnknownField>(

if (i18n) {
i18n.default_locale = i18n.default_locale ?? i18n.locales[0];
i18n.enforce_required_non_default = i18n.enforce_required_non_default ?? true;
}

throwOnMissingDefaultLocale(i18n);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ const EditorControl: FC<EditorControlProps> = ({
(!dirty && !submitted) ||
disabled ||
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,12 @@ const EditorControlPane: FC<EditorControlPaneProps> = ({

const i18n = useMemo(() => {
if (hasI18n(collection)) {
const { locales, default_locale } = getI18nInfo(collection);
const { locales, default_locale, enforce_required_non_default } = getI18nInfo(collection);
return {
currentLocale: locale ?? locales?.[0],
locales,
defaultLocale: default_locale,
enforceRequiredNonDefault: enforce_required_non_default,
} as I18nSettings;
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/constants/configSchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const i18n = {
uniqueItems: true,
},
default_locale: localeType,
enforce_required_non_default: { type: 'boolean' },
},
};

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export interface I18nSettings {
currentLocale: string;
defaultLocale: string;
locales: string[];
enforceRequiredNonDefault?: boolean;
}

export type Format = keyof typeof formatExtensions;
Expand Down Expand Up @@ -1306,6 +1307,7 @@ export interface I18nInfo {
locales: string[];
default_locale?: string;
structure: I18nStructure;
enforce_required_non_default?: boolean;
}

export interface ProcessedCodeLanguage {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ export async function getI18nEntry<EF extends BaseField>(
i18nInfo = {
structure: I18N_STRUCTURE_SINGLE_FILE,
locales: [],
enforce_required_non_default: true,
};
}

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/reducers/__tests__/entryDraft.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ describe('entryDraft', () => {
locales: ['en', 'fr', 'es'],
defaultLocale: 'en',
currentLocale: 'en',
enforceRequiredNonDefault: true,
},
isMeta: false,
},
Expand Down Expand Up @@ -155,6 +156,7 @@ describe('entryDraft', () => {
locales: ['en', 'fr', 'es'],
defaultLocale: 'en',
currentLocale: 'en',
enforceRequiredNonDefault: true,
};

let state = entryDraftReducer(startState, {
Expand Down
12 changes: 11 additions & 1 deletion packages/docs/content/docs/i18n-support.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ i18n:
# Optional, defaults to the first item in locales.
# The locale to be used for fields validation and as a baseline for the entry.
default_locale: en

# Optional, defaults to true.
# Enforce required fields in non-default locales
enforce_required_non_default: false
```
```js
Expand All @@ -44,7 +48,13 @@ i18n: {
* Optional, defaults to the first item in locales.
* 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
},
```

Expand Down

0 comments on commit 1d0141f

Please sign in to comment.