From 77950e48c76f4a3b29d01831d43039caba29888a Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 18 十一月 2025 14:12:42 +0800
Subject: [PATCH] 修改
---
app/components/tools/provider/detail.tsx | 360 +++++++++++++++++++++++++----------------------------------
1 files changed, 153 insertions(+), 207 deletions(-)
diff --git a/app/components/tools/provider/detail.tsx b/app/components/tools/provider/detail.tsx
index 045d6f1..566fe46 100644
--- a/app/components/tools/provider/detail.tsx
+++ b/app/components/tools/provider/detail.tsx
@@ -2,31 +2,21 @@
import React, { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
-import {
- RiCloseLine,
-} from '@remixicon/react'
import { AuthHeaderPrefix, AuthType, CollectionType } from '../types'
-import Link from 'next/link'
import type { Collection, CustomCollectionBackend, Tool, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '../types'
import ToolItem from './tool-item'
import cn from '@/utils/classnames'
import I18n from '@/context/i18n'
import { getLanguage } from '@/i18n/language'
import Confirm from '@/app/components/base/confirm'
+import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import Indicator from '@/app/components/header/indicator'
import { LinkExternal02, Settings01 } from '@/app/components/base/icons/src/vender/line/general'
-import Icon from '@/app/components/plugins/card/base/card-icon'
-import Title from '@/app/components/plugins/card/base/title'
-import OrgInfo from '@/app/components/plugins/card/base/org-info'
-import Description from '@/app/components/plugins/card/base/description'
import ConfigCredential from '@/app/components/tools/setting/build-in/config-credentials'
import EditCustomToolModal from '@/app/components/tools/edit-custom-collection-modal'
import WorkflowToolModal from '@/app/components/tools/workflow-tool'
import Toast from '@/app/components/base/toast'
-import Drawer from '@/app/components/base/drawer'
-import ActionButton from '@/app/components/base/action-button'
-
import {
deleteWorkflowTool,
fetchBuiltInToolList,
@@ -45,17 +35,14 @@
import { ConfigurationMethodEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import Loading from '@/app/components/base/loading'
import { useAppContext } from '@/context/app-context'
-import { useInvalidateAllWorkflowTools } from '@/service/use-tools'
type Props = {
collection: Collection
- onHide: () => void
onRefreshData: () => void
}
const ProviderDetail = ({
collection,
- onHide,
onRefreshData,
}: Props) => {
const { t } = useTranslation()
@@ -67,7 +54,7 @@
const isBuiltIn = collection.type === CollectionType.builtIn
const isModel = collection.type === CollectionType.model
const { isCurrentWorkspaceManager } = useAppContext()
- const invalidateAllWorkflowTools = useInvalidateAllWorkflowTools()
+
const [isDetailLoading, setIsDetailLoading] = useState(false)
// built in provider
@@ -166,7 +153,6 @@
workflow_tool_id: string
}>) => {
await saveWorkflowToolProvider(data)
- invalidateAllWorkflowTools()
onRefreshData()
getWorkflowToolProvider()
Toast.notify({
@@ -214,7 +200,7 @@
setToolList(list)
}
}
- catch { }
+ catch (e) { }
setIsDetailLoading(false)
}, [collection.name, collection.type])
@@ -227,204 +213,164 @@
}, [collection.name, collection.type, getCustomProvider, getProviderToolList, getWorkflowToolProvider])
return (
- <Drawer
- isOpen={!!collection}
- clickOutsideNotOpen={false}
- onClose={onHide}
- footer={null}
- mask={false}
- positionCenter={false}
- panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')}
- >
- <div className='flex h-full flex-col p-4'>
- <div className="shrink-0">
- <div className='mb-3 flex'>
- <Icon src={collection.icon} />
- <div className="ml-3 w-0 grow">
- <div className="flex h-5 items-center">
- <Title title={collection.label[language]} />
- </div>
- <div className='mb-1 flex h-4 items-center justify-between'>
- <OrgInfo
- className="mt-0.5"
- packageNameClassName='w-auto'
- orgName={collection.author}
- packageName={collection.name}
- />
- </div>
- </div>
- <div className='flex gap-1'>
- <ActionButton onClick={onHide}>
- <RiCloseLine className='h-4 w-4' />
- </ActionButton>
- </div>
+ <div className='px-6 py-3'>
+ <div className='flex items-center py-1 gap-2'>
+ <div className='relative shrink-0'>
+ {typeof collection.icon === 'string' && (
+ <div className='w-8 h-8 bg-center bg-cover bg-no-repeat rounded-md' style={{ backgroundImage: `url(${collection.icon})` }} />
+ )}
+ {typeof collection.icon !== 'string' && (
+ <AppIcon
+ size='small'
+ icon={collection.icon.content}
+ background={collection.icon.background}
+ />
+ )}
+ </div>
+ <div className='grow w-0 py-[1px]'>
+ <div className='flex items-center text-md leading-6 font-semibold text-gray-900'>
+ <div className='truncate' title={collection.label[language]}>{collection.label[language]}</div>
</div>
</div>
- {!!collection.description[language] && (
- <Description text={collection.description[language]} descriptionLineRows={2}></Description>
+ </div>
+ <div className='mt-2 min-h-[36px] text-gray-500 text-sm leading-[18px]'>{collection.description[language]}</div>
+ <div className='flex gap-1 border-b-[0.5px] border-black/5'>
+ {(collection.type === CollectionType.builtIn) && needAuth && (
+ <Button
+ variant={isAuthed ? 'secondary' : 'primary'}
+ className={cn('shrink-0 my-3 w-full', isAuthed && 'bg-white')}
+ onClick={() => {
+ if (collection.type === CollectionType.builtIn || collection.type === CollectionType.model)
+ showSettingAuthModal()
+ }}
+ disabled={!isCurrentWorkspaceManager}
+ >
+ {isAuthed && <Indicator className='mr-2' color={'green'} />}
+ <div className={cn('text-white leading-[18px] text-[13px] font-medium', isAuthed && '!text-gray-700')}>
+ {isAuthed ? t('tools.auth.authorized') : t('tools.auth.unauthorized')}
+ </div>
+ </Button>
)}
- <div className='flex gap-1 border-b-[0.5px] border-divider-subtle'>
- {collection.type === CollectionType.custom && !isDetailLoading && (
+ {collection.type === CollectionType.custom && !isDetailLoading && (
+ <Button
+ className={cn('shrink-0 my-3 w-full')}
+ onClick={() => setIsShowEditCustomCollectionModal(true)}
+ >
+ <Settings01 className='mr-1 w-4 h-4 text-gray-500' />
+ <div className='leading-5 text-sm font-medium text-gray-700'>{t('tools.createTool.editAction')}</div>
+ </Button>
+ )}
+ {collection.type === CollectionType.workflow && !isDetailLoading && customCollection && (
+ <>
<Button
- className={cn('my-3 w-full shrink-0')}
- onClick={() => setIsShowEditCustomCollectionModal(true)}
+ variant='primary'
+ className={cn('shrink-0 my-3 w-[183px]')}
>
- <Settings01 className='mr-1 h-4 w-4 text-text-tertiary' />
- <div className='system-sm-medium text-text-secondary'>{t('tools.createTool.editAction')}</div>
+ <a className='flex items-center text-white' href={`/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'>
+ <div className='leading-5 text-sm font-medium'>{t('tools.openInStudio')}</div>
+ <LinkExternal02 className='ml-1 w-4 h-4' />
+ </a>
</Button>
- )}
- {collection.type === CollectionType.workflow && !isDetailLoading && customCollection && (
- <>
- <Button
- variant='primary'
- className={cn('my-3 w-[183px] shrink-0')}
- >
- <Link className='flex items-center' href={`/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'>
- <div className='system-sm-medium'>{t('tools.openInStudio')}</div>
- <LinkExternal02 className='ml-1 h-4 w-4' />
- </Link>
- </Button>
- <Button
- className={cn('my-3 w-[183px] shrink-0')}
- onClick={() => setIsShowEditWorkflowToolModal(true)}
- disabled={!isCurrentWorkspaceManager}
- >
- <div className='system-sm-medium text-text-secondary'>{t('tools.createTool.editAction')}</div>
- </Button>
- </>
- )}
- </div>
- <div className='flex min-h-0 flex-1 flex-col pt-3'>
- {isDetailLoading && <div className='flex h-[200px]'><Loading type='app' /></div>}
- {!isDetailLoading && (
- <>
- <div className="shrink-0">
- {(collection.type === CollectionType.builtIn || collection.type === CollectionType.model) && isAuthed && (
- <div className='system-sm-semibold-uppercase mb-1 flex h-6 items-center justify-between text-text-secondary'>
- {t('plugin.detailPanel.actionNum', { num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' })}
- {needAuth && (
- <Button
- variant='secondary'
- size='small'
- onClick={() => {
- if (collection.type === CollectionType.builtIn || collection.type === CollectionType.model)
- showSettingAuthModal()
- }}
- disabled={!isCurrentWorkspaceManager}
- >
- <Indicator className='mr-2' color={'green'} />
- {t('tools.auth.authorized')}
- </Button>
- )}
- </div>
- )}
- {(collection.type === CollectionType.builtIn || collection.type === CollectionType.model) && needAuth && !isAuthed && (
- <>
- <div className='system-sm-semibold-uppercase text-text-secondary'>
- <span className=''>{t('tools.includeToolNum', { num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' }).toLocaleUpperCase()}</span>
- <span className='px-1'>路</span>
- <span className='text-util-colors-orange-orange-600'>{t('tools.auth.setup').toLocaleUpperCase()}</span>
- </div>
- <Button
- variant='primary'
- className={cn('my-3 w-full shrink-0')}
- onClick={() => {
- if (collection.type === CollectionType.builtIn || collection.type === CollectionType.model)
- showSettingAuthModal()
- }}
- disabled={!isCurrentWorkspaceManager}
- >
- {t('tools.auth.unauthorized')}
- </Button>
- </>
- )}
- {(collection.type === CollectionType.custom) && (
- <div className='system-sm-semibold-uppercase text-text-secondary'>
- <span className=''>{t('tools.includeToolNum', { num: toolList.length, action: toolList.length > 1 ? 'actions' : 'action' }).toLocaleUpperCase()}</span>
- </div>
- )}
- {(collection.type === CollectionType.workflow) && (
- <div className='system-sm-semibold-uppercase text-text-secondary'>
- <span className=''>{t('tools.createTool.toolInput.title').toLocaleUpperCase()}</span>
- </div>
- )}
- </div>
- <div className='mt-1 flex-1 overflow-y-auto py-2'>
- {collection.type !== CollectionType.workflow && toolList.map(tool => (
- <ToolItem
- key={tool.name}
- disabled={false}
- collection={collection}
- tool={tool}
- isBuiltIn={isBuiltIn}
- isModel={isModel}
- />
- ))}
- {collection.type === CollectionType.workflow && (customCollection as WorkflowToolProviderResponse)?.tool?.parameters.map(item => (
- <div key={item.name} className='mb-1 py-1'>
- <div className='mb-1 flex items-center gap-2'>
- <span className='code-sm-semibold text-text-secondary'>{item.name}</span>
- <span className='system-xs-regular text-text-tertiary'>{item.type}</span>
- <span className='system-xs-medium text-text-warning-secondary'>{item.required ? t('tools.createTool.toolInput.required') : ''}</span>
- </div>
- <div className='system-xs-regular text-text-tertiary'>{item.llm_description}</div>
- </div>
- ))}
- </div>
- </>
- )}
- </div>
- {showSettingAuth && (
- <ConfigCredential
- collection={collection}
- onCancel={() => setShowSettingAuth(false)}
- onSaved={async (value) => {
- await updateBuiltInToolCredential(collection.name, value)
- Toast.notify({
- type: 'success',
- message: t('common.api.actionSuccess'),
- })
- await onRefreshData()
- setShowSettingAuth(false)
- }}
- onRemove={async () => {
- await removeBuiltInToolCredential(collection.name)
- Toast.notify({
- type: 'success',
- message: t('common.api.actionSuccess'),
- })
- await onRefreshData()
- setShowSettingAuth(false)
- }}
- />
- )}
- {isShowEditCollectionToolModal && (
- <EditCustomToolModal
- payload={customCollection}
- onHide={() => setIsShowEditCustomCollectionModal(false)}
- onEdit={doUpdateCustomToolCollection}
- onRemove={onClickCustomToolDelete}
- />
- )}
- {isShowEditWorkflowToolModal && (
- <WorkflowToolModal
- payload={customCollection}
- onHide={() => setIsShowEditWorkflowToolModal(false)}
- onRemove={onClickWorkflowToolDelete}
- onSave={updateWorkflowToolProvider}
- />
- )}
- {showConfirmDelete && (
- <Confirm
- title={t('tools.createTool.deleteToolConfirmTitle')}
- content={t('tools.createTool.deleteToolConfirmContent')}
- isShow={showConfirmDelete}
- onConfirm={handleConfirmDelete}
- onCancel={() => setShowConfirmDelete(false)}
- />
+ <Button
+ className={cn('shrink-0 my-3 w-[183px]')}
+ onClick={() => setIsShowEditWorkflowToolModal(true)}
+ disabled={!isCurrentWorkspaceManager}
+ >
+ <div className='leading-5 text-sm font-medium text-gray-700'>{t('tools.createTool.editAction')}</div>
+ </Button>
+ </>
)}
</div>
- </Drawer>
+ {/* Tools */}
+ <div className='pt-3'>
+ {isDetailLoading && <div className='flex h-[200px]'><Loading type='app' /></div>}
+ {!isDetailLoading && (
+ <div className='text-xs font-medium leading-6 text-gray-500'>
+ {collection.type === CollectionType.workflow && <span className=''>{t('tools.createTool.toolInput.title').toLocaleUpperCase()}</span>}
+ {collection.type !== CollectionType.workflow && <span className=''>{t('tools.includeToolNum', { num: toolList.length }).toLocaleUpperCase()}</span>}
+ {needAuth && (isBuiltIn || isModel) && !isAuthed && (
+ <>
+ <span className='px-1'>路</span>
+ <span className='text-[#DC6803]'>{t('tools.auth.setup').toLocaleUpperCase()}</span>
+ </>
+ )}
+ </div>
+ )}
+ {!isDetailLoading && (
+ <div className='mt-1'>
+ {collection.type !== CollectionType.workflow && toolList.map(tool => (
+ <ToolItem
+ key={tool.name}
+ disabled={needAuth && (isBuiltIn || isModel) && !isAuthed}
+ collection={collection}
+ tool={tool}
+ isBuiltIn={isBuiltIn}
+ isModel={isModel}
+ />
+ ))}
+ {collection.type === CollectionType.workflow && (customCollection as WorkflowToolProviderResponse)?.tool?.parameters.map(item => (
+ <div key={item.name} className='mb-2 px-4 py-3 rounded-xl bg-gray-25 border-[0.5px] border-gray-200'>
+ <div className='flex items-center gap-2'>
+ <span className='font-medium text-sm text-gray-900'>{item.name}</span>
+ <span className='text-xs leading-[18px] text-gray-500'>{item.type}</span>
+ <span className='font-medium text-xs leading-[18px] text-[#ec4a0a]'>{item.required ? t('tools.createTool.toolInput.required') : ''}</span>
+ </div>
+ <div className='h-[18px] leading-[18px] text-gray-500 text-xs'>{item.llm_description}</div>
+ </div>
+ ))}
+ </div>
+ )}
+ </div>
+ {showSettingAuth && (
+ <ConfigCredential
+ collection={collection}
+ onCancel={() => setShowSettingAuth(false)}
+ onSaved={async (value) => {
+ await updateBuiltInToolCredential(collection.name, value)
+ Toast.notify({
+ type: 'success',
+ message: t('common.api.actionSuccess'),
+ })
+ await onRefreshData()
+ setShowSettingAuth(false)
+ }}
+ onRemove={async () => {
+ await removeBuiltInToolCredential(collection.name)
+ Toast.notify({
+ type: 'success',
+ message: t('common.api.actionSuccess'),
+ })
+ await onRefreshData()
+ setShowSettingAuth(false)
+ }}
+ />
+ )}
+ {isShowEditCollectionToolModal && (
+ <EditCustomToolModal
+ payload={customCollection}
+ onHide={() => setIsShowEditCustomCollectionModal(false)}
+ onEdit={doUpdateCustomToolCollection}
+ onRemove={onClickCustomToolDelete}
+ />
+ )}
+ {isShowEditWorkflowToolModal && (
+ <WorkflowToolModal
+ payload={customCollection}
+ onHide={() => setIsShowEditWorkflowToolModal(false)}
+ onRemove={onClickWorkflowToolDelete}
+ onSave={updateWorkflowToolProvider}
+ />
+ )}
+ {showConfirmDelete && (
+ <Confirm
+ title={t('tools.createTool.deleteToolConfirmTitle')}
+ content={t('tools.createTool.deleteToolConfirmContent')}
+ isShow={showConfirmDelete}
+ onConfirm={handleConfirmDelete}
+ onCancel={() => setShowConfirmDelete(false)}
+ />
+ )}
+ </div>
)
}
export default ProviderDetail
--
Gitblit v1.8.0