mirror of
https://github.com/logto-io/logto.git
synced 2025-02-03 21:48:55 -05:00
fix(console,ui): fix locale guard issue in settings page
This commit is contained in:
parent
9851619ba0
commit
e2005780a3
5 changed files with 27 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
||||||
import { ConnectorDto, ConnectorType } from '@logto/schemas';
|
import { ConnectorDto, ConnectorType } from '@logto/schemas';
|
||||||
import { languageKeyGuard } from '@logto/shared';
|
import { getDefaultLanguage } from '@logto/shared';
|
||||||
import { conditional } from '@silverhand/essentials';
|
import { conditional } from '@silverhand/essentials';
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
|
@ -31,11 +31,7 @@ const Guide = ({ connector, onClose }: Props) => {
|
||||||
const { updateSettings } = useSettings();
|
const { updateSettings } = useSettings();
|
||||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||||
const { id: connectorId, type: connectorType, name, configTemplate, readme } = connector;
|
const { id: connectorId, type: connectorType, name, configTemplate, readme } = connector;
|
||||||
|
const connectorName = name[getDefaultLanguage(i18next.language)];
|
||||||
const localeRaw = i18next.language;
|
|
||||||
const result = languageKeyGuard.safeParse(localeRaw);
|
|
||||||
const connectorName = result.success ? name[result.data] : name.en;
|
|
||||||
|
|
||||||
const isSocialConnector =
|
const isSocialConnector =
|
||||||
connectorType !== ConnectorType.Sms && connectorType !== ConnectorType.Email;
|
connectorType !== ConnectorType.Sms && connectorType !== ConnectorType.Email;
|
||||||
const methods = useForm<GuideForm>({ reValidateMode: 'onBlur' });
|
const methods = useForm<GuideForm>({ reValidateMode: 'onBlur' });
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { languageOptions } from '@logto/phrases';
|
import { languageOptions } from '@logto/phrases';
|
||||||
import { AppearanceMode } from '@logto/schemas';
|
import { AppearanceMode } from '@logto/schemas';
|
||||||
import { languageKeyGuard } from '@logto/shared';
|
import { getDefaultLanguage } from '@logto/shared';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Controller, useForm } from 'react-hook-form';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
import { toast } from 'react-hot-toast';
|
import { toast } from 'react-hot-toast';
|
||||||
|
@ -25,7 +25,7 @@ const Settings = () => {
|
||||||
i18n: { language },
|
i18n: { language },
|
||||||
} = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
} = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||||
|
|
||||||
const defaultLanguage = languageKeyGuard.default('en').parse(language);
|
const defaultLanguage = getDefaultLanguage(language);
|
||||||
|
|
||||||
const { data, error, update, isLoading, isLoaded } = useUserPreferences();
|
const { data, error, update, isLoading, isLoaded } = useUserPreferences();
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { fallback } from './utilities/zod';
|
||||||
|
|
||||||
export const languageKeys = ['en', 'fr', 'pt-PT', 'zh-CN', 'tr-TR', 'ko-KR'] as const;
|
export const languageKeys = ['en', 'fr', 'pt-PT', 'zh-CN', 'tr-TR', 'ko-KR'] as const;
|
||||||
export const languageKeyGuard = z.enum(languageKeys);
|
export const languageKeyGuard = z.enum(languageKeys);
|
||||||
export type LanguageKey = z.infer<typeof languageKeyGuard>;
|
export type LanguageKey = z.infer<typeof languageKeyGuard>;
|
||||||
|
|
||||||
|
export const getDefaultLanguage = (language: string): LanguageKey => {
|
||||||
|
return languageKeyGuard.or(fallback<LanguageKey>('en')).parse(language);
|
||||||
|
};
|
||||||
|
|
15
packages/shared/src/utilities/zod.ts
Normal file
15
packages/shared/src/utilities/zod.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { any } from 'zod';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://github.com/colinhacks/zod/issues/316#issuecomment-850906479
|
||||||
|
* Create a schema matches anything and returns a value. Use it with `or`:
|
||||||
|
*
|
||||||
|
* const schema = zod.number();
|
||||||
|
* const tolerant = schema.or(fallback(-1));
|
||||||
|
*
|
||||||
|
* schema.parse('foo') // => ZodError
|
||||||
|
* tolerant.parse('foo') // -1
|
||||||
|
*/
|
||||||
|
export function fallback<T>(value: T) {
|
||||||
|
return any().transform(() => value);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { languageKeyGuard } from '@logto/shared';
|
import { getDefaultLanguage } from '@logto/shared';
|
||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ const SocialSignInDropdown = ({ isOpen, onClose, connectors, anchorRef }: Props)
|
||||||
>
|
>
|
||||||
{connectors.map((connector) => {
|
{connectors.map((connector) => {
|
||||||
const { id, name, logo, logoDark } = connector;
|
const { id, name, logo, logoDark } = connector;
|
||||||
const localName = name[languageKeyGuard.default('en').parse(language)];
|
const localName = name[getDefaultLanguage(language)];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
|
|
Loading…
Add table
Reference in a new issue