feat: 开放平台增加OAuth

release/desktop
moonrailgun 3 years ago
parent c94932a85f
commit 2ad682b17f

@ -0,0 +1,82 @@
import React from 'react';
import {
FullModalField,
DefaultFullModalTextAreaEditorRender,
Switch,
} from '@capital/component';
import { useOpenAppInfo } from '../context';
import { OpenAppCapability } from '../types';
import { postRequest, useAsyncFn } from '@capital/common';
const OAuth: React.FC = React.memo(() => {
const { refresh, appId, capability, oauth } = useOpenAppInfo();
const [{ loading }, handleChangeOAuthCapability] = useAsyncFn(
async (checked: boolean) => {
const newCapability: OpenAppCapability[] = [...capability];
const findIndex = newCapability.findIndex((c) => c === 'oauth');
const isExist = findIndex !== -1;
if (checked && !isExist) {
newCapability.push('oauth');
} else if (!checked && isExist) {
newCapability.splice(findIndex, 1);
}
await postRequest('/openapi/app/setAppCapability', {
appId,
capability: newCapability,
});
await refresh();
},
[appId, capability, refresh]
);
const [, handleUpdateOAuthInfo] = useAsyncFn(
async (name: string, value: any) => {
await postRequest('/openapi/app/setAppOAuthInfo', {
appId,
fieldName: name,
fieldValue: value,
});
await refresh();
},
[]
);
return (
<div className="plugin-openapi-app-info_oauth">
<FullModalField
title="开启 OAuth"
content={
<Switch
disabled={loading}
checked={capability.includes('oauth')}
onChange={handleChangeOAuthCapability}
/>
}
/>
{capability.includes('oauth') && (
<FullModalField
title={'允许的回调地址'}
tip="多个回调地址单独一行"
value={(oauth?.redirectUrls ?? []).join(',')}
editable={true}
renderEditor={DefaultFullModalTextAreaEditorRender}
onSave={(str: string) =>
handleUpdateOAuthInfo(
'redirectUrls',
String(str)
.split('\n')
.map((t) => t.trim())
)
}
/>
)}
</div>
);
});
OAuth.displayName = 'OAuth';
export default OAuth;

@ -1,40 +1,58 @@
import React, { useState } from 'react'; import React, { useMemo } from 'react';
import { Menu } from '@capital/component'; import { SidebarView } from '@capital/component';
import { Loadable } from '@capital/common'; import { Loadable } from '@capital/common';
import { useOpenAppInfo } from '../context'; import { useOpenAppInfo } from '../context';
import './index.less'; import './index.less';
const menuRouteMap: Record<string, React.ComponentType> = { const Summary = Loadable(() => import('./Summary'));
summary: Loadable(() => import('./Summary')), const Profile = Loadable(() => import('./Profile'));
profile: Loadable(() => import('./Profile')), const Bot = Loadable(() => import('./Bot'));
bot: Loadable(() => import('./Bot')), const Webpage = Loadable(() => import('./Webpage'));
webpage: Loadable(() => import('./Webpage')), const OAuth = Loadable(() => import('./OAuth'));
};
const AppInfo: React.FC = React.memo(() => { const AppInfo: React.FC = React.memo(() => {
const [menu, setMenu] = useState('summary');
const { appName } = useOpenAppInfo(); const { appName } = useOpenAppInfo();
const menu = useMemo(
() => [
{
type: 'group',
title: appName,
children: [
{
type: 'item',
title: '总览',
content: <Summary />,
},
{
type: 'item',
title: '基础信息',
content: <Profile />,
},
{
type: 'item',
title: '机器人',
content: <Bot />,
},
{
type: 'item',
title: '网页',
content: <Webpage />,
},
{
type: 'item',
title: '应用登录',
content: <OAuth />,
},
],
},
],
[]
);
return ( return (
<div className="plugin-openapi-app-info"> <div className="plugin-openapi-app-info">
<div> <SidebarView menu={menu} defaultContentPath="0.children.0.content" />
<div>{appName}</div>
<Menu
style={{ width: 256 }}
selectedKeys={[menu]}
onSelect={({ key }) => setMenu(key)}
>
<Menu.Item key="summary"></Menu.Item>
<Menu.Item key="profile"></Menu.Item>
<Menu.Item key="bot"></Menu.Item>
<Menu.Item key="webpage"></Menu.Item>
</Menu>
</div>
<div className="plugin-openapi-app-info_body">
{menuRouteMap[menu] ? React.createElement(menuRouteMap[menu]) : <div />}
</div>
</div> </div>
); );
}); });

@ -6,6 +6,10 @@ const openAppCapability = [
export type OpenAppCapability = typeof openAppCapability[number]; export type OpenAppCapability = typeof openAppCapability[number];
interface OpenAppOAuth {
redirectUrls: string[];
}
export interface OpenApp { export interface OpenApp {
_id: string; _id: string;
appId: string; appId: string;
@ -14,6 +18,7 @@ export interface OpenApp {
appDesc: string; appDesc: string;
appIcon: string; appIcon: string;
capability: OpenAppCapability[]; capability: OpenAppCapability[];
oauth?: OpenAppOAuth;
owner: string; owner: string;
} }

@ -157,7 +157,7 @@ export const DefaultFullModalInputEditorRender: FullModalFieldEditorRenderCompon
export const DefaultFullModalTextAreaEditorRender: FullModalFieldEditorRenderComponent = export const DefaultFullModalTextAreaEditorRender: FullModalFieldEditorRenderComponent =
({ value, onChange }) => ( ({ value, onChange }) => (
<Input.TextArea <Input.TextArea
autoSize={true} autoSize={{ minRows: 2, maxRows: 6 }}
value={value} value={value}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
/> />

@ -16,5 +16,10 @@ export { Icon } from '@iconify/react';
export { PillTabs, PillTabPane } from '@/components/PillTabs'; export { PillTabs, PillTabPane } from '@/components/PillTabs';
export { LoadingSpinner } from '@/components/LoadingSpinner'; export { LoadingSpinner } from '@/components/LoadingSpinner';
export { WebFastForm } from '@/components/WebFastForm'; export { WebFastForm } from '@/components/WebFastForm';
export { FullModalField } from '@/components/FullModal/Field'; export {
FullModalField,
DefaultFullModalInputEditorRender,
DefaultFullModalTextAreaEditorRender,
} from '@/components/FullModal/Field';
export { Loading } from '@/components/Loading'; export { Loading } from '@/components/Loading';
export { SidebarView } from '@/components/SidebarView';

Loading…
Cancel
Save