mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(console): replace the field table with type definition code (#5519)
* refactor(console): replace the field table with type definition code replace the field table with type definition code * refactor(console): rebase and pickup the generated type definitions rebase and pickup the generated type definitions
This commit is contained in:
parent
08acdf73e3
commit
d3d0f5133b
3 changed files with 40 additions and 118 deletions
|
@ -1,19 +1,20 @@
|
||||||
import { LogtoJwtTokenPath } from '@logto/schemas';
|
import { LogtoJwtTokenPath } from '@logto/schemas';
|
||||||
import { Editor } from '@monaco-editor/react';
|
import { Editor } from '@monaco-editor/react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useCallback } from 'react';
|
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import Table from '@/ds-components/Table';
|
|
||||||
|
|
||||||
import { type JwtClaimsFormType } from '../type';
|
import { type JwtClaimsFormType } from '../type';
|
||||||
import {
|
import {
|
||||||
userDataDescription,
|
sampleCodeEditorOptions,
|
||||||
tokenDataDescription,
|
typeDefinitionCodeEditorOptions,
|
||||||
fetchExternalDataEditorOptions,
|
|
||||||
fetchExternalDataCodeExample,
|
fetchExternalDataCodeExample,
|
||||||
} from '../utils/config';
|
} from '../utils/config';
|
||||||
|
import {
|
||||||
|
accessTokenPayloadTypeDefinition,
|
||||||
|
clientCredentialsPayloadTypeDefinition,
|
||||||
|
jwtCustomizerUserContextTypeDefinition,
|
||||||
|
} from '../utils/type-definitions';
|
||||||
|
|
||||||
import EnvironmentVariablesField from './EnvironmentVariablesField';
|
import EnvironmentVariablesField from './EnvironmentVariablesField';
|
||||||
import GuideCard, { CardType } from './GuideCard';
|
import GuideCard, { CardType } from './GuideCard';
|
||||||
|
@ -30,51 +31,33 @@ function InstructionTab({ isActive }: Props) {
|
||||||
const { watch } = useFormContext<JwtClaimsFormType>();
|
const { watch } = useFormContext<JwtClaimsFormType>();
|
||||||
const tokenType = watch('tokenType');
|
const tokenType = watch('tokenType');
|
||||||
|
|
||||||
const getDataColumns = useCallback(
|
|
||||||
(valueColSpan = 10) => [
|
|
||||||
{
|
|
||||||
title: t('domain.custom.dns_table.value_field'),
|
|
||||||
dataIndex: 'value',
|
|
||||||
colSpan: valueColSpan,
|
|
||||||
render: ({ value }: (typeof userDataDescription)[0]) => (
|
|
||||||
<span className={styles.value}>{value}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t('general.description'),
|
|
||||||
dataIndex: 'description',
|
|
||||||
colSpan: 24 - valueColSpan,
|
|
||||||
render: ({ description }: (typeof userDataDescription)[0]) => (
|
|
||||||
<span className={styles.description}>{description}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[t]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(styles.tabContent, isActive && styles.active)}>
|
<div className={classNames(styles.tabContent, isActive && styles.active)}>
|
||||||
<div className={styles.description}>{t('jwt_claims.jwt_claims_description')}</div>
|
<div className={styles.description}>{t('jwt_claims.jwt_claims_description')}</div>
|
||||||
{tokenType === LogtoJwtTokenPath.AccessToken && (
|
{tokenType === LogtoJwtTokenPath.AccessToken && (
|
||||||
<GuideCard name={CardType.UserData}>
|
<GuideCard name={CardType.UserData}>
|
||||||
<Table
|
<Editor
|
||||||
hasBorder
|
language="typescript"
|
||||||
isRowHoverEffectDisabled
|
className={styles.sampleCode}
|
||||||
className={styles.table}
|
value={jwtCustomizerUserContextTypeDefinition}
|
||||||
rowIndexKey="value"
|
height="700px"
|
||||||
columns={getDataColumns()}
|
theme="logto-dark"
|
||||||
rowGroups={[{ key: 'user_data', data: userDataDescription }]}
|
options={typeDefinitionCodeEditorOptions}
|
||||||
/>
|
/>
|
||||||
</GuideCard>
|
</GuideCard>
|
||||||
)}
|
)}
|
||||||
<GuideCard name={CardType.TokenData}>
|
<GuideCard name={CardType.TokenData}>
|
||||||
<Table
|
<Editor
|
||||||
hasBorder
|
language="typescript"
|
||||||
isRowHoverEffectDisabled
|
className={styles.sampleCode}
|
||||||
className={styles.table}
|
value={
|
||||||
rowIndexKey="value"
|
tokenType === LogtoJwtTokenPath.AccessToken
|
||||||
columns={getDataColumns(6)}
|
? accessTokenPayloadTypeDefinition
|
||||||
rowGroups={[{ key: 'token_data', data: tokenDataDescription }]}
|
: clientCredentialsPayloadTypeDefinition
|
||||||
|
}
|
||||||
|
height="350px"
|
||||||
|
theme="logto-dark"
|
||||||
|
options={typeDefinitionCodeEditorOptions}
|
||||||
/>
|
/>
|
||||||
</GuideCard>
|
</GuideCard>
|
||||||
<GuideCard name={CardType.FetchExternalData}>
|
<GuideCard name={CardType.FetchExternalData}>
|
||||||
|
@ -85,7 +68,7 @@ function InstructionTab({ isActive }: Props) {
|
||||||
value={fetchExternalDataCodeExample}
|
value={fetchExternalDataCodeExample}
|
||||||
height="300px"
|
height="300px"
|
||||||
theme="logto-dark"
|
theme="logto-dark"
|
||||||
options={fetchExternalDataEditorOptions}
|
options={sampleCodeEditorOptions}
|
||||||
/>
|
/>
|
||||||
</GuideCard>
|
</GuideCard>
|
||||||
<GuideCard name={CardType.EnvironmentVariables}>
|
<GuideCard name={CardType.EnvironmentVariables}>
|
||||||
|
|
|
@ -131,81 +131,8 @@ export const clientCredentialsModel: ModelSettings = {
|
||||||
/**
|
/**
|
||||||
* JWT claims guide card configs
|
* JWT claims guide card configs
|
||||||
*/
|
*/
|
||||||
// TODO: align user properties and then i18n the descriptions
|
|
||||||
type GuideTableData = {
|
|
||||||
value: string;
|
|
||||||
description: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const userDataDescription: GuideTableData[] = [
|
export const sampleCodeEditorOptions: EditorProps['options'] = {
|
||||||
{
|
|
||||||
value: 'user.id',
|
|
||||||
description: 'Unique identifier of the user.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'user.username',
|
|
||||||
description: 'Username for sign-in',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'user.primary_email',
|
|
||||||
description: 'Primary email address of the user.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'user.primary_phone',
|
|
||||||
description: 'Primary phone number of the user.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'user.name',
|
|
||||||
description: 'Full name of the user.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'user.avatar',
|
|
||||||
description: "URL pointing to user's avatar image ",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'user.identities',
|
|
||||||
description: 'User info retrieved from social sign-in',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'user.custom_data',
|
|
||||||
description: 'Additional info in customizable properties ',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const tokenDataDescription: GuideTableData[] = [
|
|
||||||
{
|
|
||||||
value: 'jti',
|
|
||||||
description:
|
|
||||||
'(JWT ID) Unique identifier for the JWT. Useful for tracking and preventing reuse of the token.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'iat',
|
|
||||||
description: '(issued at) Time at which the JWT was issued.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'exp',
|
|
||||||
description: '(expiration) Time after which the JWT expires.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'client_id',
|
|
||||||
description: 'Client ID of the application that requested the JWT.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'kind',
|
|
||||||
description:
|
|
||||||
'Type of the token. `AccessToken` for user access tokens and `ClientCredentials` for machine-to-machine access tokens.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'scope',
|
|
||||||
description: 'Scopes requested by the client joint by space.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'aud',
|
|
||||||
description: '(audience) Audience for which the JWT is intended.',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const fetchExternalDataEditorOptions: EditorProps['options'] = {
|
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
wordWrap: 'on',
|
wordWrap: 'on',
|
||||||
minimap: { enabled: false },
|
minimap: { enabled: false },
|
||||||
|
@ -217,6 +144,13 @@ export const fetchExternalDataEditorOptions: EditorProps['options'] = {
|
||||||
lineNumbers: 'off',
|
lineNumbers: 'off',
|
||||||
scrollbar: { vertical: 'hidden', horizontal: 'hidden', handleMouseWheel: false },
|
scrollbar: { vertical: 'hidden', horizontal: 'hidden', handleMouseWheel: false },
|
||||||
folding: false,
|
folding: false,
|
||||||
|
tabSize: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const typeDefinitionCodeEditorOptions: EditorProps['options'] = {
|
||||||
|
...sampleCodeEditorOptions,
|
||||||
|
scrollbar: { vertical: 'auto', horizontal: 'auto' },
|
||||||
|
folding: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchExternalDataCodeExample = `const response = await fetch('https://api.example.com/data', {
|
export const fetchExternalDataCodeExample = `const response = await fetch('https://api.example.com/data', {
|
||||||
|
|
|
@ -7,7 +7,12 @@ import {
|
||||||
|
|
||||||
import { type JwtClaimsFormType } from '../type';
|
import { type JwtClaimsFormType } from '../type';
|
||||||
|
|
||||||
export { JwtCustomizerTypeDefinitionKey } from '@/consts/jwt-customizer-type-definition';
|
export {
|
||||||
|
JwtCustomizerTypeDefinitionKey,
|
||||||
|
accessTokenPayloadTypeDefinition,
|
||||||
|
clientCredentialsPayloadTypeDefinition,
|
||||||
|
jwtCustomizerUserContextTypeDefinition,
|
||||||
|
} from '@/consts/jwt-customizer-type-definition';
|
||||||
|
|
||||||
export const buildAccessTokenJwtCustomizerContextTsDefinition = () => {
|
export const buildAccessTokenJwtCustomizerContextTsDefinition = () => {
|
||||||
return `declare ${jwtCustomizerUserContextTypeDefinition}
|
return `declare ${jwtCustomizerUserContextTypeDefinition}
|
||||||
|
|
Loading…
Reference in a new issue