tachybase_todo/packages/plugins/oidc/src/client/OIDCButton.tsx
YANG QIA 70d5b9e44b
feat: localization management (#2210)
* feat: init localization-management

* feat: resource api

* Merge branch 'main' into T-62

* chore: change name

* feat: basic feature

* feat: support filter & sync

* feat: support auto get texts afterSave

* Merge branch 'main' into T-62

* chore: upgrade

* fix: dependency

* fix: field type

* fix: type error

* chore: remove some translations

* feat: support extract text from menu

* chore: cache text keys

* chore: remove test key

* fix: issue of extracting menu titles

* feat: translate collections & fields name

* fix: remove unique of text

* refactor: improve cache

* chore: remove listeners after disable

* chore: translation

* fix: lang switch bug

* refactor: actions & filter

* fix: translation

* refactor: merge lang bundles at backend

* fix: style & field name

* fix: translate issues

* fix: cache bug

* fix: translation merge bug

* fix: translate issues

* fix: map translation

* fix: translation issues

* fix: card title bug

* feat: cover mobile client tabbar

* fix: menu title

* refactor: add locale plugin

* chore: merge locale plugin

* fix: map translation

* chore: remove no data

* style: change button style

* fix: sync bug

* docs: add README

* chore: change name

---------

Co-authored-by: chenos <chenlinxh@gmail.com>
2023-07-17 23:23:44 +08:00

87 lines
2.2 KiB
TypeScript

import { LoginOutlined } from '@ant-design/icons';
import { Authenticator, css, useAPIClient, useRedirect } from '@nocobase/client';
import { useMemoizedFn } from 'ahooks';
import { Button, Space } from 'antd';
import React, { useEffect, useState } from 'react';
import { useOidcTranslation } from './locale';
export interface OIDCProvider {
clientId: string;
title: string;
}
export const OIDCButton = (props: { authenticator: Authenticator }) => {
const { t } = useOidcTranslation();
const [windowHandler, setWindowHandler] = useState<Window | undefined>();
const api = useAPIClient();
const redirect = useRedirect();
/**
* 打开登录弹出框
*/
const handleOpen = async (name: string) => {
const response = await api.request({
method: 'post',
url: 'oidc:getAuthUrl',
headers: {
'X-Authenticator': name,
},
});
const authUrl = response?.data?.data;
const { width, height } = screen;
const win = window.open(
authUrl,
'_blank',
`width=800,height=600,left=${(width - 800) / 2},top=${
(height - 600) / 2
},toolbar=no,menubar=no,location=no,status=no`,
);
setWindowHandler(win);
};
/**
* 从弹出窗口,发消息回来进行登录
*/
const handleOIDCLogin = useMemoizedFn(async (event: MessageEvent) => {
const { state } = event.data;
const search = new URLSearchParams(state);
const authenticator = search.get('name');
try {
await api.auth.signIn(event.data, authenticator);
redirect();
} catch (err) {
console.error(err);
}
});
/**
* 监听弹出窗口的消息
*/
useEffect(() => {
if (!windowHandler) return;
const channel = new BroadcastChannel('nocobase-oidc-response');
channel.onmessage = handleOIDCLogin;
return () => {
channel.close();
};
}, [windowHandler, handleOIDCLogin]);
const authenticator = props.authenticator;
return (
<Space
direction="vertical"
className={css`
display: flex;
`}
>
<Button shape="round" block icon={<LoginOutlined />} onClick={() => handleOpen(authenticator.name)}>
{t(authenticator.title)}
</Button>
</Space>
);
};