From c723bd2c961837ff2d2cd29e4bd819cf4e24c162 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Thu, 14 Nov 2024 13:02:12 +0800 Subject: [PATCH] app selector trigger --- .../model-provider-page/model-modal/Form.tsx | 2 +- .../app-selector/app-trigger.tsx | 49 +++++++ .../app-selector/index.tsx | 129 ++++++++++++++++++ .../plugin-detail-panel/endpoint-modal.tsx | 9 ++ .../tool-selector/index.tsx | 4 +- .../tool-selector/tool-credentials-form.tsx | 0 .../tool-selector/tool-trigger.tsx | 0 web/i18n/en-US/app.ts | 5 + web/i18n/zh-Hans/app.ts | 5 + 9 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 web/app/components/plugins/plugin-detail-panel/app-selector/app-trigger.tsx create mode 100644 web/app/components/plugins/plugin-detail-panel/app-selector/index.tsx rename web/app/components/{tools => plugins/plugin-detail-panel}/tool-selector/index.tsx (96%) rename web/app/components/{tools => plugins/plugin-detail-panel}/tool-selector/tool-credentials-form.tsx (100%) rename web/app/components/{tools => plugins/plugin-detail-panel}/tool-selector/tool-trigger.tsx (100%) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index cef2146daa..bb6f8f19d8 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -18,7 +18,7 @@ import { SimpleSelect } from '@/app/components/base/select' import Tooltip from '@/app/components/base/tooltip' import Radio from '@/app/components/base/radio' import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' -import ToolSelector from '@/app/components/tools/tool-selector' +import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-selector' type FormProps = { className?: string diff --git a/web/app/components/plugins/plugin-detail-panel/app-selector/app-trigger.tsx b/web/app/components/plugins/plugin-detail-panel/app-selector/app-trigger.tsx new file mode 100644 index 0000000000..845a69d7e7 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/app-selector/app-trigger.tsx @@ -0,0 +1,49 @@ +'use client' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { + RiArrowDownSLine, +} from '@remixicon/react' +import AppIcon from '@/app/components/base/app-icon' +import type { App } from '@/types/app' +import cn from '@/utils/classnames' + +type Props = { + open: boolean + appDetail?: App +} + +const AppTrigger = ({ + open, + appDetail, +}: Props) => { + const { t } = useTranslation() + return ( +
+ {appDetail && ( +
+ +
+ )} + {appDetail && ( +
{appDetail.name}
+ )} + {!appDetail && ( +
{t('app.appSelector.placeholder')}
+ )} + +
+ ) +} + +export default AppTrigger diff --git a/web/app/components/plugins/plugin-detail-panel/app-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/app-selector/index.tsx new file mode 100644 index 0000000000..2407526b75 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/app-selector/index.tsx @@ -0,0 +1,129 @@ +'use client' +import type { FC } from 'react' +import React, { useMemo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import AppTrigger from '@/app/components/plugins/plugin-detail-panel/app-selector/app-trigger' +import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' +import Button from '@/app/components/base/button' + +import { + useAllBuiltInTools, + useAllCustomTools, + useAllWorkflowTools, +} from '@/service/use-tools' +import { CollectionType } from '@/app/components/tools/types' +import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types' +import type { + OffsetOptions, + Placement, +} from '@floating-ui/react' +import cn from '@/utils/classnames' + +type Props = { + value?: { + provider: string + tool_name: string + } + disabled?: boolean + placement?: Placement + offset?: OffsetOptions + onSelect: (tool: { + provider: string + tool_name: string + }) => void + supportAddCustomTool?: boolean +} +const AppSelector: FC = ({ + value, + disabled, + placement = 'bottom', + offset = 4, + onSelect, +}) => { + const { t } = useTranslation() + const [isShow, onShowChange] = useState(false) + const handleTriggerClick = () => { + if (disabled) return + onShowChange(true) + } + + const { data: buildInTools } = useAllBuiltInTools() + const { data: customTools } = useAllCustomTools() + const { data: workflowTools } = useAllWorkflowTools() + const currentProvider = useMemo(() => { + const mergedTools = [...(buildInTools || []), ...(customTools || []), ...(workflowTools || [])] + return mergedTools.find((toolWithProvider) => { + return toolWithProvider.id === value?.provider && toolWithProvider.tools.some(tool => tool.name === value?.tool_name) + }) + }, [value, buildInTools, customTools, workflowTools]) + const [isShowChooseApp, setIsShowChooseApp] = useState(false) + const handleSelectTool = (tool: ToolDefaultValue) => { + const toolValue = { + provider: tool.provider_id, + tool_name: tool.tool_name, + } + onSelect(toolValue) + setIsShowChooseApp(false) + if (tool.provider_type === CollectionType.builtIn && tool.is_team_authorization) + onShowChange(false) + } + + return ( + <> + + + + + +
+
+
{t('tools.toolSelector.label')}
+ + } + isShow={isShowChooseApp} + onShowChange={setIsShowChooseApp} + disabled={false} + supportAddCustomTool + onSelect={handleSelectTool} + /> +
+ {/* app inputs config panel */} +
+ +
+
+
+
+ + ) +} +export default React.memo(AppSelector) diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx index ca4813d3c6..704ef9dd41 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx @@ -11,6 +11,8 @@ import Toast from '@/app/components/base/toast' import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' import cn from '@/utils/classnames' +import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-selector' + type Props = { formSchemas: any defaultValues?: any @@ -38,6 +40,8 @@ const EndpointModal: FC = ({ onSaved(tempCredential) } + const [mockApp, setMockApp] = React.useState(null) + return ( = ({ ) : null} /> +
diff --git a/web/app/components/tools/tool-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx similarity index 96% rename from web/app/components/tools/tool-selector/index.tsx rename to web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx index 0b13ab9bc2..eab0dd94d2 100644 --- a/web/app/components/tools/tool-selector/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx @@ -7,11 +7,11 @@ import { PortalToFollowElemContent, PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' -import ToolTrigger from '@/app/components/tools/tool-selector/tool-trigger' +import ToolTrigger from '@/app/components/plugins/plugin-detail-panel/tool-selector/tool-trigger' import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' import Button from '@/app/components/base/button' import Indicator from '@/app/components/header/indicator' -import ToolCredentialForm from '@/app/components/tools/tool-selector/tool-credentials-form' +import ToolCredentialForm from '@/app/components/plugins/plugin-detail-panel/tool-selector/tool-credentials-form' import Toast from '@/app/components/base/toast' import { useAppContext } from '@/context/app-context' diff --git a/web/app/components/tools/tool-selector/tool-credentials-form.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/tool-credentials-form.tsx similarity index 100% rename from web/app/components/tools/tool-selector/tool-credentials-form.tsx rename to web/app/components/plugins/plugin-detail-panel/tool-selector/tool-credentials-form.tsx diff --git a/web/app/components/tools/tool-selector/tool-trigger.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/tool-trigger.tsx similarity index 100% rename from web/app/components/tools/tool-selector/tool-trigger.tsx rename to web/app/components/plugins/plugin-detail-panel/tool-selector/tool-trigger.tsx diff --git a/web/i18n/en-US/app.ts b/web/i18n/en-US/app.ts index 3377a9b2f3..c39b173fea 100644 --- a/web/i18n/en-US/app.ts +++ b/web/i18n/en-US/app.ts @@ -133,6 +133,11 @@ const translation = { removeConfirmContent: 'The current configuration is in use, removing it will turn off the Tracing feature.', }, }, + appSelector: { + label: 'APP', + placeholder: 'Select an app...', + params: 'APP PARAMETERS', + }, } export default translation diff --git a/web/i18n/zh-Hans/app.ts b/web/i18n/zh-Hans/app.ts index ee316200fa..625b87acec 100644 --- a/web/i18n/zh-Hans/app.ts +++ b/web/i18n/zh-Hans/app.ts @@ -132,6 +132,11 @@ const translation = { removeConfirmContent: '当前配置正在使用中,删除它将关闭追踪功能。', }, }, + appSelector: { + label: '应用', + placeholder: '选择一个应用', + params: '应用参数', + }, } export default translation