mirror of https://github.com/langgenius/dify.git
dark mode for tools
This commit is contained in:
parent
a0e999e438
commit
5c98f1a5aa
|
|
@ -58,15 +58,15 @@ const DrawerPlus: FC<Props> = ({
|
|||
panelClassname={cn('mt-16 mx-2 sm:mr-2 mb-3 !p-0 rounded-xl', panelClassName, maxWidthClassName)}
|
||||
>
|
||||
<div
|
||||
className={cn(contentClassName, 'w-full flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl')}
|
||||
className={cn(contentClassName, 'w-full flex flex-col bg-components-panel-bg border-[0.5px] border-divider-subtle rounded-xl shadow-xl')}
|
||||
style={{
|
||||
height,
|
||||
}}
|
||||
ref={ref}
|
||||
>
|
||||
<div className={cn(headerClassName, 'shrink-0 border-b border-b-gray-100 py-4')}>
|
||||
<div className={cn(headerClassName, 'shrink-0 border-b border-divider-subtle py-4')}>
|
||||
<div className='flex justify-between items-center pl-6 pr-5 h-6'>
|
||||
<div className='text-base font-semibold text-gray-900'>
|
||||
<div className='system-xl-semibold text-text-primary'>
|
||||
{title}
|
||||
</div>
|
||||
<div className='flex items-center'>
|
||||
|
|
@ -74,12 +74,12 @@ const DrawerPlus: FC<Props> = ({
|
|||
onClick={onHide}
|
||||
className='flex justify-center items-center w-6 h-6 cursor-pointer'
|
||||
>
|
||||
<RiCloseLine className='w-4 h-4 text-gray-500' />
|
||||
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{titleDescription && (
|
||||
<div className='pl-6 pr-10 leading-[18px] text-xs font-normal text-gray-500'>
|
||||
<div className='pl-6 pr-10 system-xs-regular text-text-tertiary'>
|
||||
{titleDescription}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -49,18 +49,18 @@ export default function Drawer({
|
|||
<Dialog.Overlay
|
||||
className={cn('z-40 fixed inset-0', mask && 'bg-black bg-opacity-30')}
|
||||
/>
|
||||
<div className={cn('relative z-50 flex flex-col justify-between bg-white w-full max-w-sm p-6 overflow-hidden text-left align-middle shadow-xl', panelClassname)}>
|
||||
<div className={cn('relative z-50 flex flex-col justify-between bg-components-panel-bg w-full max-w-sm p-6 overflow-hidden text-left align-middle shadow-xl', panelClassname)}>
|
||||
<>
|
||||
{title && <Dialog.Title
|
||||
as="h3"
|
||||
className="text-lg font-medium leading-6 text-gray-900"
|
||||
className="text-lg font-medium leading-6 text-text-primary"
|
||||
>
|
||||
{title}
|
||||
</Dialog.Title>}
|
||||
{showClose && <Dialog.Title className="flex items-center mb-4" as="div">
|
||||
<XMarkIcon className='w-4 h-4 text-gray-500' onClick={onClose} />
|
||||
<XMarkIcon className='w-4 h-4 text-text-tertiary' onClick={onClose} />
|
||||
</Dialog.Title>}
|
||||
{description && <Dialog.Description className='text-gray-500 text-xs font-normal mt-2'>{description}</Dialog.Description>}
|
||||
{description && <Dialog.Description className='text-text-tertiary text-xs font-normal mt-2'>{description}</Dialog.Description>}
|
||||
{children}
|
||||
</>
|
||||
{footer || (footer === null
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ import { init } from 'emoji-mart'
|
|||
import {
|
||||
MagnifyingGlassIcon,
|
||||
} from '@heroicons/react/24/outline'
|
||||
import cn from '@/utils/classnames'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import { searchEmoji } from '@/utils/emoji'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line ts/no-namespace
|
||||
|
|
@ -72,12 +73,12 @@ const EmojiPickerInner: FC<IEmojiPickerInnerProps> = ({
|
|||
<div className='flex flex-col items-center w-full px-3'>
|
||||
<div className="relative w-full">
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<MagnifyingGlassIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
|
||||
<MagnifyingGlassIcon className="w-5 h-5 text-text-quaternary" aria-hidden="true" />
|
||||
</div>
|
||||
<input
|
||||
<Input
|
||||
className="pl-10"
|
||||
type="search"
|
||||
id="search"
|
||||
className='block w-full h-10 px-3 pl-10 text-sm font-normal bg-gray-100 rounded-lg'
|
||||
placeholder="Search emojis..."
|
||||
onChange={async (e: ChangeEvent<HTMLInputElement>) => {
|
||||
if (e.target.value === '') {
|
||||
|
|
@ -92,12 +93,12 @@ const EmojiPickerInner: FC<IEmojiPickerInnerProps> = ({
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Divider className='m-0 mb-3' />
|
||||
<Divider className='my-3' />
|
||||
|
||||
<div className="w-full max-h-[200px] overflow-x-hidden overflow-y-auto px-3">
|
||||
{isSearching && <>
|
||||
<div key={'category-search'} className='flex flex-col'>
|
||||
<p className='font-medium uppercase text-xs text-[#101828] mb-1'>Search</p>
|
||||
<p className='system-xs-medium-uppercase text-text-primary mb-1'>Search</p>
|
||||
<div className='w-full h-full grid grid-cols-8 gap-1'>
|
||||
{searchedEmojis.map((emoji: string, index: number) => {
|
||||
return <div
|
||||
|
|
@ -107,7 +108,7 @@ const EmojiPickerInner: FC<IEmojiPickerInnerProps> = ({
|
|||
setSelectedEmoji(emoji)
|
||||
}}
|
||||
>
|
||||
<div className='cursor-pointer w-8 h-8 p-1 flex items-center justify-center rounded-lg hover:ring-1 ring-offset-1 ring-gray-300'>
|
||||
<div className='cursor-pointer w-8 h-8 p-1 flex items-center justify-center rounded-lg hover:ring-1 ring-offset-1 ring-components-input-border-hover'>
|
||||
<em-emoji id={emoji} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -118,7 +119,7 @@ const EmojiPickerInner: FC<IEmojiPickerInnerProps> = ({
|
|||
|
||||
{categories.map((category, index: number) => {
|
||||
return <div key={`category-${index}`} className='flex flex-col'>
|
||||
<p className='font-medium uppercase text-xs text-[#101828] mb-1'>{category.id}</p>
|
||||
<p className='system-xs-medium-uppercase text-text-primary mb-1'>{category.id}</p>
|
||||
<div className='w-full h-full grid grid-cols-8 gap-1'>
|
||||
{category.emojis.map((emoji, index: number) => {
|
||||
return <div
|
||||
|
|
@ -128,7 +129,7 @@ const EmojiPickerInner: FC<IEmojiPickerInnerProps> = ({
|
|||
setSelectedEmoji(emoji)
|
||||
}}
|
||||
>
|
||||
<div className='cursor-pointer w-8 h-8 p-1 flex items-center justify-center rounded-lg hover:ring-1 ring-offset-1 ring-gray-300'>
|
||||
<div className='cursor-pointer w-8 h-8 p-1 flex items-center justify-center rounded-lg hover:ring-1 ring-offset-1 ring-components-input-border-hover'>
|
||||
<em-emoji id={emoji} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -141,7 +142,7 @@ const EmojiPickerInner: FC<IEmojiPickerInnerProps> = ({
|
|||
|
||||
{/* Color Select */}
|
||||
<div className={cn('p-3 pb-0', selectedEmoji === '' ? 'opacity-25' : '')}>
|
||||
<p className='font-medium uppercase text-xs text-[#101828] mb-2'>Choose Style</p>
|
||||
<p className='system-xs-medium-uppercase text-text-primary mb-2'>Choose Style</p>
|
||||
<div className='w-full h-full grid grid-cols-8 gap-1'>
|
||||
{backgroundColors.map((color) => {
|
||||
return <div
|
||||
|
|
@ -151,7 +152,7 @@ const EmojiPickerInner: FC<IEmojiPickerInnerProps> = ({
|
|||
'cursor-pointer',
|
||||
'hover:ring-1 ring-offset-1',
|
||||
'inline-flex w-10 h-10 rounded-lg items-center justify-center',
|
||||
color === selectedBackground ? 'ring-1 ring-gray-300' : '',
|
||||
color === selectedBackground ? 'ring-1 ring-components-input-border-hover' : '',
|
||||
)}
|
||||
onClick={() => {
|
||||
setSelectedBackground(color)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
import type { FC } from 'react'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import s from './style.module.css'
|
||||
import EmojiPickerInner from './Inner'
|
||||
import cn from '@/utils/classnames'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
|
|
@ -37,12 +36,12 @@ const EmojiPicker: FC<IEmojiPickerProps> = ({
|
|||
isShow
|
||||
closable={false}
|
||||
wrapperClassName={className}
|
||||
className={cn(s.container, '!w-[362px] !p-0')}
|
||||
className={cn('flex flex-col max-h-[552px] border-[0.5px] border-divider-subtle rounded-xl shadow-xl p-0')}
|
||||
>
|
||||
<EmojiPickerInner
|
||||
className="pt-3"
|
||||
onSelect={handleSelectEmoji} />
|
||||
<Divider className='m-0' />
|
||||
<Divider className='mb-0 mt-3' />
|
||||
<div className='w-full flex items-center justify-center p-3 gap-2'>
|
||||
<Button className='w-full' onClick={() => {
|
||||
onClose && onClose()
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 362px;
|
||||
max-height: 552px;
|
||||
|
||||
border: 0.5px solid #EAECF0;
|
||||
box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
|
|
@ -3,5 +3,5 @@
|
|||
}
|
||||
|
||||
.modal-panel {
|
||||
@apply w-full max-w-[480px] transform rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all;
|
||||
@apply w-full max-w-[480px] transform rounded-2xl bg-components-panel-bg p-6 text-left align-middle shadow-xl transition-all;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,22 +60,22 @@ export default function Modal({
|
|||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className={classNames(
|
||||
'modal-panel',
|
||||
'w-full max-w-[480px] transform rounded-2xl bg-components-panel-bg p-6 text-left align-middle shadow-xl transition-all',
|
||||
overflowVisible ? 'overflow-visible' : 'overflow-hidden',
|
||||
className,
|
||||
)}>
|
||||
{title && <Dialog.Title
|
||||
as="h3"
|
||||
className="text-lg font-medium leading-6 text-gray-900"
|
||||
className="text-lg font-medium leading-6 text-text-primary"
|
||||
>
|
||||
{title}
|
||||
</Dialog.Title>}
|
||||
{description && <Dialog.Description className='text-gray-500 text-xs font-normal mt-2'>
|
||||
{description && <Dialog.Description className='text-text-tertiary text-xs font-normal mt-2'>
|
||||
{description}
|
||||
</Dialog.Description>}
|
||||
{closable
|
||||
&& <div className='absolute z-10 top-6 right-6 w-5 h-5 rounded-2xl flex items-center justify-center hover:cursor-pointer hover:bg-gray-100'>
|
||||
<XMarkIcon className='w-4 h-4 text-gray-500' onClick={
|
||||
&& <div className='absolute z-10 top-6 right-6 w-5 h-5 rounded-2xl flex items-center justify-center hover:cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover'>
|
||||
<XMarkIcon className='w-4 h-4 text-text-tertiary' onClick={
|
||||
(e) => {
|
||||
e.stopPropagation()
|
||||
onClose()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const RadioUI: FC<Props> = ({
|
|||
isChecked,
|
||||
}) => {
|
||||
return (
|
||||
<div className={cn(isChecked ? 'border-[5px] border-[#155eef]' : 'border-[2px] border-gray-200', 'w-4 h-4 rounded-full')}>
|
||||
<div className={cn(isChecked ? 'border-[5px] border-components-radio-border-checked' : 'border-[2px] border-components-radio-border', 'w-4 h-4 rounded-full')}>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ const TabSliderNew: FC<TabSliderProps> = ({
|
|||
key={option.value}
|
||||
onClick={() => onChange(option.value)}
|
||||
className={cn(
|
||||
'mr-1 px-3 py-[7px] h-[32px] flex items-center rounded-lg border-[0.5px] border-transparent text-gray-700 text-[13px] font-medium leading-[18px] cursor-pointer hover:bg-gray-200',
|
||||
value === option.value && 'bg-white border-gray-200 shadow-xs text-primary-600 hover:bg-white',
|
||||
'mr-1 px-3 py-[7px] h-[32px] flex items-center rounded-lg border-[0.5px] border-transparent text-text-tertiary text-[13px] font-medium leading-[18px] cursor-pointer hover:bg-components-main-nav-nav-button-bg-active',
|
||||
value === option.value && 'bg-components-main-nav-nav-button-bg-active border-components-main-nav-nav-button-border shadow-xs text-components-main-nav-nav-button-text-active',
|
||||
)}
|
||||
>
|
||||
{option.icon}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const Tooltip: FC<TooltipProps> = ({
|
|||
>
|
||||
{popupContent && (<div
|
||||
className={cn(
|
||||
'relative px-3 py-2 text-xs font-normal text-gray-700 bg-white rounded-md shadow-lg break-words',
|
||||
'relative px-3 py-2 system-xs-regular text-text-secondary bg-components-panel-bg rounded-md shadow-lg break-words',
|
||||
popupClassName,
|
||||
)}
|
||||
onMouseEnter={() => triggerMethod === 'hover' && setHoverPopup()}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const ModelBadge: FC<ModelBadgeProps> = ({
|
|||
}) => {
|
||||
return (
|
||||
<div className={classNames(
|
||||
'flex items-center px-1 h-[18px] rounded-[5px] border border-black/8 bg-white/[0.48] text-[10px] font-medium text-gray-500 cursor-default',
|
||||
'flex items-center px-1 h-[18px] rounded-[5px] border border-divider-deep system-2xs-medium-uppercase text-text-tertiary cursor-default',
|
||||
className,
|
||||
)}>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import type {
|
|||
import { useLanguage } from '../hooks'
|
||||
import { CubeOutline } from '@/app/components/base/icons/src/vender/line/shapes'
|
||||
import { OpenaiViolet } from '@/app/components/base/icons/src/public/llm'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type ModelIconProps = {
|
||||
provider?: Model | ModelProvider
|
||||
|
|
@ -20,7 +21,7 @@ const ModelIcon: FC<ModelIconProps> = ({
|
|||
const language = useLanguage()
|
||||
|
||||
if (provider?.provider.includes('openai') && (modelName?.startsWith('gpt-4') || modelName?.includes('4o')))
|
||||
return <OpenaiViolet className={`w-4 h-4 ${className}`}/>
|
||||
return <OpenaiViolet className={cn('w-4 h-4', className)}/>
|
||||
|
||||
if (provider?.icon_small) {
|
||||
return (
|
||||
|
|
@ -28,17 +29,17 @@ const ModelIcon: FC<ModelIconProps> = ({
|
|||
<img
|
||||
alt='model-icon'
|
||||
src={`${provider.icon_small[language] || provider.icon_small.en_US}`}
|
||||
className={`w-4 h-4 ${className}`}
|
||||
className={cn('w-4 h-4', className)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`
|
||||
flex items-center justify-center w-6 h-6 rounded border-[0.5px] border-black/5 bg-gray-50
|
||||
${className}
|
||||
`}>
|
||||
<CubeOutline className='w-4 h-4 text-gray-400' />
|
||||
<div className={cn(
|
||||
'flex items-center justify-center w-6 h-6 rounded border-[0.5px] border-black/5 bg-gray-50',
|
||||
className,
|
||||
)}>
|
||||
<CubeOutline className='w-4 h-4 text-text-quaternary' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { useLanguage } from '../hooks'
|
|||
import type { ModelItem } from '../declarations'
|
||||
import ModelBadge from '../model-badge'
|
||||
import FeatureIcon from '../model-selector/feature-icon'
|
||||
import classNames from '@/utils/classnames'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type ModelNameProps = PropsWithChildren<{
|
||||
modelItem: ModelItem
|
||||
|
|
@ -37,12 +37,7 @@ const ModelName: FC<ModelNameProps> = ({
|
|||
if (!modelItem)
|
||||
return null
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
flex items-center truncate text-[13px] font-medium text-gray-800
|
||||
${className}
|
||||
`}
|
||||
>
|
||||
<div className={cn('flex items-center truncate text-components-input-text-filled system-sm-regular', className)}>
|
||||
<div
|
||||
className='truncate'
|
||||
title={modelItem.label[language] || modelItem.label.en_US}
|
||||
|
|
@ -51,14 +46,14 @@ const ModelName: FC<ModelNameProps> = ({
|
|||
</div>
|
||||
{
|
||||
showModelType && modelItem.model_type && (
|
||||
<ModelBadge className={classNames('ml-1', modelTypeClassName)}>
|
||||
<ModelBadge className={cn('ml-1', modelTypeClassName)}>
|
||||
{modelTypeFormat(modelItem.model_type)}
|
||||
</ModelBadge>
|
||||
)
|
||||
}
|
||||
{
|
||||
modelItem.model_properties.mode && showMode && (
|
||||
<ModelBadge className={classNames('ml-1', modeClassName)}>
|
||||
<ModelBadge className={cn('ml-1', modeClassName)}>
|
||||
{(modelItem.model_properties.mode as string).toLocaleUpperCase()}
|
||||
</ModelBadge>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const HeaderWrapper = ({
|
|||
<div className={classNames(
|
||||
'sticky top-0 left-0 right-0 z-30 flex flex-col grow-0 shrink-0 basis-auto min-h-[56px]',
|
||||
s.header,
|
||||
isBordered ? 'border-b border-gray-200' : '',
|
||||
isBordered ? 'border-b border-divider-regular' : '',
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@ const ToolsNav = ({
|
|||
|
||||
return (
|
||||
<Link href="/tools" className={classNames(
|
||||
className, 'group',
|
||||
activated && 'bg-white shadow-md',
|
||||
activated ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200',
|
||||
'group text-sm font-medium',
|
||||
activated && 'font-semibold bg-components-main-nav-nav-button-bg-active hover:bg-components-main-nav-nav-button-bg-active-hover shadow-md',
|
||||
activated ? 'text-components-main-nav-nav-button-text-active' : 'text-components-main-nav-nav-button-text hover:bg-components-main-nav-nav-button-bg-hover',
|
||||
className,
|
||||
)}>
|
||||
{
|
||||
activated
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ const Empty = () => {
|
|||
return (
|
||||
<div className='flex flex-col items-center'>
|
||||
<div className="shrink-0 w-[163px] h-[149px] bg-cover bg-no-repeat bg-[url('~@/app/components/tools/add-tool-modal/empty.png')]"></div>
|
||||
<div className='mb-1 text-[13px] font-medium text-gray-700 leading-[18px]'>{t('tools.addToolModal.emptyTitle')}</div>
|
||||
<div className='text-[13px] text-gray-500 leading-[18px]'>{t('tools.addToolModal.emptyTip')}</div>
|
||||
<div className='mb-1 text-[13px] font-medium text-text-secondary leading-[18px]'>{t('tools.addToolModal.emptyTitle')}</div>
|
||||
<div className='text-[13px] text-text-tertiary leading-[18px]'>{t('tools.addToolModal.emptyTip')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import cn from '@/utils/classnames'
|
||||
import type { Credential } from '@/app/components/tools/types'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Drawer from '@/app/components/base/drawer-plus'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Radio from '@/app/components/base/radio/ui'
|
||||
|
|
@ -16,7 +17,6 @@ type Props = {
|
|||
onChange: (credential: Credential) => void
|
||||
onHide: () => void
|
||||
}
|
||||
const keyClassNames = 'py-2 leading-5 text-sm font-medium text-gray-900'
|
||||
|
||||
type ItemProps = {
|
||||
text: string
|
||||
|
|
@ -28,11 +28,11 @@ type ItemProps = {
|
|||
const SelectItem: FC<ItemProps> = ({ text, value, isChecked, onClick }) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(isChecked ? 'border-[2px] border-indigo-600 shadow-sm bg-white' : 'border border-gray-100', 'mb-2 flex items-center h-9 pl-3 w-[150px] rounded-xl bg-gray-25 hover:bg-gray-50 cursor-pointer space-x-2')}
|
||||
className={cn(isChecked ? 'border-[2px] border-util-colors-indigo-indigo-600 shadow-sm bg-components-panel-on-panel-item-bg' : 'border border-components-card-border', 'mb-2 flex items-center h-9 pl-3 w-[150px] rounded-xl bg-components-panel-on-panel-item-bg hover:bg-components-panel-on-panel-item-bg-hover cursor-pointer space-x-2')}
|
||||
onClick={() => onClick(value)}
|
||||
>
|
||||
<Radio isChecked={isChecked} />
|
||||
<div className='text-sm font-normal text-gray-900'>{text}</div>
|
||||
<div className='system-sm-regular text-text-primary'>{text}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -55,12 +55,12 @@ const ConfigCredential: FC<Props> = ({
|
|||
panelClassName='mt-2 !w-[520px] h-fit'
|
||||
maxWidthClassName='!max-w-[520px]'
|
||||
height={'fit-content'}
|
||||
headerClassName='!border-b-black/5'
|
||||
headerClassName='!border-b-divider-regular'
|
||||
body={
|
||||
<div className='pt-2 px-6'>
|
||||
<div className='space-y-4'>
|
||||
<div>
|
||||
<div className={keyClassNames}>{t('tools.createTool.authMethod.type')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.authMethod.type')}</div>
|
||||
<div className='flex space-x-3'>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authMethod.types.none')}
|
||||
|
|
@ -84,52 +84,52 @@ const ConfigCredential: FC<Props> = ({
|
|||
</div>
|
||||
{tempCredential.auth_type === AuthType.apiKey && (
|
||||
<>
|
||||
<div className={keyClassNames}>{t('tools.createTool.authHeaderPrefix.title')}</div>
|
||||
<div className='flex space-x-3'>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.basic')}
|
||||
value={AuthHeaderPrefix.basic}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.basic}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.bearer')}
|
||||
value={AuthHeaderPrefix.bearer}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.bearer}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.custom')}
|
||||
value={AuthHeaderPrefix.custom}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.custom}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
<div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.authHeaderPrefix.title')}</div>
|
||||
<div className='flex space-x-3'>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.basic')}
|
||||
value={AuthHeaderPrefix.basic}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.basic}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.bearer')}
|
||||
value={AuthHeaderPrefix.bearer}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.bearer}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
<SelectItem
|
||||
text={t('tools.createTool.authHeaderPrefix.types.custom')}
|
||||
value={AuthHeaderPrefix.custom}
|
||||
isChecked={tempCredential.api_key_header_prefix === AuthHeaderPrefix.custom}
|
||||
onClick={value => setTempCredential({ ...tempCredential, api_key_header_prefix: value as AuthHeaderPrefix })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className='flex items-center h-8 text-[13px] font-medium text-gray-900'>
|
||||
<div className='flex items-center py-2 system-sm-medium text-text-primary'>
|
||||
{t('tools.createTool.authMethod.key')}
|
||||
<Tooltip
|
||||
popupContent={
|
||||
<div className='w-[261px] text-gray-500'>
|
||||
<div className='w-[261px] text-text-tertiary'>
|
||||
{t('tools.createTool.authMethod.keyTooltip')}
|
||||
</div>
|
||||
}
|
||||
triggerClassName='ml-0.5 w-4 h-4'
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
<Input
|
||||
value={tempCredential.api_key_header}
|
||||
onChange={e => setTempCredential({ ...tempCredential, api_key_header: e.target.value })}
|
||||
className='w-full h-10 px-3 text-sm font-normal border border-transparent bg-gray-100 rounded-lg grow outline-none focus:bg-components-input-bg-active focus:border-components-input-border-active focus:shadow-xs'
|
||||
placeholder={t('tools.createTool.authMethod.types.apiKeyPlaceholder')!}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={keyClassNames}>{t('tools.createTool.authMethod.value')}</div>
|
||||
<input
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.authMethod.value')}</div>
|
||||
<Input
|
||||
value={tempCredential.api_key_value}
|
||||
onChange={e => setTempCredential({ ...tempCredential, api_key_value: e.target.value })}
|
||||
className='w-full h-10 px-3 text-sm font-normal border border-transparent bg-gray-100 rounded-lg grow outline-none focus:bg-components-input-bg-active focus:border-components-input-border-active focus:shadow-xs'
|
||||
placeholder={t('tools.createTool.authMethod.types.apiValuePlaceholder')!}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
import Toast from '../../base/toast'
|
||||
import examples from './examples'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Input from '@/app/components/base/input'
|
||||
import { importSchemaFromURL } from '@/service/tools'
|
||||
|
||||
type Props = {
|
||||
|
|
@ -63,14 +64,14 @@ const GetSchema: FC<Props> = ({
|
|||
onClick={() => { setShowImportFromUrl(!showImportFromUrl) }}
|
||||
>
|
||||
<RiAddLine className='w-3 h-3' />
|
||||
<div className='text-xs font-medium text-gray-700'>{t('tools.createTool.importFromUrl')}</div>
|
||||
<div className='system-xs-medium text-text-secondary'>{t('tools.createTool.importFromUrl')}</div>
|
||||
</Button>
|
||||
{showImportFromUrl && (
|
||||
<div className=' absolute left-[-35px] top-[26px] p-2 rounded-lg border border-gray-200 bg-white shadow-lg'>
|
||||
<div className=' absolute left-[-35px] top-[26px] p-2 rounded-lg border border-components-panel-border bg-components-panel-bg shadow-lg'>
|
||||
<div className='relative'>
|
||||
<input
|
||||
<Input
|
||||
type='text'
|
||||
className='w-[244px] h-8 pl-1.5 pr-[44px] overflow-x-auto border border-gray-200 rounded-lg text-[13px] focus:outline-none focus:border-components-input-border-active'
|
||||
className='w-[244px]'
|
||||
placeholder={t('tools.createTool.importFromUrlPlaceHolder')!}
|
||||
value={importUrl}
|
||||
onChange={e => setImportUrl(e.target.value)}
|
||||
|
|
@ -95,11 +96,11 @@ const GetSchema: FC<Props> = ({
|
|||
className='space-x-1'
|
||||
onClick={() => { setShowExamples(!showExamples) }}
|
||||
>
|
||||
<div className='text-xs font-medium text-gray-700'>{t('tools.createTool.examples')}</div>
|
||||
<div className='system-xs-medium text-text-secondary'>{t('tools.createTool.examples')}</div>
|
||||
<RiArrowDownSLine className='w-3 h-3' />
|
||||
</Button>
|
||||
{showExamples && (
|
||||
<div className='absolute top-7 right-0 p-1 rounded-lg bg-white shadow-sm'>
|
||||
<div className='absolute top-7 right-0 p-1 rounded-lg bg-components-panel-bg shadow-sm'>
|
||||
{examples.map(item => (
|
||||
<div
|
||||
key={item.key}
|
||||
|
|
@ -107,7 +108,7 @@ const GetSchema: FC<Props> = ({
|
|||
onChange(item.content)
|
||||
setShowExamples(false)
|
||||
}}
|
||||
className='px-3 py-1.5 rounded-lg hover:bg-gray-50 leading-5 text-sm font-normal text-gray-700 cursor-pointer whitespace-nowrap'
|
||||
className='px-3 py-1.5 rounded-lg hover:bg-components-panel-on-panel-item-bg-hover leading-5 system-sm-regular text-text-secondary cursor-pointer whitespace-nowrap'
|
||||
>
|
||||
{t(`tools.createTool.exampleOptions.${item.key}`)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ import type { FC } from 'react'
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useDebounce, useGetState } from 'ahooks'
|
||||
import { RiSettings2Line } from '@remixicon/react'
|
||||
import produce from 'immer'
|
||||
import { LinkExternal02, Settings01 } from '../../base/icons/src/vender/line/general'
|
||||
import { LinkExternal02 } from '../../base/icons/src/vender/line/general'
|
||||
import type { Credential, CustomCollectionBackend, CustomParamSchema, Emoji } from '../types'
|
||||
import { AuthHeaderPrefix, AuthType } from '../types'
|
||||
import GetSchema from './get-schema'
|
||||
|
|
@ -21,7 +22,6 @@ import { parseParamsSchema } from '@/service/tools'
|
|||
import LabelSelector from '@/app/components/tools/labels/selector'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
|
||||
const fieldNameClassNames = 'py-2 leading-5 text-sm font-medium text-gray-900'
|
||||
type Props = {
|
||||
positionLeft?: boolean
|
||||
payload: any
|
||||
|
|
@ -189,12 +189,12 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
panelClassName='mt-2 !w-[640px]'
|
||||
maxWidthClassName='!max-w-[640px]'
|
||||
height='calc(100vh - 16px)'
|
||||
headerClassName='!border-b-black/5'
|
||||
headerClassName='!border-b-divider-regular'
|
||||
body={
|
||||
<div className='flex flex-col h-full'>
|
||||
<div className='grow h-0 overflow-y-auto px-6 py-3 space-y-4'>
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='flex items-center justify-between gap-3'>
|
||||
<AppIcon size='large' onClick={() => { setShowEmojiPicker(true) }} className='cursor-pointer' icon={emoji.content} background={emoji.background} />
|
||||
<Input
|
||||
|
|
@ -214,12 +214,12 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
<div className='select-none'>
|
||||
<div className='flex justify-between items-center'>
|
||||
<div className='flex items-center'>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.schema')}<span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='mx-2 w-px h-3 bg-black/5'></div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.schema')}<span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='mx-2 w-px h-3 bg-divider-regular'></div>
|
||||
<a
|
||||
href="https://swagger.io/specification/"
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
className='flex items-center h-[18px] space-x-1 text-[#155EEF]'
|
||||
className='flex items-center h-[18px] space-x-1 text-text-accent'
|
||||
>
|
||||
<div className='text-xs font-normal'>{t('tools.createTool.viewSchemaSpec')}</div>
|
||||
<LinkExternal02 className='w-3 h-3' />
|
||||
|
|
@ -238,11 +238,11 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
|
||||
{/* Available Tools */}
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.availableTools.title')}</div>
|
||||
<div className='rounded-lg border border-gray-200 w-full overflow-x-auto'>
|
||||
<table className='w-full leading-[18px] text-xs text-gray-700 font-normal'>
|
||||
<thead className='text-gray-500 uppercase'>
|
||||
<tr className={cn(paramsSchemas.length > 0 && 'border-b', 'border-gray-200')}>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.availableTools.title')}</div>
|
||||
<div className='rounded-lg border border-divider-regular w-full overflow-x-auto'>
|
||||
<table className='w-full system-xs-regular text-text-secondary'>
|
||||
<thead className='text-text-tertiary uppercase'>
|
||||
<tr className={cn(paramsSchemas.length > 0 && 'border-b', 'border-divider-regular')}>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.availableTools.name')}</th>
|
||||
<th className="p-2 pl-3 font-medium w-[236px]">{t('tools.createTool.availableTools.description')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.availableTools.method')}</th>
|
||||
|
|
@ -252,9 +252,9 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
</thead>
|
||||
<tbody>
|
||||
{paramsSchemas.map((item, index) => (
|
||||
<tr key={index} className='border-b last:border-0 border-gray-200'>
|
||||
<tr key={index} className='border-b last:border-0 border-divider-regular'>
|
||||
<td className="p-2 pl-3">{item.operation_id}</td>
|
||||
<td className="p-2 pl-3 text-gray-500 w-[236px]">{item.summary}</td>
|
||||
<td className="p-2 pl-3 w-[236px]">{item.summary}</td>
|
||||
<td className="p-2 pl-3">{item.method}</td>
|
||||
<td className="p-2 pl-3">{getPath(item.server_url)}</td>
|
||||
<td className="p-2 pl-3 w-[62px]">
|
||||
|
|
@ -277,22 +277,22 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
|
||||
{/* Authorization method */}
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className='flex items-center h-9 justify-between px-2.5 bg-gray-100 rounded-lg cursor-pointer' onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className='text-sm font-normal text-gray-900'>{t(`tools.createTool.authMethod.types.${credential.auth_type}`)}</div>
|
||||
<Settings01 className='w-4 h-4 text-gray-700 opacity-60' />
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className='flex items-center h-9 justify-between px-2.5 bg-components-input-bg-normal rounded-lg cursor-pointer' onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className='system-xs-regular text-text-primary'>{t(`tools.createTool.authMethod.types.${credential.auth_type}`)}</div>
|
||||
<RiSettings2Line className='w-4 h-4 text-text-secondary' />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Labels */}
|
||||
<div>
|
||||
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.toolInput.label')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.toolInput.label')}</div>
|
||||
<LabelSelector value={labels} onChange={handleLabelSelect} />
|
||||
</div>
|
||||
|
||||
{/* Privacy Policy */}
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.privacyPolicy')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.privacyPolicy')}</div>
|
||||
<Input
|
||||
value={customCollection.privacy_policy}
|
||||
onChange={(e) => {
|
||||
|
|
@ -305,7 +305,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.customDisclaimer')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.customDisclaimer')}</div>
|
||||
<Input
|
||||
value={customCollection.custom_disclaimer}
|
||||
onChange={(e) => {
|
||||
|
|
@ -318,10 +318,10 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div className={cn(isEdit ? 'justify-between' : 'justify-end', 'mt-2 shrink-0 flex py-4 px-6 rounded-b-[10px] bg-gray-50 border-t border-black/5')} >
|
||||
<div className={cn(isEdit ? 'justify-between' : 'justify-end', 'mt-2 shrink-0 flex py-4 px-6 rounded-b-[10px] bg-background-section-burn border-t border-divider-regular')} >
|
||||
{
|
||||
isEdit && (
|
||||
<Button onClick={onRemove} className='text-red-500 border-red-50 hover:border-red-500'>{t('common.operation.delete')}</Button>
|
||||
<Button variant='warning' onClick={onRemove}>{t('common.operation.delete')}</Button>
|
||||
)
|
||||
}
|
||||
<div className='flex space-x-2 '>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import Toast from '@/app/components/base/toast'
|
|||
import Modal from '../../base/modal'
|
||||
import Button from '@/app/components/base/button'
|
||||
|
||||
const fieldNameClassNames = 'py-2 leading-5 text-sm font-medium text-gray-900'
|
||||
type Props = {
|
||||
positionLeft?: boolean
|
||||
payload: any
|
||||
|
|
@ -187,12 +186,12 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
className='!p-0 !max-w-[630px] !h-[calc(100vh-16px)]'
|
||||
>
|
||||
<div className='flex flex-col h-full'>
|
||||
<div className='ml-6 mt-6 text-base font-semibold text-gray-900'>
|
||||
<div className='ml-6 mt-6 text-base font-semibold text-text-primary'>
|
||||
{t('tools.createTool.title')}
|
||||
</div>
|
||||
<div className='grow h-0 overflow-y-auto px-6 py-3 space-y-4'>
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='flex items-center justify-between gap-3'>
|
||||
<AppIcon size='large' onClick={() => { setShowEmojiPicker(true) }} className='cursor-pointer' icon={emoji.content} background={emoji.background} />
|
||||
<Input
|
||||
|
|
@ -212,12 +211,12 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
<div className='select-none'>
|
||||
<div className='flex justify-between items-center'>
|
||||
<div className='flex items-center'>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.schema')}<span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='mx-2 w-px h-3 bg-black/5'></div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.schema')}<span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='mx-2 w-px h-3 bg-divider-regular'></div>
|
||||
<a
|
||||
href="https://swagger.io/specification/"
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
className='flex items-center h-[18px] space-x-1 text-[#155EEF]'
|
||||
className='flex items-center h-[18px] space-x-1 text-text-accent'
|
||||
>
|
||||
<div className='text-xs font-normal'>{t('tools.createTool.viewSchemaSpec')}</div>
|
||||
<LinkExternal02 className='w-3 h-3' />
|
||||
|
|
@ -236,11 +235,11 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
|
||||
{/* Available Tools */}
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.availableTools.title')}</div>
|
||||
<div className='rounded-lg border border-gray-200 w-full overflow-x-auto'>
|
||||
<table className='w-full leading-[18px] text-xs text-gray-700 font-normal'>
|
||||
<thead className='text-gray-500 uppercase'>
|
||||
<tr className={cn(paramsSchemas.length > 0 && 'border-b', 'border-gray-200')}>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.availableTools.title')}</div>
|
||||
<div className='rounded-lg border border-divider-regular w-full overflow-x-auto'>
|
||||
<table className='w-full system-xs-regular text-text-secondary'>
|
||||
<thead className='text-text-tertiary uppercase'>
|
||||
<tr className={cn(paramsSchemas.length > 0 && 'border-b', 'border-divider-regular')}>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.availableTools.name')}</th>
|
||||
<th className="p-2 pl-3 font-medium w-[236px]">{t('tools.createTool.availableTools.description')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.availableTools.method')}</th>
|
||||
|
|
@ -250,9 +249,9 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
</thead>
|
||||
<tbody>
|
||||
{paramsSchemas.map((item, index) => (
|
||||
<tr key={index} className='border-b last:border-0 border-gray-200'>
|
||||
<tr key={index} className='border-b last:border-0 border-divider-regular'>
|
||||
<td className="p-2 pl-3">{item.operation_id}</td>
|
||||
<td className="p-2 pl-3 text-gray-500 w-[236px]">{item.summary}</td>
|
||||
<td className="p-2 pl-3 w-[236px]">{item.summary}</td>
|
||||
<td className="p-2 pl-3">{item.method}</td>
|
||||
<td className="p-2 pl-3">{getPath(item.server_url)}</td>
|
||||
<td className="p-2 pl-3 w-[62px]">
|
||||
|
|
@ -275,22 +274,22 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
|
||||
{/* Authorization method */}
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className='flex items-center h-9 justify-between px-2.5 bg-gray-100 rounded-lg cursor-pointer' onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className='text-sm font-normal text-gray-900'>{t(`tools.createTool.authMethod.types.${credential.auth_type}`)}</div>
|
||||
<Settings01 className='w-4 h-4 text-gray-700 opacity-60' />
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className='flex items-center h-9 justify-between px-2.5 bg-components-input-bg-normal rounded-lg cursor-pointer' onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className='system-xs-regular text-text-primary'>{t(`tools.createTool.authMethod.types.${credential.auth_type}`)}</div>
|
||||
<Settings01 className='w-4 h-4 text-text-secondary' />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Labels */}
|
||||
<div>
|
||||
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.toolInput.label')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.toolInput.label')}</div>
|
||||
<LabelSelector value={labels} onChange={handleLabelSelect} />
|
||||
</div>
|
||||
|
||||
{/* Privacy Policy */}
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.privacyPolicy')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.privacyPolicy')}</div>
|
||||
<Input
|
||||
value={customCollection.privacy_policy}
|
||||
onChange={(e) => {
|
||||
|
|
@ -303,7 +302,7 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div className={fieldNameClassNames}>{t('tools.createTool.customDisclaimer')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.customDisclaimer')}</div>
|
||||
<Input
|
||||
value={customCollection.custom_disclaimer}
|
||||
onChange={(e) => {
|
||||
|
|
@ -316,10 +315,10 @@ const EditCustomCollectionModal: FC<Props> = ({
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div className={cn(isEdit ? 'justify-between' : 'justify-end', 'mt-2 shrink-0 flex py-4 px-6 rounded-b-[10px] bg-gray-50 border-t border-black/5')} >
|
||||
<div className={cn(isEdit ? 'justify-between' : 'justify-end', 'mt-2 shrink-0 flex py-4 px-6 rounded-b-[10px] bg-background-section-burn border-t border-divider-regular')} >
|
||||
{
|
||||
isEdit && (
|
||||
<Button onClick={onRemove} className='text-red-500 border-red-50 hover:border-red-500'>{t('common.operation.delete')}</Button>
|
||||
<Button variant='warning' onClick={onRemove}>{t('common.operation.delete')}</Button>
|
||||
)
|
||||
}
|
||||
<div className='flex space-x-2 '>
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ import type { FC } from 'react'
|
|||
import React, { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { Settings01 } from '../../base/icons/src/vender/line/general'
|
||||
import { RiSettings2Line } from '@remixicon/react'
|
||||
import ConfigCredentials from './config-credentials'
|
||||
import { AuthType, type Credential, type CustomCollectionBackend, type CustomParamSchema } from '@/app/components/tools/types'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Drawer from '@/app/components/base/drawer-plus'
|
||||
import I18n from '@/context/i18n'
|
||||
import { testAPIAvailable } from '@/service/tools'
|
||||
|
|
@ -19,8 +20,6 @@ type Props = {
|
|||
onHide: () => void
|
||||
}
|
||||
|
||||
const keyClassNames = 'py-2 leading-5 text-sm font-medium text-gray-900'
|
||||
|
||||
const TestApi: FC<Props> = ({
|
||||
positionCenter,
|
||||
customCollection,
|
||||
|
|
@ -65,39 +64,40 @@ const TestApi: FC<Props> = ({
|
|||
panelClassName='mt-2 !w-[600px]'
|
||||
maxWidthClassName='!max-w-[600px]'
|
||||
height='calc(100vh - 16px)'
|
||||
headerClassName='!border-b-black/5'
|
||||
headerClassName='!border-b-divider-regular'
|
||||
body={
|
||||
<div className='pt-2 px-6 overflow-y-auto'>
|
||||
<div className='space-y-4'>
|
||||
<div>
|
||||
<div className={keyClassNames}>{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className='flex items-center h-9 justify-between px-2.5 bg-gray-100 rounded-lg cursor-pointer' onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className='text-sm font-normal text-gray-900'>{t(`tools.createTool.authMethod.types.${tempCredential.auth_type}`)}</div>
|
||||
<Settings01 className='w-4 h-4 text-gray-700 opacity-60' />
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.authMethod.title')}</div>
|
||||
<div className='flex items-center h-9 justify-between px-2.5 bg-components-input-bg-normal rounded-lg cursor-pointer' onClick={() => setCredentialsModalShow(true)}>
|
||||
<div className='system-xs-regular text-text-primary'>{t(`tools.createTool.authMethod.types.${tempCredential.auth_type}`)}</div>
|
||||
<RiSettings2Line className='w-4 h-4 text-text-secondary' />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className={keyClassNames}>{t('tools.test.parametersValue')}</div>
|
||||
<div className='rounded-lg border border-gray-200'>
|
||||
<table className='w-full leading-[18px] text-xs text-gray-700 font-normal'>
|
||||
<thead className='text-gray-500 uppercase'>
|
||||
<tr className='border-b border-gray-200'>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.test.parametersValue')}</div>
|
||||
<div className='rounded-lg border border-divider-regular'>
|
||||
<table className='w-full system-xs-regular text-text-secondary font-normal'>
|
||||
<thead className='text-text-tertiary uppercase'>
|
||||
<tr className='border-b border-divider-regular'>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.test.parameters')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.test.value')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{parameters.map((item, index) => (
|
||||
<tr key={index} className='border-b last:border-0 border-gray-200'>
|
||||
<tr key={index} className='border-b last:border-0 border-divider-regular'>
|
||||
<td className="py-2 pl-3 pr-2.5">
|
||||
{item.label[language]}
|
||||
</td>
|
||||
<td className="">
|
||||
<input
|
||||
<Input
|
||||
value={parametersValue[item.name] || ''}
|
||||
onChange={e => setParametersValue({ ...parametersValue, [item.name]: e.target.value })}
|
||||
type='text' className='px-3 h-[34px] w-full outline-none focus:bg-gray-100' ></input>
|
||||
type='text'
|
||||
className='!bg-transparent !border-transparent !hover:border-transparent !hover:bg-transparent !focus:border-transparent !focus:bg-transparent' />
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
|
@ -110,11 +110,11 @@ const TestApi: FC<Props> = ({
|
|||
<Button variant='primary' className=' mt-4 w-full h-10' onClick={handleTest}>{t('tools.test.title')}</Button>
|
||||
<div className='mt-6'>
|
||||
<div className='flex items-center space-x-3'>
|
||||
<div className='leading-[18px] text-xs font-semibold text-gray-500'>{t('tools.test.testResult')}</div>
|
||||
<div className='system-xs-semibold text-text-tertiary'>{t('tools.test.testResult')}</div>
|
||||
<div className='grow w-0 h-px bg-[rgb(243, 244, 246)]'></div>
|
||||
</div>
|
||||
<div className='mt-2 px-3 py-2 h-[200px] overflow-y-auto overflow-x-hidden rounded-lg bg-gray-100 leading-4 text-xs font-normal text-gray-700'>
|
||||
{result || <span className='text-gray-400'>{t('tools.test.testResultPlaceholder')}</span>}
|
||||
<div className='mt-2 px-3 py-2 h-[200px] overflow-y-auto overflow-x-hidden rounded-lg bg-components-input-bg-normal system-xs-regular text-text-secondary'>
|
||||
{result || <span className='text-text-quaternary'>{t('tools.test.testResultPlaceholder')}</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -67,24 +67,23 @@ const LabelFilter: FC<LabelFilterProps> = ({
|
|||
className='block'
|
||||
>
|
||||
<div className={cn(
|
||||
'flex items-center gap-1 px-2 h-8 rounded-lg border-[0.5px] border-transparent bg-gray-200 cursor-pointer hover:bg-gray-300',
|
||||
open && !value.length && '!bg-gray-300 hover:bg-gray-300',
|
||||
!open && !!value.length && '!bg-white/80 shadow-xs !border-black/5 hover:!bg-gray-200',
|
||||
open && !!value.length && '!bg-gray-200 !border-black/5 shadow-xs hover:!bg-gray-200',
|
||||
'flex items-center gap-1 px-2 h-8 rounded-lg border-[0.5px] border-transparent bg-components-input-bg-normal cursor-pointer hover:bg-components-input-bg-hover',
|
||||
!open && !!value.length && 'shadow-xs',
|
||||
open && !!value.length && 'shadow-xs',
|
||||
)}>
|
||||
<div className='p-[1px]'>
|
||||
<Tag01 className='h-3.5 w-3.5 text-gray-700' />
|
||||
<Tag01 className='h-3.5 w-3.5 text-text-tertiary' />
|
||||
</div>
|
||||
<div className='text-[13px] leading-[18px] text-gray-700'>
|
||||
<div className='text-[13px] leading-[18px] text-text-tertiary'>
|
||||
{!value.length && t('common.tag.placeholder')}
|
||||
{!!value.length && currentLabel?.label}
|
||||
</div>
|
||||
{value.length > 1 && (
|
||||
<div className='text-xs font-medium leading-[18px] text-gray-500'>{`+${value.length - 1}`}</div>
|
||||
<div className='text-xs font-medium leading-[18px] text-text-tertiary'>{`+${value.length - 1}`}</div>
|
||||
)}
|
||||
{!value.length && (
|
||||
<div className='p-[1px]'>
|
||||
<RiArrowDownSLine className='h-3.5 w-3.5 text-gray-700' />
|
||||
<RiArrowDownSLine className='h-3.5 w-3.5 text-text-tertiary' />
|
||||
</div>
|
||||
)}
|
||||
{!!value.length && (
|
||||
|
|
@ -92,14 +91,14 @@ const LabelFilter: FC<LabelFilterProps> = ({
|
|||
e.stopPropagation()
|
||||
onChange([])
|
||||
}}>
|
||||
<XCircle className='h-3.5 w-3.5 text-gray-400 group-hover/clear:text-gray-600' />
|
||||
<XCircle className='h-3.5 w-3.5 text-text-tertiary group-hover/clear:text-text-secondary' />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-[1002]'>
|
||||
<div className='relative w-[240px] bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg'>
|
||||
<div className='p-2 border-b-[0.5px] border-black/5'>
|
||||
<div className='relative w-[240px] bg-components-panel-bg-blur rounded-lg border-[0.5px] backdrop-blur-[5px] border-components-panel-border shadow-lg'>
|
||||
<div className='p-2'>
|
||||
<Input
|
||||
showLeftIcon
|
||||
showClearIcon
|
||||
|
|
@ -112,17 +111,17 @@ const LabelFilter: FC<LabelFilterProps> = ({
|
|||
{filteredLabelList.map(label => (
|
||||
<div
|
||||
key={label.name}
|
||||
className='flex items-center gap-2 pl-3 py-[6px] pr-2 rounded-lg cursor-pointer hover:bg-gray-100'
|
||||
className='flex items-center gap-2 pl-3 py-[6px] pr-2 rounded-lg cursor-pointer hover:bg-state-base-hover'
|
||||
onClick={() => selectLabel(label)}
|
||||
>
|
||||
<div title={label.label} className='grow text-sm text-gray-700 leading-5 truncate'>{label.label}</div>
|
||||
{value.includes(label.name) && <Check className='shrink-0 w-4 h-4 text-primary-600' />}
|
||||
<div title={label.label} className='grow text-sm text-text-secondary leading-5 truncate'>{label.label}</div>
|
||||
{value.includes(label.name) && <Check className='shrink-0 w-4 h-4 text-text-accent' />}
|
||||
</div>
|
||||
))}
|
||||
{!filteredLabelList.length && (
|
||||
<div className='p-3 flex flex-col items-center gap-1'>
|
||||
<Tag03 className='h-6 w-6 text-gray-300' />
|
||||
<div className='text-gray-500 text-xs leading-[14px]'>{t('common.tag.noTag')}</div>
|
||||
<Tag03 className='h-6 w-6 text-text-quaternary' />
|
||||
<div className='text-text-tertiary text-xs leading-[14px]'>{t('common.tag.noTag')}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -66,21 +66,21 @@ const LabelSelector: FC<LabelSelectorProps> = ({
|
|||
className='block'
|
||||
>
|
||||
<div className={cn(
|
||||
'flex items-center gap-1 px-3 h-10 rounded-lg border-[0.5px] border-transparent bg-gray-100 cursor-pointer hover:bg-gray-200',
|
||||
open && '!bg-gray-200 hover:bg-gray-200',
|
||||
'flex items-center gap-1 px-3 h-10 rounded-lg border-[0.5px] border-transparent bg-components-input-bg-normal cursor-pointer hover:bg-components-input-bg-hover',
|
||||
open && '!hover:bg-components-input-bg-hover hover:bg-components-input-bg-hover',
|
||||
)}>
|
||||
<div title={value.length > 0 ? selectedLabels : ''} className={cn('grow text-[13px] leading-[18px] text-gray-700 truncate', !value.length && '!text-gray-400')}>
|
||||
<div title={value.length > 0 ? selectedLabels : ''} className={cn('grow text-[13px] leading-[18px] text-text-secondary truncate', !value.length && '!text-text-quaternary')}>
|
||||
{!value.length && t('tools.createTool.toolInput.labelPlaceholder')}
|
||||
{!!value.length && selectedLabels}
|
||||
</div>
|
||||
<div className='shrink-0 ml-1 text-gray-700 opacity-60'>
|
||||
<div className='shrink-0 ml-1 text-text-secondary opacity-60'>
|
||||
<RiArrowDownSLine className='h-4 w-4' />
|
||||
</div>
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-[1040]'>
|
||||
<div className='relative w-[591px] bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg'>
|
||||
<div className='p-2 border-b-[0.5px] border-black/5'>
|
||||
<div className='relative w-[591px] bg-components-panel-bg-blur backdrop-blur-[5px] rounded-lg border-[0.5px] border-components-panel-border shadow-lg'>
|
||||
<div className='p-2 border-b-[0.5px] border-divider-regular'>
|
||||
<Input
|
||||
showLeftIcon
|
||||
showClearIcon
|
||||
|
|
@ -93,7 +93,7 @@ const LabelSelector: FC<LabelSelectorProps> = ({
|
|||
{filteredLabelList.map(label => (
|
||||
<div
|
||||
key={label.name}
|
||||
className='flex items-center gap-2 pl-3 py-[6px] pr-2 rounded-lg cursor-pointer hover:bg-gray-100'
|
||||
className='flex items-center gap-2 pl-3 py-[6px] pr-2 rounded-lg cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover'
|
||||
onClick={() => selectLabel(label)}
|
||||
>
|
||||
<Checkbox
|
||||
|
|
@ -101,13 +101,13 @@ const LabelSelector: FC<LabelSelectorProps> = ({
|
|||
checked={value.includes(label.name)}
|
||||
onCheck={() => { }}
|
||||
/>
|
||||
<div title={label.label} className='grow text-sm text-gray-700 leading-5 truncate'>{label.label}</div>
|
||||
<div title={label.label} className='grow text-sm text-text-secondary leading-5 truncate'>{label.label}</div>
|
||||
</div>
|
||||
))}
|
||||
{!filteredLabelList.length && (
|
||||
<div className='p-3 flex flex-col items-center gap-1'>
|
||||
<Tag03 className='h-6 w-6 text-gray-300' />
|
||||
<div className='text-gray-500 text-xs leading-[14px]'>{t('common.tag.noTag')}</div>
|
||||
<Tag03 className='h-6 w-6 text-text-quaternary' />
|
||||
<div className='text-text-tertiary text-xs leading-[14px]'>{t('common.tag.noTag')}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -63,13 +63,13 @@ const ProviderList = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className='relative flex overflow-hidden bg-gray-100 shrink-0 h-0 grow'>
|
||||
<div className='relative flex overflow-hidden shrink-0 h-0 grow'>
|
||||
<div
|
||||
ref={containerRef}
|
||||
className='relative flex flex-col overflow-y-auto bg-gray-100 grow'
|
||||
className='relative flex flex-col overflow-y-auto bg-background-body grow'
|
||||
>
|
||||
<div className={cn(
|
||||
'sticky top-0 flex justify-between items-center pt-4 px-12 pb-2 leading-[56px] bg-gray-100 z-20 flex-wrap gap-y-2',
|
||||
'sticky top-0 flex justify-between items-center pt-4 px-12 pb-2 leading-[56px] z-20 flex-wrap gap-y-2',
|
||||
currentProvider && 'pr-6',
|
||||
)}>
|
||||
<TabSliderNew
|
||||
|
|
@ -96,6 +96,7 @@ const ProviderList = () => {
|
|||
{(filteredCollectionList.length > 0 || activeTab !== 'builtin') && (
|
||||
<div className={cn(
|
||||
'relative grid content-start grid-cols-1 gap-4 px-12 pt-2 pb-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 shrink-0',
|
||||
!filteredCollectionList.length && activeTab === 'workflow' && 'grow',
|
||||
)}>
|
||||
{activeTab === 'api' && <CustomCreateCard onRefreshData={refetch} />}
|
||||
{filteredCollectionList.map(collection => (
|
||||
|
|
|
|||
|
|
@ -45,16 +45,16 @@ const Contribute = ({ onRefreshData }: Props) => {
|
|||
return (
|
||||
<>
|
||||
{isCurrentWorkspaceManager && (
|
||||
<div className='flex flex-col col-span-1 bg-gray-200 border-[0.5px] border-black/5 rounded-xl min-h-[135px] transition-all duration-200 ease-in-out cursor-pointer hover:bg-gray-50 hover:shadow-lg'>
|
||||
<div className='group grow rounded-t-xl hover:bg-white' onClick={() => setIsShowEditCustomCollectionModal(true)}>
|
||||
<div className='flex flex-col col-span-1 bg-components-panel-on-panel-item-bg border-[0.5px] border-divider-subtle rounded-xl min-h-[135px] transition-all duration-200 ease-in-out cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover hover:shadow-lg'>
|
||||
<div className='group grow rounded-t-xl hover:bg-background-body' onClick={() => setIsShowEditCustomCollectionModal(true)}>
|
||||
<div className='shrink-0 flex items-center p-4 pb-3'>
|
||||
<div className='w-10 h-10 flex items-center justify-center border border-gray-200 bg-gray-100 rounded-lg group-hover:border-primary-100 group-hover:bg-primary-50'>
|
||||
<RiAddLine className='w-4 h-4 text-gray-500 group-hover:text-primary-600'/>
|
||||
<div className='w-10 h-10 flex items-center justify-center border border-components-option-card-option-border bg-components-option-card-option-bg rounded-lg group-hover:border-components-option-card-option-border-hover group-hover:bg-components-option-card-option-bg-hover'>
|
||||
<RiAddLine className='w-4 h-4 text-text-tertiary group-hover:text-text-accent'/>
|
||||
</div>
|
||||
<div className='ml-3 text-sm font-semibold leading-5 text-gray-800 group-hover:text-primary-600'>{t('tools.createCustomTool')}</div>
|
||||
<div className='ml-3 text-sm font-semibold leading-5 text-text-primary group-hover:text-text-accent'>{t('tools.createCustomTool')}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='px-4 py-3 rounded-b-xl border-t-[0.5px] border-black/5 text-gray-500 hover:text-[#155EEF] hover:bg-white'>
|
||||
<div className='px-4 py-3 rounded-b-xl border-t-[0.5px] border-divider-regular text-text-tertiary hover:text-text-accent hover:bg-background-body'>
|
||||
<a href={linkUrl} target='_blank' rel='noopener noreferrer' className='flex items-center space-x-1'>
|
||||
<BookOpen01 className='shrink-0 w-3 h-3' />
|
||||
<div className='grow leading-[18px] text-xs font-normal truncate' title={t('tools.customToolTip') || ''}>{t('tools.customToolTip')}</div>
|
||||
|
|
|
|||
|
|
@ -260,14 +260,14 @@ const ProviderDetail = ({
|
|||
{!!collection.description[language] && (
|
||||
<Description text={collection.description[language]} descriptionLineRows={2}></Description>
|
||||
)}
|
||||
<div className='flex gap-1 border-b-[0.5px] border-black/5'>
|
||||
<div className='flex gap-1 border-b-[0.5px] border-divider-subtle'>
|
||||
{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>
|
||||
<Settings01 className='mr-1 w-4 h-4 text-text-tertiary' />
|
||||
<div className='system-sm-medium text-text-secondary'>{t('tools.createTool.editAction')}</div>
|
||||
</Button>
|
||||
)}
|
||||
{collection.type === CollectionType.workflow && !isDetailLoading && customCollection && (
|
||||
|
|
@ -276,8 +276,8 @@ const ProviderDetail = ({
|
|||
variant='primary'
|
||||
className={cn('shrink-0 my-3 w-[183px]')}
|
||||
>
|
||||
<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>
|
||||
<a className='flex items-center text-text-primary' 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 w-4 h-4' />
|
||||
</a>
|
||||
</Button>
|
||||
|
|
@ -286,7 +286,7 @@ const ProviderDetail = ({
|
|||
onClick={() => setIsShowEditWorkflowToolModal(true)}
|
||||
disabled={!isCurrentWorkspaceManager}
|
||||
>
|
||||
<div className='leading-5 text-sm font-medium text-gray-700'>{t('tools.createTool.editAction')}</div>
|
||||
<div className='system-sm-medium text-text-secondary'>{t('tools.createTool.editAction')}</div>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
|
@ -319,7 +319,7 @@ const ProviderDetail = ({
|
|||
<div className='text-text-secondary system-sm-semibold-uppercase'>
|
||||
<span className=''>{t('tools.includeToolNum', { num: toolList.length }).toLocaleUpperCase()}</span>
|
||||
<span className='px-1'>·</span>
|
||||
<span className='text-[#DC6803]'>{t('tools.auth.setup').toLocaleUpperCase()}</span>
|
||||
<span className='text-util-colors-orange-orange-600'>{t('tools.auth.setup').toLocaleUpperCase()}</span>
|
||||
</div>
|
||||
<Button
|
||||
variant='primary'
|
||||
|
|
|
|||
|
|
@ -71,11 +71,11 @@ const ConfigCredential: FC<Props> = ({
|
|||
onHide={onCancel}
|
||||
title={t('tools.auth.setupModalTitle') as string}
|
||||
titleDescription={t('tools.auth.setupModalTitleDescription') as string}
|
||||
panelClassName='mt-[64px] mb-2 !w-[420px]'
|
||||
panelClassName='mt-[64px] mb-2 !w-[420px] border-components-panel-border'
|
||||
maxWidthClassName='!max-w-[420px]'
|
||||
height='calc(100vh - 64px)'
|
||||
contentClassName='!bg-gray-100'
|
||||
headerClassName='!border-b-black/5'
|
||||
contentClassName='!bg-components-panel-bg'
|
||||
headerClassName='!border-b-divider-subtle'
|
||||
body={
|
||||
|
||||
<div className='px-6 py-3 h-full'>
|
||||
|
|
@ -92,12 +92,12 @@ const ConfigCredential: FC<Props> = ({
|
|||
isEditMode={true}
|
||||
showOnVariableMap={{}}
|
||||
validating={false}
|
||||
inputClassName='!bg-gray-50'
|
||||
inputClassName='!bg-components-input-bg-normal'
|
||||
fieldMoreInfo={item => item.url
|
||||
? (<a
|
||||
href={item.url}
|
||||
target='_blank' rel='noopener noreferrer'
|
||||
className='inline-flex items-center text-xs text-primary-600'
|
||||
className='inline-flex items-center text-xs text-text-accent'
|
||||
>
|
||||
{t('tools.howToGet')}
|
||||
<LinkExternal02 className='ml-1 w-3 h-3' />
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import s from './style.module.css'
|
||||
import cn from '@/utils/classnames'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
|
|
@ -19,24 +18,24 @@ const ConfirmModal = ({ show, onConfirm, onClose }: ConfirmModalProps) => {
|
|||
|
||||
return (
|
||||
<Modal
|
||||
className={cn('p-8 max-w-[600px] w-[600px]', s.bg)}
|
||||
className={cn('p-8 max-w-[600px] w-[600px]')}
|
||||
isShow={show}
|
||||
onClose={() => { }}
|
||||
>
|
||||
<div className='absolute right-4 top-4 p-2 cursor-pointer' onClick={onClose}>
|
||||
<RiCloseLine className='w-4 h-4 text-gray-500' />
|
||||
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
|
||||
</div>
|
||||
<div className='w-12 h-12 p-3 bg-white rounded-xl border-[0.5px] border-gray-100 shadow-xl'>
|
||||
<div className='w-12 h-12 p-3 bg-background-section rounded-xl border-[0.5px] border-divider-regular shadow-xl'>
|
||||
<AlertTriangle className='w-6 h-6 text-[rgb(247,144,9)]' />
|
||||
</div>
|
||||
<div className='relative mt-3 text-xl font-semibold leading-[30px] text-gray-900'>{t('tools.createTool.confirmTitle')}</div>
|
||||
<div className='my-1 text-gray-500 text-sm leading-5'>
|
||||
<div className='relative mt-3 text-xl font-semibold leading-[30px] text-text-primary'>{t('tools.createTool.confirmTitle')}</div>
|
||||
<div className='my-1 text-text-tertiary text-sm leading-5'>
|
||||
{t('tools.createTool.confirmTip')}
|
||||
</div>
|
||||
<div className='pt-6 flex justify-end items-center'>
|
||||
<div className='flex items-center'>
|
||||
<Button className='mr-2' onClick={onClose}>{t('common.operation.cancel')}</Button>
|
||||
<Button className='border-red-700' variant="warning" onClick={onConfirm}>{t('common.operation.confirm')}</Button>
|
||||
<Button variant="warning" onClick={onConfirm}>{t('common.operation.confirm')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
.bg {
|
||||
background: linear-gradient(180deg, rgba(247, 144, 9, 0.05) 0%, rgba(247, 144, 9, 0.00) 24.41%), #F9FAFB;
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ import LabelSelector from '@/app/components/tools/labels/selector'
|
|||
import ConfirmModal from '@/app/components/tools/workflow-tool/confirm-modal'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
|
||||
interface Props {
|
||||
type Props = {
|
||||
isAdd?: boolean
|
||||
payload: any
|
||||
onHide: () => void
|
||||
|
|
@ -124,13 +124,13 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
panelClassName='mt-2 !w-[640px]'
|
||||
maxWidthClassName='!max-w-[640px]'
|
||||
height='calc(100vh - 16px)'
|
||||
headerClassName='!border-b-black/5'
|
||||
headerClassName='!border-b-divider'
|
||||
body={
|
||||
<div className='flex flex-col h-full'>
|
||||
<div className='grow h-0 overflow-y-auto px-6 py-3 space-y-4'>
|
||||
{/* name & icon */}
|
||||
<div>
|
||||
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.name')} <span className='ml-1 text-red-500'>*</span></div>
|
||||
<div className='flex items-center justify-between gap-3'>
|
||||
<AppIcon size='large' onClick={() => { setShowEmojiPicker(true) }} className='cursor-pointer' iconType='emoji' icon={emoji.content} background={emoji.background} />
|
||||
<Input
|
||||
|
|
@ -143,7 +143,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
</div>
|
||||
{/* name for tool call */}
|
||||
<div>
|
||||
<div className='flex items-center py-2 leading-5 text-sm font-medium text-gray-900'>
|
||||
<div className='flex items-center py-2 system-sm-medium text-text-primary'>
|
||||
{t('tools.createTool.nameForToolCall')} <span className='ml-1 text-red-500'>*</span>
|
||||
<Tooltip
|
||||
popupContent={
|
||||
|
|
@ -165,7 +165,7 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
</div>
|
||||
{/* description */}
|
||||
<div>
|
||||
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.description')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.description')}</div>
|
||||
<Textarea
|
||||
placeholder={t('tools.createTool.descriptionPlaceholder') || ''}
|
||||
value={description}
|
||||
|
|
@ -174,11 +174,11 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
</div>
|
||||
{/* Tool Input */}
|
||||
<div>
|
||||
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.toolInput.title')}</div>
|
||||
<div className='rounded-lg border border-gray-200 w-full overflow-x-auto'>
|
||||
<table className='w-full leading-[18px] text-xs text-gray-700 font-normal'>
|
||||
<thead className='text-gray-500 uppercase'>
|
||||
<tr className='border-b border-gray-200'>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.toolInput.title')}</div>
|
||||
<div className='rounded-lg border border-divider-regular w-full overflow-x-auto'>
|
||||
<table className='w-full leading-[18px] text-xs text-text-secondary font-normal'>
|
||||
<thead className='text-text-tertiary uppercase'>
|
||||
<tr className='border-b border-divider-regular'>
|
||||
<th className="p-2 pl-3 font-medium w-[156px]">{t('tools.createTool.toolInput.name')}</th>
|
||||
<th className="p-2 pl-3 font-medium w-[102px]">{t('tools.createTool.toolInput.method')}</th>
|
||||
<th className="p-2 pl-3 font-medium">{t('tools.createTool.toolInput.description')}</th>
|
||||
|
|
@ -186,22 +186,22 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
</thead>
|
||||
<tbody>
|
||||
{parameters.map((item, index) => (
|
||||
<tr key={index} className='border-b last:border-0 border-gray-200'>
|
||||
<tr key={index} className='border-b last:border-0 border-divider-regular'>
|
||||
<td className="p-2 pl-3 max-w-[156px]">
|
||||
<div className='text-[13px] leading-[18px]'>
|
||||
<div title={item.name} className='flex'>
|
||||
<span className='font-medium text-gray-900 truncate'>{item.name}</span>
|
||||
<span className='font-medium text-text-primary truncate'>{item.name}</span>
|
||||
<span className='shrink-0 pl-1 text-[#ec4a0a] text-xs leading-[18px]'>{item.required ? t('tools.createTool.toolInput.required') : ''}</span>
|
||||
</div>
|
||||
<div className='text-gray-500'>{item.type}</div>
|
||||
<div className='text-text-tertiary'>{item.type}</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{item.name === '__image' && (
|
||||
<div className={cn(
|
||||
'flex items-center gap-1 min-h-[56px] px-3 py-2 h-9 bg-white cursor-default',
|
||||
'flex items-center gap-1 min-h-[56px] px-3 py-2 h-9 bg-transparent cursor-default',
|
||||
)}>
|
||||
<div className={cn('grow text-[13px] leading-[18px] text-gray-700 truncate')}>
|
||||
<div className={cn('grow text-[13px] leading-[18px] text-text-secondary truncate')}>
|
||||
{t('tools.createTool.toolInput.methodParameter')}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -210,10 +210,10 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
<MethodSelector value={item.form} onChange={value => handleParameterChange('form', value, index)} />
|
||||
)}
|
||||
</td>
|
||||
<td className="p-2 pl-3 text-gray-500 w-[236px]">
|
||||
<td className="p-2 pl-3 text-text-tertiary w-[236px]">
|
||||
<input
|
||||
type='text'
|
||||
className='grow text-gray-700 text-[13px] leading-[18px] font-normal bg-white outline-none appearance-none caret-primary-600 placeholder:text-gray-300'
|
||||
className='w-full text-text-secondary text-[13px] leading-[18px] font-normal bg-transparent outline-none appearance-none caret-primary-600 placeholder:text-text-quaternary'
|
||||
placeholder={t('tools.createTool.toolInput.descriptionPlaceholder')!}
|
||||
value={item.description}
|
||||
onChange={e => handleParameterChange('description', e.target.value, index)}
|
||||
|
|
@ -227,12 +227,12 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
</div>
|
||||
{/* Tags */}
|
||||
<div>
|
||||
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.toolInput.label')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.toolInput.label')}</div>
|
||||
<LabelSelector value={labels} onChange={handleLabelSelect} />
|
||||
</div>
|
||||
{/* Privacy Policy */}
|
||||
<div>
|
||||
<div className='py-2 leading-5 text-sm font-medium text-gray-900'>{t('tools.createTool.privacyPolicy')}</div>
|
||||
<div className='py-2 system-sm-medium text-text-primary'>{t('tools.createTool.privacyPolicy')}</div>
|
||||
<Input
|
||||
className='h-10'
|
||||
value={privacyPolicy}
|
||||
|
|
@ -240,9 +240,9 @@ const WorkflowToolAsModal: FC<Props> = ({
|
|||
placeholder={t('tools.createTool.privacyPolicyPlaceholder') || ''} />
|
||||
</div>
|
||||
</div>
|
||||
<div className={cn((!isAdd && onRemove) ? 'justify-between' : 'justify-end', 'mt-2 shrink-0 flex py-4 px-6 rounded-b-[10px] bg-gray-50 border-t border-black/5')} >
|
||||
<div className={cn((!isAdd && onRemove) ? 'justify-between' : 'justify-end', 'mt-2 shrink-0 flex py-4 px-6 rounded-b-[10px] bg-background-section-burn border-t border-divider-regular')} >
|
||||
{!isAdd && onRemove && (
|
||||
<Button onClick={onRemove} className='text-red-500 border-red-50 hover:border-red-500'>{t('common.operation.delete')}</Button>
|
||||
<Button variant='warning' onClick={onRemove}>{t('common.operation.delete')}</Button>
|
||||
)}
|
||||
<div className='flex space-x-2 '>
|
||||
<Button onClick={onHide}>{t('common.operation.cancel')}</Button>
|
||||
|
|
|
|||
|
|
@ -34,37 +34,37 @@ const MethodSelector: FC<MethodSelectorProps> = ({
|
|||
className='block'
|
||||
>
|
||||
<div className={cn(
|
||||
'flex items-center gap-1 min-h-[56px] px-3 py-2 h-9 bg-white cursor-pointer hover:bg-gray-100',
|
||||
open && '!bg-gray-100 hover:bg-gray-100',
|
||||
'flex items-center gap-1 min-h-[56px] px-3 py-2 h-9 bg-transparent cursor-pointer hover:bg-background-section-burn',
|
||||
open && '!bg-background-section-burn hover:bg-background-section-burn',
|
||||
)}>
|
||||
<div className={cn('grow text-[13px] leading-[18px] text-gray-700 truncate')}>
|
||||
<div className={cn('grow text-[13px] leading-[18px] text-text-secondary truncate')}>
|
||||
{value === 'llm' ? t('tools.createTool.toolInput.methodParameter') : t('tools.createTool.toolInput.methodSetting')}
|
||||
</div>
|
||||
<div className='shrink-0 ml-1 text-gray-700 opacity-60'>
|
||||
<div className='shrink-0 ml-1 text-text-secondary opacity-60'>
|
||||
<RiArrowDownSLine className='h-4 w-4' />
|
||||
</div>
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-[1040]'>
|
||||
<div className='relative w-[320px] bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg'>
|
||||
<div className='relative w-[320px] bg-components-panel-bg-blur backdrop-blur-sm rounded-lg border-[0.5px] border-components-panel-border shadow-lg'>
|
||||
<div className='p-1'>
|
||||
<div className='pl-3 pr-2 py-2.5 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => onChange('llm')}>
|
||||
<div className='pl-3 pr-2 py-2.5 rounded-lg hover:bg-components-panel-on-panel-item-bg-hover cursor-pointer' onClick={() => onChange('llm')}>
|
||||
<div className='flex item-center gap-1'>
|
||||
<div className='shrink-0 w-4 h-4'>
|
||||
{value === 'llm' && <Check className='shrink-0 w-4 h-4 text-primary-600' />}
|
||||
{value === 'llm' && <Check className='shrink-0 w-4 h-4 text-text-accent' />}
|
||||
</div>
|
||||
<div className='text-[13px] text-gray-700 font-medium leading-[18px]'>{t('tools.createTool.toolInput.methodParameter')}</div>
|
||||
<div className='text-[13px] text-text-secondary font-medium leading-[18px]'>{t('tools.createTool.toolInput.methodParameter')}</div>
|
||||
</div>
|
||||
<div className='pl-5 text-gray-500 text-[13px] leading-[18px]'>{t('tools.createTool.toolInput.methodParameterTip')}</div>
|
||||
<div className='pl-5 text-text-tertiary text-[13px] leading-[18px]'>{t('tools.createTool.toolInput.methodParameterTip')}</div>
|
||||
</div>
|
||||
<div className='pl-3 pr-2 py-2.5 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => onChange('form')}>
|
||||
<div className='pl-3 pr-2 py-2.5 rounded-lg hover:bg-components-panel-on-panel-item-bg-hover cursor-pointer' onClick={() => onChange('form')}>
|
||||
<div className='flex item-center gap-1'>
|
||||
<div className='shrink-0 w-4 h-4'>
|
||||
{value === 'form' && <Check className='shrink-0 w-4 h-4 text-primary-600' />}
|
||||
{value === 'form' && <Check className='shrink-0 w-4 h-4 text-text-accent' />}
|
||||
</div>
|
||||
<div className='text-[13px] text-gray-700 font-medium leading-[18px]'>{t('tools.createTool.toolInput.methodSetting')}</div>
|
||||
<div className='text-[13px] text-text-secondary font-medium leading-[18px]'>{t('tools.createTool.toolInput.methodSetting')}</div>
|
||||
</div>
|
||||
<div className='pl-5 text-gray-500 text-[13px] leading-[18px]'>{t('tools.createTool.toolInput.methodSettingTip')}</div>
|
||||
<div className='pl-5 text-text-tertiary text-[13px] leading-[18px]'>{t('tools.createTool.toolInput.methodSettingTip')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
|
|||
setCurrentWorkspace(currentWorkspaceResponse)
|
||||
}, [currentWorkspaceResponse])
|
||||
|
||||
const [theme, setTheme] = useState<Theme>(Theme.light)
|
||||
const [theme, setTheme] = useState<Theme>(Theme.dark)
|
||||
const handleSetTheme = useCallback((theme: Theme) => {
|
||||
setTheme(theme)
|
||||
globalThis.document.documentElement.setAttribute('data-theme', theme)
|
||||
|
|
|
|||
Loading…
Reference in New Issue