mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 01:48:04 +08:00
action panel header
This commit is contained in:
@ -3,21 +3,29 @@ import type { FC } from 'react'
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useContext } from 'use-context-selector'
|
import { useContext } from 'use-context-selector'
|
||||||
import cn from '@/utils/classnames'
|
import {
|
||||||
import Drawer from '@/app/components/base/drawer-plus'
|
RiArrowLeftLine,
|
||||||
|
RiCloseLine,
|
||||||
|
} from '@remixicon/react'
|
||||||
|
import Drawer from '@/app/components/base/drawer'
|
||||||
|
import Loading from '@/app/components/base/loading'
|
||||||
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
|
import Icon from '@/app/components/plugins/card/base/card-icon'
|
||||||
|
import OrgInfo from '@/app/components/plugins/card/base/org-info'
|
||||||
|
import Description from '@/app/components/plugins/card/base/description'
|
||||||
|
import Button from '@/app/components/base/button'
|
||||||
import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
|
import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
|
||||||
import { addDefaultValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
|
import { addDefaultValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
|
||||||
import type { Collection, Tool } from '@/app/components/tools/types'
|
import type { Collection, Tool } from '@/app/components/tools/types'
|
||||||
import { CollectionType } from '@/app/components/tools/types'
|
import { CollectionType } from '@/app/components/tools/types'
|
||||||
import { fetchBuiltInToolList, fetchCustomToolList, fetchModelToolList, fetchWorkflowToolList } from '@/service/tools'
|
import { fetchBuiltInToolList, fetchCustomToolList, fetchModelToolList, fetchWorkflowToolList } from '@/service/tools'
|
||||||
import I18n from '@/context/i18n'
|
import I18n from '@/context/i18n'
|
||||||
import Button from '@/app/components/base/button'
|
|
||||||
import Loading from '@/app/components/base/loading'
|
|
||||||
import { DiagonalDividingLine } from '@/app/components/base/icons/src/public/common'
|
import { DiagonalDividingLine } from '@/app/components/base/icons/src/public/common'
|
||||||
import { getLanguage } from '@/i18n/language'
|
import { getLanguage } from '@/i18n/language'
|
||||||
import AppIcon from '@/app/components/base/app-icon'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
|
showBackButton?: boolean
|
||||||
collection: Collection
|
collection: Collection
|
||||||
isBuiltIn?: boolean
|
isBuiltIn?: boolean
|
||||||
isModel?: boolean
|
isModel?: boolean
|
||||||
@ -29,6 +37,7 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SettingBuiltInTool: FC<Props> = ({
|
const SettingBuiltInTool: FC<Props> = ({
|
||||||
|
showBackButton = false,
|
||||||
collection,
|
collection,
|
||||||
isBuiltIn = true,
|
isBuiltIn = true,
|
||||||
isModel = true,
|
isModel = true,
|
||||||
@ -98,13 +107,6 @@ const SettingBuiltInTool: FC<Props> = ({
|
|||||||
|
|
||||||
const infoUI = (
|
const infoUI = (
|
||||||
<div className='pt-2'>
|
<div className='pt-2'>
|
||||||
<div className='leading-5 text-sm font-medium text-gray-900'>
|
|
||||||
{t('tools.setBuiltInTools.toolDescription')}
|
|
||||||
</div>
|
|
||||||
<div className='mt-1 leading-[18px] text-xs font-normal text-gray-600'>
|
|
||||||
{currTool?.description[language]}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{infoSchemas.length > 0 && (
|
{infoSchemas.length > 0 && (
|
||||||
<div className='my-2'>
|
<div className='my-2'>
|
||||||
<div className='pt-3 text-text-secondary system-sm-semibold-uppercase'>
|
<div className='pt-3 text-text-secondary system-sm-semibold-uppercase'>
|
||||||
@ -148,75 +150,83 @@ const SettingBuiltInTool: FC<Props> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
isShow
|
isOpen
|
||||||
onHide={onHide}
|
clickOutsideNotOpen={false}
|
||||||
title={(
|
onClose={onHide}
|
||||||
<div className='flex items-center'>
|
footer={null}
|
||||||
{typeof collection.icon === 'string'
|
mask={false}
|
||||||
? (
|
positionCenter={false}
|
||||||
<div
|
panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')}
|
||||||
className='w-6 h-6 bg-cover bg-center rounded-md flex-shrink-0'
|
>
|
||||||
style={{
|
<>
|
||||||
backgroundImage: `url(${collection.icon})`,
|
{isLoading && <Loading type='app' />}
|
||||||
}}
|
{!isLoading && (
|
||||||
></div>
|
<>
|
||||||
)
|
{/* header */}
|
||||||
: (
|
<div className='relative p-4 pb-3 border-b border-divider-subtle'>
|
||||||
<AppIcon
|
<div className='absolute top-3 right-3'>
|
||||||
className='rounded-md'
|
<ActionButton onClick={onHide}>
|
||||||
size='tiny'
|
<RiCloseLine className='w-4 h-4' />
|
||||||
icon={(collection.icon as any)?.content}
|
</ActionButton>
|
||||||
background={(collection.icon as any)?.background}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className='ml-2 leading-6 text-base font-semibold text-gray-900'>{currTool?.label[language]}</div>
|
|
||||||
{(hasSetting && !readonly) && (<>
|
|
||||||
<DiagonalDividingLine className='mx-4' />
|
|
||||||
<div className='flex space-x-6'>
|
|
||||||
<div
|
|
||||||
className={cn(isInfoActive ? 'text-gray-900 font-semibold' : 'font-normal text-gray-600 cursor-pointer', 'relative text-base')}
|
|
||||||
onClick={() => setCurrType('info')}
|
|
||||||
>
|
|
||||||
{t('tools.setBuiltInTools.info')}
|
|
||||||
{isInfoActive && <div className='absolute left-0 bottom-[-16px] w-full h-0.5 bg-primary-600'></div>}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={cn(!isInfoActive ? 'text-gray-900 font-semibold' : 'font-normal text-gray-600 cursor-pointer', 'relative text-base ')}
|
{showBackButton && (
|
||||||
onClick={() => setCurrType('setting')}
|
<div
|
||||||
>
|
className='mb-2 flex items-center gap-1 text-text-accent-secondary system-xs-semibold-uppercase cursor-pointer'
|
||||||
{t('tools.setBuiltInTools.setting')}
|
onClick={onHide}
|
||||||
{!isInfoActive && <div className='absolute left-0 bottom-[-16px] w-full h-0.5 bg-primary-600'></div>}
|
>
|
||||||
</div>
|
<RiArrowLeftLine className='w-4 h-4' />
|
||||||
</div>
|
BACK
|
||||||
</>)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
panelClassName='mt-[64px] mb-2 !w-[420px]'
|
|
||||||
maxWidthClassName='!max-w-[420px]'
|
|
||||||
height='calc(100vh - 64px)'
|
|
||||||
headerClassName='!border-b-black/5'
|
|
||||||
body={
|
|
||||||
<div className='h-full pt-3'>
|
|
||||||
{isLoading
|
|
||||||
? <div className='flex h-full items-center'>
|
|
||||||
<Loading type='app' />
|
|
||||||
</div>
|
|
||||||
: (<div className='flex flex-col h-full'>
|
|
||||||
<div className='grow h-0 overflow-y-auto px-4'>
|
|
||||||
{isInfoActive ? infoUI : settingUI}
|
|
||||||
</div>
|
|
||||||
{!readonly && !isInfoActive && (
|
|
||||||
<div className='mt-2 shrink-0 flex justify-end py-4 px-6 space-x-2 rounded-b-[10px] bg-gray-50 border-t border-black/5'>
|
|
||||||
<Button className='flex items-center h-8 !px-3 !text-[13px] font-medium !text-gray-700' onClick={onHide}>{t('common.operation.cancel')}</Button>
|
|
||||||
<Button className='flex items-center h-8 !px-3 !text-[13px] font-medium' variant='primary' disabled={!isValid} onClick={() => onSave?.(addDefaultValue(tempSetting, formSchemas))}>{t('common.operation.save')}</Button>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>)}
|
<div className='flex items-center gap-1'>
|
||||||
</div>
|
<Icon size='xs' className='w-5 h-5' src={collection.icon} />
|
||||||
}
|
<OrgInfo
|
||||||
isShowMask={false}
|
packageNameClassName='w-auto'
|
||||||
clickOutsideNotOpen={false}
|
orgName={collection.author}
|
||||||
/>
|
packageName={collection.name}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='mt-1 text-text-primary system-md-semibold'>{currTool?.label[language]}</div>
|
||||||
|
{!!currTool?.description[language] && (
|
||||||
|
<Description className='mt-3' text={currTool.description[language]} descriptionLineRows={2}></Description>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/* form */}
|
||||||
|
<div className='h-full'>
|
||||||
|
<div className='flex flex-col h-full'>
|
||||||
|
<div className='grow h-0 overflow-y-auto px-4'>
|
||||||
|
{(hasSetting && !readonly) && (<>
|
||||||
|
<DiagonalDividingLine className='mx-4' />
|
||||||
|
<div className='flex space-x-6'>
|
||||||
|
<div
|
||||||
|
className={cn(isInfoActive ? 'text-gray-900 font-semibold' : 'font-normal text-gray-600 cursor-pointer', 'relative text-base')}
|
||||||
|
onClick={() => setCurrType('info')}
|
||||||
|
>
|
||||||
|
{t('tools.setBuiltInTools.parameters')}
|
||||||
|
{isInfoActive && <div className='absolute left-0 bottom-[-16px] w-full h-0.5 bg-primary-600'></div>}
|
||||||
|
</div>
|
||||||
|
<div className={cn(!isInfoActive ? 'text-gray-900 font-semibold' : 'font-normal text-gray-600 cursor-pointer', 'relative text-base ')}
|
||||||
|
onClick={() => setCurrType('setting')}
|
||||||
|
>
|
||||||
|
{t('tools.setBuiltInTools.setting')}
|
||||||
|
{!isInfoActive && <div className='absolute left-0 bottom-[-16px] w-full h-0.5 bg-primary-600'></div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>)}
|
||||||
|
{isInfoActive ? infoUI : settingUI}
|
||||||
|
</div>
|
||||||
|
{!readonly && !isInfoActive && (
|
||||||
|
<div className='mt-2 shrink-0 flex justify-end py-4 px-6 space-x-2 rounded-b-[10px] bg-gray-50 border-t border-black/5'>
|
||||||
|
<Button className='flex items-center h-8 !px-3 !text-[13px] font-medium !text-gray-700' onClick={onHide}>{t('common.operation.cancel')}</Button>
|
||||||
|
<Button className='flex items-center h-8 !px-3 !text-[13px] font-medium' variant='primary' disabled={!isValid} onClick={() => onSave?.(addDefaultValue(tempSetting, formSchemas))}>{t('common.operation.save')}</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</Drawer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default React.memo(SettingBuiltInTool)
|
export default React.memo(SettingBuiltInTool)
|
||||||
|
|||||||
@ -7,6 +7,7 @@ const Icon = ({
|
|||||||
src,
|
src,
|
||||||
installed = false,
|
installed = false,
|
||||||
installFailed = false,
|
installFailed = false,
|
||||||
|
size,
|
||||||
}: {
|
}: {
|
||||||
className?: string
|
className?: string
|
||||||
src: string | {
|
src: string | {
|
||||||
@ -15,13 +16,14 @@ const Icon = ({
|
|||||||
}
|
}
|
||||||
installed?: boolean
|
installed?: boolean
|
||||||
installFailed?: boolean
|
installFailed?: boolean
|
||||||
|
size?: 'xs' | 'tiny' | 'small' | 'medium' | 'large'
|
||||||
}) => {
|
}) => {
|
||||||
const iconClassName = 'flex justify-center items-center gap-2 absolute bottom-[-4px] right-[-4px] w-[18px] h-[18px] rounded-full border-2 border-components-panel-bg'
|
const iconClassName = 'flex justify-center items-center gap-2 absolute bottom-[-4px] right-[-4px] w-[18px] h-[18px] rounded-full border-2 border-components-panel-bg'
|
||||||
if (typeof src === 'object') {
|
if (typeof src === 'object') {
|
||||||
return (
|
return (
|
||||||
<div className={cn('relative', className)}>
|
<div className={cn('relative', className)}>
|
||||||
<AppIcon
|
<AppIcon
|
||||||
size='large'
|
size={size || 'large'}
|
||||||
iconType={'emoji'}
|
iconType={'emoji'}
|
||||||
icon={src.content}
|
icon={src.content}
|
||||||
background={src.background}
|
background={src.background}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ const ActionCard = () => {
|
|||||||
|
|
||||||
const ActionList = () => {
|
const ActionList = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
// TODO use tool-item add api in tool providers
|
||||||
return (
|
return (
|
||||||
<div className='px-4 pt-2 pb-4'>
|
<div className='px-4 pt-2 pb-4'>
|
||||||
<div className='mb-1 py-1'>
|
<div className='mb-1 py-1'>
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import I18n from '@/context/i18n'
|
|||||||
import { getLanguage } from '@/i18n/language'
|
import { getLanguage } from '@/i18n/language'
|
||||||
import SettingBuiltInTool from '@/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool'
|
import SettingBuiltInTool from '@/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool'
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
collection: Collection
|
collection: Collection
|
||||||
tool: Tool
|
tool: Tool
|
||||||
@ -37,6 +37,7 @@ const ToolItem = ({
|
|||||||
</div>
|
</div>
|
||||||
{showDetail && (
|
{showDetail && (
|
||||||
<SettingBuiltInTool
|
<SettingBuiltInTool
|
||||||
|
showBackButton
|
||||||
collection={collection}
|
collection={collection}
|
||||||
toolName={tool.name}
|
toolName={tool.name}
|
||||||
readonly
|
readonly
|
||||||
|
|||||||
Reference in New Issue
Block a user