mirror of
https://github.com/logto-io/logto.git
synced 2025-03-24 22:41:28 -05:00
refactor(console): refactor connector creation modal (#4183)
This commit is contained in:
parent
3c51ecc29d
commit
1b0f9be88b
23 changed files with 257 additions and 145 deletions
|
@ -0,0 +1,30 @@
|
||||||
|
@use '@/scss/underscore' as _;
|
||||||
|
|
||||||
|
.connector {
|
||||||
|
font: var(--font-body-2);
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: _.unit(3);
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font: var(--font-label-2);
|
||||||
|
@include _.multi-line-ellipsis(1);
|
||||||
|
padding-right: _.unit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.connectorId {
|
||||||
|
margin-top: _.unit(1);
|
||||||
|
font: var(--font-body-3);
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font: var(--font-body-3);
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin-top: _.unit(1);
|
||||||
|
@include _.multi-line-ellipsis(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { type ConnectorFactoryResponse } from '@logto/schemas';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import ConnectorLogo from '@/components/ConnectorLogo';
|
||||||
|
import UnnamedTrans from '@/components/UnnamedTrans';
|
||||||
|
import { type ConnectorGroup } from '@/types/connector';
|
||||||
|
|
||||||
|
import * as styles from './index.module.scss';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
data: ConnectorGroup<ConnectorFactoryResponse>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ConnectorRadio({ data: { name, logo, logoDark, description } }: Props) {
|
||||||
|
return (
|
||||||
|
<div className={styles.connector}>
|
||||||
|
<ConnectorLogo data={{ logo, logoDark }} />
|
||||||
|
<div className={styles.content}>
|
||||||
|
<div className={classNames(styles.name)}>
|
||||||
|
<UnnamedTrans resource={name} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.description}>
|
||||||
|
<UnnamedTrans resource={description} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConnectorRadio;
|
|
@ -0,0 +1,40 @@
|
||||||
|
@use '@/scss/underscore' as _;
|
||||||
|
@use '@/scss/dimensions' as dim;
|
||||||
|
|
||||||
|
.connectorGroup {
|
||||||
|
gap: _.unit(4);
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
|
||||||
|
@media screen and (max-width: dim.$modal-layout-grid-large) {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: dim.$modal-layout-grid-medium) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
||||||
|
grid-template-columns: repeat(1, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.medium {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
|
||||||
|
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
||||||
|
grid-template-columns: repeat(1, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.large {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
|
||||||
|
@media screen and (max-width: dim.$modal-layout-grid-medium) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
||||||
|
grid-template-columns: repeat(1, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { type ConnectorFactoryResponse } from '@logto/schemas';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import RadioGroup, { Radio } from '@/ds-components/RadioGroup';
|
||||||
|
import { type ConnectorGroup } from '@/types/connector';
|
||||||
|
|
||||||
|
import ConnectorRadio from './ConnectorRadio';
|
||||||
|
import * as styles from './index.module.scss';
|
||||||
|
|
||||||
|
export type ConnectorRadioGroupSize = 'medium' | 'large' | 'xlarge';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
name: string;
|
||||||
|
value?: string;
|
||||||
|
groups: Array<ConnectorGroup<ConnectorFactoryResponse>>;
|
||||||
|
size: ConnectorRadioGroupSize;
|
||||||
|
onChange: (groupId: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ConnectorRadioGroup({ name, groups, value, size, onChange }: Props) {
|
||||||
|
return (
|
||||||
|
<RadioGroup
|
||||||
|
name={name}
|
||||||
|
value={value}
|
||||||
|
type="card"
|
||||||
|
className={classNames(styles.connectorGroup, styles[size])}
|
||||||
|
onChange={onChange}
|
||||||
|
>
|
||||||
|
{groups.map((data) => (
|
||||||
|
<Radio key={data.id} value={data.id}>
|
||||||
|
<ConnectorRadio data={data} />
|
||||||
|
</Radio>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConnectorRadioGroup;
|
|
@ -1,17 +1,18 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import * as layout from '../index.module.scss';
|
import * as radioStyles from '../ConnectorRadioGroup/ConnectorRadio/index.module.scss';
|
||||||
|
import * as radioGroupStyles from '../ConnectorRadioGroup/index.module.scss';
|
||||||
|
|
||||||
import * as styles from './index.module.scss';
|
import * as styles from './index.module.scss';
|
||||||
|
|
||||||
function Skeleton() {
|
function Skeleton() {
|
||||||
return (
|
return (
|
||||||
<div className={layout.connectorGroup}>
|
<div className={radioGroupStyles.connectorGroup}>
|
||||||
{Array.from({ length: 8 }).map((_, index) => (
|
{Array.from({ length: 8 }).map((_, index) => (
|
||||||
// eslint-disable-next-line react/no-array-index-key
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
<div key={index} className={classNames(layout.connector, styles.connector)}>
|
<div key={index} className={classNames(radioStyles.connector, styles.connector)}>
|
||||||
<div className={styles.logo} />
|
<div className={styles.logo} />
|
||||||
<div className={layout.content}>
|
<div className={radioStyles.content}>
|
||||||
<div className={styles.name} />
|
<div className={styles.name} />
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.description} />
|
<div className={styles.description} />
|
||||||
|
|
|
@ -1,71 +1,6 @@
|
||||||
@use '@/scss/underscore' as _;
|
@use '@/scss/underscore' as _;
|
||||||
@use '@/scss/dimensions' as dim;
|
|
||||||
|
|
||||||
.body {
|
.standardLabel {
|
||||||
.connectorGroup {
|
font: var(--font-label-2);
|
||||||
gap: _.unit(4);
|
margin: _.unit(6) 0 _.unit(4);
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
|
|
||||||
@media screen and (max-width: dim.$modal-layout-grid-large) {
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: dim.$modal-layout-grid-medium) {
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
|
||||||
grid-template-columns: repeat(1, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.medium {
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
|
|
||||||
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
|
||||||
grid-template-columns: repeat(1, 1fr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.large {
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
|
|
||||||
@media screen and (max-width: dim.$modal-layout-grid-medium) {
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
|
||||||
grid-template-columns: repeat(1, 1fr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.connector {
|
|
||||||
font: var(--font-body-2);
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.content {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: _.unit(3);
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font: var(--font-label-2);
|
|
||||||
@include _.multi-line-ellipsis(1);
|
|
||||||
padding-right: _.unit(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.connectorId {
|
|
||||||
margin-top: _.unit(1);
|
|
||||||
font: var(--font-body-3);
|
|
||||||
color: var(--color-text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
font: var(--font-body-3);
|
|
||||||
color: var(--color-text-secondary);
|
|
||||||
margin-top: _.unit(1);
|
|
||||||
@include _.multi-line-ellipsis(4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
import { ConnectorType } from '@logto/schemas';
|
import {
|
||||||
import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas';
|
ConnectorType,
|
||||||
import classNames from 'classnames';
|
type ConnectorFactoryResponse,
|
||||||
|
type ConnectorResponse,
|
||||||
|
} from '@logto/schemas';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
import ConnectorLogo from '@/components/ConnectorLogo';
|
|
||||||
import UnnamedTrans from '@/components/UnnamedTrans';
|
|
||||||
import Button from '@/ds-components/Button';
|
import Button from '@/ds-components/Button';
|
||||||
|
import DynamicT from '@/ds-components/DynamicT';
|
||||||
import ModalLayout from '@/ds-components/ModalLayout';
|
import ModalLayout from '@/ds-components/ModalLayout';
|
||||||
import RadioGroup, { Radio } from '@/ds-components/RadioGroup';
|
|
||||||
import type { RequestError } from '@/hooks/use-api';
|
import type { RequestError } from '@/hooks/use-api';
|
||||||
import * as modalStyles from '@/scss/modal.module.scss';
|
import * as modalStyles from '@/scss/modal.module.scss';
|
||||||
|
|
||||||
import { getConnectorGroups } from '../../pages/Connectors/utils';
|
import { getConnectorGroups } from '../../pages/Connectors/utils';
|
||||||
|
|
||||||
|
import ConnectorRadioGroup from './ConnectorRadioGroup';
|
||||||
import PlatformSelector from './PlatformSelector';
|
import PlatformSelector from './PlatformSelector';
|
||||||
import Skeleton from './Skeleton';
|
import Skeleton from './Skeleton';
|
||||||
import * as styles from './index.module.scss';
|
import * as styles from './index.module.scss';
|
||||||
import { getConnectorOrder } from './utils';
|
import { compareConnectors, getConnectorRadioGroupSize, getModalTitle } from './utils';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
@ -60,12 +61,7 @@ function CreateConnectorForm({ onClose, isOpen: isFormOpen, type }: Props) {
|
||||||
}))
|
}))
|
||||||
.filter(({ connectors }) => !connectors.every(({ added }) => added))
|
.filter(({ connectors }) => !connectors.every(({ added }) => added))
|
||||||
.slice()
|
.slice()
|
||||||
.sort((connectorA, connectorB) => {
|
.sort(compareConnectors);
|
||||||
const orderA = getConnectorOrder(connectorA.target, connectorA.isStandard);
|
|
||||||
const orderB = getConnectorOrder(connectorB.target, connectorB.isStandard);
|
|
||||||
|
|
||||||
return orderA - orderB;
|
|
||||||
});
|
|
||||||
}, [factories, type, existingConnectors]);
|
}, [factories, type, existingConnectors]);
|
||||||
|
|
||||||
const activeGroup = useMemo(
|
const activeGroup = useMemo(
|
||||||
|
@ -73,41 +69,11 @@ function CreateConnectorForm({ onClose, isOpen: isFormOpen, type }: Props) {
|
||||||
[activeGroupId, groups]
|
[activeGroupId, groups]
|
||||||
);
|
);
|
||||||
|
|
||||||
const cardTitle = useMemo(() => {
|
const cardTitle = useMemo(() => getModalTitle(type), [type]);
|
||||||
if (type === ConnectorType.Email) {
|
const radioGroupSize = useMemo(
|
||||||
return 'connectors.setup_title.email';
|
() => getConnectorRadioGroupSize(groups.length, type),
|
||||||
}
|
[groups.length, type]
|
||||||
|
);
|
||||||
if (type === ConnectorType.Sms) {
|
|
||||||
return 'connectors.setup_title.sms';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'connectors.setup_title.social';
|
|
||||||
}, [type]);
|
|
||||||
|
|
||||||
const modalSize = useMemo(() => {
|
|
||||||
/**
|
|
||||||
* Note:
|
|
||||||
* Fix the size to large, since now we have little passwordless connectors.
|
|
||||||
*/
|
|
||||||
if (type !== ConnectorType.Social) {
|
|
||||||
return 'large';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (groups.length <= 2) {
|
|
||||||
return 'medium';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (groups.length === 3) {
|
|
||||||
return 'large';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'xlarge';
|
|
||||||
}, [groups.length, type]);
|
|
||||||
|
|
||||||
if (!isFormOpen) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleGroupChange = (groupId: string) => {
|
const handleGroupChange = (groupId: string) => {
|
||||||
setActiveGroupId(groupId);
|
setActiveGroupId(groupId);
|
||||||
|
@ -123,6 +89,17 @@ function CreateConnectorForm({ onClose, isOpen: isFormOpen, type }: Props) {
|
||||||
setActiveFactoryId(firstAvailableConnector?.id);
|
setActiveFactoryId(firstAvailableConnector?.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const defaultGroups = useMemo(
|
||||||
|
() => (type === ConnectorType.Social ? groups.filter((group) => !group.isStandard) : groups),
|
||||||
|
[groups, type]
|
||||||
|
);
|
||||||
|
|
||||||
|
const standardGroups = useMemo(() => groups.filter((group) => group.isStandard), [groups]);
|
||||||
|
|
||||||
|
if (!isFormOpen) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
shouldCloseOnEsc
|
shouldCloseOnEsc
|
||||||
|
@ -145,35 +122,32 @@ function CreateConnectorForm({ onClose, isOpen: isFormOpen, type }: Props) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
className={styles.body}
|
size={radioGroupSize}
|
||||||
size={modalSize}
|
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
>
|
>
|
||||||
{isLoading && <Skeleton />}
|
{isLoading && <Skeleton />}
|
||||||
{factoriesError?.message ?? connectorsError?.message}
|
{factoriesError?.message ?? connectorsError?.message}
|
||||||
<RadioGroup
|
<ConnectorRadioGroup
|
||||||
name="group"
|
name="group"
|
||||||
|
groups={defaultGroups}
|
||||||
value={activeGroupId}
|
value={activeGroupId}
|
||||||
type="card"
|
size={radioGroupSize}
|
||||||
className={classNames(styles.connectorGroup, styles[modalSize])}
|
|
||||||
onChange={handleGroupChange}
|
onChange={handleGroupChange}
|
||||||
>
|
/>
|
||||||
{groups.map(({ id, name, logo, logoDark, description }) => (
|
{standardGroups.length > 0 && (
|
||||||
<Radio key={id} value={id}>
|
<>
|
||||||
<div className={styles.connector}>
|
<div className={styles.standardLabel}>
|
||||||
<ConnectorLogo data={{ logo, logoDark }} />
|
<DynamicT forKey="connectors.standard_connectors" />
|
||||||
<div className={styles.content}>
|
</div>
|
||||||
<div className={classNames(styles.name)}>
|
<ConnectorRadioGroup
|
||||||
<UnnamedTrans resource={name} />
|
name="group"
|
||||||
</div>
|
groups={standardGroups}
|
||||||
<div className={styles.description}>
|
value={activeGroupId}
|
||||||
<UnnamedTrans resource={description} />
|
size={radioGroupSize}
|
||||||
</div>
|
onChange={handleGroupChange}
|
||||||
</div>
|
/>
|
||||||
</div>
|
</>
|
||||||
</Radio>
|
)}
|
||||||
))}
|
|
||||||
</RadioGroup>
|
|
||||||
{activeGroup && (
|
{activeGroup && (
|
||||||
<PlatformSelector
|
<PlatformSelector
|
||||||
connectorGroup={activeGroup}
|
connectorGroup={activeGroup}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
import { type AdminConsoleKey } from '@logto/phrases';
|
||||||
|
import { ConnectorType, type ConnectorResponse } from '@logto/schemas';
|
||||||
|
|
||||||
|
import { type ConnectorRadioGroupSize } from './ConnectorRadioGroup';
|
||||||
import { featuredConnectorTargets } from './constants';
|
import { featuredConnectorTargets } from './constants';
|
||||||
|
|
||||||
export const getConnectorOrder = (target: string, isStandard?: boolean): number => {
|
const getConnectorOrder = (target: string, isStandard?: boolean): number => {
|
||||||
const order = featuredConnectorTargets.indexOf(target);
|
const order = featuredConnectorTargets.indexOf(target);
|
||||||
|
|
||||||
if (order === -1) {
|
if (order === -1) {
|
||||||
|
@ -10,3 +14,48 @@ export const getConnectorOrder = (target: string, isStandard?: boolean): number
|
||||||
|
|
||||||
return order;
|
return order;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const compareConnectors = <T extends Pick<ConnectorResponse, 'target' | 'isStandard'>>(
|
||||||
|
connectorA: T,
|
||||||
|
connectorB: T
|
||||||
|
) => {
|
||||||
|
const orderA = getConnectorOrder(connectorA.target, connectorA.isStandard);
|
||||||
|
const orderB = getConnectorOrder(connectorB.target, connectorB.isStandard);
|
||||||
|
|
||||||
|
return orderA - orderB;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getConnectorRadioGroupSize = (
|
||||||
|
connectorCount: number,
|
||||||
|
connectorType?: ConnectorType
|
||||||
|
): ConnectorRadioGroupSize => {
|
||||||
|
/**
|
||||||
|
* Note:
|
||||||
|
* Fix the size to large, since now we have little passwordless connectors.
|
||||||
|
*/
|
||||||
|
if (connectorType !== ConnectorType.Social) {
|
||||||
|
return 'large';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectorCount <= 2) {
|
||||||
|
return 'medium';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectorCount === 3) {
|
||||||
|
return 'large';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'xlarge';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getModalTitle = (connectorType?: ConnectorType): AdminConsoleKey => {
|
||||||
|
if (connectorType === ConnectorType.Email) {
|
||||||
|
return 'connectors.setup_title.email';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectorType === ConnectorType.Sms) {
|
||||||
|
return 'connectors.setup_title.sms';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'connectors.setup_title.social';
|
||||||
|
};
|
||||||
|
|
|
@ -88,6 +88,7 @@ const connectors = {
|
||||||
drawer_title: 'Connector Anleitung',
|
drawer_title: 'Connector Anleitung',
|
||||||
drawer_subtitle: 'Folge den Anweisungen, um deinen Connector zu integrieren',
|
drawer_subtitle: 'Folge den Anweisungen, um deinen Connector zu integrieren',
|
||||||
unknown: 'Unbekannter Connector',
|
unknown: 'Unbekannter Connector',
|
||||||
|
standard_connectors: 'Standard-Connectoren',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -87,6 +87,7 @@ const connectors = {
|
||||||
drawer_title: 'Connector Guide',
|
drawer_title: 'Connector Guide',
|
||||||
drawer_subtitle: 'Follow the instructions to integrate your connector',
|
drawer_subtitle: 'Follow the instructions to integrate your connector',
|
||||||
unknown: 'Unknown Connector',
|
unknown: 'Unknown Connector',
|
||||||
|
standard_connectors: 'Standard connectors',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -88,6 +88,7 @@ const connectors = {
|
||||||
drawer_title: 'Guía del conector',
|
drawer_title: 'Guía del conector',
|
||||||
drawer_subtitle: 'Siga las instrucciones para integrar su conector',
|
drawer_subtitle: 'Siga las instrucciones para integrar su conector',
|
||||||
unknown: 'Conector desconocido',
|
unknown: 'Conector desconocido',
|
||||||
|
standard_connectors: 'Conectores estándar',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -90,6 +90,7 @@ const connectors = {
|
||||||
drawer_title: 'Guide des connecteurs',
|
drawer_title: 'Guide des connecteurs',
|
||||||
drawer_subtitle: 'Suivez les instructions pour intégrer votre connecteur',
|
drawer_subtitle: 'Suivez les instructions pour intégrer votre connecteur',
|
||||||
unknown: 'Connecteur inconnu',
|
unknown: 'Connecteur inconnu',
|
||||||
|
standard_connectors: 'Connecteurs standard',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -88,6 +88,7 @@ const connectors = {
|
||||||
drawer_title: 'Guida per il connettore',
|
drawer_title: 'Guida per il connettore',
|
||||||
drawer_subtitle: 'Segui le istruzioni per integrare il tuo connettore',
|
drawer_subtitle: 'Segui le istruzioni per integrare il tuo connettore',
|
||||||
unknown: 'Connettore sconosciuto',
|
unknown: 'Connettore sconosciuto',
|
||||||
|
standard_connectors: 'Connettori standard',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -86,6 +86,7 @@ const connectors = {
|
||||||
drawer_title: 'コネクターガイド',
|
drawer_title: 'コネクターガイド',
|
||||||
drawer_subtitle: 'インテグレーションの手順に従ってください',
|
drawer_subtitle: 'インテグレーションの手順に従ってください',
|
||||||
unknown: '不明なコネクタ',
|
unknown: '不明なコネクタ',
|
||||||
|
standard_connectors: '標準コネクタ',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -83,6 +83,7 @@ const connectors = {
|
||||||
drawer_title: '연동 가이드',
|
drawer_title: '연동 가이드',
|
||||||
drawer_subtitle: '연동하기 위해 가이드를 따라 주세요.',
|
drawer_subtitle: '연동하기 위해 가이드를 따라 주세요.',
|
||||||
unknown: '알 수 없는 연동',
|
unknown: '알 수 없는 연동',
|
||||||
|
standard_connectors: '기본 커넥터',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -87,6 +87,7 @@ const connectors = {
|
||||||
drawer_title: 'Poradnik łącznika',
|
drawer_title: 'Poradnik łącznika',
|
||||||
drawer_subtitle: 'Postępuj zgodnie z instrukcjami, aby zintegrować swój łącznik',
|
drawer_subtitle: 'Postępuj zgodnie z instrukcjami, aby zintegrować swój łącznik',
|
||||||
unknown: 'Nieznany Łącznik',
|
unknown: 'Nieznany Łącznik',
|
||||||
|
standard_connectors: 'Standardowe łączniki',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -22,7 +22,7 @@ const connectors = {
|
||||||
'Fora de uso significa que sua experiência de login não usou esse método de login. <a>{{link}}</a> para adicionar este método de login. ',
|
'Fora de uso significa que sua experiência de login não usou esse método de login. <a>{{link}}</a> para adicionar este método de login. ',
|
||||||
go_to_sie: 'Vá para a experiência de login',
|
go_to_sie: 'Vá para a experiência de login',
|
||||||
},
|
},
|
||||||
placeholder_title: 'Social connector',
|
placeholder_title: 'Conector social',
|
||||||
placeholder_description:
|
placeholder_description:
|
||||||
'Logto tem fornecido muitos conectores de login social amplamente utilizados enquanto você pode criar o seu próprio com padrões padrão.',
|
'Logto tem fornecido muitos conectores de login social amplamente utilizados enquanto você pode criar o seu próprio com padrões padrão.',
|
||||||
save_and_done: 'Salvar e completar',
|
save_and_done: 'Salvar e completar',
|
||||||
|
@ -43,7 +43,7 @@ const connectors = {
|
||||||
test_connection: 'Teste de conexão',
|
test_connection: 'Teste de conexão',
|
||||||
name: 'Nome do botão de login social',
|
name: 'Nome do botão de login social',
|
||||||
name_placeholder: 'Insira o nome do botão de login social',
|
name_placeholder: 'Insira o nome do botão de login social',
|
||||||
name_tip: 'O nome do botão do conector será exibido como "Continue com {{Nome do Conector}}".',
|
name_tip: 'O nome do botão do conector será exibido como "Continuar com {{Nome do Conector}}".',
|
||||||
logo: 'URL do logo para o botão de login social',
|
logo: 'URL do logo para o botão de login social',
|
||||||
logo_placeholder: 'https://your.cdn.domain/logo.png',
|
logo_placeholder: 'https://your.cdn.domain/logo.png',
|
||||||
logo_tip: 'A imagem do logotipo também será exibida no botão do conector.',
|
logo_tip: 'A imagem do logotipo também será exibida no botão do conector.',
|
||||||
|
@ -86,6 +86,7 @@ const connectors = {
|
||||||
drawer_title: 'Guia do Conector',
|
drawer_title: 'Guia do Conector',
|
||||||
drawer_subtitle: 'Siga as instruções para integrar seu conector',
|
drawer_subtitle: 'Siga as instruções para integrar seu conector',
|
||||||
unknown: 'Conector desconhecido',
|
unknown: 'Conector desconhecido',
|
||||||
|
standard_connectors: 'Conectores padrão',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -88,6 +88,7 @@ const connectors = {
|
||||||
drawer_title: 'Guia do conector',
|
drawer_title: 'Guia do conector',
|
||||||
drawer_subtitle: 'Siga as instruções para integrar o conector',
|
drawer_subtitle: 'Siga as instruções para integrar o conector',
|
||||||
unknown: 'Conector desconhecido',
|
unknown: 'Conector desconhecido',
|
||||||
|
standard_connectors: 'Conectores padrão',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -87,6 +87,7 @@ const connectors = {
|
||||||
drawer_title: 'Руководство Коннектора',
|
drawer_title: 'Руководство Коннектора',
|
||||||
drawer_subtitle: 'Следуйте инструкциям, чтобы интегрировать свой коннектор',
|
drawer_subtitle: 'Следуйте инструкциям, чтобы интегрировать свой коннектор',
|
||||||
unknown: 'Неизвестный коннектор',
|
unknown: 'Неизвестный коннектор',
|
||||||
|
standard_connectors: 'стандартные разъемы',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -87,6 +87,7 @@ const connectors = {
|
||||||
drawer_title: 'Connector Kılavuzu',
|
drawer_title: 'Connector Kılavuzu',
|
||||||
drawer_subtitle: 'Connectorı entegre etmek için yönergeleri izleyin',
|
drawer_subtitle: 'Connectorı entegre etmek için yönergeleri izleyin',
|
||||||
unknown: 'Bilinmeyen connector',
|
unknown: 'Bilinmeyen connector',
|
||||||
|
standard_connectors: 'Standart connectorlar',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -78,6 +78,7 @@ const connectors = {
|
||||||
drawer_title: '连接器配置指南',
|
drawer_title: '连接器配置指南',
|
||||||
drawer_subtitle: '参考以下步骤完善或修改你的连接器设置',
|
drawer_subtitle: '参考以下步骤完善或修改你的连接器设置',
|
||||||
unknown: '未知连接器',
|
unknown: '未知连接器',
|
||||||
|
standard_connectors: '标准连接器',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -78,6 +78,7 @@ const connectors = {
|
||||||
drawer_title: '連接器配置指南',
|
drawer_title: '連接器配置指南',
|
||||||
drawer_subtitle: '參考以下步驟完善或修改你的連接器設置',
|
drawer_subtitle: '參考以下步驟完善或修改你的連接器設置',
|
||||||
unknown: '未知連接器',
|
unknown: '未知連接器',
|
||||||
|
standard_connectors: '標準連接器',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
|
@ -78,6 +78,7 @@ const connectors = {
|
||||||
drawer_title: '連接器配置指南',
|
drawer_title: '連接器配置指南',
|
||||||
drawer_subtitle: '參考以下步驟完善或修改你的連接器設置',
|
drawer_subtitle: '參考以下步驟完善或修改你的連接器設置',
|
||||||
unknown: '未知連接器',
|
unknown: '未知連接器',
|
||||||
|
standard_connectors: '標準連接器',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connectors;
|
export default connectors;
|
||||||
|
|
Loading…
Add table
Reference in a new issue