action panel header

This commit is contained in:
JzoNg
2024-10-27 12:11:49 +08:00
parent 35a66ffe9f
commit aba48749da
4 changed files with 95 additions and 81 deletions

View File

@ -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)

View File

@ -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}

View File

@ -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'>

View File

@ -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