Skip to content

Commit

Permalink
✨ feat: support OpenAPI Authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx authored and canisminor1990 committed Dec 15, 2023
1 parent 11a39b1 commit 820c15e
Show file tree
Hide file tree
Showing 10 changed files with 656 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/features/PluginSettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const PluginSettingsConfig = memo<PluginSettingsConfigProps>(({ schema, id }) =>
const items = transformPluginSettings(schema);

return (
<Form form={form} layout={'vertical'}>
<Form form={form} layout={'vertical'} style={{ width: '100%' }}>
{items.map((item) => (
<Form.Item
desc={item.desc && <Markdown className={styles.markdown}>{item.desc as string}</Markdown>}
Expand Down
103 changes: 53 additions & 50 deletions src/features/PluginStore/PluginItem.tsx
Original file line number Diff line number Diff line change
@@ -1,82 +1,85 @@
import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
import { Avatar, Icon, Tag } from '@lobehub/ui';
import { Avatar, Tag } from '@lobehub/ui';
import { Button } from 'antd';
import { createStyles, useResponsive } from 'antd-style';
import { BadgeCheck, CircleUser } from 'lucide-react';
import { createStyles } from 'antd-style';
import Link from 'next/link';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { useToolStore } from '@/store/tool';
import { pluginSelectors, pluginStoreSelectors } from '@/store/tool/selectors';
import { InstallPluginMeta } from '@/types/tool/plugin';

import PluginSettings from './PluginSettings';

const useStyles = createStyles(({ css, token }) => ({
desc: css`
color: ${token.colorTextDescription};
color: ${token.colorTextSecondary};
`,
link: css`
color: ${token.colorText};
color: ${token.colorTextDescription};
`,
tag: css`
color: ${token.colorTextSecondary};
font-weight: normal;
`,
title: css`
font-size: ${token.fontSizeLG}px;
font-weight: bold;
line-height: 2;
`,
}));
const PluginItem = memo<LobeChatPluginMeta>(({ identifier, homepage, author, meta }) => {
const [installed, installing, installPlugin, unInstallPlugin] = useToolStore((s) => [
pluginSelectors.isPluginInstalled(identifier)(s),
pluginStoreSelectors.isPluginInstallLoading(identifier)(s),
s.installPlugin,
s.uninstallPlugin,
]);
const { mobile } = useResponsive();
const { styles } = useStyles();

const { t } = useTranslation('plugin');
return (
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'}>
<Flexbox align={'center'} gap={8} horizontal>
<Avatar avatar={meta.avatar} size={mobile ? 40 : 56} style={{ flex: 'none' }} />
<Flexbox gap={4}>
<Flexbox align={'center'} gap={8} horizontal>
<Link className={styles.link} href={homepage} target={'_blank'}>
<div className={styles.title}>{meta.title}</div>
</Link>
const PluginItem = memo<InstallPluginMeta>(
({ identifier, createdAt, homepage, author, type, meta = {} }) => {
console.log(type);
const [installed, installing, installPlugin, unInstallPlugin] = useToolStore((s) => [
pluginSelectors.isPluginInstalled(identifier)(s),
pluginStoreSelectors.isPluginInstallLoading(identifier)(s),
s.installPlugin,
s.uninstallPlugin,
]);
const { styles } = useStyles();

const { t } = useTranslation('plugin');
return (
<Flexbox gap={8} padding={16}>
<Flexbox horizontal justify={'space-between'}>
<Avatar avatar={meta.avatar} size={56} style={{ flex: 'none' }} />

<Tag
className={styles.tag}
icon={<Icon icon={author === 'LobeHub' ? BadgeCheck : CircleUser} />}
<Flexbox gap={8} horizontal>
<PluginSettings identifier={identifier} />
<Button
loading={installing}
onClick={() => {
if (installed) {
unInstallPlugin(identifier);
} else installPlugin(identifier);
}}
type={installed ? 'default' : 'primary'}
>
{author}
</Tag>
{t(installed ? 'store.uninstall' : 'store.install')}
</Button>
</Flexbox>
</Flexbox>

<Flexbox gap={4}>
<Flexbox align={'center'} gap={8} horizontal>
<div className={styles.title}>{meta.title}</div>
<Tag className={styles.tag}> {identifier}</Tag>
</Flexbox>
<div className={styles.desc}>{meta.description}</div>
<Flexbox className={styles.link} gap={8} horizontal>
{author && (
<Link className={styles.link} href={homepage ?? ''} target={'_blank'}>
@{author}
</Link>
)}
{createdAt && t('store.releasedAt', { createdAt })}
</Flexbox>
<div className={styles.desc}>{meta.description} </div>
</Flexbox>
</Flexbox>
<Flexbox align={'center'} gap={8} horizontal>
<PluginSettings identifier={identifier} />
<Button
loading={installing}
onClick={() => {
if (installed) {
unInstallPlugin(identifier);
} else installPlugin(identifier);
}}
size={mobile ? 'small' : undefined}
type={installed ? 'default' : 'primary'}
>
{t(installed ? 'store.uninstall' : 'store.install')}
</Button>
</Flexbox>
</Flexbox>
);
});
);
},
);

export default PluginItem;
125 changes: 125 additions & 0 deletions src/services/__tests__/__snapshots__/plugin.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,128 @@ exports[`PluginService > convertOpenAPIToPluginSchema > can convert OpenAPI v3.1
},
]
`;

exports[`PluginService > getPluginManifest > support OpenAPI manifest > should get plugin manifest 1`] = `
{
"$schema": "../node_modules/@lobehub/chat-plugin-sdk/schema.json",
"api": [
{
"description": "Read Course Segments",
"name": "read_course_segments_course_segments__get",
"parameters": {
"properties": {},
"type": "object",
},
},
{
"description": "Read Problem Set Item",
"name": "read_problem_set_item_problem_set__problem_set_id___question_number__get",
"parameters": {
"properties": {
"problem_set_id": {
"title": "Problem Set Id",
"type": "integer",
},
"question_number": {
"title": "Question Number",
"type": "integer",
},
},
"required": [
"problem_set_id",
"question_number",
],
"type": "object",
},
},
{
"description": "Read Random Problem Set Items",
"name": "read_random_problem_set_items_problem_set_random__problem_set_id___n_items__get",
"parameters": {
"properties": {
"n_items": {
"title": "N Items",
"type": "integer",
},
"problem_set_id": {
"title": "Problem Set Id",
"type": "integer",
},
},
"required": [
"problem_set_id",
"n_items",
],
"type": "object",
},
},
{
"description": "Read Range Of Problem Set Items",
"name": "read_range_of_problem_set_items_problem_set_range__problem_set_id___start___end__get",
"parameters": {
"properties": {
"end": {
"title": "End",
"type": "integer",
},
"problem_set_id": {
"title": "Problem Set Id",
"type": "integer",
},
"start": {
"title": "Start",
"type": "integer",
},
},
"required": [
"problem_set_id",
"start",
"end",
],
"type": "object",
},
},
{
"description": "Read User Id",
"name": "read_user_id_user__get",
"parameters": {
"properties": {},
"type": "object",
},
},
],
"author": "LobeHub",
"createAt": "2023-08-12",
"homepage": "https://github.com/lobehub/chat-plugin-realtime-weather",
"identifier": "realtime-weather",
"meta": {
"avatar": "🌈",
"description": "Get realtime weather information",
"tags": [
"weather",
"realtime",
],
"title": "Realtime Weather",
},
"openapi": "http://fake-url.com/openapiUrl.json",
"settings": {
"properties": {
"HTTPBearer": {
"description": "HTTPBearer Bearer token",
"format": "password",
"title": "HTTPBearer",
"type": "string",
},
},
"required": [
"HTTPBearer",
],
"type": "object",
},
"ui": {
"height": 310,
"url": "https://realtime-weather.chat-plugin.lobehub.com/iframe",
},
"version": "1",
}
`;
Loading

0 comments on commit 820c15e

Please sign in to comment.