From 4e2a4cd9fe5f4dcb5a83335ffaa5620873eed618 Mon Sep 17 00:00:00 2001 From: sealday Date: Mon, 20 May 2024 20:52:05 +0800 Subject: [PATCH] feat: multi app and plugins (#1020) Reviewed-on: https://git.daoyoucloud.com/daoyoucloud/tachybase/pulls/1020 --- package.json | 1 + packages/core/app/package.json | 1 + packages/core/client/src/pm/PluginCard.tsx | 43 +++++ packages/core/client/src/pm/PluginManager.tsx | 109 +++++------ .../route-switch/antd/admin-layout/index.tsx | 19 +- packages/presets/mini/.npmignore | 2 + packages/presets/mini/client.d.ts | 3 + packages/presets/mini/client.js | 1 + packages/presets/mini/package.json | 67 +++++++ packages/presets/mini/server.d.ts | 3 + packages/presets/mini/server.js | 1 + packages/presets/mini/src/client/index.ts | 3 + packages/presets/mini/src/index.ts | 1 + packages/presets/mini/src/server/index.ts | 31 +++ pnpm-lock.yaml | 181 ++++++++++++++++++ 15 files changed, 407 insertions(+), 59 deletions(-) create mode 100644 packages/presets/mini/.npmignore create mode 100644 packages/presets/mini/client.d.ts create mode 100644 packages/presets/mini/client.js create mode 100644 packages/presets/mini/package.json create mode 100644 packages/presets/mini/server.d.ts create mode 100644 packages/presets/mini/server.js create mode 100644 packages/presets/mini/src/client/index.ts create mode 100644 packages/presets/mini/src/index.ts create mode 100644 packages/presets/mini/src/server/index.ts diff --git a/package.json b/package.json index b5ca9acab..80e53c0d8 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "@tachybase/cli": "workspace:*", "@tachybase/preset-hera-rental": "workspace:*", "@tachybase/preset-hera-sancongtou": "workspace:*", + "@tachybase/preset-mini": "workspace:*", "@tachybase/preset-tachybase": "workspace:*", "@tachybase/test": "workspace:*", "@types/react": "^18.2.79", diff --git a/packages/core/app/package.json b/packages/core/app/package.json index 570b76ca1..f5f38c21f 100644 --- a/packages/core/app/package.json +++ b/packages/core/app/package.json @@ -9,6 +9,7 @@ "@tachybase/database": "workspace:*", "@tachybase/preset-hera-rental": "workspace:*", "@tachybase/preset-hera-sancongtou": "workspace:*", + "@tachybase/preset-mini": "workspace:*", "@tachybase/preset-tachybase": "workspace:*", "@tachybase/server": "workspace:*" }, diff --git a/packages/core/client/src/pm/PluginCard.tsx b/packages/core/client/src/pm/PluginCard.tsx index 12f4e8be8..a839582a4 100644 --- a/packages/core/client/src/pm/PluginCard.tsx +++ b/packages/core/client/src/pm/PluginCard.tsx @@ -18,6 +18,49 @@ interface IPluginInfo extends IPluginCard { onClick: () => void; } +export const SwitchAction = (props: IPluginData) => { + const { name, enabled, builtIn, error, isCompatible } = props; + const api = useAPIClient(); + const { t } = useTranslation(); + const { modal } = App.useApp(); + return ( + { + e.stopPropagation(); + if (!isCompatible && checked) { + message.error(t("Dependencies check failed, can't enable.")); + return; + } + if (!checked) { + modal.confirm({ + title: t('Are you sure to disable this plugin?'), + onOk: async () => { + await api.request({ + url: `pm:disable`, + params: { + filterByTk: name, + }, + }); + }, + }); + } else { + await api.request({ + url: `pm:enable`, + params: { + filterByTk: name, + }, + }); + } + }} + checked={!!enabled} + > + ); +}; + function PluginInfo(props: IPluginInfo) { const { data, onClick } = props; const app = useApp(); diff --git a/packages/core/client/src/pm/PluginManager.tsx b/packages/core/client/src/pm/PluginManager.tsx index e097a62c8..0a30ebb51 100644 --- a/packages/core/client/src/pm/PluginManager.tsx +++ b/packages/core/client/src/pm/PluginManager.tsx @@ -1,7 +1,8 @@ export * from './PluginManagerLink'; +import type { TableProps } from 'antd'; import { PageHeader } from '@ant-design/pro-layout'; import { useDebounce } from 'ahooks'; -import { Button, Col, Divider, Input, List, Result, Row, Space, Spin, Tabs } from 'antd'; +import { Button, Card, Col, Divider, Input, List, Result, Row, Space, Spin, Tabs, Table, Tag } from 'antd'; import _ from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -11,10 +12,10 @@ import { css } from '@emotion/css'; import { useACLRoleContext } from '../acl/ACLProvider'; import { useRequest } from '../api-client'; import { useToken } from '../style'; -import { PluginCard } from './PluginCard'; -import { PluginAddModal } from './PluginForm/modal/PluginAddModal'; +import { PluginCard, SwitchAction } from './PluginCard'; import { useStyles } from './style'; import { IPluginData } from './types'; +import { fuzzysearch } from '@tachybase/utils/client'; export interface TData { data: IPluginData[]; @@ -35,12 +36,46 @@ export interface AllowedActions { destroy: number[]; } +const columns: TableProps['columns'] = [ + { + title: 'Name', + dataIndex: 'name', + key: 'name', + render: (text) => {text}, + }, + { + title: 'Keywords', + dataIndex: 'keywords', + key: 'keywords', + render: (keywords) => keywords?.map((keyword) => {keyword}), + }, + { + title: 'Description', + dataIndex: 'description', + key: 'description', + }, + { + title: 'Action', + key: 'action', + render: (_, record) => ( + + + + ), + }, +]; + const LocalPlugins = () => { const { t } = useTranslation(); const { theme } = useStyles(); const { data, loading, refresh } = useRequest({ url: 'pm:list', }); + + const [searchValue, setSearchValue] = useState(''); + const filteredList = (data?.data || []).filter( + (data) => fuzzysearch(searchValue, data.name) || fuzzysearch(searchValue, data.description ?? ''), + ); const filterList = useMemo(() => { let list = data?.data || []; list = list.reverse(); @@ -69,8 +104,6 @@ const LocalPlugins = () => { }, [data?.data]); const [filterIndex, setFilterIndex] = useState(0); - const [isShowAddForm, setShowAddForm] = useState(false); - const [searchValue, setSearchValue] = useState(''); const [keyword, setKeyword] = useState(null); const debouncedSearchValue = useDebounce(searchValue, { wait: 100 }); @@ -140,15 +173,7 @@ const LocalPlugins = () => { } return ( <> - { - setShowAddForm(false); - // if (isRefresh) refresh(); - }} - /> - -
+ {/*
{ />
-
- - - -
@@ -222,8 +240,20 @@ const LocalPlugins = () => { ))}
- - + */} + setSearchValue(e.target.value)} + /> + } + > + + + {/* */} ); }; @@ -251,37 +281,8 @@ export const PluginManager = () => { return snippets.includes('pm') ? (
- { - navigate(`/admin/pm/list/${activeKey}`); - }} - items={[ - { - key: 'local', - label: t('Local'), - }, - { - key: 'marketplace', - label: t('Marketplace'), - }, - ]} - /> - } - /> -
- {React.createElement( - { - local: LocalPlugins, - marketplace: MarketplacePlugins, - }[tabName], - )} -
+ +
) : ( diff --git a/packages/core/client/src/route-switch/antd/admin-layout/index.tsx b/packages/core/client/src/route-switch/antd/admin-layout/index.tsx index 363328aa4..b4381d779 100644 --- a/packages/core/client/src/route-switch/antd/admin-layout/index.tsx +++ b/packages/core/client/src/route-switch/antd/admin-layout/index.tsx @@ -25,7 +25,6 @@ import { } from '../../../'; import { Plugin } from '../../../application/Plugin'; import { useAppSpin } from '../../../application/hooks/useAppSpin'; -import { Help } from '../../../user/Help'; import { VariablesProvider } from '../../../variables'; const filterByACL = (schema, options) => { @@ -338,23 +337,33 @@ export const InternalAdminLayout = (props: any) => { >
+

+ {result?.data?.data?.title} +