Localization tab (#685)
* localization wip wip localization return key value data as array localization table css lint lint clean up log stmts clean up log stmts * PR feedback from Erik * fix logic for supported locales * update empty state text * set default value * fix cypress test * Update src/realm-settings/RealmSettingsSection.tsx Co-authored-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * fix rsa-generated delete bug; PR feedback frog Erik * revert locale abbreviation * remove log stmts * PR feedback from Erik, fix undefined * fix loader w Erik Co-authored-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
2c9b77c425
commit
d2bf69fac7
7 changed files with 333 additions and 34 deletions
|
@ -54,3 +54,7 @@ td.pf-c-table__check > input {
|
||||||
margin-top: var(--pf-c-table__check--input--MarginTop);
|
margin-top: var(--pf-c-table__check--input--MarginTop);
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pf-c-pagination.pf-m-bottom.pf-m-compact {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
277
src/realm-settings/LocalizationTab.tsx
Normal file
277
src/realm-settings/LocalizationTab.tsx
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||||
|
import {
|
||||||
|
ActionGroup,
|
||||||
|
Button,
|
||||||
|
FormGroup,
|
||||||
|
PageSection,
|
||||||
|
Select,
|
||||||
|
SelectOption,
|
||||||
|
SelectVariant,
|
||||||
|
Switch,
|
||||||
|
TextContent,
|
||||||
|
} from "@patternfly/react-core";
|
||||||
|
|
||||||
|
import type RealmRepresentation from "keycloak-admin/lib/defs/realmRepresentation";
|
||||||
|
import { FormAccess } from "../components/form-access/FormAccess";
|
||||||
|
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||||
|
import { FormPanel } from "../components/scroll-form/FormPanel";
|
||||||
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
|
import { useAdminClient } from "../context/auth/AdminClient";
|
||||||
|
import { getBaseUrl } from "../util";
|
||||||
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
|
|
||||||
|
type LocalizationTabProps = {
|
||||||
|
save: (realm: RealmRepresentation) => void;
|
||||||
|
reset: () => void;
|
||||||
|
refresh: () => void;
|
||||||
|
realm: RealmRepresentation;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LocalizationTab = ({
|
||||||
|
save,
|
||||||
|
reset,
|
||||||
|
realm,
|
||||||
|
}: LocalizationTabProps) => {
|
||||||
|
const { t } = useTranslation("realm-settings");
|
||||||
|
const adminClient = useAdminClient();
|
||||||
|
const [key, setKey] = useState(0);
|
||||||
|
|
||||||
|
const [supportedLocalesOpen, setSupportedLocalesOpen] = useState(false);
|
||||||
|
const [defaultLocaleOpen, setDefaultLocaleOpen] = useState(false);
|
||||||
|
|
||||||
|
const { getValues, control, handleSubmit } = useFormContext();
|
||||||
|
// const [selectedLocale, setSelectedLocale] = useState("en");
|
||||||
|
const [valueSelected, setValueSelected] = useState(false);
|
||||||
|
const themeTypes = useServerInfo().themes!;
|
||||||
|
|
||||||
|
const watchSupportedLocales = useWatch({
|
||||||
|
control,
|
||||||
|
name: "supportedLocales",
|
||||||
|
defaultValue: themeTypes?.account![0].locales,
|
||||||
|
});
|
||||||
|
|
||||||
|
const internationalizationEnabled = useWatch({
|
||||||
|
control,
|
||||||
|
name: "internationalizationEnabled",
|
||||||
|
defaultValue: realm?.internationalizationEnabled,
|
||||||
|
});
|
||||||
|
|
||||||
|
const loader = async () => {
|
||||||
|
if (realm) {
|
||||||
|
const response = await fetch(
|
||||||
|
`${getBaseUrl(adminClient)}admin/realms/${realm.realm}/localization/${
|
||||||
|
getValues("defaultLocale") || "en"
|
||||||
|
}`,
|
||||||
|
{
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `bearer ${await adminClient.getAccessToken()}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
const resultTest = Object.keys(result).map((key) => [key, result[key]]);
|
||||||
|
return resultTest;
|
||||||
|
}
|
||||||
|
return [[]];
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageSection variant="light">
|
||||||
|
<FormPanel
|
||||||
|
className="kc-login-screen"
|
||||||
|
title="Login screen customization"
|
||||||
|
>
|
||||||
|
<FormAccess
|
||||||
|
isHorizontal
|
||||||
|
role="manage-realm"
|
||||||
|
className="pf-u-mt-lg"
|
||||||
|
onSubmit={handleSubmit(save)}
|
||||||
|
>
|
||||||
|
<FormGroup
|
||||||
|
label={t("internationalization")}
|
||||||
|
fieldId="kc-internationalization"
|
||||||
|
>
|
||||||
|
<Controller
|
||||||
|
name="internationalizationEnabled"
|
||||||
|
control={control}
|
||||||
|
defaultValue={realm?.internationalizationEnabled}
|
||||||
|
render={({ onChange, value }) => (
|
||||||
|
<Switch
|
||||||
|
id="kc-l-internationalization"
|
||||||
|
label={t("common:enabled")}
|
||||||
|
labelOff={t("common:disabled")}
|
||||||
|
isChecked={internationalizationEnabled}
|
||||||
|
data-testid={
|
||||||
|
value
|
||||||
|
? "internationalization-enabled"
|
||||||
|
: "internationalization-disabled"
|
||||||
|
}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
{internationalizationEnabled && (
|
||||||
|
<>
|
||||||
|
<FormGroup
|
||||||
|
label={t("supportedLocales")}
|
||||||
|
fieldId="kc-l-supported-locales"
|
||||||
|
>
|
||||||
|
<Controller
|
||||||
|
name="supportedLocales"
|
||||||
|
control={control}
|
||||||
|
defaultValue={themeTypes?.account![0].locales}
|
||||||
|
render={({ onChange }) => (
|
||||||
|
<Select
|
||||||
|
toggleId="kc-l-supported-locales"
|
||||||
|
onToggle={() => {
|
||||||
|
setSupportedLocalesOpen(!supportedLocalesOpen);
|
||||||
|
}}
|
||||||
|
onSelect={(_, v) => {
|
||||||
|
const option = v as string;
|
||||||
|
if (!watchSupportedLocales) {
|
||||||
|
onChange([option]);
|
||||||
|
} else if (watchSupportedLocales!.includes(option)) {
|
||||||
|
onChange(
|
||||||
|
watchSupportedLocales.filter(
|
||||||
|
(item: string) => item !== option
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
onChange([...watchSupportedLocales, option]);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onClear={() => {
|
||||||
|
onChange([]);
|
||||||
|
}}
|
||||||
|
selections={watchSupportedLocales}
|
||||||
|
variant={SelectVariant.typeaheadMulti}
|
||||||
|
aria-label={t("supportedLocales")}
|
||||||
|
isOpen={supportedLocalesOpen}
|
||||||
|
placeholderText={"Select locales"}
|
||||||
|
>
|
||||||
|
{themeTypes?.login![0].locales.map(
|
||||||
|
(locale: string, idx: number) => (
|
||||||
|
<SelectOption
|
||||||
|
selected={true}
|
||||||
|
key={`locale-${idx}`}
|
||||||
|
value={locale}
|
||||||
|
>
|
||||||
|
{t(`allSupportedLocales.${locale}`)}
|
||||||
|
</SelectOption>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup
|
||||||
|
label={t("defaultLocale")}
|
||||||
|
fieldId="kc-l-default-locale"
|
||||||
|
>
|
||||||
|
<Controller
|
||||||
|
name="defaultLocale"
|
||||||
|
control={control}
|
||||||
|
defaultValue={realm?.defaultLocale}
|
||||||
|
render={({ onChange, value }) => (
|
||||||
|
<Select
|
||||||
|
toggleId="kc-default-locale"
|
||||||
|
onToggle={() =>
|
||||||
|
setDefaultLocaleOpen(!defaultLocaleOpen)
|
||||||
|
}
|
||||||
|
onSelect={(_, value) => {
|
||||||
|
onChange(value as string);
|
||||||
|
setValueSelected(true);
|
||||||
|
// setSelectedLocale(value as string);
|
||||||
|
setKey(new Date().getTime());
|
||||||
|
setDefaultLocaleOpen(false);
|
||||||
|
}}
|
||||||
|
selections={
|
||||||
|
valueSelected
|
||||||
|
? t(`allSupportedLocales.${value}`)
|
||||||
|
: realm.defaultLocale !== ""
|
||||||
|
? t(
|
||||||
|
`allSupportedLocales.${
|
||||||
|
realm.defaultLocale || "en"
|
||||||
|
}`
|
||||||
|
)
|
||||||
|
: t("placeholderText")
|
||||||
|
}
|
||||||
|
variant={SelectVariant.single}
|
||||||
|
aria-label={t("defaultLocale")}
|
||||||
|
isOpen={defaultLocaleOpen}
|
||||||
|
placeholderText={t("placeholderText")}
|
||||||
|
data-testid="select-default-locale"
|
||||||
|
>
|
||||||
|
{watchSupportedLocales.map(
|
||||||
|
(locale: string, idx: number) => (
|
||||||
|
<SelectOption
|
||||||
|
key={`default-locale-${idx}`}
|
||||||
|
value={locale}
|
||||||
|
>
|
||||||
|
{t(`allSupportedLocales.${locale}`)}
|
||||||
|
</SelectOption>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<ActionGroup>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
type="submit"
|
||||||
|
data-testid="localization-tab-save"
|
||||||
|
>
|
||||||
|
{t("common:save")}
|
||||||
|
</Button>
|
||||||
|
<Button variant="link" onClick={reset}>
|
||||||
|
{t("common:revert")}
|
||||||
|
</Button>
|
||||||
|
</ActionGroup>
|
||||||
|
</FormAccess>
|
||||||
|
</FormPanel>
|
||||||
|
|
||||||
|
<FormPanel className="kc-login-screen" title="Edit message bundles">
|
||||||
|
<TextContent className="messageBundleDescription">
|
||||||
|
{t("messageBundleDescription")}
|
||||||
|
</TextContent>
|
||||||
|
<div className="tableBorder">
|
||||||
|
<KeycloakDataTable
|
||||||
|
key={key}
|
||||||
|
loader={loader}
|
||||||
|
ariaLabelKey="client-scopes:clientScopeList"
|
||||||
|
searchPlaceholderKey=" "
|
||||||
|
emptyState={
|
||||||
|
<ListEmptyState
|
||||||
|
hasIcon={true}
|
||||||
|
message={t("noMessageBundles")}
|
||||||
|
instructions={t("noMessageBundlesInstructions")}
|
||||||
|
onPrimaryAction={() => {}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
canSelectAll
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
name: "Key",
|
||||||
|
cellRenderer: (row) => row[0],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Value",
|
||||||
|
cellRenderer: (row) => row[1],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</FormPanel>
|
||||||
|
</PageSection>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -214,8 +214,9 @@ export const RSAGeneratedModal = ({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="algorithm"
|
name="config.algorithm"
|
||||||
defaultValue=""
|
control={control}
|
||||||
|
defaultValue={["RS256"]}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="kc-rsa-algorithm"
|
toggleId="kc-rsa-algorithm"
|
||||||
|
@ -223,7 +224,7 @@ export const RSAGeneratedModal = ({
|
||||||
setIsRSAalgDropdownOpen(!isRSAalgDropdownOpen)
|
setIsRSAalgDropdownOpen(!isRSAalgDropdownOpen)
|
||||||
}
|
}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange([value + ""]);
|
||||||
setIsRSAalgDropdownOpen(false);
|
setIsRSAalgDropdownOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={[value + ""]}
|
selections={[value + ""]}
|
||||||
|
|
|
@ -80,3 +80,15 @@ button.pf-c-button.pf-m-link.add-provider {
|
||||||
.add-provider-modal > div.pf-c-modal-box__body {
|
.add-provider-modal > div.pf-c-modal-box__body {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pf-c-content.messageBundleDescription {
|
||||||
|
max-width: 1024px;
|
||||||
|
padding-bottom: var(--pf-global--spacer--lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.tableBorder {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: var(--pf-global--BorderColor--100);
|
||||||
|
max-width: 1024px;
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import { EventsTab } from "./event-config/EventsTab";
|
||||||
import type ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
|
import type ComponentRepresentation from "keycloak-admin/lib/defs/componentRepresentation";
|
||||||
import { KeysProviderTab } from "./KeysProvidersTab";
|
import { KeysProviderTab } from "./KeysProvidersTab";
|
||||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||||
|
import { LocalizationTab } from "./LocalizationTab";
|
||||||
|
|
||||||
type RealmSettingsHeaderProps = {
|
type RealmSettingsHeaderProps = {
|
||||||
onChange: (value: boolean) => void;
|
onChange: (value: boolean) => void;
|
||||||
|
@ -129,9 +130,9 @@ export const RealmSettingsSection = () => {
|
||||||
const { addAlert } = useAlerts();
|
const { addAlert } = useAlerts();
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
const { control, getValues, setValue, reset: resetForm } = form;
|
const { control, getValues, setValue, reset: resetForm } = form;
|
||||||
|
const [key, setKey] = useState(0);
|
||||||
const [realm, setRealm] = useState<RealmRepresentation>();
|
const [realm, setRealm] = useState<RealmRepresentation>();
|
||||||
const [activeTab, setActiveTab] = useState(0);
|
const [activeTab, setActiveTab] = useState(0);
|
||||||
const [key, setKey] = useState(0);
|
|
||||||
const [realmComponents, setRealmComponents] = useState<
|
const [realmComponents, setRealmComponents] = useState<
|
||||||
ComponentRepresentation[]
|
ComponentRepresentation[]
|
||||||
>();
|
>();
|
||||||
|
@ -149,17 +150,6 @@ export const RealmSettingsSection = () => {
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const update = async () => {
|
|
||||||
const realmComponents = await adminClient.components.find({
|
|
||||||
type: "org.keycloak.keys.KeyProvider",
|
|
||||||
realm: realmName,
|
|
||||||
});
|
|
||||||
setRealmComponents(realmComponents);
|
|
||||||
};
|
|
||||||
setTimeout(update, 100);
|
|
||||||
}, [key]);
|
|
||||||
|
|
||||||
useFetch(
|
useFetch(
|
||||||
async () => {
|
async () => {
|
||||||
const realm = await adminClient.realms.findOne({ realm: realmName });
|
const realm = await adminClient.realms.findOne({ realm: realmName });
|
||||||
|
@ -174,24 +164,13 @@ export const RealmSettingsSection = () => {
|
||||||
setRealm(result.realm);
|
setRealm(result.realm);
|
||||||
setRealmComponents(result.realmComponents);
|
setRealmComponents(result.realmComponents);
|
||||||
},
|
},
|
||||||
[]
|
[key]
|
||||||
);
|
);
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
setKey(new Date().getTime());
|
setKey(new Date().getTime());
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const update = async () => {
|
|
||||||
const realmComponents = await adminClient.components.find({
|
|
||||||
type: "org.keycloak.keys.KeyProvider",
|
|
||||||
realm: realmName,
|
|
||||||
});
|
|
||||||
setRealmComponents(realmComponents);
|
|
||||||
};
|
|
||||||
setTimeout(update, 100);
|
|
||||||
}, [key]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (realm) setupForm(realm);
|
if (realm) setupForm(realm);
|
||||||
}, [realm]);
|
}, [realm]);
|
||||||
|
@ -264,6 +243,7 @@ export const RealmSettingsSection = () => {
|
||||||
<RealmSettingsThemesTab
|
<RealmSettingsThemesTab
|
||||||
save={save}
|
save={save}
|
||||||
reset={() => setupForm(realm!)}
|
reset={() => setupForm(realm!)}
|
||||||
|
realm={realm!}
|
||||||
/>
|
/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
|
@ -306,6 +286,22 @@ export const RealmSettingsSection = () => {
|
||||||
>
|
>
|
||||||
<EventsTab />
|
<EventsTab />
|
||||||
</Tab>
|
</Tab>
|
||||||
|
|
||||||
|
{realm && (
|
||||||
|
<Tab
|
||||||
|
id="localization"
|
||||||
|
eventKey="localization"
|
||||||
|
title={<TabTitleText>{t("localization")}</TabTitleText>}
|
||||||
|
>
|
||||||
|
<LocalizationTab
|
||||||
|
key={key}
|
||||||
|
refresh={refresh}
|
||||||
|
save={save}
|
||||||
|
reset={() => setupForm(realm)}
|
||||||
|
realm={realm}
|
||||||
|
/>
|
||||||
|
</Tab>
|
||||||
|
)}
|
||||||
</KeycloakTabs>
|
</KeycloakTabs>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</PageSection>
|
</PageSection>
|
||||||
|
|
|
@ -20,11 +20,13 @@ import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||||
type RealmSettingsThemesTabProps = {
|
type RealmSettingsThemesTabProps = {
|
||||||
save: (realm: RealmRepresentation) => void;
|
save: (realm: RealmRepresentation) => void;
|
||||||
reset: () => void;
|
reset: () => void;
|
||||||
|
realm: RealmRepresentation;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RealmSettingsThemesTab = ({
|
export const RealmSettingsThemesTab = ({
|
||||||
save,
|
save,
|
||||||
reset,
|
reset,
|
||||||
|
realm,
|
||||||
}: RealmSettingsThemesTabProps) => {
|
}: RealmSettingsThemesTabProps) => {
|
||||||
const { t } = useTranslation("realm-settings");
|
const { t } = useTranslation("realm-settings");
|
||||||
|
|
||||||
|
@ -49,7 +51,7 @@ export const RealmSettingsThemesTab = ({
|
||||||
const internationalizationEnabled = useWatch({
|
const internationalizationEnabled = useWatch({
|
||||||
control,
|
control,
|
||||||
name: "internationalizationEnabled",
|
name: "internationalizationEnabled",
|
||||||
defaultValue: false,
|
defaultValue: realm?.internationalizationEnabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -242,10 +244,10 @@ export const RealmSettingsThemesTab = ({
|
||||||
<Controller
|
<Controller
|
||||||
name="internationalizationEnabled"
|
name="internationalizationEnabled"
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue={false}
|
defaultValue={internationalizationEnabled}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Switch
|
<Switch
|
||||||
id="kc-internationalization"
|
id="kc-t-internationalization"
|
||||||
label={t("common:enabled")}
|
label={t("common:enabled")}
|
||||||
labelOff={t("common:disabled")}
|
labelOff={t("common:disabled")}
|
||||||
isChecked={value}
|
isChecked={value}
|
||||||
|
@ -263,7 +265,7 @@ export const RealmSettingsThemesTab = ({
|
||||||
<>
|
<>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={t("supportedLocales")}
|
label={t("supportedLocales")}
|
||||||
fieldId="kc-supported-locales"
|
fieldId="kc-t-supported-locales"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="supportedLocales"
|
name="supportedLocales"
|
||||||
|
@ -271,7 +273,7 @@ export const RealmSettingsThemesTab = ({
|
||||||
defaultValue={themeTypes?.account![0].locales}
|
defaultValue={themeTypes?.account![0].locales}
|
||||||
render={({ value, onChange }) => (
|
render={({ value, onChange }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="kc-supported-locales"
|
toggleId="kc-t-supported-locales"
|
||||||
onToggle={() => {
|
onToggle={() => {
|
||||||
setSupportedLocalesOpen(!supportedLocalesOpen);
|
setSupportedLocalesOpen(!supportedLocalesOpen);
|
||||||
}}
|
}}
|
||||||
|
@ -318,7 +320,7 @@ export const RealmSettingsThemesTab = ({
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
toggleId="kc-default-locale"
|
toggleId="kc-t-default-locale"
|
||||||
onToggle={() => setDefaultLocaleOpen(!defaultLocaleOpen)}
|
onToggle={() => setDefaultLocaleOpen(!defaultLocaleOpen)}
|
||||||
onSelect={(_, value) => {
|
onSelect={(_, value) => {
|
||||||
onChange(value as string);
|
onChange(value as string);
|
||||||
|
|
|
@ -127,6 +127,7 @@
|
||||||
"tr": "Türkçe",
|
"tr": "Türkçe",
|
||||||
"zh-CN": "中文"
|
"zh-CN": "中文"
|
||||||
},
|
},
|
||||||
|
"placeholderText": "Select one",
|
||||||
"userManagedAccess": "User-managed access",
|
"userManagedAccess": "User-managed access",
|
||||||
"endpoints": "Endpoints",
|
"endpoints": "Endpoints",
|
||||||
"openIDEndpointConfiguration": "OpenID Endpoint Configuration",
|
"openIDEndpointConfiguration": "OpenID Endpoint Configuration",
|
||||||
|
@ -136,6 +137,9 @@
|
||||||
"adminTheme": "Admin console theme",
|
"adminTheme": "Admin console theme",
|
||||||
"emailTheme": "Email theme",
|
"emailTheme": "Email theme",
|
||||||
"internationalization": "Internationalization",
|
"internationalization": "Internationalization",
|
||||||
|
"localization": "Localization",
|
||||||
|
"key": "Key",
|
||||||
|
"value": "Value",
|
||||||
"supportedLocales": "Supported locales",
|
"supportedLocales": "Supported locales",
|
||||||
"defaultLocale": "Default locale",
|
"defaultLocale": "Default locale",
|
||||||
|
|
||||||
|
@ -489,7 +493,10 @@
|
||||||
"user-events-cleared-error": "Could not clear the user events {{error}}",
|
"user-events-cleared-error": "Could not clear the user events {{error}}",
|
||||||
"events-disable-title": "Unsave events?",
|
"events-disable-title": "Unsave events?",
|
||||||
"events-disable-confirm": "If \"Save events\" is disabled, subsequent events will not be displayed in the \"Events\" menu",
|
"events-disable-confirm": "If \"Save events\" is disabled, subsequent events will not be displayed in the \"Events\" menu",
|
||||||
"confirm": "Confirm"
|
"confirm": "Confirm",
|
||||||
|
"noMessageBundles": "No message bundles",
|
||||||
|
"noMessageBundlesInstructions": "Add a message bundle to get started.",
|
||||||
|
"messageBundleDescription": "You can edit the supported locales. If you haven't selected supported locales yet, you can only edit the English locale."
|
||||||
},
|
},
|
||||||
"partial-import": {
|
"partial-import": {
|
||||||
"partialImportHeaderText": "Partial import allows you to import users, clients, and other resources from a previously exported json file.",
|
"partialImportHeaderText": "Partial import allows you to import users, clients, and other resources from a previously exported json file.",
|
||||||
|
|
Loading…
Reference in a new issue