mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(console): api resource details (#2464)
This commit is contained in:
parent
e4f77447c1
commit
e9d53dc546
21 changed files with 135 additions and 102 deletions
|
@ -0,0 +1,23 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.container {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
>:not(:first-child) {
|
||||
margin-top: _.unit(4);
|
||||
}
|
||||
|
||||
.fields {
|
||||
flex-grow: 1;
|
||||
|
||||
> :not(:first-child) {
|
||||
margin-top: _.unit(4);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: _.unit(6);
|
||||
}
|
||||
}
|
||||
}
|
30
packages/console/src/components/DetailsForm/index.tsx
Normal file
30
packages/console/src/components/DetailsForm/index.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { forwardRef } from 'react';
|
||||
import type { ForwardedRef, HTMLProps, ReactNode } from 'react';
|
||||
|
||||
import SubmitFormChangesActionBar from '../SubmitFormChangesActionBar';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
type Props = HTMLProps<HTMLFormElement> & {
|
||||
isDirty: boolean;
|
||||
isSubmitting: boolean;
|
||||
children: ReactNode;
|
||||
onDiscard: () => void;
|
||||
};
|
||||
|
||||
const DetailsForm = (
|
||||
{ isDirty, isSubmitting, onDiscard, children, ...rest }: Props,
|
||||
reference: ForwardedRef<HTMLFormElement>
|
||||
) => {
|
||||
return (
|
||||
<form {...rest} ref={reference} className={styles.container}>
|
||||
<div className={styles.fields}>{children}</div>
|
||||
<SubmitFormChangesActionBar
|
||||
isOpen={isDirty}
|
||||
isSubmitting={isSubmitting}
|
||||
onDiscard={onDiscard}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default forwardRef(DetailsForm);
|
|
@ -14,7 +14,14 @@ const SubmitFormChangesActionBar = ({ isOpen, isSubmitting, onDiscard }: Props)
|
|||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Button size="medium" title="general.discard" disabled={isSubmitting} onClick={onDiscard} />
|
||||
<Button
|
||||
size="medium"
|
||||
title="general.discard"
|
||||
disabled={isSubmitting}
|
||||
onClick={() => {
|
||||
onDiscard();
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
isLoading={isSubmitting}
|
||||
htmlType="submit"
|
||||
|
|
|
@ -59,22 +59,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
> :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-top: _.unit(8);
|
||||
}
|
||||
|
||||
.fields {
|
||||
padding-bottom: _.unit(10);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.textField {
|
||||
@include _.form-text-field;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import type { Resource } from '@logto/schemas';
|
||||
import { AppearanceMode } from '@logto/schemas';
|
||||
import { managementResource } from '@logto/schemas/lib/seeds';
|
||||
import classNames from 'classnames';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
@ -15,11 +14,12 @@ import Back from '@/assets/images/back.svg';
|
|||
import Delete from '@/assets/images/delete.svg';
|
||||
import More from '@/assets/images/more.svg';
|
||||
import ActionMenu, { ActionMenuItem } from '@/components/ActionMenu';
|
||||
import Button from '@/components/Button';
|
||||
import Card from '@/components/Card';
|
||||
import CopyToClipboard from '@/components/CopyToClipboard';
|
||||
import DeleteConfirmModal from '@/components/DeleteConfirmModal';
|
||||
import DetailsForm from '@/components/DetailsForm';
|
||||
import DetailsSkeleton from '@/components/DetailsSkeleton';
|
||||
import FormCard from '@/components/FormCard';
|
||||
import FormField from '@/components/FormField';
|
||||
import LinkButton from '@/components/LinkButton';
|
||||
import TabNav, { TabNavItem } from '@/components/TabNav';
|
||||
|
@ -159,47 +159,38 @@ const ApiResourceDetails = () => {
|
|||
</div>
|
||||
)}
|
||||
</Card>
|
||||
<Card className={classNames(styles.body, detailsStyles.body)}>
|
||||
<TabNav>
|
||||
<TabNavItem href={location.pathname}>{t('general.settings_nav')}</TabNavItem>
|
||||
</TabNav>
|
||||
<form className={classNames(styles.form, detailsStyles.body)} onSubmit={onSubmit}>
|
||||
<div className={styles.fields}>
|
||||
<FormField isRequired title="api_resources.api_name" className={styles.textField}>
|
||||
<TextInput
|
||||
{...register('name', { required: true })}
|
||||
hasError={Boolean(errors.name)}
|
||||
readOnly={isLogtoManagementApiResource}
|
||||
placeholder={t('api_resources.api_name_placeholder')}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField
|
||||
isRequired
|
||||
title="api_resource_details.token_expiration_time_in_seconds"
|
||||
className={styles.textField}
|
||||
>
|
||||
<TextInput
|
||||
{...register('accessTokenTtl', { required: true, valueAsNumber: true })}
|
||||
hasError={Boolean(errors.accessTokenTtl)}
|
||||
placeholder={t(
|
||||
'api_resource_details.token_expiration_time_in_seconds_placeholder'
|
||||
)}
|
||||
/>
|
||||
</FormField>
|
||||
</div>
|
||||
<div className={detailsStyles.footer}>
|
||||
<div className={detailsStyles.footerMain}>
|
||||
<Button
|
||||
isLoading={isSubmitting}
|
||||
htmlType="submit"
|
||||
type="primary"
|
||||
title="general.save_changes"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Card>
|
||||
<TabNav>
|
||||
<TabNavItem href={location.pathname}>{t('general.settings_nav')}</TabNavItem>
|
||||
</TabNav>
|
||||
<DetailsForm
|
||||
isDirty={isDirty}
|
||||
isSubmitting={isSubmitting}
|
||||
onDiscard={reset}
|
||||
onSubmit={onSubmit}
|
||||
>
|
||||
<FormCard
|
||||
title="api_resource_details.settings"
|
||||
description="api_resource_details.settings_description"
|
||||
>
|
||||
<FormField isRequired title="api_resources.api_name">
|
||||
<TextInput
|
||||
{...register('name', { required: true })}
|
||||
hasError={Boolean(errors.name)}
|
||||
readOnly={isLogtoManagementApiResource}
|
||||
placeholder={t('api_resources.api_name_placeholder')}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField isRequired title="api_resource_details.token_expiration_time_in_seconds">
|
||||
<TextInput
|
||||
{...register('accessTokenTtl', { required: true, valueAsNumber: true })}
|
||||
hasError={Boolean(errors.accessTokenTtl)}
|
||||
placeholder={t(
|
||||
'api_resource_details.token_expiration_time_in_seconds_placeholder'
|
||||
)}
|
||||
/>
|
||||
</FormField>
|
||||
</FormCard>
|
||||
</DetailsForm>
|
||||
</>
|
||||
)}
|
||||
<UnsavedChangesAlertModal hasUnsavedChanges={!isDeleted && isDirty} />
|
||||
|
|
|
@ -18,24 +18,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
.formContent {
|
||||
>:not(:first-child) {
|
||||
margin-top: _.unit(4);
|
||||
}
|
||||
|
||||
.fieldsContent {
|
||||
> :not(:first-child) {
|
||||
margin-top: _.unit(4);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: _.unit(6);
|
||||
}
|
||||
}
|
||||
|
||||
.textField {
|
||||
@include _.form-text-field;
|
||||
}
|
||||
.textField {
|
||||
@include _.form-text-field;
|
||||
}
|
||||
|
||||
.header {
|
||||
|
|
|
@ -16,10 +16,10 @@ import Button from '@/components/Button';
|
|||
import Card from '@/components/Card';
|
||||
import CopyToClipboard from '@/components/CopyToClipboard';
|
||||
import DeleteConfirmModal from '@/components/DeleteConfirmModal';
|
||||
import DetailsForm from '@/components/DetailsForm';
|
||||
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';
|
||||
|
@ -205,19 +205,15 @@ const ApplicationDetails = () => {
|
|||
</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>
|
||||
<DetailsForm
|
||||
isDirty={isDirty}
|
||||
isSubmitting={isSubmitting}
|
||||
onDiscard={reset}
|
||||
onSubmit={onSubmit}
|
||||
>
|
||||
<Settings data={data} />
|
||||
<AdvancedSettings applicationType={data.type} oidcConfig={oidcConfig} />
|
||||
</DetailsForm>
|
||||
</FormProvider>
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const api_resource_details = {
|
||||
back_to_api_resources: 'Zurück zu API Ressourcen',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
token_expiration_time_in_seconds: 'Token Ablaufzeit (in Sekunden)',
|
||||
token_expiration_time_in_seconds_placeholder: 'Gib die Ablaufzeit des Tokens ein',
|
||||
delete_description:
|
||||
|
|
|
@ -3,7 +3,7 @@ const application_details = {
|
|||
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
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto 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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const api_resource_details = {
|
||||
back_to_api_resources: 'Back to API resources',
|
||||
settings: 'Settings',
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto for Authentication. Configure the allowed Callback URLs and Secrets for your Application.',
|
||||
token_expiration_time_in_seconds: 'Token expiration time (in seconds)',
|
||||
token_expiration_time_in_seconds_placeholder: 'Enter your token expiration time',
|
||||
delete_description:
|
||||
|
|
|
@ -3,7 +3,7 @@ const application_details = {
|
|||
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.',
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto 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.',
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const api_resource_details = {
|
||||
back_to_api_resources: 'Retour aux ressources API',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
token_expiration_time_in_seconds: "Temps d'expiration du jeton (en secondes)",
|
||||
token_expiration_time_in_seconds_placeholder: "Entrez le délai d'expiration de votre jeton",
|
||||
delete_description:
|
||||
|
|
|
@ -3,7 +3,7 @@ const application_details = {
|
|||
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
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto 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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const api_resource_details = {
|
||||
back_to_api_resources: 'API 리소스로 돌아가기',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
token_expiration_time_in_seconds: '토큰 만료 시간 (초)',
|
||||
token_expiration_time_in_seconds_placeholder: '토큰 만료 시간을 입력해주세요',
|
||||
delete_description:
|
||||
|
|
|
@ -3,7 +3,7 @@ const application_details = {
|
|||
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
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto 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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const api_resource_details = {
|
||||
back_to_api_resources: 'Voltar aos recursos API',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
token_expiration_time_in_seconds: 'Tempo de expiração do token (em segundos)',
|
||||
token_expiration_time_in_seconds_placeholder: 'Insira o tempo de expiração do token',
|
||||
delete_description:
|
||||
|
|
|
@ -3,7 +3,7 @@ const application_details = {
|
|||
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
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto 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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const api_resource_details = {
|
||||
back_to_api_resources: 'API Kaynaklarına geri dön',
|
||||
settings: 'Settings', // UNTRANSLATED
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
token_expiration_time_in_seconds: 'Token sona erme süresi (saniye)',
|
||||
token_expiration_time_in_seconds_placeholder: 'Token zaman aşım süresini giriniz',
|
||||
delete_description:
|
||||
|
|
|
@ -3,7 +3,7 @@ const application_details = {
|
|||
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
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto 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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const api_resource_details = {
|
||||
back_to_api_resources: '返回 API 资源',
|
||||
settings: '设置',
|
||||
settings_description:
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto for Authentication. Configure the allowed Callback URLs and Secrets for your Application.', // UNTRANSLATED
|
||||
token_expiration_time_in_seconds: 'Token 过期时间(秒)',
|
||||
token_expiration_time_in_seconds_placeholder: '请输入你的 token 过期时间',
|
||||
delete_description:
|
||||
|
|
|
@ -3,7 +3,7 @@ const application_details = {
|
|||
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
|
||||
'With Applications you can. Setup a mobile, web or IoT application to use Logto 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
|
||||
|
|
Loading…
Reference in a new issue