280 lines
9.7 KiB
TypeScript
280 lines
9.7 KiB
TypeScript
import React, { useEffect } from 'react';
|
||
import { Form, Input, Switch, Button, Space, Upload, Select, Typography, Modal } from 'antd';
|
||
import { UploadOutlined } from '@ant-design/icons';
|
||
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
||
import Styles from './styles.module.less';
|
||
import { EntityDict } from '../../../../../oak-app-domain';
|
||
const { Text } = Typography;
|
||
|
||
const Upsert = (
|
||
props: WebComponentProps<
|
||
EntityDict,
|
||
'oauthProvider',
|
||
false,
|
||
{
|
||
item: RowWithActions<EntityDict, 'oauthProvider'>;
|
||
open: boolean;
|
||
onCancel: () => void;
|
||
onOk: () => void;
|
||
hideModal: boolean;
|
||
isCreation: boolean;
|
||
},
|
||
{
|
||
setHideModal: (hide: boolean) => void;
|
||
}
|
||
>
|
||
) => {
|
||
const { item, open, onCancel, onOk, hideModal, isCreation } = props.data;
|
||
const { t, update, setHideModal } = props.methods;
|
||
const [form] = Form.useForm();
|
||
|
||
useEffect(() => {
|
||
if (item) {
|
||
form.setFieldsValue({
|
||
name: item.name,
|
||
type: item.type ? [item.type] : [],
|
||
logo: item.logo,
|
||
authorizationEndpoint: item.authorizationEndpoint,
|
||
tokenEndpoint: item.tokenEndpoint,
|
||
refreshEndpoint: item.refreshEndpoint,
|
||
userInfoEndpoint: item.userInfoEndpoint,
|
||
revokeEndpoint: item.revokeEndpoint,
|
||
clientId: item.clientId,
|
||
clientSecret: item.clientSecret,
|
||
scopes: item.scopes,
|
||
redirectUri: item.redirectUri,
|
||
autoRegister: item.autoRegister,
|
||
ableState: item.ableState === 'enabled',
|
||
});
|
||
}
|
||
}, [item, form]);
|
||
|
||
const handleOk = async () => {
|
||
try {
|
||
await form.validateFields();
|
||
setHideModal(true);
|
||
setTimeout(() => {
|
||
onOk();
|
||
}, 300);
|
||
} catch (error) {
|
||
console.log('Validation failed:', error);
|
||
}
|
||
};
|
||
|
||
const handleCancel = () => {
|
||
setHideModal(true);
|
||
setTimeout(() => {
|
||
onCancel();
|
||
}, 300);
|
||
}
|
||
|
||
if (item === undefined) {
|
||
return null;
|
||
}
|
||
|
||
return (
|
||
<Modal
|
||
open={open && !hideModal}
|
||
destroyOnClose={true}
|
||
width={600}
|
||
onCancel={handleCancel}
|
||
onOk={handleOk}
|
||
title={t('oauthProvider')}
|
||
okText={isCreation ? t('create') : t('update')}
|
||
cancelText={t('cancel')}
|
||
>
|
||
<div className={Styles.id}>
|
||
<Form
|
||
form={form}
|
||
layout="vertical"
|
||
autoComplete="off"
|
||
>
|
||
<Form.Item
|
||
label={t('name')}
|
||
name="name"
|
||
rules={[{ required: true, message: t('nameRequired') }]}
|
||
>
|
||
<Input placeholder={t('namePlaceholder')}
|
||
onChange={(v) => {
|
||
update({ name: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('type')}
|
||
name="type"
|
||
rules={[{ required: true, message: t('typeRequired') }]}
|
||
extra={
|
||
item.type && item.type !== 'oak' && item.type !== 'gitea' ? (
|
||
<Text type="warning">
|
||
「{item.type}」不是预设类型,请自行注入 handler。
|
||
</Text>
|
||
) : undefined
|
||
}
|
||
>
|
||
<Select
|
||
mode="tags"
|
||
placeholder={t('typePlaceholder')}
|
||
onChange={(v) => {
|
||
// 只取最后一个输入或选择的值
|
||
const last = v.slice(-1)[0] as
|
||
| "oak"
|
||
| "gitea"
|
||
| string
|
||
| undefined;
|
||
|
||
update({ type: last });
|
||
}}
|
||
tokenSeparators={[',']}
|
||
maxTagCount={1} // 只显示一个标签
|
||
options={[
|
||
{ value: 'oak', label: 'Oak' },
|
||
{ value: 'gitea', label: 'Gitea' },
|
||
]}
|
||
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('logo')}
|
||
name="logo"
|
||
>
|
||
<Input placeholder={t('logoPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ logo: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('authorizationEndpoint')}
|
||
name="authorizationEndpoint"
|
||
rules={[{ required: true, message: t('authorizationEndpointRequired') }]}
|
||
>
|
||
<Input placeholder={t('authorizationEndpointPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ authorizationEndpoint: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('tokenEndpoint')}
|
||
name="tokenEndpoint"
|
||
rules={[{ required: true, message: t('tokenEndpointRequired') }]}
|
||
>
|
||
<Input placeholder={t('tokenEndpointPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ tokenEndpoint: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('refreshEndpoint')}
|
||
name="refreshEndpoint"
|
||
>
|
||
<Input placeholder={t('refreshEndpointPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ refreshEndpoint: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('userInfoEndpoint')}
|
||
name="userInfoEndpoint"
|
||
>
|
||
<Input placeholder={t('userInfoEndpointPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ userInfoEndpoint: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('revokeEndpoint')}
|
||
name="revokeEndpoint"
|
||
>
|
||
<Input placeholder={t('revokeEndpointPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ revokeEndpoint: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('clientId')}
|
||
name="clientId"
|
||
rules={[{ required: true, message: t('clientIdRequired') }]}
|
||
>
|
||
<Input placeholder={t('clientIdPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ clientId: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('clientSecret')}
|
||
name="clientSecret"
|
||
rules={[{ required: true, message: t('clientSecretRequired') }]}
|
||
>
|
||
<Input.Password placeholder={t('clientSecretPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ clientSecret: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('scopes')}
|
||
name="scopes"
|
||
>
|
||
<Select
|
||
mode="tags"
|
||
placeholder={t('scopesPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ scopes: v });
|
||
}}
|
||
tokenSeparators={[',']}
|
||
open={false}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('redirectUri')}
|
||
name="redirectUri"
|
||
rules={[{ required: true, message: t('redirectUriRequired') }]}
|
||
>
|
||
<Input placeholder={t('redirectUriPlaceholder')}
|
||
onChange={(v) => {
|
||
update({ redirectUri: v.target.value });
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('autoRegister')}
|
||
name="autoRegister"
|
||
valuePropName="checked"
|
||
>
|
||
<Switch onChange={(checked) => update({ autoRegister: checked })} />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label={t('ableState')}
|
||
name="ableState"
|
||
valuePropName="checked"
|
||
>
|
||
<Switch onChange={(checked) => update({ ableState: checked ? "enabled" : "disabled" })} />
|
||
</Form.Item>
|
||
|
||
</Form>
|
||
</div>
|
||
</Modal>
|
||
);
|
||
};
|
||
|
||
export default Upsert; |