mirror of
https://github.com/logto-io/logto.git
synced 2025-03-24 22:41:28 -05:00
feat(console): connector in use status (#1012)
This commit is contained in:
parent
a506dc5511
commit
542d57426f
8 changed files with 74 additions and 66 deletions
16
packages/console/src/hooks/use-connector-in-use.ts
Normal file
16
packages/console/src/hooks/use-connector-in-use.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { SignInExperience } from '@logto/schemas';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { RequestError } from './use-api';
|
||||
|
||||
const useConnectorInUse = (connectorTarget?: string): boolean | undefined => {
|
||||
const { data } = useSWR<SignInExperience, RequestError>(connectorTarget && '/api/sign-in-exp');
|
||||
|
||||
if (!data || !connectorTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
return data.socialSignInConnectorTargets.includes(connectorTarget);
|
||||
};
|
||||
|
||||
export default useConnectorInUse;
|
|
@ -18,6 +18,7 @@ import Status from '@/components/Status';
|
|||
import TabNav, { TabNavItem } from '@/components/TabNav';
|
||||
import UnnamedTrans from '@/components/UnnamedTrans';
|
||||
import useApi, { RequestError } from '@/hooks/use-api';
|
||||
import useConnectorInUse from '@/hooks/use-connector-in-use';
|
||||
import Back from '@/icons/Back';
|
||||
import Delete from '@/icons/Delete';
|
||||
import More from '@/icons/More';
|
||||
|
@ -41,6 +42,7 @@ const ConnectorDetails = () => {
|
|||
const { data, error } = useSWR<ConnectorDTO, RequestError>(
|
||||
connectorId && `/api/connectors/${connectorId}`
|
||||
);
|
||||
const inUse = useConnectorInUse(data?.type === ConnectorType.Social ? data.target : undefined);
|
||||
const isLoading = !data && !error;
|
||||
const api = useApi();
|
||||
const navigate = useNavigate();
|
||||
|
@ -127,11 +129,20 @@ const ConnectorDetails = () => {
|
|||
<div>
|
||||
<ConnectorTypeName type={data.type} />
|
||||
<div className={styles.verticalBar} />
|
||||
<Status status={data.enabled ? 'enabled' : 'disabled'} varient="outlined">
|
||||
{t('connectors.connector_status', {
|
||||
context: data.enabled ? 'enabled' : 'disabled',
|
||||
})}
|
||||
</Status>
|
||||
{data.type === ConnectorType.Social && inUse !== undefined && (
|
||||
<Status status={inUse ? 'enabled' : 'disabled'} varient="outlined">
|
||||
{t('connectors.connector_status', {
|
||||
context: inUse ? 'in_use' : 'not_in_use',
|
||||
})}
|
||||
</Status>
|
||||
)}
|
||||
{data.type !== ConnectorType.Social && (
|
||||
<Status status={data.enabled ? 'enabled' : 'disabled'} varient="outlined">
|
||||
{t('connectors.connector_status', {
|
||||
context: data.enabled ? 'in_use' : 'not_in_use',
|
||||
})}
|
||||
</Status>
|
||||
)}
|
||||
<div className={styles.verticalBar} />
|
||||
<div className={styles.id}>{data.id}</div>
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
a.link {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
@ -8,3 +10,12 @@ a.link {
|
|||
height: 40px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.previewTitle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> *:first-child {
|
||||
margin-right: _.unit(2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import React from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import ItemPreview from '@/components/ItemPreview';
|
||||
import UnnamedTrans from '@/components/UnnamedTrans';
|
||||
import { connectorIconPlaceHolder, connectorTitlePlaceHolder } from '@/consts/connectors';
|
||||
|
@ -14,15 +15,23 @@ type Props = {
|
|||
type: ConnectorType;
|
||||
connector?: ConnectorDTO;
|
||||
isShowId?: boolean;
|
||||
onClickSetup?: () => void;
|
||||
};
|
||||
|
||||
const ConnectorName = ({ type, connector, isShowId = false }: Props) => {
|
||||
const ConnectorName = ({ type, connector, onClickSetup, isShowId = false }: Props) => {
|
||||
const { t } = useTranslation(undefined);
|
||||
|
||||
if (!connector) {
|
||||
return (
|
||||
<ItemPreview
|
||||
title={t(connectorTitlePlaceHolder[type])}
|
||||
title={
|
||||
<div className={styles.previewTitle}>
|
||||
<div>{t(connectorTitlePlaceHolder[type])}</div>
|
||||
{type !== ConnectorType.Social && (
|
||||
<Button title="admin_console.connectors.set_up" onClick={onClickSetup} />
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
icon={<img src={connectorIconPlaceHolder[type]} />}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.statusItems {
|
||||
display: flex;
|
||||
|
||||
.statusItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:not(:last-child) {
|
||||
.line {
|
||||
margin: 0 _.unit(2);
|
||||
height: 16px;
|
||||
@include _.vertical-bar;
|
||||
}
|
||||
}
|
||||
|
||||
.platform {
|
||||
margin-left: _.unit(1);
|
||||
color: var(--color-caption);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
import { ConnectorDTO, ConnectorType } from '@logto/schemas';
|
||||
import { conditional } from '@silverhand/essentials';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import Status from '@/components/Status';
|
||||
import { connectorPlatformLabel, connectorTitlePlaceHolder } from '@/consts/connectors';
|
||||
import { connectorTitlePlaceHolder } from '@/consts/connectors';
|
||||
import useConnectorInUse from '@/hooks/use-connector-in-use';
|
||||
|
||||
import ConnectorName from '../ConnectorName';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
type: ConnectorType;
|
||||
|
@ -17,6 +17,9 @@ type Props = {
|
|||
|
||||
const ConnectorRow = ({ type, connectors, onClickSetup }: Props) => {
|
||||
const { t } = useTranslation(undefined);
|
||||
const inUse = useConnectorInUse(
|
||||
conditional(type === ConnectorType.Social && connectors[0]?.target)
|
||||
);
|
||||
|
||||
return (
|
||||
<tr>
|
||||
|
@ -25,41 +28,22 @@ const ConnectorRow = ({ type, connectors, onClickSetup }: Props) => {
|
|||
type={type}
|
||||
connector={connectors[0]}
|
||||
isShowId={type !== ConnectorType.Social}
|
||||
onClickSetup={onClickSetup}
|
||||
/>
|
||||
</td>
|
||||
<td>{t(connectorTitlePlaceHolder[type])}</td>
|
||||
<td>
|
||||
{type === ConnectorType.Social && (
|
||||
<div className={styles.statusItems}>
|
||||
{connectors.map(({ id, enabled, platform }) => {
|
||||
const status = enabled ? 'enabled' : 'disabled';
|
||||
|
||||
return (
|
||||
<div key={id} className={styles.statusItem}>
|
||||
<Status status={enabled ? 'enabled' : 'disabled'}>
|
||||
{t(`admin_console.connectors.connector_status_${status}`)}
|
||||
</Status>
|
||||
<div className={styles.platform}>
|
||||
{platform && t(connectorPlatformLabel[platform])}
|
||||
</div>
|
||||
<div className={styles.line} />
|
||||
</div>
|
||||
);
|
||||
{type === ConnectorType.Social && inUse !== undefined && (
|
||||
<Status status={inUse ? 'enabled' : 'disabled'}>
|
||||
{t('admin_console.connectors.connector_status', {
|
||||
context: inUse ? 'in_use' : 'not_in_use',
|
||||
})}
|
||||
</div>
|
||||
</Status>
|
||||
)}
|
||||
{type !== ConnectorType.Social && connectors[0] && (
|
||||
<Status status="enabled">{t('admin_console.connectors.connector_status_enabled')}</Status>
|
||||
)}
|
||||
{type !== ConnectorType.Social && !connectors[0] && (
|
||||
<Button
|
||||
title="admin_console.connectors.set_up"
|
||||
type="outline"
|
||||
onClick={() => {
|
||||
onClickSetup?.();
|
||||
}}
|
||||
/>
|
||||
<Status status="enabled">{t('admin_console.connectors.connector_status_in_use')}</Status>
|
||||
)}
|
||||
{type !== ConnectorType.Social && !connectors[0] && '-'}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
|
|
@ -244,9 +244,9 @@ const translation = {
|
|||
tab_social: 'Social connectors',
|
||||
connector_name: 'Connector name',
|
||||
connector_type: 'Type',
|
||||
connector_status: 'Status',
|
||||
connector_status_enabled: 'Enabled',
|
||||
connector_status_disabled: 'Disabled',
|
||||
connector_status: 'Sign in Experience',
|
||||
connector_status_in_use: 'In use',
|
||||
connector_status_not_in_use: 'Not in use',
|
||||
social_connector_eg: 'e.g.: Google, Facebook, Twitter',
|
||||
next: 'Next',
|
||||
type: {
|
||||
|
|
|
@ -243,9 +243,9 @@ const translation = {
|
|||
tab_social: '社会化登录',
|
||||
connector_name: '连接器',
|
||||
connector_type: '类型',
|
||||
connector_status: '状态',
|
||||
connector_status_enabled: '已启用',
|
||||
connector_status_disabled: '已禁用',
|
||||
connector_status: '登录体验',
|
||||
connector_status_in_use: '使用中',
|
||||
connector_status_not_in_use: '未使用',
|
||||
social_connector_eg: '如: 微信登录,支付宝登录,微博登录',
|
||||
next: '下一步',
|
||||
type: {
|
||||
|
|
Loading…
Add table
Reference in a new issue