mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(console): application details (#2460)
This commit is contained in:
parent
3c9edb9ca4
commit
e4f77447c1
25 changed files with 173 additions and 117 deletions
|
@ -55,7 +55,6 @@ const Main = () => {
|
|||
<Route path=":id">
|
||||
<Route index element={<Navigate replace to="settings" />} />
|
||||
<Route path="settings" element={<ApplicationDetails />} />
|
||||
<Route path="advanced-settings" element={<ApplicationDetails />} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="api-resources">
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
flex-shrink: 0;
|
||||
width: 248px;
|
||||
overflow-y: auto;
|
||||
margin-bottom: _.unit(6);
|
||||
|
||||
> div + div {
|
||||
margin-top: _.unit(6);
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
.content {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
margin-bottom: _.unit(6);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex-grow: 1;
|
||||
padding: 0 _.unit(3) 0 _.unit(2);
|
||||
padding: 0 _.unit(2);
|
||||
overflow-y: scroll;
|
||||
|
||||
> * {
|
||||
|
|
35
packages/console/src/components/FormCard/index.module.scss
Normal file
35
packages/console/src/components/FormCard/index.module.scss
Normal file
|
@ -0,0 +1,35 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.container {
|
||||
padding: _.unit(6) _.unit(8);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.introduction {
|
||||
width: 296px;
|
||||
margin-right: _.unit(14);
|
||||
flex-shrink: 0;
|
||||
|
||||
> :not(:first-child) {
|
||||
margin-top: _.unit(2);
|
||||
}
|
||||
|
||||
.title {
|
||||
@include _.subhead-cap;
|
||||
color: var(--color-neutral-variant-60);
|
||||
}
|
||||
|
||||
.description {
|
||||
font: var(--font-body-medium);
|
||||
color: var(--color-text-secondary);
|
||||
|
||||
a {
|
||||
color: var(--color-text-link);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
flex-grow: 1;
|
||||
}
|
32
packages/console/src/components/FormCard/index.tsx
Normal file
32
packages/console/src/components/FormCard/index.tsx
Normal file
|
@ -0,0 +1,32 @@
|
|||
import type { AdminConsoleKey } from '@logto/phrases';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import Card from '../Card';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
title: AdminConsoleKey;
|
||||
description: AdminConsoleKey;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const FormCard = ({ title, description, children }: Props) => {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
||||
return (
|
||||
<Card className={styles.container}>
|
||||
<div className={styles.introduction}>
|
||||
<div className={styles.title}>{t(title)}</div>
|
||||
<div className={styles.description}>
|
||||
{t(description)} {/* TODO: @Yijun update this link when @Guamian is ready for this */}{' '}
|
||||
<Link to="#">{t('general.learn_more')}</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.form}>{children}</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormCard;
|
|
@ -3,5 +3,5 @@
|
|||
.nav {
|
||||
border-bottom: 1px solid var(--color-divider);
|
||||
display: flex;
|
||||
margin: _.unit(1) 0;
|
||||
margin-top: _.unit(1);
|
||||
}
|
||||
|
|
|
@ -1,44 +1,31 @@
|
|||
import type { Application, SnakeCaseOidcConfig } from '@logto/schemas';
|
||||
import { ApplicationType, UserRole } from '@logto/schemas';
|
||||
import { useEffect } from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import CopyToClipboard from '@/components/CopyToClipboard';
|
||||
import FormCard from '@/components/FormCard';
|
||||
import FormField from '@/components/FormField';
|
||||
import Switch from '@/components/Switch';
|
||||
import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal';
|
||||
|
||||
import * as styles from '../index.module.scss';
|
||||
|
||||
type Props = {
|
||||
applicationType: ApplicationType;
|
||||
oidcConfig: SnakeCaseOidcConfig;
|
||||
defaultData: Application;
|
||||
isDeleted: boolean;
|
||||
};
|
||||
|
||||
const AdvancedSettings = ({ applicationType, oidcConfig, defaultData, isDeleted }: Props) => {
|
||||
const {
|
||||
control,
|
||||
reset,
|
||||
formState: { isDirty },
|
||||
} = useFormContext<Application>();
|
||||
const AdvancedSettings = ({ applicationType, oidcConfig }: Props) => {
|
||||
const { control } = useFormContext<Application>();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
||||
useEffect(() => {
|
||||
reset(defaultData);
|
||||
|
||||
return () => {
|
||||
reset(defaultData);
|
||||
};
|
||||
}, [reset, defaultData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormCard
|
||||
title="application_details.advanced_settings"
|
||||
description="application_details.advanced_settings_description"
|
||||
>
|
||||
<FormField
|
||||
title="application_details.authorization_endpoint"
|
||||
className={styles.textField}
|
||||
tooltip="application_details.authorization_endpoint_tip"
|
||||
>
|
||||
<CopyToClipboard
|
||||
|
@ -83,8 +70,7 @@ const AdvancedSettings = ({ applicationType, oidcConfig, defaultData, isDeleted
|
|||
/>
|
||||
</FormField>
|
||||
)}
|
||||
<UnsavedChangesAlertModal hasUnsavedChanges={!isDeleted && isDirty} />
|
||||
</>
|
||||
</FormCard>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,43 +1,32 @@
|
|||
import type { Application, SnakeCaseOidcConfig } from '@logto/schemas';
|
||||
import type { Application } from '@logto/schemas';
|
||||
import { ApplicationType, validateRedirectUrl } from '@logto/schemas';
|
||||
import { useEffect } from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import CopyToClipboard from '@/components/CopyToClipboard';
|
||||
import FormCard from '@/components/FormCard';
|
||||
import FormField from '@/components/FormField';
|
||||
import MultiTextInput from '@/components/MultiTextInput';
|
||||
import type { MultiTextInputRule } from '@/components/MultiTextInput/types';
|
||||
import { createValidatorForRhf, convertRhfErrorMessage } from '@/components/MultiTextInput/utils';
|
||||
import TextInput from '@/components/TextInput';
|
||||
import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal';
|
||||
import { uriOriginValidator } from '@/utilities/validator';
|
||||
|
||||
import * as styles from '../index.module.scss';
|
||||
|
||||
type Props = {
|
||||
applicationType: ApplicationType;
|
||||
oidcConfig: SnakeCaseOidcConfig;
|
||||
defaultData: Application;
|
||||
isDeleted: boolean;
|
||||
data: Application;
|
||||
};
|
||||
|
||||
const Settings = ({ applicationType, oidcConfig, defaultData, isDeleted }: Props) => {
|
||||
const Settings = ({ data }: Props) => {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const {
|
||||
control,
|
||||
register,
|
||||
reset,
|
||||
formState: { errors, isDirty },
|
||||
formState: { errors },
|
||||
} = useFormContext<Application>();
|
||||
|
||||
useEffect(() => {
|
||||
reset(defaultData);
|
||||
|
||||
return () => {
|
||||
reset(defaultData);
|
||||
};
|
||||
}, [reset, defaultData]);
|
||||
const { id, secret, type: applicationType } = data;
|
||||
|
||||
const isNativeApp = applicationType === ApplicationType.Native;
|
||||
const uriPatternRules: MultiTextInputRule = {
|
||||
|
@ -48,36 +37,35 @@ const Settings = ({ applicationType, oidcConfig, defaultData, isDeleted }: Props
|
|||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
isRequired
|
||||
title="application_details.application_name"
|
||||
className={styles.textField}
|
||||
>
|
||||
<FormCard
|
||||
title="application_details.settings"
|
||||
description="application_details.settings_description"
|
||||
>
|
||||
<FormField isRequired title="application_details.application_name">
|
||||
<TextInput
|
||||
{...register('name', { required: true })}
|
||||
hasError={Boolean(errors.name)}
|
||||
placeholder={t('application_details.application_name_placeholder')}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField title="application_details.description" className={styles.textField}>
|
||||
<FormField title="application_details.description">
|
||||
<TextInput
|
||||
{...register('description')}
|
||||
placeholder={t('application_details.description_placeholder')}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField title="application_details.application_id" className={styles.textField}>
|
||||
<CopyToClipboard className={styles.textField} value={defaultData.id} variant="border" />
|
||||
<FormField title="application_details.application_id">
|
||||
<CopyToClipboard value={id} variant="border" className={styles.textField} />
|
||||
</FormField>
|
||||
{[ApplicationType.Traditional, ApplicationType.MachineToMachine].includes(
|
||||
applicationType
|
||||
) && (
|
||||
<FormField title="application_details.application_secret" className={styles.textField}>
|
||||
<FormField title="application_details.application_secret">
|
||||
<CopyToClipboard
|
||||
hasVisibilityToggle
|
||||
className={styles.textField}
|
||||
value={defaultData.secret}
|
||||
value={secret}
|
||||
variant="border"
|
||||
className={styles.textField}
|
||||
/>
|
||||
</FormField>
|
||||
)}
|
||||
|
@ -85,7 +73,6 @@ const Settings = ({ applicationType, oidcConfig, defaultData, isDeleted }: Props
|
|||
<FormField
|
||||
isRequired
|
||||
title="application_details.redirect_uris"
|
||||
className={styles.textField}
|
||||
tooltip="application_details.redirect_uri_tip"
|
||||
>
|
||||
<Controller
|
||||
|
@ -117,7 +104,6 @@ const Settings = ({ applicationType, oidcConfig, defaultData, isDeleted }: Props
|
|||
{applicationType !== ApplicationType.MachineToMachine && (
|
||||
<FormField
|
||||
title="application_details.post_sign_out_redirect_uris"
|
||||
className={styles.textField}
|
||||
tooltip="application_details.post_sign_out_redirect_uri_tip"
|
||||
>
|
||||
<Controller
|
||||
|
@ -142,7 +128,6 @@ const Settings = ({ applicationType, oidcConfig, defaultData, isDeleted }: Props
|
|||
{applicationType !== ApplicationType.MachineToMachine && (
|
||||
<FormField
|
||||
title="application_details.cors_allowed_origins"
|
||||
className={styles.textField}
|
||||
tooltip="application_details.cors_allowed_origins_tip"
|
||||
>
|
||||
<Controller
|
||||
|
@ -169,8 +154,7 @@ const Settings = ({ applicationType, oidcConfig, defaultData, isDeleted }: Props
|
|||
/>
|
||||
</FormField>
|
||||
)}
|
||||
<UnsavedChangesAlertModal hasUnsavedChanges={!isDeleted && isDirty} />
|
||||
</>
|
||||
</FormCard>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -18,18 +18,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
> :first-child {
|
||||
margin-top: 0;
|
||||
.formContent {
|
||||
>:not(:first-child) {
|
||||
margin-top: _.unit(4);
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-top: _.unit(8);
|
||||
}
|
||||
.fieldsContent {
|
||||
> :not(:first-child) {
|
||||
margin-top: _.unit(4);
|
||||
}
|
||||
|
||||
.fields {
|
||||
padding-bottom: _.unit(10);
|
||||
flex: 1;
|
||||
&:last-child {
|
||||
margin-bottom: _.unit(6);
|
||||
}
|
||||
}
|
||||
|
||||
.textField {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type { Application, SnakeCaseOidcConfig } from '@logto/schemas';
|
||||
import { ApplicationType } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
@ -20,7 +19,9 @@ import DeleteConfirmModal from '@/components/DeleteConfirmModal';
|
|||
import DetailsSkeleton from '@/components/DetailsSkeleton';
|
||||
import Drawer from '@/components/Drawer';
|
||||
import LinkButton from '@/components/LinkButton';
|
||||
import SubmitFormChangesActionBar from '@/components/SubmitFormChangesActionBar';
|
||||
import TabNav, { TabNavItem } from '@/components/TabNav';
|
||||
import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal';
|
||||
import type { RequestError } from '@/hooks/use-api';
|
||||
import useApi from '@/hooks/use-api';
|
||||
import useDocumentationUrl from '@/hooks/use-documentation-url';
|
||||
|
@ -62,7 +63,7 @@ const ApplicationDetails = () => {
|
|||
const {
|
||||
handleSubmit,
|
||||
reset,
|
||||
formState: { isSubmitting },
|
||||
formState: { isSubmitting, isDirty },
|
||||
} = formMethods;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -123,8 +124,6 @@ const ApplicationDetails = () => {
|
|||
setIsReadmeOpen(false);
|
||||
};
|
||||
|
||||
const isAdvancedSettings = pathname.includes('advanced-settings');
|
||||
|
||||
return (
|
||||
<div className={detailsStyles.container}>
|
||||
<LinkButton
|
||||
|
@ -200,51 +199,29 @@ const ApplicationDetails = () => {
|
|||
</DeleteConfirmModal>
|
||||
</div>
|
||||
</Card>
|
||||
<Card className={classNames(styles.body, detailsStyles.body)}>
|
||||
<TabNav>
|
||||
<TabNavItem href={`/applications/${data.id}/settings`}>
|
||||
{t('general.settings_nav')}
|
||||
</TabNavItem>
|
||||
<TabNavItem href={`/applications/${data.id}/advanced-settings`}>
|
||||
{t('application_details.advanced_settings')}
|
||||
</TabNavItem>
|
||||
</TabNav>
|
||||
<FormProvider {...formMethods}>
|
||||
<form className={classNames(styles.form, detailsStyles.body)} onSubmit={onSubmit}>
|
||||
<div className={styles.fields}>
|
||||
{isAdvancedSettings && (
|
||||
<AdvancedSettings
|
||||
applicationType={data.type}
|
||||
oidcConfig={oidcConfig}
|
||||
defaultData={data}
|
||||
isDeleted={isDeleted}
|
||||
/>
|
||||
)}
|
||||
{!isAdvancedSettings && (
|
||||
<Settings
|
||||
applicationType={data.type}
|
||||
oidcConfig={oidcConfig}
|
||||
defaultData={data}
|
||||
isDeleted={isDeleted}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={detailsStyles.footer}>
|
||||
<div className={detailsStyles.footerMain}>
|
||||
<Button
|
||||
isLoading={isSubmitting}
|
||||
htmlType="submit"
|
||||
type="primary"
|
||||
size="large"
|
||||
title="general.save_changes"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</FormProvider>
|
||||
</Card>
|
||||
<TabNav>
|
||||
<TabNavItem href={`/applications/${data.id}/settings`}>
|
||||
{t('general.settings_nav')}
|
||||
</TabNavItem>
|
||||
</TabNav>
|
||||
<FormProvider {...formMethods}>
|
||||
<form className={styles.formContent} onSubmit={onSubmit}>
|
||||
<div className={styles.fieldsContent}>
|
||||
<Settings data={data} />
|
||||
<AdvancedSettings applicationType={data.type} oidcConfig={oidcConfig} />
|
||||
</div>
|
||||
<SubmitFormChangesActionBar
|
||||
isOpen={isDirty}
|
||||
isSubmitting={isSubmitting}
|
||||
onDiscard={() => {
|
||||
reset();
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
</FormProvider>
|
||||
</>
|
||||
)}
|
||||
<UnsavedChangesAlertModal hasUnsavedChanges={!isDeleted && isDirty} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
|
||||
@mixin form-text-field {
|
||||
width: dim.$form-text-field-width;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@mixin vertical-bar {
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
const application_details = {
|
||||
back_to_applications: 'Zurück zu Anwendungen',
|
||||
check_guide: 'Zur Anleitung',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Auth0 for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
advanced_settings: 'Erweiterte Einstellungen',
|
||||
advanced_settings_description:
|
||||
'It real sent your at. Amounted all shy set why followed declared.', // UNTRANSLATED
|
||||
application_name: 'Anwendungsname',
|
||||
application_name_placeholder: 'Meine App',
|
||||
description: 'Beschreibung',
|
||||
|
|
|
@ -40,6 +40,7 @@ const general = {
|
|||
type_to_search: 'Tippe um zu suchen',
|
||||
got_it: 'Got it', // UNTRANSLATED
|
||||
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
|
||||
learn_more: 'Learn more', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default general;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
const application_details = {
|
||||
back_to_applications: 'Back to Applications',
|
||||
check_guide: 'Check Guide',
|
||||
settings: 'Settings',
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Auth0 for Authentication. Configure the allowed Callback URLs and Secrets for your Application.',
|
||||
advanced_settings: 'Advanced settings',
|
||||
advanced_settings_description:
|
||||
'It real sent your at. Amounted all shy set why followed declared.',
|
||||
application_name: 'Application name',
|
||||
application_name_placeholder: 'My App',
|
||||
description: 'Description',
|
||||
|
|
|
@ -39,6 +39,7 @@ const general = {
|
|||
type_to_search: 'Type to search',
|
||||
got_it: 'Got it',
|
||||
page_info: '{{min, number}}-{{max, number}} of {{total, number}}',
|
||||
learn_more: 'Learn more',
|
||||
};
|
||||
|
||||
export default general;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
const application_details = {
|
||||
back_to_applications: 'Retour aux applications',
|
||||
check_guide: 'Aller voir le guide',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Auth0 for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
advanced_settings: 'Paramètres avancés',
|
||||
advanced_settings_description:
|
||||
'It real sent your at. Amounted all shy set why followed declared.', // UNTRANSLATED
|
||||
application_name: "Nom de l'application",
|
||||
application_name_placeholder: 'Mon App',
|
||||
description: 'Description',
|
||||
|
|
|
@ -40,6 +40,7 @@ const general = {
|
|||
type_to_search: 'Type to search', // UNTRANSLATED
|
||||
got_it: 'Got it', // UNTRANSLATED
|
||||
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
|
||||
learn_more: 'Learn more', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default general;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
const application_details = {
|
||||
back_to_applications: '어플리케이션으로 돌아가기',
|
||||
check_guide: '가이드 확인',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Auth0 for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
advanced_settings: '고급 설정',
|
||||
advanced_settings_description:
|
||||
'It real sent your at. Amounted all shy set why followed declared.', // UNTRANSLATED
|
||||
application_name: '어플리케이션 이름',
|
||||
application_name_placeholder: '나의 앱',
|
||||
description: '설명',
|
||||
|
|
|
@ -39,6 +39,7 @@ const general = {
|
|||
type_to_search: 'Type to search', // UNTRANSLATED
|
||||
got_it: 'Got it', // UNTRANSLATED
|
||||
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
|
||||
learn_more: 'Learn more', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default general;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
const application_details = {
|
||||
back_to_applications: 'Voltar para aplicações',
|
||||
check_guide: 'Guia de verificação',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Auth0 for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
advanced_settings: 'Configurações avançadas',
|
||||
advanced_settings_description:
|
||||
'It real sent your at. Amounted all shy set why followed declared.', // UNTRANSLATED
|
||||
application_name: 'Nome da aplicação',
|
||||
application_name_placeholder: 'Ex: Site Empresa',
|
||||
description: 'Descrição',
|
||||
|
|
|
@ -39,6 +39,7 @@ const general = {
|
|||
type_to_search: 'Type to search', // UNTRANSLATED
|
||||
got_it: 'Got it', // UNTRANSLATED
|
||||
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
|
||||
learn_more: 'Learn more', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default general;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
const application_details = {
|
||||
back_to_applications: 'Uygulamalara geri dön',
|
||||
check_guide: 'Kılavuza Göz At',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Auth0 for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
advanced_settings: 'Gelişmiş Ayarlar',
|
||||
advanced_settings_description:
|
||||
'It real sent your at. Amounted all shy set why followed declared.', // UNTRANSLATED
|
||||
application_name: 'Uygulama Adı',
|
||||
application_name_placeholder: 'Uygulamam',
|
||||
description: 'Açıklama',
|
||||
|
|
|
@ -40,6 +40,7 @@ const general = {
|
|||
type_to_search: 'Type to search', // UNTRANSLATED
|
||||
got_it: 'Got it', // UNTRANSLATED
|
||||
page_info: '{{min, number}}-{{max, number}} of {{total, number}}', // UNTRANSLATED
|
||||
learn_more: 'Learn more', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default general;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
const application_details = {
|
||||
back_to_applications: '返回全部应用',
|
||||
check_guide: '查看指南',
|
||||
settings: '设置',
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Auth0 for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
advanced_settings: '高级设置',
|
||||
advanced_settings_description:
|
||||
'It real sent your at. Amounted all shy set why followed declared.', // UNTRANSLATED
|
||||
application_name: '应用名称',
|
||||
application_name_placeholder: '我的应用',
|
||||
description: '描述',
|
||||
|
|
|
@ -39,6 +39,7 @@ const general = {
|
|||
type_to_search: '输入搜索',
|
||||
got_it: 'Got it', // UNTRANSLATED
|
||||
page_info: '{{min, number}}-{{max, number}} 共 {{total, number}} 条', // UNTRANSLATED
|
||||
learn_more: 'Learn more', // UNTRANSLATED
|
||||
};
|
||||
|
||||
export default general;
|
||||
|
|
Loading…
Reference in a new issue