feat: tooltip (#7634)

This commit is contained in:
Yi Xiao 2024-08-26 13:00:02 +08:00 committed by GitHub
parent 1ba3d3acd6
commit 3be756eaed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
93 changed files with 640 additions and 758 deletions

View File

@ -10,7 +10,7 @@ import { TracingProvider } from './type'
import ProviderConfigModal from './provider-config-modal'
import Indicator from '@/app/components/header/indicator'
import Switch from '@/app/components/base/switch'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
const I18N_PREFIX = 'app.tracing'
@ -121,12 +121,11 @@ const ConfigPopup: FC<PopupProps> = ({
<>
{providerAllNotConfigured
? (
<TooltipPlus
<Tooltip
popupContent={t(`${I18N_PREFIX}.disabledTip`)}
>
{switchContent}
</TooltipPlus>
</Tooltip>
)
: switchContent}
</>

View File

@ -3,7 +3,7 @@ import { ChevronDoubleDownIcon } from '@heroicons/react/20/solid'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import React, { useCallback } from 'react'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
const I18N_PREFIX = 'app.tracing'
@ -25,9 +25,8 @@ const ToggleFoldBtn: FC<Props> = ({
return (
// text-[0px] to hide spacing between tooltip elements
<div className='shrink-0 cursor-pointer text-[0px]' onClick={handleFoldChange}>
<TooltipPlus
<Tooltip
popupContent={t(`${I18N_PREFIX}.${isFold ? 'expand' : 'collapse'}`)}
hideArrow
>
{isFold && (
<div className='p-1 rounded-md text-gray-500 hover:text-gray-800 hover:bg-black/5'>
@ -39,7 +38,7 @@ const ToggleFoldBtn: FC<Props> = ({
<ChevronDoubleDownIcon className='w-4 h-4 transform rotate-180' />
</div>
)}
</TooltipPlus>
</Tooltip>
</div>
)
}

View File

@ -4,9 +4,7 @@ import { useContext } from 'use-context-selector'
import { useRouter } from 'next/navigation'
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiMoreFill,
} from '@remixicon/react'
import { RiMoreFill } from '@remixicon/react'
import cn from '@/utils/classnames'
import Confirm from '@/app/components/base/confirm'
import { ToastContext } from '@/app/components/base/toast'
@ -129,10 +127,9 @@ const DatasetCard = ({
<div className={cn('truncate', !dataset.embedding_available && 'opacity-50 hover:opacity-100')} title={dataset.name}>{dataset.name}</div>
{!dataset.embedding_available && (
<Tooltip
selector={`dataset-tag-${dataset.id}`}
htmlContent={t('dataset.unavailableTip')}
popupContent={t('dataset.unavailableTip')}
>
<span className='shrink-0 inline-flex w-max ml-1 px-1 border boder-gray-200 rounded-md text-gray-500 text-xs font-normal leading-[18px]'>{t('dataset.unavailable')}</span>
<span className='shrink-0 inline-flex w-max ml-1 px-1 border border-gray-200 rounded-md text-gray-500 text-xs font-normal leading-[18px]'>{t('dataset.unavailable')}</span>
</Tooltip>
)}
</div>

View File

@ -1,10 +1,6 @@
import React from 'react'
import {
InformationCircleIcon,
} from '@heroicons/react/24/outline'
import Tooltip from '../base/tooltip'
import AppIcon from '../base/app-icon'
import { randomString } from '@/utils'
import Tooltip from '@/app/components/base/tooltip'
export type IAppBasicProps = {
iconType?: 'app' | 'api' | 'dataset' | 'webapp' | 'notion'
@ -74,9 +70,17 @@ export default function AppBasic({ icon, icon_background, name, type, hoverTip,
<div className={`flex flex-row items-center text-sm font-semibold text-gray-700 group-hover:text-gray-900 break-all ${textStyle?.main ?? ''}`}>
{name}
{hoverTip
&& <Tooltip content={hoverTip} selector={`a${randomString(16)}`}>
<InformationCircleIcon className='w-4 h-4 ml-1 text-gray-400' />
</Tooltip>}
&& <Tooltip
popupContent={
<div className='w-[240px]'>
{hoverTip}
</div>
}
popupClassName='ml-1'
triggerClassName='w-4 h-4 ml-1'
position='top'
/>
}
</div>
<div className={`text-xs font-normal text-gray-500 group-hover:text-gray-700 break-all ${textStyle?.extra ?? ''}`}>{type}</div>
</div>}

View File

@ -9,7 +9,6 @@ import produce from 'immer'
import {
RiDeleteBinLine,
RiErrorWarningFill,
RiQuestionLine,
} from '@remixicon/react'
import s from './style.module.css'
import MessageTypeSelector from './message-type-selector'
@ -174,12 +173,12 @@ const AdvancedPromptInput: FC<Props> = ({
<div className='text-sm font-semibold uppercase text-indigo-800'>{t('appDebug.pageTitle.line1')}
</div>
<Tooltip
htmlContent={<div className='w-[180px]'>
{t('appDebug.promptTip')}
</div>}
selector='config-prompt-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-indigo-400' />
</Tooltip>
popupContent={
<div className='w-[180px]'>
{t('appDebug.promptTip')}
</div>
}
/>
</div>)}
<div className={cn(s.optionWrap, 'items-center space-x-1')}>
{canDelete && (

View File

@ -3,9 +3,6 @@ import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import {
RiQuestionLine,
} from '@remixicon/react'
import produce from 'immer'
import { useContext } from 'use-context-selector'
import ConfirmAddVar from './confirm-add-var'
@ -156,12 +153,12 @@ const Prompt: FC<ISimplePromptInput> = ({
<div className='h2'>{mode !== AppType.completion ? t('appDebug.chatSubTitle') : t('appDebug.completionSubTitle')}</div>
{!readonly && (
<Tooltip
htmlContent={<div className='w-[180px]'>
{t('appDebug.promptTip')}
</div>}
selector='config-prompt-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-indigo-400' />
</Tooltip>
popupContent={
<div className='w-[180px]'>
{t('appDebug.promptTip')}
</div>
}
/>
)}
</div>
<div className='flex items-center'>

View File

@ -8,7 +8,6 @@ import { useContext } from 'use-context-selector'
import produce from 'immer'
import {
RiDeleteBinLine,
RiQuestionLine,
} from '@remixicon/react'
import Panel from '../base/feature-panel'
import EditModal from './config-modal'
@ -282,11 +281,13 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
<div className='flex items-center'>
<div className='mr-1'>{t('appDebug.variableTitle')}</div>
{!readonly && (
<Tooltip htmlContent={<div className='w-[180px]'>
{t('appDebug.variableTip')}
</div>} selector='config-var-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]'>
{t('appDebug.variableTip')}
</div>
}
/>
)}
</div>
}

View File

@ -2,9 +2,6 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import { useContext } from 'use-context-selector'
import Panel from '../base/feature-panel'
import ParamConfig from './param-config'
@ -33,11 +30,13 @@ const ConfigVision: FC = () => {
title={
<div className='flex items-center'>
<div className='mr-1'>{t('appDebug.vision.name')}</div>
<Tooltip htmlContent={<div className='w-[180px]' >
{t('appDebug.vision.description')}
</div>} selector='config-vision-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]' >
{t('appDebug.vision.description')}
</div>
}
/>
</div>
}
headerRight={

View File

@ -3,9 +3,6 @@ import type { FC } from 'react'
import React from 'react'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import RadioGroup from './radio-group'
import ConfigContext from '@/context/debug-configuration'
import { Resolution, TransferMethod } from '@/types/app'
@ -37,13 +34,15 @@ const ParamConfigContent: FC = () => {
<div>
<div className='mb-2 flex items-center space-x-1'>
<div className='leading-[18px] text-[13px] font-semibold text-gray-800'>{t('appDebug.vision.visionSettings.resolution')}</div>
<Tooltip htmlContent={<div className='w-[180px]' >
{t('appDebug.vision.visionSettings.resolutionTooltip').split('\n').map(item => (
<div key={item}>{item}</div>
))}
</div>} selector='config-resolution-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]' >
{t('appDebug.vision.visionSettings.resolutionTooltip').split('\n').map(item => (
<div key={item}>{item}</div>
))}
</div>
}
/>
</div>
<RadioGroup
className='space-x-3'

View File

@ -3,9 +3,6 @@ import useSWR from 'swr'
import type { FC } from 'react'
import { useContext } from 'use-context-selector'
import React, { Fragment } from 'react'
import {
RiQuestionLine,
} from '@remixicon/react'
import { usePathname } from 'next/navigation'
import { useTranslation } from 'react-i18next'
import { Listbox, Transition } from '@headlessui/react'
@ -50,13 +47,15 @@ const VoiceParamConfig: FC = () => {
<div className='mb-2 flex items-center space-x-1'>
<div
className='leading-[18px] text-[13px] font-semibold text-gray-800'>{t('appDebug.voice.voiceSettings.language')}</div>
<Tooltip htmlContent={<div className='w-[180px]'>
{t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => (
<div key={item}>{item}</div>
))}
</div>} selector='config-resolution-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]'>
{t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => (
<div key={item}>{item}</div>
))}
</div>
}
/>
</div>
<Listbox
value={languageItem}

View File

@ -1,7 +1,6 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { RiQuestionLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import Tooltip from '@/app/components/base/tooltip'
type Props = {
@ -25,14 +24,12 @@ const ItemPanel: FC<Props> = ({
{icon}
<div className='ml-3 mr-1 leading-6 text-sm font-semibold text-gray-800'>{name}</div>
<Tooltip
htmlContent={
popupContent={
<div className='w-[180px]'>
{description}
</div>
}
selector={`agent-setting-tooltip-${name}`}
>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
</div>
<div>

View File

@ -7,13 +7,11 @@ import produce from 'immer'
import {
RiDeleteBinLine,
RiHammerFill,
RiQuestionLine,
} from '@remixicon/react'
import { useFormattingChangedDispatcher } from '../../../debug/hooks'
import SettingBuiltInTool from './setting-built-in-tool'
import cn from '@/utils/classnames'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import Tooltip from '@/app/components/base/tooltip'
import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import AppIcon from '@/app/components/base/app-icon'
@ -23,7 +21,7 @@ import type { AgentTool } from '@/types/app'
import { type Collection, CollectionType } from '@/app/components/tools/types'
import { MAX_TOOLS_NUM } from '@/config'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { DefaultToolIcon } from '@/app/components/base/icons/src/public/other'
import AddToolModal from '@/app/components/tools/add-tool-modal'
@ -68,11 +66,13 @@ const AgentTools: FC = () => {
title={
<div className='flex items-center'>
<div className='mr-1'>{t('appDebug.agent.tools.name')}</div>
<Tooltip htmlContent={<div className='w-[180px]'>
{t('appDebug.agent.tools.description')}
</div>} selector='config-tools-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]'>
{t('appDebug.agent.tools.description')}
</div>
}
/>
</div>
}
headerRight={
@ -119,19 +119,20 @@ const AgentTools: FC = () => {
className={cn((item.isDeleted || item.notAuthor) ? 'line-through opacity-50' : '', 'grow w-0 ml-2 leading-[18px] text-[13px] font-medium text-gray-800 truncate')}
>
<span className='text-gray-800 pr-2'>{item.provider_type === CollectionType.builtIn ? item.provider_name : item.tool_label}</span>
<TooltipPlus
<Tooltip
popupContent={t('tools.toolNameUsageTip')}
>
<span className='text-gray-500'>{item.tool_name}</span>
</TooltipPlus>
</Tooltip>
</div>
</div>
<div className='shrink-0 ml-1 flex items-center'>
{(item.isDeleted || item.notAuthor)
? (
<div className='flex items-center'>
<TooltipPlus
<Tooltip
popupContent={t(`tools.${item.isDeleted ? 'toolRemoved' : 'notAuthorized'}`)}
needsDelay
>
<div className='mr-1 p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
if (item.notAuthor)
@ -139,7 +140,7 @@ const AgentTools: FC = () => {
}}>
<AlertTriangle className='w-4 h-4 text-[#F79009]' />
</div>
</TooltipPlus>
</Tooltip>
<div className='p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
const newModelConfig = produce(modelConfig, (draft) => {
@ -155,16 +156,17 @@ const AgentTools: FC = () => {
)
: (
<div className='hidden group-hover:flex items-center'>
<TooltipPlus
<Tooltip
popupContent={t('tools.setBuiltInTools.infoAndSetting')}
needsDelay
>
<div className='mr-1 p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
<div className='p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
setCurrentTool(item)
setIsShowSettingTool(true)
}}>
<InfoCircle className='w-4 h-4 text-gray-500' />
</div>
</TooltipPlus>
</Tooltip>
<div className='p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
const newModelConfig = produce(modelConfig, (draft) => {

View File

@ -39,10 +39,9 @@ const CardItem: FC<ICardItemProps> = ({
<div className={cn('text-[13px] leading-[18px] font-medium text-gray-800 overflow-hidden text-ellipsis whitespace-nowrap', !config.embedding_available && 'opacity-50')}>{config.name}</div>
{!config.embedding_available && (
<Tooltip
selector={`unavailable-tag-${config.id}`}
htmlContent={t('dataset.unavailableTip')}
popupContent={t('dataset.unavailableTip')}
>
<span className='shrink-0 inline-flex whitespace-nowrap px-1 border boder-gray-200 rounded-md text-gray-500 text-xs font-normal leading-[18px]'>{t('dataset.unavailable')}</span>
<span className='shrink-0 inline-flex whitespace-nowrap px-1 border border-gray-200 rounded-md text-gray-500 text-xs font-normal leading-[18px]'>{t('dataset.unavailable')}</span>
</Tooltip>
)}
</div>

View File

@ -2,9 +2,6 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import type { Props } from './var-picker'
import VarPicker from './var-picker'
import cn from '@/utils/classnames'
@ -24,13 +21,12 @@ const ContextVar: FC<Props> = (props) => {
</div>
<div className='mr-1 text-sm font-medium text-gray-800'>{t('appDebug.feature.dataSet.queryVariable.title')}</div>
<Tooltip
htmlContent={<div className='w-[180px]'>
{t('appDebug.feature.dataSet.queryVariable.tip')}
</div>}
selector='context-var-tooltip'
>
<RiQuestionLine className='w-3.5 h-3.5 text-gray-400' />
</Tooltip>
popupContent={
<div className='w-[180px]'>
{t('appDebug.feature.dataSet.queryVariable.tip')}
</div>
}
/>
</div>
<VarPicker {...props} />

View File

@ -5,7 +5,6 @@ import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiAlertFill,
RiQuestionLine,
} from '@remixicon/react'
import WeightedScore from './weighted-score'
import TopKItem from '@/app/components/base/param-item/top-k-item'
@ -23,7 +22,7 @@ import ModelSelector from '@/app/components/header/account-setting/model-provide
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import type { ModelConfig } from '@/app/components/workflow/types'
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type {
DataSet,
@ -173,7 +172,7 @@ const ConfigContent: FC<Props> = ({
title={(
<div className='flex items-center'>
{t('appDebug.datasetConfig.retrieveOneWay.title')}
<TooltipPlus
<Tooltip
popupContent={(
<div className='w-[320px]'>
{t('dataset.nTo1RetrievalLegacy')}
@ -181,7 +180,7 @@ const ConfigContent: FC<Props> = ({
)}
>
<div className='ml-1 flex items-center px-[5px] h-[18px] rounded-[5px] border border-text-accent-secondary system-2xs-medium-uppercase text-text-accent-secondary'>legacy</div>
</TooltipPlus>
</Tooltip>
</div>
)}
description={t('appDebug.datasetConfig.retrieveOneWay.description')}
@ -250,12 +249,15 @@ const ConfigContent: FC<Props> = ({
onClick={() => handleRerankModeChange(option.value)}
>
<div className='truncate'>{option.label}</div>
<TooltipPlus
popupContent={<div className='w-[200px]'>{option.tips}</div>}
hideArrow
>
<RiQuestionLine className='ml-0.5 w-3.5 h-4.5 text-text-quaternary' />
</TooltipPlus>
<Tooltip
popupContent={
<div className='w-[200px]'>
{option.tips}
</div>
}
popupClassName='ml-0.5'
triggerClassName='ml-0.5 w-3.5 h-3.5'
/>
</div>
))
}
@ -281,9 +283,15 @@ const ConfigContent: FC<Props> = ({
)
}
<div className='ml-2 leading-[32px] text-[13px] font-medium text-gray-900'>{t('common.modelProvider.rerankModel.key')}</div>
<TooltipPlus popupContent={<div className="w-[200px]">{t('common.modelProvider.rerankModel.tip')}</div>}>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-gray-400' />
</TooltipPlus>
<Tooltip
popupContent={
<div className="w-[200px]">
{t('common.modelProvider.rerankModel.tip')}
</div>
}
popupClassName='ml-0.5'
triggerClassName='ml-0.5 w-3.5 h-3.5'
/>
</div>
<div>
<ModelSelector
@ -361,11 +369,9 @@ const ConfigContent: FC<Props> = ({
<div className='mt-4'>
<div className='flex items-center space-x-0.5'>
<div className='leading-[32px] text-[13px] font-medium text-gray-900'>{t('common.modelProvider.systemReasoningModel.key')}</div>
<TooltipPlus
<Tooltip
popupContent={t('common.modelProvider.systemReasoningModel.tip')}
>
<RiQuestionLine className='w-3.5 h-4.5 text-gray-400' />
</TooltipPlus>
/>
</div>
<ModelParameterModal
isInWorkflow={isInWorkflow}

View File

@ -13,7 +13,7 @@ import {
} from '@/app/components/header/account-setting/model-provider-page/declarations'
import { useDebugConfigurationContext } from '@/context/debug-configuration'
import { CubeOutline } from '@/app/components/base/icons/src/vender/line/shapes'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
@ -111,9 +111,9 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({
<RiArrowDownSLine className={`w-3 h-3 ${(currentModel && currentProvider) ? 'text-gray-800' : 'text-primary-600'}`} />
{
currentModel && currentModel.status !== ModelStatusEnum.active && (
<TooltipPlus popupContent={MODEL_STATUS_TEXT[currentModel.status][language]}>
<Tooltip popupContent={MODEL_STATUS_TEXT[currentModel.status][language]}>
<AlertTriangle className='w-4 h-4 text-[#F79009]' />
</TooltipPlus>
</Tooltip>
)
}
</div>

View File

@ -2,9 +2,6 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import SuggestedQuestionsAfterAnswerIcon from '@/app/components/app/configuration/base/icons/suggested-questions-after-answer-icon'
import Tooltip from '@/app/components/base/tooltip'
@ -15,13 +12,15 @@ const SuggestedQuestionsAfterAnswer: FC = () => {
return (
<Panel
title={
<div className='flex items-center gap-2'>
<div className='flex items-center gap-1'>
<div>{t('appDebug.feature.suggestedQuestionsAfterAnswer.title')}</div>
<Tooltip htmlContent={<div className='w-[180px]'>
{t('appDebug.feature.suggestedQuestionsAfterAnswer.description')}
</div>} selector='suggestion-question-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]'>
{t('appDebug.feature.suggestedQuestionsAfterAnswer.description')}
</div>
}
/>
</div>
}
headerIcon={<SuggestedQuestionsAfterAnswerIcon />}

View File

@ -16,7 +16,7 @@ import { AppType, ModelModeType } from '@/types/app'
import Select from '@/app/components/base/select'
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import Button from '@/app/components/base/button'
import Tooltip from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader'
import type { VisionFile, VisionSettings } from '@/types/app'
@ -207,6 +207,7 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
{canNotRun
? (<Tooltip
popupContent={t('appDebug.otherError.promptNoBeEmpty')}
needsDelay
>
{renderRunButton()}
</Tooltip>)

View File

@ -8,7 +8,7 @@ import { MessageCheckRemove, MessageFastPlus } from '@/app/components/base/icons
import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication'
import { Edit04 } from '@/app/components/base/icons/src/vender/line/general'
import RemoveAnnotationConfirmModal from '@/app/components/app/annotation/remove-annotation-confirm-modal'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { addAnnotation, delAnnotation } from '@/service/annotation'
import Toast from '@/app/components/base/toast'
import { useProviderContext } from '@/context/provider-context'
@ -99,8 +99,9 @@ const CacheCtrlBtn: FC<Props> = ({
)
: answer
? (
<TooltipPlus
popupContent={t('appDebug.feature.annotation.add') as string}
<Tooltip
popupContent={t('appDebug.feature.annotation.add')}
needsDelay
>
<div
className='p-1 rounded-md hover:bg-[#EEF4FF] hover:text-[#444CE7] cursor-pointer'
@ -108,12 +109,13 @@ const CacheCtrlBtn: FC<Props> = ({
>
<MessageFastPlus className='w-4 h-4' />
</div>
</TooltipPlus>
</Tooltip>
)
: null
}
<TooltipPlus
popupContent={t('appDebug.feature.annotation.edit') as string}
<Tooltip
popupContent={t('appDebug.feature.annotation.edit')}
needsDelay
>
<div
className='p-1 cursor-pointer rounded-md hover:bg-black/5'
@ -121,7 +123,7 @@ const CacheCtrlBtn: FC<Props> = ({
>
<Edit04 className='w-4 h-4' />
</div>
</TooltipPlus>
</Tooltip>
</div>
<RemoveAnnotationConfirmModal

View File

@ -4,13 +4,10 @@ import React from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { usePathname, useRouter } from 'next/navigation'
import {
RiQuestionLine,
} from '@remixicon/react'
import ConfigParamModal from './config-param-modal'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { LinkExternal02, Settings04 } from '@/app/components/base/icons/src/vender/line/general'
import ConfigContext from '@/context/debug-configuration'
import type { EmbeddingModelConfig } from '@/app/components/app/annotation/type'
@ -31,13 +28,11 @@ export const Item: FC<{ title: string; tooltip: string; children: JSX.Element }>
<div>
<div className='flex items-center space-x-1'>
<div>{title}</div>
<TooltipPlus
<Tooltip
popupContent={
<div className='max-w-[200px] leading-[18px] text-[13px] font-medium text-gray-800'>{tooltip}</div>
}
>
<RiQuestionLine className='w-3.5 h-3.5 text-gray-400' />
</TooltipPlus>
/>
</div>
<div>{children}</div>
</div>

View File

@ -7,11 +7,10 @@ import {
RiAddLine,
RiArrowDownSLine,
RiDeleteBinLine,
RiQuestionLine,
} from '@remixicon/react'
import ConfigContext from '@/context/debug-configuration'
import Switch from '@/app/components/base/switch'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { Tool03 } from '@/app/components/base/icons/src/vender/solid/general'
import {
Settings01,
@ -107,9 +106,13 @@ const Tools = () => {
<div className='mr-1 text-sm font-semibold text-gray-800'>
{t('appDebug.feature.tools.title')}
</div>
<TooltipPlus popupContent={<div className='max-w-[160px]'>{t('appDebug.feature.tools.tips')}</div>}>
<RiQuestionLine className='w-3.5 h-3.5 text-gray-400' />
</TooltipPlus>
<Tooltip
popupContent={
<div className='max-w-[160px]'>
{t('appDebug.feature.tools.tips')}
</div>
}
/>
</div>
{
!expanded && !!externalDataToolsConfig.length && (
@ -143,7 +146,7 @@ const Tools = () => {
background={item.icon_background}
/>
<div className='mr-2 text-[13px] font-medium text-gray-800'>{item.label}</div>
<TooltipPlus
<Tooltip
popupContent={copied ? t('appApi.copied') : `${item.variable}, ${t('appApi.copy')}`}
>
<div
@ -155,7 +158,7 @@ const Tools = () => {
>
{item.variable}
</div>
</TooltipPlus>
</Tooltip>
</div>
<div
className='hidden group-hover:flex items-center justify-center mr-1 w-6 h-6 hover:bg-black/5 rounded-md cursor-pointer'

View File

@ -23,7 +23,7 @@ import AppIcon from '@/app/components/base/app-icon'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import { AiText, ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication'
import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { getRedirection } from '@/utils/app-redirection'
@ -100,8 +100,7 @@ const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => {
<div className='py-2 px-8'>
<div className='py-2 text-sm leading-[20px] font-medium text-gray-900'>{t('app.newApp.captionAppType')}</div>
<div className='flex'>
<TooltipPlus
hideArrow
<Tooltip
popupContent={
<div className='max-w-[280px] leading-[18px] text-xs text-gray-700'>{t('app.newApp.chatbotDescription')}</div>
}
@ -120,9 +119,8 @@ const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => {
<ChatBot className='w-6 h-6 text-[#1570EF]' />
<div className='h-5 text-[13px] font-medium leading-[18px]'>{t('app.types.chatbot')}</div>
</div>
</TooltipPlus>
<TooltipPlus
hideArrow
</Tooltip>
<Tooltip
popupContent={
<div className='flex flex-col max-w-[320px] leading-[18px] text-xs'>
<div className='text-gray-700'>{t('app.newApp.completionDescription')}</div>
@ -143,9 +141,8 @@ const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => {
<AiText className='w-6 h-6 text-[#0E9384]' />
<div className='h-5 text-[13px] font-medium leading-[18px]'>{t('app.newApp.completeApp')}</div>
</div>
</TooltipPlus>
<TooltipPlus
hideArrow
</Tooltip>
<Tooltip
popupContent={
<div className='max-w-[280px] leading-[18px] text-xs text-gray-700'>{t('app.newApp.agentDescription')}</div>
}
@ -164,9 +161,8 @@ const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => {
<CuteRobote className='w-6 h-6 text-indigo-600' />
<div className='h-5 text-[13px] font-medium leading-[18px]'>{t('app.types.agent')}</div>
</div>
</TooltipPlus>
<TooltipPlus
hideArrow
</Tooltip>
<Tooltip
popupContent={
<div className='flex flex-col max-w-[320px] leading-[18px] text-xs'>
<div className='text-gray-700'>{t('app.newApp.workflowDescription')}</div>
@ -188,7 +184,7 @@ const CreateAppModal = ({ show, onSuccess, onClose }: CreateAppDialogProps) => {
<div className='h-5 text-[13px] font-medium leading-[18px]'>{t('app.types.workflow')}</div>
<span className='absolute top-[-3px] right-[-3px] px-1 rounded-[5px] bg-white border border-black/8 text-gray-500 text-[10px] leading-[18px] font-medium'>BETA</span>
</div>
</TooltipPlus>
</Tooltip>
</div>
</div>
{showChatBotType && (

View File

@ -5,10 +5,9 @@ import useSWR from 'swr'
import {
HandThumbDownIcon,
HandThumbUpIcon,
InformationCircleIcon,
XMarkIcon,
} from '@heroicons/react/24/outline'
import { RiEditFill } from '@remixicon/react'
import { RiEditFill, RiQuestionLine } from '@remixicon/react'
import { get } from 'lodash-es'
import InfiniteScroll from 'react-infinite-scroll-component'
import dayjs from 'dayjs'
@ -20,7 +19,6 @@ import { useTranslation } from 'react-i18next'
import s from './style.module.css'
import VarPanel from './var-panel'
import cn from '@/utils/classnames'
import { randomString } from '@/utils'
import type { FeedbackFunc, Feedbacktype, IChatItem, SubmitAnnotationFunc } from '@/app/components/base/chat/chat/type'
import type { Annotation, ChatConversationFullDetailResponse, ChatConversationGeneralDetail, ChatConversationsResponse, ChatMessage, ChatMessagesRequest, CompletionConversationFullDetailResponse, CompletionConversationGeneralDetail, CompletionConversationsResponse, LogAnnotation } from '@/models/log'
import type { App } from '@/types/app'
@ -28,7 +26,6 @@ import Loading from '@/app/components/base/loading'
import Drawer from '@/app/components/base/drawer'
import Popover from '@/app/components/base/popover'
import Chat from '@/app/components/base/chat/chat'
import Tooltip from '@/app/components/base/tooltip'
import { ToastContext } from '@/app/components/base/toast'
import { fetchChatConversationDetail, fetchChatMessages, fetchCompletionConversationDetail, updateLogMessageAnnotations, updateLogMessageFeedbacks } from '@/service/log'
import { TONE_LIST } from '@/config'
@ -42,7 +39,7 @@ import MessageLogModal from '@/app/components/base/message-log-modal'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useAppContext } from '@/context/app-context'
import useTimestamp from '@/hooks/use-timestamp'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { CopyIcon } from '@/app/components/base/copy-icon'
dayjs.extend(utc)
@ -346,11 +343,11 @@ function DetailPanel<T extends ChatConversationFullDetailResponse | CompletionCo
<div className='text-gray-500 text-[10px] leading-[14px]'>{isChatMode ? t('appLog.detail.conversationId') : t('appLog.detail.time')}</div>
{isChatMode && (
<div className='flex items-center text-gray-700 text-[13px] leading-[18px]'>
<TooltipPlus
hideArrow
popupContent={detail.id}>
<Tooltip
popupContent={detail.id}
>
<div className='max-w-[105px] truncate'>{detail.id}</div>
</TooltipPlus>
</Tooltip>
<CopyIcon content={detail.id} />
</div>
)}
@ -380,7 +377,7 @@ function DetailPanel<T extends ChatConversationFullDetailResponse | CompletionCo
btnClassName='mr-4 !bg-gray-50 !py-1.5 !px-2.5 border-none font-normal'
btnElement={<>
<span className='text-[13px]'>{targetTone}</span>
<InformationCircleIcon className='h-4 w-4 text-gray-800 ml-1.5' />
<RiQuestionLine className='h-4 w-4 text-gray-800 ml-1.5' />
</>}
htmlContent={<div className='w-[280px]'>
<div className='flex justify-between py-2 px-4 font-medium text-sm text-gray-700'>
@ -641,13 +638,12 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
const renderTdValue = (value: string | number | null, isEmptyStyle: boolean, isHighlight = false, annotation?: LogAnnotation) => {
return (
<Tooltip
htmlContent={
popupContent={
<span className='text-xs text-gray-500 inline-flex items-center'>
<RiEditFill className='w-3 h-3 mr-1' />{`${t('appLog.detail.annotationTip', { user: annotation?.account?.name })} ${formatTime(annotation?.created_at || dayjs().unix(), 'MM-DD hh:mm A')}`}
</span>
}
className={(isHighlight && !isChatMode) ? '' : '!hidden'}
selector={`highlight-${randomString(16)}`}
popupClassName={(isHighlight && !isChatMode) ? '' : '!hidden'}
>
<div className={cn(isEmptyStyle ? 'text-gray-400' : 'text-gray-700', !isHighlight ? '' : 'bg-orange-100', 'text-sm overflow-hidden text-ellipsis whitespace-nowrap')}>
{value || '-'}

View File

@ -195,8 +195,7 @@ function AppCard({
)}
{isApp && isCurrentWorkspaceManager && (
<Tooltip
content={t('appOverview.overview.appInfo.regenerate') || ''}
selector={`code-generate-${randomString(8)}`}
popupContent={t('appOverview.overview.appInfo.regenerate') || ''}
>
<div
className="w-8 h-8 ml-0.5 cursor-pointer hover:bg-gray-200 rounded-lg"
@ -227,11 +226,10 @@ function AppCard({
disabled={disabled}
>
<Tooltip
content={
popupContent={
t('appOverview.overview.appInfo.preUseReminder') ?? ''
}
selector={`op-btn-${randomString(16)}`}
className={disabled ? 'mt-[-8px]' : '!hidden'}
popupClassName={disabled ? 'mt-[-8px]' : '!hidden'}
>
<div className="flex flex-row items-center">
<op.opIcon className="h-4 w-4 mr-1.5 stroke-[1.8px]" />

View File

@ -153,8 +153,7 @@ const Embedded = ({ siteInfo, isShow, onClose, appBaseUrl, accessToken, classNam
</div>
<div className="flex items-center justify-center gap-1 p-2 rounded-lg">
<Tooltip
selector={'code-copy-feedback'}
content={(isCopied[option] ? t(`${prefixEmbedded}.copied`) : t(`${prefixEmbedded}.copy`)) || ''}
popupContent={(isCopied[option] ? t(`${prefixEmbedded}.copied`) : t(`${prefixEmbedded}.copy`)) || ''}
>
<div className="w-8 h-8 rounded-lg cursor-pointer hover:bg-gray-100">
<div onClick={onClickCopy} className={`w-full h-full ${copyStyle.copyIcon} ${isCopied[option] ? copyStyle.copied : ''}`}></div>

View File

@ -15,7 +15,7 @@ import type { AppDetailResponse } from '@/models/app'
import type { AppIconType, AppSSO, Language } from '@/types/app'
import { useToastContext } from '@/app/components/base/toast'
import { languages } from '@/i18n/language'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import AppContext from '@/context/app-context'
import type { AppIconSelection } from '@/app/components/base/app-icon-picker'
import AppIconPicker from '@/app/components/base/app-icon-picker'
@ -240,9 +240,15 @@ const SettingsModal: FC<ISettingsModalProps> = ({
<p className='system-xs-medium text-gray-500'>{t(`${prefixSettings}.sso.label`)}</p>
<div className='flex justify-between items-center'>
<div className='font-medium system-sm-semibold flex-grow text-gray-900'>{t(`${prefixSettings}.sso.title`)}</div>
<TooltipPlus disabled={systemFeatures.sso_enforced_for_web} popupContent={<div className='w-[180px]'>{t(`${prefixSettings}.sso.tooltip`)}</div>}>
<Tooltip
disabled={systemFeatures.sso_enforced_for_web}
popupContent={
<div className='w-[180px]'>{t(`${prefixSettings}.sso.tooltip`)}</div>
}
asChild={false}
>
<Switch disabled={!systemFeatures.sso_enforced_for_web} defaultValue={systemFeatures.sso_enforced_for_web && inputInfo.enable_sso} onChange={v => setInputInfo({ ...inputInfo, enable_sso: v })}></Switch>
</TooltipPlus>
</Tooltip>
</div>
<p className='body-xs-regular text-gray-500'>{t(`${prefixSettings}.sso.description`)}</p>
</div>}

View File

@ -83,25 +83,25 @@ const AudioBtn = ({
}[audioState]
return (
<div className={`${(audioState === 'loading' || audioState === 'playing') ? 'mr-1' : className}`}>
<div className={`inline-flex items-center justify-center ${(audioState === 'loading' || audioState === 'playing') ? 'mr-1' : className}`}>
<Tooltip
selector={selector.current}
content={tooltipContent}
className='z-10'
popupContent={tooltipContent}
>
<button
disabled={audioState === 'loading'}
className={`box-border p-0.5 flex items-center justify-center cursor-pointer ${isAudition || '!p-0 rounded-md bg-white'}`}
className={`box-border w-6 h-6 flex items-center justify-center cursor-pointer ${isAudition ? 'p-0.5' : 'p-0 rounded-md bg-white'}`}
onClick={handleToggle}
>
{audioState === 'loading'
? (
<div className='w-6 h-6 rounded-md flex items-center justify-center p-2'>
<div className='w-full h-full rounded-md flex items-center justify-center'>
<Loading />
</div>
)
: (
<div className={`w-6 h-6 rounded-md ${!isAudition ? 'w-4 h-4 hover:bg-gray-50' : 'hover:bg-gray-50'} ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>
<div className={`w-full h-full rounded-md flex items-center justify-center ${!isAudition ? 'hover:bg-gray-50' : 'hover:bg-gray-50'}`}>
<div className={`w-4 h-4 ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>
</div>
)}
</button>
</Tooltip>

View File

@ -17,7 +17,7 @@ import {
ThumbsDown,
ThumbsUp,
} from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import Log from '@/app/components/base/chat/chat/log'
type OperationProps = {
@ -162,28 +162,34 @@ const Operation: FC<OperationProps> = ({
{
config?.supportFeedback && !localFeedback?.rating && onFeedback && !isOpeningStatement && (
<div className='hidden group-hover:flex ml-1 shrink-0 items-center px-0.5 bg-white border-[0.5px] border-gray-100 shadow-md text-gray-500 rounded-lg'>
<TooltipPlus popupContent={t('appDebug.operation.agree')}>
<Tooltip
popupContent={t('appDebug.operation.agree')}
>
<div
className='flex items-center justify-center mr-0.5 w-6 h-6 rounded-md hover:bg-black/5 hover:text-gray-800 cursor-pointer'
onClick={() => handleFeedback('like')}
>
<ThumbsUp className='w-4 h-4' />
</div>
</TooltipPlus>
<TooltipPlus popupContent={t('appDebug.operation.disagree')}>
</Tooltip>
<Tooltip
popupContent={t('appDebug.operation.disagree')}
>
<div
className='flex items-center justify-center w-6 h-6 rounded-md hover:bg-black/5 hover:text-gray-800 cursor-pointer'
onClick={() => handleFeedback('dislike')}
>
<ThumbsDown className='w-4 h-4' />
</div>
</TooltipPlus>
</Tooltip>
</div>
)
}
{
config?.supportFeedback && localFeedback?.rating && onFeedback && !isOpeningStatement && (
<TooltipPlus popupContent={localFeedback.rating === 'like' ? t('appDebug.operation.cancelAgree') : t('appDebug.operation.cancelDisagree')}>
<Tooltip
popupContent={localFeedback.rating === 'like' ? t('appDebug.operation.cancelAgree') : t('appDebug.operation.cancelDisagree')}
>
<div
className={`
flex items-center justify-center w-7 h-7 rounded-[10px] border-[2px] border-white cursor-pointer
@ -203,7 +209,7 @@ const Operation: FC<OperationProps> = ({
)
}
</div>
</TooltipPlus>
</Tooltip>
)
}
</div>

View File

@ -17,7 +17,7 @@ import { TransferMethod } from '../types'
import { useChatWithHistoryContext } from '../chat-with-history/context'
import type { Theme } from '../embedded-chatbot/theme/theme-context'
import { CssTransform } from '../embedded-chatbot/theme/utils'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { ToastContext } from '@/app/components/base/toast'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import VoiceInput from '@/app/components/base/voice-input'
@ -220,7 +220,7 @@ const ChatInput: FC<ChatInputProps> = ({
{isMobile
? sendBtn
: (
<TooltipPlus
<Tooltip
popupContent={
<div>
<div>{t('common.operation.send')} Enter</div>
@ -229,7 +229,7 @@ const ChatInput: FC<ChatInputProps> = ({
}
>
{sendBtn}
</TooltipPlus>
</Tooltip>
)}
</div>
{

View File

@ -41,9 +41,7 @@ const Header: FC<IHeaderProps> = ({
</div>
</div>
<Tooltip
selector={'embed-scene-restart-button'}
htmlContent={t('share.chat.resetChat')}
position='top'
popupContent={t('share.chat.resetChat')}
>
<div className='flex cursor-pointer hover:rounded-lg hover:bg-black/5 w-8 h-8 items-center justify-center' onClick={() => {
onCreateNewChat?.()

View File

@ -88,9 +88,7 @@ const Chatbot = () => {
{!isMobile && (
<div className='absolute top-2.5 right-3 z-20'>
<Tooltip
selector={'embed-scene-restart-button'}
htmlContent={t('share.chat.resetChat')}
position='top'
popupContent={t('share.chat.resetChat')}
>
<div className='p-1.5 bg-white border-[0.5px] border-gray-100 rounded-lg shadow-md cursor-pointer' onClick={handleNewConversation}>
<RiLoopLeftLine className="h-4 w-4 text-gray-500"/>

View File

@ -1,10 +1,9 @@
'use client'
import { useRef, useState } from 'react'
import { useState } from 'react'
import { t } from 'i18next'
import copy from 'copy-to-clipboard'
import s from './style.module.css'
import Tooltip from '@/app/components/base/tooltip'
import { randomString } from '@/utils'
type ICopyBtnProps = {
value: string
@ -18,14 +17,11 @@ const CopyBtn = ({
isPlain,
}: ICopyBtnProps) => {
const [isCopied, setIsCopied] = useState(false)
const selector = useRef(`copy-tooltip-${randomString(4)}`)
return (
<div className={`${className}`}>
<Tooltip
selector={selector.current}
content={(isCopied ? t('appApi.copied') : t('appApi.copy')) as string}
className='z-10'
popupContent={(isCopied ? t('appApi.copied') : t('appApi.copy'))}
>
<div
className={'box-border p-0.5 flex items-center justify-center rounded-md bg-white cursor-pointer'}

View File

@ -3,19 +3,17 @@ import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { debounce } from 'lodash-es'
import copy from 'copy-to-clipboard'
import Tooltip from '../tooltip'
import TooltipPlus from '../tooltip-plus'
import copyStyle from './style.module.css'
import Tooltip from '@/app/components/base/tooltip'
type Props = {
content: string
selectorId: string
className?: string
}
const prefixEmbedded = 'appOverview.overview.appInfo.embedded'
const CopyFeedback = ({ content, selectorId, className }: Props) => {
const CopyFeedback = ({ content, className }: Props) => {
const { t } = useTranslation()
const [isCopied, setIsCopied] = useState<boolean>(false)
@ -30,8 +28,7 @@ const CopyFeedback = ({ content, selectorId, className }: Props) => {
return (
<Tooltip
selector={`common-copy-feedback-${selectorId}`}
content={
popupContent={
(isCopied
? t(`${prefixEmbedded}.copied`)
: t(`${prefixEmbedded}.copy`)) || ''
@ -41,10 +38,10 @@ const CopyFeedback = ({ content, selectorId, className }: Props) => {
className={`w-8 h-8 cursor-pointer hover:bg-gray-100 rounded-lg ${
className ?? ''
}`}
onMouseLeave={onMouseLeave}
>
<div
onClick={onClickCopy}
onMouseLeave={onMouseLeave}
className={`w-full h-full ${copyStyle.copyIcon} ${
isCopied ? copyStyle.copied : ''
}`}
@ -70,7 +67,7 @@ export const CopyFeedbackNew = ({ content, className }: Pick<Props, 'className'
}, 100)
return (
<TooltipPlus
<Tooltip
popupContent={
(isCopied
? t(`${prefixEmbedded}.copied`)
@ -81,15 +78,15 @@ export const CopyFeedbackNew = ({ content, className }: Pick<Props, 'className'
className={`w-8 h-8 cursor-pointer hover:bg-gray-100 rounded-lg ${
className ?? ''
}`}
onMouseLeave={onMouseLeave}
>
<div
onClick={onClickCopy}
onMouseLeave={onMouseLeave}
className={`w-full h-full ${copyStyle.copyIcon} ${
isCopied ? copyStyle.copied : ''
}`}
></div>
</div>
</TooltipPlus>
</Tooltip>
)
}

View File

@ -3,7 +3,7 @@ import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { debounce } from 'lodash-es'
import copy from 'copy-to-clipboard'
import TooltipPlus from '../tooltip-plus'
import Tooltip from '../tooltip'
import {
Clipboard,
ClipboardCheck,
@ -29,7 +29,7 @@ export const CopyIcon = ({ content }: Props) => {
}, 100)
return (
<TooltipPlus
<Tooltip
popupContent={
(isCopied
? t(`${prefixEmbedded}.copied`)
@ -46,7 +46,7 @@ export const CopyIcon = ({ content }: Props) => {
)
}
</div>
</TooltipPlus>
</Tooltip>
)
}

View File

@ -2,11 +2,8 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import { MessageSmileSquare } from '@/app/components/base/icons/src/vender/solid/communication'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
const SuggestedQuestionsAfterAnswer: FC = () => {
const { t } = useTranslation()
@ -18,9 +15,7 @@ const SuggestedQuestionsAfterAnswer: FC = () => {
</div>
<div className='shrink-0 mr-2 flex items-center whitespace-nowrap text-sm text-gray-800 font-semibold'>
<div className='mr-2'>{t('appDebug.feature.suggestedQuestionsAfterAnswer.title')}</div>
<TooltipPlus popupContent={t('appDebug.feature.suggestedQuestionsAfterAnswer.description')}>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</TooltipPlus>
<Tooltip popupContent={t('appDebug.feature.suggestedQuestionsAfterAnswer.description')}/>
</div>
<div className='grow'></div>
<div className='text-xs text-gray-500'>{t('appDebug.feature.suggestedQuestionsAfterAnswer.resDes')}</div>

View File

@ -2,9 +2,6 @@
import useSWR from 'swr'
import produce from 'immer'
import React, { Fragment } from 'react'
import {
RiQuestionLine,
} from '@remixicon/react'
import { usePathname } from 'next/navigation'
import { useTranslation } from 'react-i18next'
import { Listbox, Transition } from '@headlessui/react'
@ -74,13 +71,16 @@ const VoiceParamConfig = ({
<div className='mb-2 flex items-center space-x-1'>
<div
className='leading-[18px] text-[13px] font-semibold text-gray-800'>{t('appDebug.voice.voiceSettings.language')}</div>
<Tooltip htmlContent={<div className='w-[180px]'>
{t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => (
<div key={item}>{item}</div>
))}
</div>} selector='config-resolution-tooltip'>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400'/>
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]'>
{t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => (
<div key={item}>{item}
</div>
))}
</div>
}
/>
</div>
<Listbox
value={languageItem}

View File

@ -8,7 +8,7 @@ import {
import cn from '@/utils/classnames'
import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import type { ImageFile } from '@/types/app'
import { TransferMethod } from '@/types/app'
import ImagePreview from '@/app/components/base/image-uploader/image-preview'
@ -87,11 +87,11 @@ const ImageList: FC<ImageListProps> = ({
<RiLoader2Line className="animate-spin w-5 h-5 text-white" />
)}
{item.progress === -1 && (
<TooltipPlus
<Tooltip
popupContent={t('common.imageUploader.pasteImageLinkInvalid')}
>
<AlertTriangle className="w-4 h-4 text-[#DC6803]" />
</TooltipPlus>
</Tooltip>
)}
</div>
)}

View File

@ -1,10 +1,6 @@
'use client'
import type { FC } from 'react'
import {
RiQuestionLine,
} from '@remixicon/react'
import Tooltip from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import Slider from '@/app/components/base/slider'
import Switch from '@/app/components/base/switch'
@ -40,9 +36,9 @@ const ParamItem: FC<Props> = ({ className, id, name, noTooltip, tip, step = 0.1,
)}
<span className="mx-1 text-gray-900 text-[13px] leading-[18px] font-medium">{name}</span>
{!noTooltip && (
<Tooltip popupContent={<div className="w-[200px]">{tip}</div>}>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={<div className="w-[200px]">{tip}</div>}
/>
)}
</div>

View File

@ -25,7 +25,7 @@ import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others
import { VarBlockIcon } from '@/app/components/workflow/block-icon'
import { Line3 } from '@/app/components/base/icons/src/public/common'
import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type WorkflowVariableBlockComponentProps = {
nodeKey: string
@ -113,9 +113,9 @@ const WorkflowVariableBlockComponent = ({
if (!node && !isEnv && !isChatVar) {
return (
<TooltipPlus popupContent={t('workflow.errorMsg.invalidVariable')}>
<Tooltip popupContent={t('workflow.errorMsg.invalidVariable')}>
{Item}
</TooltipPlus>
</Tooltip>
)
}

View File

@ -2,8 +2,8 @@
import React, { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import QRCode from 'qrcode.react'
import Tooltip from '../tooltip'
import QrcodeStyle from './style.module.css'
import Tooltip from '@/app/components/base/tooltip'
type Props = {
content: string
@ -51,8 +51,7 @@ const ShareQRCode = ({ content, selectorId, className }: Props) => {
return (
<Tooltip
selector={`common-qrcode-show-${selectorId}`}
content={t(`${prefixEmbedded}`) || ''}
popupContent={t(`${prefixEmbedded}`) || ''}
>
<div
className={`w-8 h-8 cursor-pointer rounded-lg ${className ?? ''}`}

View File

@ -1,109 +0,0 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { useBoolean } from 'ahooks'
import type { OffsetOptions, Placement } from '@floating-ui/react'
import cn from '@/utils/classnames'
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
export type TooltipProps = {
position?: Placement
triggerMethod?: 'hover' | 'click'
disabled?: boolean
popupContent: React.ReactNode
children: React.ReactNode
hideArrow?: boolean
popupClassName?: string
offset?: OffsetOptions
asChild?: boolean
}
const arrow = (
<svg className="absolute text-white h-2 w-full left-0 top-full" x="0px" y="0px" viewBox="0 0 255 255"><polygon className="fill-current" points="0,0 127.5,127.5 255,0"></polygon></svg>
)
const Tooltip: FC<TooltipProps> = ({
position = 'top',
triggerMethod = 'hover',
disabled = false,
popupContent,
children,
hideArrow,
popupClassName,
offset,
asChild,
}) => {
const [open, setOpen] = useState(false)
const [isHoverPopup, {
setTrue: setHoverPopup,
setFalse: setNotHoverPopup,
}] = useBoolean(false)
const isHoverPopupRef = useRef(isHoverPopup)
useEffect(() => {
isHoverPopupRef.current = isHoverPopup
}, [isHoverPopup])
const [isHoverTrigger, {
setTrue: setHoverTrigger,
setFalse: setNotHoverTrigger,
}] = useBoolean(false)
const isHoverTriggerRef = useRef(isHoverTrigger)
useEffect(() => {
isHoverTriggerRef.current = isHoverTrigger
}, [isHoverTrigger])
const handleLeave = (isTrigger: boolean) => {
if (isTrigger)
setNotHoverTrigger()
else
setNotHoverPopup()
// give time to move to the popup
setTimeout(() => {
if (!isHoverPopupRef.current && !isHoverTriggerRef.current)
setOpen(false)
}, 500)
}
return (
<PortalToFollowElem
open={disabled ? false : open}
onOpenChange={setOpen}
placement={position}
offset={offset ?? 10}
>
<PortalToFollowElemTrigger
onClick={() => triggerMethod === 'click' && setOpen(v => !v)}
onMouseEnter={() => {
if (triggerMethod === 'hover') {
setHoverTrigger()
setOpen(true)
}
}}
onMouseLeave={() => triggerMethod === 'hover' && handleLeave(true)}
asChild={asChild}
>
{children}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent
className="z-[9999]"
>
<div
className={cn(
'relative px-3 py-2 text-xs font-normal text-gray-700 bg-white rounded-md shadow-lg',
popupClassName,
)}
onMouseEnter={() => triggerMethod === 'hover' && setHoverPopup()}
onMouseLeave={() => triggerMethod === 'hover' && handleLeave(false)}
>
{popupContent}
{!hideArrow && arrow}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default React.memo(Tooltip)

View File

@ -1,52 +1,112 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { Tooltip as ReactTooltip } from 'react-tooltip' // fixed version to 5.8.3 https://github.com/ReactTooltip/react-tooltip/issues/972
import classNames from '@/utils/classnames'
import 'react-tooltip/dist/react-tooltip.css'
type TooltipProps = {
selector: string
content?: string
import React, { useEffect, useRef, useState } from 'react'
import { useBoolean } from 'ahooks'
import type { OffsetOptions, Placement } from '@floating-ui/react'
import { RiQuestionLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
export type TooltipProps = {
position?: Placement
triggerMethod?: 'hover' | 'click'
triggerClassName?: string
disabled?: boolean
htmlContent?: React.ReactNode
className?: string // This should use !impornant to override the default styles eg: '!bg-white'
position?: 'top' | 'right' | 'bottom' | 'left'
clickable?: boolean
children: React.ReactNode
noArrow?: boolean
popupContent?: React.ReactNode
children?: React.ReactNode
popupClassName?: string
offset?: OffsetOptions
needsDelay?: boolean
asChild?: boolean
}
const Tooltip: FC<TooltipProps> = ({
selector,
content,
disabled,
position = 'top',
triggerMethod = 'hover',
triggerClassName,
disabled = false,
popupContent,
children,
htmlContent,
className,
clickable,
noArrow,
popupClassName,
offset,
asChild = true,
needsDelay = false,
}) => {
const [open, setOpen] = useState(false)
const [isHoverPopup, {
setTrue: setHoverPopup,
setFalse: setNotHoverPopup,
}] = useBoolean(false)
const isHoverPopupRef = useRef(isHoverPopup)
useEffect(() => {
isHoverPopupRef.current = isHoverPopup
}, [isHoverPopup])
const [isHoverTrigger, {
setTrue: setHoverTrigger,
setFalse: setNotHoverTrigger,
}] = useBoolean(false)
const isHoverTriggerRef = useRef(isHoverTrigger)
useEffect(() => {
isHoverTriggerRef.current = isHoverTrigger
}, [isHoverTrigger])
const handleLeave = (isTrigger: boolean) => {
if (isTrigger)
setNotHoverTrigger()
else
setNotHoverPopup()
// give time to move to the popup
if (needsDelay) {
setTimeout(() => {
if (!isHoverPopupRef.current && !isHoverTriggerRef.current)
setOpen(false)
}, 500)
}
else {
setOpen(false)
}
}
return (
<div className='tooltip-container'>
{React.cloneElement(children as React.ReactElement, {
'data-tooltip-id': selector,
})
}
<ReactTooltip
id={selector}
content={content}
className={classNames('!z-[999] !bg-white !text-xs !font-normal !text-gray-700 !shadow-lg !opacity-100', className)}
place={position}
clickable={clickable}
isOpen={disabled ? false : undefined}
noArrow={noArrow}
<PortalToFollowElem
open={disabled ? false : open}
onOpenChange={setOpen}
placement={position}
offset={offset ?? 8}
>
<PortalToFollowElemTrigger
onClick={() => triggerMethod === 'click' && setOpen(v => !v)}
onMouseEnter={() => {
if (triggerMethod === 'hover') {
setHoverTrigger()
setOpen(true)
}
}}
onMouseLeave={() => triggerMethod === 'hover' && handleLeave(true)}
asChild={asChild}
>
{htmlContent && htmlContent}
</ReactTooltip>
</div>
{children || <div className={triggerClassName || 'p-[1px] w-3.5 h-3.5 shrink-0'}><RiQuestionLine className='text-text-quaternary hover:text-text-tertiary w-full h-full' /></div>}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent
className="z-[9999]"
>
{popupContent && (<div
className={cn(
'relative px-3 py-2 text-xs font-normal text-gray-700 bg-white rounded-md shadow-lg break-words',
popupClassName,
)}
onMouseEnter={() => triggerMethod === 'hover' && setHoverPopup()}
onMouseLeave={() => triggerMethod === 'hover' && handleLeave(false)}
>
{popupContent}
</div>)}
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default Tooltip
export default React.memo(Tooltip)

View File

@ -2,14 +2,11 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import { useContext } from 'use-context-selector'
import { Plan } from '../type'
import { ALL_PLANS, NUM_INFINITE, contactSalesUrl, contractSales, unAvailable } from '../config'
import Toast from '../../base/toast'
import TooltipPlus from '../../base/tooltip-plus'
import Tooltip from '../../base/tooltip'
import { PlanRange } from './select-plan-range'
import cn from '@/utils/classnames'
import { useAppContext } from '@/context/app-context'
@ -30,13 +27,11 @@ const KeyValue = ({ label, value, tooltip }: { label: string; value: string | nu
<div className='flex items-center text-gray-500 space-x-1'>
<div>{label}</div>
{tooltip && (
<TooltipPlus
<Tooltip
popupContent={
<div className='w-[200px]'>{tooltip}</div>
}
>
<RiQuestionLine className='w-3 h-3 text-gray-400' />
</TooltipPlus>
/>
)}
</div>
<div className='mt-0.5 text-gray-900'>{value}</div>
@ -136,25 +131,21 @@ const PlanItem: FC<Props> = ({
<div className='mt-3.5 flex items-center space-x-1'>
<span>+ </span>
<div>{t('billing.plansCommon.supportItems.llmLoadingBalancing')}</div>
<TooltipPlus
<Tooltip
popupContent={
<div className='w-[200px]'>{t('billing.plansCommon.supportItems.llmLoadingBalancingTooltip')}</div>
}
>
<RiQuestionLine className='w-3 h-3 text-gray-400' />
</TooltipPlus>
/>
</div>
<div className='mt-3.5 flex items-center space-x-1'>
<div className='flex items-center'>
+
<div className='mr-0.5'>&nbsp;{t('billing.plansCommon.supportItems.ragAPIRequest')}</div>
<TooltipPlus
<Tooltip
popupContent={
<div className='w-[200px]'>{t('billing.plansCommon.ragAPIRequestTooltip')}</div>
}
>
<RiQuestionLine className='w-3 h-3 text-gray-400' />
</TooltipPlus>
/>
</div>
<div>{comingSoon}</div>
</div>

View File

@ -9,7 +9,7 @@ import {
ZapFast,
ZapNarrow,
} from '@/app/components/base/icons/src/vender/solid/general'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
const PriorityLabel = () => {
const { t } = useTranslation()
@ -27,7 +27,7 @@ const PriorityLabel = () => {
}, [plan])
return (
<TooltipPlus popupContent={
<Tooltip popupContent={
<div>
<div className='mb-1 text-xs font-semibold text-gray-700'>{`${t('billing.plansCommon.documentProcessingPriority')}: ${t(`billing.plansCommon.priority.${priority}`)}`}</div>
{
@ -53,7 +53,7 @@ const PriorityLabel = () => {
}
{t(`billing.plansCommon.priority.${priority}`)}
</span>
</TooltipPlus>
</Tooltip>
)
}

View File

@ -2,7 +2,6 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { InfoCircle } from '../../base/icons/src/vender/line/general'
import ProgressBar from '../progress-bar'
import { NUM_INFINITE } from '../config'
import Tooltip from '@/app/components/base/tooltip'
@ -48,11 +47,13 @@ const UsageInfo: FC<Props> = ({
<Icon className='w-4 h-4 text-gray-700' />
<div className='mx-1 leading-5 text-sm font-medium text-gray-700'>{name}</div>
{tooltip && (
<Tooltip htmlContent={<div className='w-[180px]'>
{tooltip}
</div>} selector='config-var-tooltip'>
<InfoCircle className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className='w-[180px]'>
{tooltip}
</div>
}
/>
)}
</div>
<div className='flex items-center leading-[18px] text-[13px] font-normal'>

View File

@ -2,15 +2,13 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import cn from '@/utils/classnames'
import TopKItem from '@/app/components/base/param-item/top-k-item'
import ScoreThresholdItem from '@/app/components/base/param-item/score-threshold-item'
import { RETRIEVE_METHOD } from '@/types/app'
import Switch from '@/app/components/base/switch'
import Tooltip from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import type { RetrievalConfig } from '@/types/app'
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
import { useModelListAndDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
@ -114,9 +112,11 @@ const RetrievalParamConfig: FC<Props> = ({
)}
<div className='flex items-center'>
<span className='mr-0.5'>{t('common.modelProvider.rerankModel.key')}</span>
<Tooltip popupContent={<div className="w-[200px]">{t('common.modelProvider.rerankModel.tip')}</div>}>
<RiQuestionLine className='w-[14px] h-[14px] text-gray-400' />
</Tooltip>
<Tooltip
popupContent={
<div className="w-[200px]">{t('common.modelProvider.rerankModel.tip')}</div>
}
/>
</div>
</div>
<ModelSelector
@ -191,10 +191,8 @@ const RetrievalParamConfig: FC<Props> = ({
<div className='truncate'>{option.label}</div>
<Tooltip
popupContent={<div className='w-[200px]'>{option.tips}</div>}
hideArrow
>
<RiQuestionLine className='ml-0.5 w-3.5 h-4.5 text-text-quaternary' />
</Tooltip>
triggerClassName='ml-0.5 w-3.5 h-4.5'
/>
</div>
))
}

View File

@ -22,7 +22,7 @@ import { Plan } from '@/app/components/billing/type'
import { ZapFast } from '@/app/components/base/icons/src/vender/solid/general'
import UpgradeBtn from '@/app/components/billing/upgrade-btn'
import { useProviderContext } from '@/context/provider-context'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { sleep } from '@/utils'
type Props = {
@ -259,16 +259,18 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
<div className={s.percent}>{`${getSourcePercent(indexingStatusDetail)}%`}</div>
)}
{indexingStatusDetail.indexing_status === 'error' && indexingStatusDetail.error && (
<TooltipPlus popupContent={(
<div className='max-w-[400px]'>
{indexingStatusDetail.error}
</div>
)}>
<Tooltip
popupContent={(
<div className='max-w-[400px]'>
{indexingStatusDetail.error}
</div>
)}
>
<div className={cn(s.percent, s.error, 'flex items-center')}>
Error
<RiErrorWarningFill className='ml-1 w-4 h-4' />
</div>
</TooltipPlus>
</Tooltip>
)}
{indexingStatusDetail.indexing_status === 'error' && !indexingStatusDetail.error && (
<div className={cn(s.percent, s.error, 'flex items-center')}>

View File

@ -7,7 +7,6 @@ import { XMarkIcon } from '@heroicons/react/20/solid'
import { RocketLaunchIcon } from '@heroicons/react/24/outline'
import {
RiCloseLine,
RiQuestionLine,
} from '@remixicon/react'
import Link from 'next/link'
import { groupBy } from 'lodash-es'
@ -43,7 +42,6 @@ import { IS_CE_EDITION } from '@/config'
import { RETRIEVE_METHOD } from '@/types/app'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Tooltip from '@/app/components/base/tooltip'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { LanguagesSupported } from '@/i18n/language'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
@ -556,7 +554,7 @@ const StepTwo = ({
className='border-[0.5px] !h-8 hover:outline hover:outline-[0.5px] hover:outline-gray-300 text-gray-700 font-medium bg-white shadow-[0px_1px_2px_0px_rgba(16,24,40,0.05)]'
onClick={setShowPreview}
>
<Tooltip selector='data-preview-toggle'>
<Tooltip>
<div className="flex flex-row items-center">
<RocketLaunchIcon className="h-4 w-4 mr-1.5 stroke-[1.8px]" />
<span className="text-[13px]">{t('datasetCreation.stepTwo.previewTitleButton')}</span>
@ -628,13 +626,13 @@ const StepTwo = ({
<div className='w-full'>
<div className={s.label}>
{t('datasetCreation.stepTwo.overlap')}
<TooltipPlus popupContent={
<div className='max-w-[200px]'>
{t('datasetCreation.stepTwo.overlapTip')}
</div>
}>
<RiQuestionLine className='ml-1 w-3.5 h-3.5 text-gray-400' />
</TooltipPlus>
<Tooltip
popupContent={
<div className='max-w-[200px]'>
{t('datasetCreation.stepTwo.overlapTip')}
</div>
}
/>
</div>
<input
type="number"

View File

@ -1,12 +1,9 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import {
RiQuestionLine,
} from '@remixicon/react'
import Input from './input'
import cn from '@/utils/classnames'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type Props = {
className?: string
@ -37,11 +34,12 @@ const Field: FC<Props> = ({
<div className={cn(labelClassName, 'flex items-center h-[18px] text-[13px] font-medium text-gray-900')}>{label} </div>
{isRequired && <span className='ml-0.5 text-xs font-semibold text-[#D92D20]'>*</span>}
{tooltip && (
<TooltipPlus popupContent={
<div className='w-[200px]'>{tooltip}</div>
}>
<RiQuestionLine className='relative top-[3px] w-3 h-3 ml-1 text-gray-500' />
</TooltipPlus>
<Tooltip
popupContent={
<div className='w-[200px]'>{tooltip}</div>
}
popupClassName='relative top-[3px] w-3 h-3 ml-1'
/>
)}
</div>
<Input

View File

@ -102,7 +102,9 @@ const IconButton: FC<{
const metadataMap = useMetadataMap()
return (
<Tooltip content={metadataMap[type].text} selector={`doc-metadata-${type}`}>
<Tooltip
popupContent={metadataMap[type].text}
>
<button className={cn(s.iconWrapper, 'group', isChecked ? s.iconCheck : '')}>
<TypeIcon
iconName={metadataMap[type].iconName || ''}

View File

@ -7,14 +7,12 @@ import { ArrowDownIcon, TrashIcon } from '@heroicons/react/24/outline'
import { pick } from 'lodash-es'
import {
RiMoreFill,
RiQuestionLine,
} from '@remixicon/react'
import { useContext } from 'use-context-selector'
import { useRouter } from 'next/navigation'
import { useTranslation } from 'react-i18next'
import dayjs from 'dayjs'
import { Edit03 } from '../../base/icons/src/vender/solid/general'
import TooltipPlus from '../../base/tooltip-plus'
import { Globe01 } from '../../base/icons/src/vender/line/mapsAndTravel'
import s from './style.module.css'
import RenameModal from './rename-modal'
@ -94,13 +92,11 @@ export const StatusItem: FC<{
{
errorMessage && (
<Tooltip
selector='dataset-document-detail-item-status'
htmlContent={
popupContent={
<div className='max-w-[260px] break-all'>{errorMessage}</div>
}
>
<RiQuestionLine className='ml-1 w-[14px] h-[14px] text-gray-700' />
</Tooltip>
triggerClassName='ml-1 w-4 h-4'
/>
)
}
</div>
@ -201,7 +197,11 @@ export const OperationAction: FC<{
{isListScene && embeddingAvailable && (
<>
{archived
? <Tooltip selector={`list-switch-${id}`} content={t('datasetDocuments.list.action.enableWarning') as string} className='!font-semibold'>
? <Tooltip
popupContent={t('datasetDocuments.list.action.enableWarning')}
popupClassName='!font-semibold'
needsDelay
>
<div>
<Switch defaultValue={false} onChange={() => { }} disabled={true} size='md' />
</div>
@ -221,9 +221,9 @@ export const OperationAction: FC<{
{!archived && enabled ? t('datasetDocuments.list.index.enable') : t('datasetDocuments.list.index.disable')}
</span>
<Tooltip
selector={`detail-switch-${id}`}
content={t('datasetDocuments.list.action.enableWarning') as string}
className='!font-semibold'
popupContent={t('datasetDocuments.list.action.enableWarning')}
popupClassName='!font-semibold'
needsDelay
disabled={!archived}
>
<div>
@ -426,7 +426,9 @@ const DocumentList: FC<IDocumentListProps> = ({ embeddingAvailable, documents =
}
</span>
<div className='group-hover:flex hidden'>
<TooltipPlus popupContent={t('datasetDocuments.list.table.rename')}>
<Tooltip
popupContent={t('datasetDocuments.list.table.rename')}
>
<div
className='p-1 rounded-md cursor-pointer hover:bg-black/5'
onClick={(e) => {
@ -436,7 +438,7 @@ const DocumentList: FC<IDocumentListProps> = ({ embeddingAvailable, documents =
>
<Edit03 className='w-4 h-4 text-gray-500' />
</div>
</TooltipPlus>
</Tooltip>
</div>
</div>

View File

@ -1,9 +1,9 @@
import { useTranslation } from 'react-i18next'
import Button from '../../base/button'
import Tag from '../../base/tag'
import Tooltip from '../../base/tooltip'
import { getIcon } from '../common/retrieval-method-info'
import s from './style.module.css'
import Tooltip from '@/app/components/base/tooltip'
import cn from '@/utils/classnames'
import type { HitTestingResponse } from '@/models/datasets'
import { hitTesting } from '@/service/datasets'
@ -74,8 +74,7 @@ const TextAreaWithButton = ({
{t('datasetHitTesting.input.title')}
</span>
<Tooltip
selector={'change-retrieval-method'}
htmlContent={t('dataset.retrieval.changeRetrievalMethod')}
popupContent={t('dataset.retrieval.changeRetrievalMethod')}
>
<div
onClick={onClickRetrievalMethod}
@ -99,8 +98,7 @@ const TextAreaWithButton = ({
{text?.length > 200
? (
<Tooltip
content={t('datasetHitTesting.input.countWarning') as string}
selector="hit-testing-warning"
popupContent={t('datasetHitTesting.input.countWarning')}
>
<div>
<Tag color="red" className="!text-red-600">

View File

@ -1,9 +1,8 @@
'use client'
import React, { useEffect, useRef, useState } from 'react'
import React, { useEffect, useState } from 'react'
import copy from 'copy-to-clipboard'
import { t } from 'i18next'
import s from './style.module.css'
import { randomString } from '@/utils'
import Tooltip from '@/app/components/base/tooltip'
type IInputCopyProps = {
@ -21,8 +20,6 @@ const InputCopy = ({
}: IInputCopyProps) => {
const [isCopied, setIsCopied] = useState(false)
const selector = useRef(`input-tooltip-${randomString(4)}`)
useEffect(() => {
if (isCopied) {
const timeout = setTimeout(() => {
@ -40,22 +37,22 @@ const InputCopy = ({
<div className="flex items-center flex-grow h-5">
{children}
<div className='flex-grow bg-gray-50 text-[13px] relative h-full'>
<Tooltip
selector={selector.current}
content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
className='z-10'
>
<div className='absolute top-0 left-0 w-full pl-2 pr-2 truncate cursor-pointer r-0' onClick={() => {
copy(value)
setIsCopied(true)
}}>{value}</div>
</Tooltip>
<div className='absolute top-0 left-0 w-full pl-2 pr-2 truncate cursor-pointer r-0' onClick={() => {
copy(value)
setIsCopied(true)
}}>
<Tooltip
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
position='bottom'
>
{value}
</Tooltip>
</div>
</div>
<div className="flex-shrink-0 h-4 bg-gray-200 border" />
<Tooltip
selector={selector.current}
content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
className='z-10'
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
position='bottom'
>
<div className="px-0.5 flex-shrink-0">
<div className={`box-border w-[30px] h-[30px] flex items-center justify-center rounded-lg hover:bg-gray-100 cursor-pointer ${s.copyIcon} ${isCopied ? s.copied : ''}`} onClick={() => {

View File

@ -118,9 +118,8 @@ const SecretKeyModal = ({
<div className='flex-shrink-0 px-3 truncate w-[200px]'>{api.last_used_at ? formatTime(Number(api.last_used_at), t('appLog.dateTimeFormat') as string) : t('appApi.never')}</div>
<div className='flex flex-grow px-3'>
<Tooltip
selector={`key-${api.token}`}
content={copyValue === api.token ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
className='z-10'
popupContent={copyValue === api.token ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
popupClassName='mr-1'
>
<div className={`flex items-center justify-center flex-shrink-0 w-6 h-6 mr-1 rounded-lg cursor-pointer hover:bg-gray-100 ${s.copyIcon} ${copyValue === api.token ? s.copied : ''}`} onClick={() => {
// setIsCopied(true)

View File

@ -1,5 +1,6 @@
import { CheckCircleIcon } from '@heroicons/react/24/solid'
import { QuestionMarkCircleIcon, XMarkIcon } from '@heroicons/react/24/outline'
import { XMarkIcon } from '@heroicons/react/24/outline'
import { RiQuestionLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { useMemo } from 'react'
import InvitationLink from './invitation-link'
@ -64,12 +65,11 @@ const InvitedModal = ({
failedInvationResults.map(item =>
<div key={item.email} className='flex justify-center border border-red-300 rounded-md px-1 bg-orange-50'>
<Tooltip
selector={`invitation-tag-${item.email}`}
htmlContent={item.message}
popupContent={item.message}
>
<div className='flex justify-center items-center text-sm gap-1'>
{item.email}
<QuestionMarkCircleIcon className='w-4 h-4 text-red-300' />
<RiQuestionLine className='w-4 h-4 text-red-300' />
</div>
</Tooltip>
</div>,

View File

@ -39,18 +39,14 @@ const InvitationLink = ({
<div className="flex items-center flex-grow h-5">
<div className='flex-grow bg-gray-100 text-[13px] relative h-full'>
<Tooltip
selector={selector.current}
content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
className='z-10'
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
>
<div className='absolute top-0 left-0 w-full pl-2 pr-2 truncate cursor-pointer r-0' onClick={copyHandle}>{value.url}</div>
</Tooltip>
</div>
<div className="flex-shrink-0 h-4 bg-gray-200 border" />
<Tooltip
selector={selector.current}
content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
className='z-10'
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
>
<div className="px-0.5 flex-shrink-0">
<div className={`box-border w-[30px] h-[30px] flex items-center justify-center rounded-lg hover:bg-gray-100 cursor-pointer ${s.copyIcon} ${isCopied ? s.copied : ''}`} onClick={copyHandle}>

View File

@ -1,8 +1,6 @@
import { Fragment, useState } from 'react'
import type { FC } from 'react'
import {
RiQuestionLine,
} from '@remixicon/react'
import { RiQuestionLine } from '@remixicon/react'
import { ValidatingTip } from '../../key-validator/ValidateStatus'
import type {
CredentialFormSchema,
@ -18,7 +16,7 @@ import { useLanguage } from '../hooks'
import Input from './Input'
import cn from '@/utils/classnames'
import { SimpleSelect } from '@/app/components/base/select'
import Tooltip from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import Radio from '@/app/components/base/radio'
type FormProps = {
className?: string

View File

@ -1,8 +1,5 @@
import type { FC } from 'react'
import { useEffect, useRef, useState } from 'react'
import {
RiQuestionLine,
} from '@remixicon/react'
import type { ModelParameterRule } from '../declarations'
import { useLanguage } from '../hooks'
import { isNullOrUndefined } from '../utils'
@ -241,18 +238,18 @@ const ParameterItem: FC<ParameterItemProps> = ({
{
parameterRule.help && (
<Tooltip
selector={`model-parameter-rule-${parameterRule.name}`}
htmlContent={(
popupContent={(
<div className='w-[200px] whitespace-pre-wrap'>{parameterRule.help[language] || parameterRule.help.en_US}</div>
)}
>
<RiQuestionLine className='mr-1.5 w-3.5 h-3.5 text-gray-400' />
</Tooltip>
popupClassName='mr-1'
triggerClassName='mr-1 w-4 h-4 shrink-0'
/>
)
}
{
!parameterRule.required && parameterRule.name !== 'stop' && (
<Switch
className='mr-1'
defaultValue={!isNullOrUndefined(value)}
onChange={handleSwitch}
size='md'

View File

@ -14,7 +14,7 @@ import cn from '@/utils/classnames'
import { useProviderContext } from '@/context/provider-context'
import { SlidersH } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
export type TriggerProps = {
open?: boolean
@ -90,7 +90,7 @@ const Trigger: FC<TriggerProps> = ({
{
disabled
? (
<TooltipPlus
<Tooltip
popupContent={
hasDeprecated
? t('common.modelProvider.deprecated')
@ -100,7 +100,7 @@ const Trigger: FC<TriggerProps> = ({
}
>
<AlertTriangle className='w-4 h-4 text-[#F79009]' />
</TooltipPlus>
</Tooltip>
)
: (
<SlidersH className={cn(!isInWorkflow ? 'text-indigo-600' : 'text-gray-500', 'shrink-0 w-4 h-4')} />

View File

@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import ModelIcon from '../model-icon'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import { useProviderContext } from '@/context/provider-context'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type ModelTriggerProps = {
modelName: string
@ -35,9 +35,9 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
{modelName}
</div>
<div className='shrink-0 flex items-center justify-center w-4 h-4'>
<TooltipPlus popupContent={t('common.modelProvider.deprecated')}>
<Tooltip popupContent={t('common.modelProvider.deprecated')}>
<AlertTriangle className='w-4 h-4 text-[#F79009]' />
</TooltipPlus>
</Tooltip>
</div>
</div>
)

View File

@ -11,7 +11,7 @@ import {
// MagicWand,
// Robot,
} from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type FeatureIconProps = {
feature: ModelFeatureEnum
@ -25,49 +25,51 @@ const FeatureIcon: FC<FeatureIconProps> = ({
// if (feature === ModelFeatureEnum.agentThought) {
// return (
// <TooltipPlus
// <Tooltip
// popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.agentThought })}
// >
// <ModelBadge className={`mr-0.5 !px-0 w-[18px] justify-center text-gray-500 ${className}`}>
// <Robot className='w-3 h-3' />
// </ModelBadge>
// </TooltipPlus>
// </Tooltip>
// )
// }
// if (feature === ModelFeatureEnum.toolCall) {
// return (
// <TooltipPlus
// <Tooltip
// popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.toolCall })}
// >
// <ModelBadge className={`mr-0.5 !px-0 w-[18px] justify-center text-gray-500 ${className}`}>
// <MagicWand className='w-3 h-3' />
// </ModelBadge>
// </TooltipPlus>
// </Tooltip>
// )
// }
// if (feature === ModelFeatureEnum.multiToolCall) {
// return (
// <TooltipPlus
// <Tooltip
// popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.multiToolCall })}
// >
// <ModelBadge className={`mr-0.5 !px-0 w-[18px] justify-center text-gray-500 ${className}`}>
// <MagicBox className='w-3 h-3' />
// </ModelBadge>
// </TooltipPlus>
// </Tooltip>
// )
// }
if (feature === ModelFeatureEnum.vision) {
return (
<TooltipPlus
<Tooltip
popupContent={t('common.modelProvider.featureSupported', { feature: ModelFeatureTextEnum.vision })}
>
<ModelBadge className={`mr-0.5 !px-0 w-[18px] justify-center text-gray-500 ${className}`}>
<MagicEyes className='w-3 h-3' />
</ModelBadge>
</TooltipPlus>
<div className='inline-block cursor-help'>
<ModelBadge className={`mr-0.5 !px-0 w-[18px] justify-center text-gray-500 ${className}`}>
<MagicEyes className='w-3 h-3' />
</ModelBadge>
</div>
</Tooltip>
)
}

View File

@ -12,7 +12,7 @@ import { useLanguage } from '../hooks'
import ModelIcon from '../model-icon'
import ModelName from '../model-name'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type ModelTriggerProps = {
open: boolean
@ -56,9 +56,9 @@ const ModelTrigger: FC<ModelTriggerProps> = ({
{
model.status !== ModelStatusEnum.active
? (
<TooltipPlus popupContent={MODEL_STATUS_TEXT[model.status][language]}>
<Tooltip popupContent={MODEL_STATUS_TEXT[model.status][language]}>
<AlertTriangle className='w-4 h-4 text-[#F79009]' />
</TooltipPlus>
</Tooltip>
)
: (
<RiArrowDownSLine

View File

@ -70,9 +70,8 @@ const PopupItem: FC<PopupItemProps> = ({
{
model.models.map(modelItem => (
<Tooltip
selector={`${modelItem.model}-${modelItem.status}`}
key={modelItem.model}
content={modelItem.status !== ModelStatusEnum.active ? MODEL_STATUS_TEXT[modelItem.status][language] : undefined}
popupContent={modelItem.status !== ModelStatusEnum.active ? MODEL_STATUS_TEXT[modelItem.status][language] : undefined}
position='right'
>
<div

View File

@ -2,7 +2,7 @@ import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useLatest } from 'ahooks'
import SimplePieChart from '@/app/components/base/simple-pie-chart'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
export type CooldownTimerProps = {
secondsRemaining?: number
@ -54,9 +54,9 @@ const CooldownTimer = ({ secondsRemaining, onFinish }: CooldownTimerProps) => {
return displayTime
? (
<TooltipPlus popupContent={t('common.modelProvider.apiKeyRateLimit', { seconds: displayTime })}>
<Tooltip popupContent={t('common.modelProvider.apiKeyRateLimit', { seconds: displayTime })}>
<SimplePieChart percentage={Math.round(displayTime / 60 * 100)} className='w-3 h-3' />
</TooltipPlus>
</Tooltip>
)
: null
}

View File

@ -11,7 +11,7 @@ import Button from '@/app/components/base/button'
import { Balance } from '@/app/components/base/icons/src/vender/line/financeAndECommerce'
import { Settings01 } from '@/app/components/base/icons/src/vender/line/general'
import Switch from '@/app/components/base/switch'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { useProviderContext, useProviderContextSelector } from '@/context/provider-context'
import { disableModel, enableModel } from '@/service/common'
import { Plan } from '@/app/components/billing/type'
@ -99,9 +99,14 @@ const ModelListItem = ({ model, provider, isConfigurable, onConfig, onModifyLoad
{
model.deprecated
? (
<TooltipPlus popupContent={<span className='font-semibold'>{t('common.modelProvider.modelHasBeenDeprecated')}</span>} offset={{ mainAxis: 4 }}>
<Tooltip
popupContent={
<span className='font-semibold'>{t('common.modelProvider.modelHasBeenDeprecated')}</span>} offset={{ mainAxis: 4 }
}
needsDelay
>
<Switch defaultValue={false} disabled size='md' />
</TooltipPlus>
</Tooltip>
)
: (isCurrentWorkspaceManager && (
<Switch

View File

@ -3,13 +3,12 @@ import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiDeleteBinLine,
RiQuestionLine,
} from '@remixicon/react'
import type { ConfigurationMethodEnum, CustomConfigurationModelFixedFields, ModelLoadBalancingConfig, ModelLoadBalancingConfigEntry, ModelProvider } from '../declarations'
import Indicator from '../../../indicator'
import CooldownTimer from './cooldown-timer'
import classNames from '@/utils/classnames'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import Switch from '@/app/components/base/switch'
import { Balance } from '@/app/components/base/icons/src/vender/line/financeAndECommerce'
import { Edit02, Plus02 } from '@/app/components/base/icons/src/vender/line/general'
@ -160,9 +159,11 @@ const ModelLoadBalancingConfigs = ({
<div className='grow'>
<div className='flex items-center gap-1 text-sm'>
{t('common.modelProvider.loadBalancing')}
<TooltipPlus popupContent={t('common.modelProvider.loadBalancingInfo')} popupClassName='max-w-[300px]'>
<RiQuestionLine className='w-3 h-3 text-gray-400' />
</TooltipPlus>
<Tooltip
popupContent={t('common.modelProvider.loadBalancingInfo')}
popupClassName='max-w-[300px]'
triggerClassName='w-3 h-3'
/>
</div>
<div className='text-xs text-gray-500'>{t('common.modelProvider.loadBalancingDescription')}</div>
</div>
@ -191,9 +192,9 @@ const ModelLoadBalancingConfigs = ({
<CooldownTimer secondsRemaining={config.ttl} onFinish={() => clearCountdown(index)} />
)
: (
<TooltipPlus popupContent={t('common.modelProvider.apiKeyStatusNormal')}>
<Tooltip popupContent={t('common.modelProvider.apiKeyStatusNormal')}>
<Indicator color='green' />
</TooltipPlus>
</Tooltip>
)}
</div>
<div className='text-[13px] mr-1'>

View File

@ -7,8 +7,7 @@ const PriorityUseTip = () => {
return (
<Tooltip
selector='provider-quota-credential-priority-using'
content={t('common.modelProvider.priorityUsing') || ''}
popupContent={t('common.modelProvider.priorityUsing') || ''}
>
<div className='absolute -right-[5px] -top-[5px] bg-indigo-50 rounded-[5px] border-[0.5px] border-indigo-100 cursor-pointer'>
<ChevronDownDouble className='rotate-180 w-3 h-3 text-indigo-600' />

View File

@ -10,8 +10,7 @@ import {
MODEL_PROVIDER_QUOTA_GET_PAID,
} from '../utils'
import PriorityUseTip from './priority-use-tip'
import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { formatNumber } from '@/utils/format'
type QuotaPanelProps = {
@ -32,13 +31,12 @@ const QuotaPanel: FC<QuotaPanelProps> = ({
<div className='group relative shrink-0 min-w-[112px] px-3 py-2 rounded-lg bg-white/[0.3] border-[0.5px] border-black/5'>
<div className='flex items-center mb-2 h-4 text-xs font-medium text-gray-500'>
{t('common.modelProvider.quota')}
<TooltipPlus popupContent={
<Tooltip popupContent={
openaiOrAnthropic
? t('common.modelProvider.card.tip')
: t('common.modelProvider.quotaTip')
}>
<InfoCircle className='ml-0.5 w-3 h-3 text-gray-400' />
</TooltipPlus>
}
/>
</div>
{
currentQuota && (

View File

@ -1,9 +1,6 @@
import type { FC } from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import ModelSelector from '../model-selector'
import {
useModelList,
@ -146,13 +143,13 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
<div className='flex items-center h-8 text-[13px] font-medium text-gray-900'>
{t('common.modelProvider.systemReasoningModel.key')}
<Tooltip
selector='model-page-system-reasoning-model-tip'
htmlContent={
<div className='w-[261px] text-gray-500'>{t('common.modelProvider.systemReasoningModel.tip')}</div>
popupContent={
<div className='w-[261px] text-gray-500'>
{t('common.modelProvider.systemReasoningModel.tip')}
</div>
}
>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-gray-400' />
</Tooltip>
triggerClassName='ml-0.5'
/>
</div>
<div>
<ModelSelector
@ -166,13 +163,14 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
<div className='flex items-center h-8 text-[13px] font-medium text-gray-900'>
{t('common.modelProvider.embeddingModel.key')}
<Tooltip
selector='model-page-system-embedding-model-tip'
htmlContent={
<div className='w-[261px] text-gray-500'>{t('common.modelProvider.embeddingModel.tip')}</div>
popupContent={
<div className='w-[261px] text-gray-500'>
{t('common.modelProvider.embeddingModel.tip')}
</div>
}
>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-gray-400' />
</Tooltip>
needsDelay={false}
triggerClassName='ml-0.5'
/>
</div>
<div>
<ModelSelector
@ -186,13 +184,14 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
<div className='flex items-center h-8 text-[13px] font-medium text-gray-900'>
{t('common.modelProvider.rerankModel.key')}
<Tooltip
selector='model-page-system-rerankModel-model-tip'
htmlContent={
<div className='w-[261px] text-gray-500'>{t('common.modelProvider.rerankModel.tip')}</div>
popupContent={
<div className='w-[261px] text-gray-500'>
{t('common.modelProvider.rerankModel.tip')}
</div>
}
>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-gray-400' />
</Tooltip>
needsDelay={false}
triggerClassName='ml-0.5'
/>
</div>
<div>
<ModelSelector
@ -206,13 +205,14 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
<div className='flex items-center h-8 text-[13px] font-medium text-gray-900'>
{t('common.modelProvider.speechToTextModel.key')}
<Tooltip
selector='model-page-system-speechToText-model-tip'
htmlContent={
<div className='w-[261px] text-gray-500'>{t('common.modelProvider.speechToTextModel.tip')}</div>
popupContent={
<div className='w-[261px] text-gray-500'>
{t('common.modelProvider.speechToTextModel.tip')}
</div>
}
>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-gray-400' />
</Tooltip>
needsDelay={false}
triggerClassName='ml-0.5'
/>
</div>
<div>
<ModelSelector
@ -226,13 +226,13 @@ const SystemModel: FC<SystemModelSelectorProps> = ({
<div className='flex items-center h-8 text-[13px] font-medium text-gray-900'>
{t('common.modelProvider.ttsModel.key')}
<Tooltip
selector='model-page-system-tts-model-tip'
htmlContent={
<div className='w-[261px] text-gray-500'>{t('common.modelProvider.ttsModel.tip')}</div>
popupContent={
<div className='w-[261px] text-gray-500'>
{t('common.modelProvider.ttsModel.tip')}
</div>
}
>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-gray-400' />
</Tooltip>
triggerClassName='ml-0.5'
/>
</div>
<div>
<ModelSelector

View File

@ -42,8 +42,7 @@ const Header: FC<IResultHeaderProps> = ({
{showFeedback && feedback.rating && feedback.rating === 'like' && (
<Tooltip
selector="undo-feedback-like"
content="Undo Great Rating"
popupContent="Undo Great Rating"
>
<div
onClick={() => {
@ -59,8 +58,7 @@ const Header: FC<IResultHeaderProps> = ({
{showFeedback && feedback.rating && feedback.rating === 'dislike' && (
<Tooltip
selector="undo-feedback-dislike"
content="Undo Undesirable Response"
popupContent="Undo Undesirable Response"
>
<div
onClick={() => {
@ -77,8 +75,8 @@ const Header: FC<IResultHeaderProps> = ({
{showFeedback && !feedback.rating && (
<div className='flex rounded-lg border border-gray-200 p-[1px] space-x-1'>
<Tooltip
selector="feedback-like"
content="Great Rating"
popupContent="Great Rating"
needsDelay={false}
>
<div
onClick={() => {
@ -91,8 +89,8 @@ const Header: FC<IResultHeaderProps> = ({
</div>
</Tooltip>
<Tooltip
selector="feedback-dislike"
content="Undesirable Response"
popupContent="Undesirable Response"
needsDelay={false}
>
<div
onClick={() => {

View File

@ -68,10 +68,9 @@ const Blocks = ({
return (
<Tooltip
key={tool.name}
selector={`workflow-block-tool-${tool.name}`}
position='bottom'
className='!p-0 !px-3 !py-2.5 !w-[210px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !bg-transparent !rounded-xl !shadow-lg translate-x-[108px]'
htmlContent={(
popupClassName='!p-0 !px-3 !py-2.5 !w-[210px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !bg-transparent !rounded-xl !shadow-lg translate-x-[108px]'
popupContent={(
<div>
<BlockIcon
size='md'
@ -91,7 +90,7 @@ const Blocks = ({
)}
</div>
)}
noArrow
needsDelay
>
<div className='group/item flex items-center w-full pl-3 pr-1 h-8 rounded-lg hover:bg-gray-50 cursor-pointer'>
<BlockIcon

View File

@ -2,10 +2,7 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import Tooltip from '../../base/tooltip'
import Tooltip from '@/app/components/base/tooltip'
import cn from '@/utils/classnames'
import type { Credential } from '@/app/components/tools/types'
import Drawer from '@/app/components/base/drawer-plus'
@ -112,15 +109,13 @@ const ConfigCredential: FC<Props> = ({
<div className='flex items-center h-8 text-[13px] font-medium text-gray-900'>
{t('tools.createTool.authMethod.key')}
<Tooltip
selector='model-page-system-reasoning-model-tip'
htmlContent={
popupContent={
<div className='w-[261px] text-gray-500'>
{t('tools.createTool.authMethod.keyTooltip')}
</div>
}
>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-gray-400' />
</Tooltip>
triggerClassName='ml-0.5'
/>
</div>
<input
value={tempCredential.api_key_header}

View File

@ -2,9 +2,6 @@
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import produce from 'immer'
import type { Emoji, WorkflowToolProviderParameter, WorkflowToolProviderRequest } from '../types'
import cn from '@/utils/classnames'
@ -148,15 +145,12 @@ const WorkflowToolAsModal: FC<Props> = ({
<div className='flex items-center py-2 leading-5 text-sm font-medium text-gray-900'>
{t('tools.createTool.nameForToolCall')} <span className='ml-1 text-red-500'>*</span>
<Tooltip
htmlContent={
popupContent={
<div className='w-[180px]'>
{t('tools.createTool.nameForToolCallPlaceHolder')}
</div>
}
selector='workflow-tool-modal-tooltip'
>
<RiQuestionLine className='ml-2 w-[14px] h-[14px] text-gray-400' />
</Tooltip>
/>
</div>
<input
type='text'

View File

@ -67,10 +67,9 @@ const Blocks = ({
list.map(block => (
<Tooltip
key={block.type}
selector={`workflow-block-${block.type}`}
position='right'
className='!p-0 !px-3 !py-2.5 !w-[200px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !rounded-xl !shadow-lg'
htmlContent={(
popupClassName='!p-0 !px-3 !py-2.5 !w-[200px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !rounded-xl !shadow-lg'
popupContent={(
<div>
<BlockIcon
size='md'
@ -81,7 +80,6 @@ const Blocks = ({
<div className='text-xs text-gray-700 leading-[18px]'>{nodesExtraData[block.type].about}</div>
</div>
)}
noArrow
>
<div
key={block.type}

View File

@ -44,10 +44,9 @@ const Blocks = ({
list.map(tool => (
<Tooltip
key={tool.name}
selector={`workflow-block-tool-${tool.name}`}
position='right'
className='!p-0 !px-3 !py-2.5 !w-[200px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !rounded-xl !shadow-lg'
htmlContent={(
popupClassName='!p-0 !px-3 !py-2.5 !w-[200px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !rounded-xl !shadow-lg'
popupContent={(
<div>
<BlockIcon
size='md'
@ -59,7 +58,6 @@ const Blocks = ({
<div className='text-xs text-gray-700 leading-[18px]'>{tool.description[language]}</div>
</div>
)}
noArrow
>
<div
className='flex items-center px-3 w-full h-8 rounded-lg hover:bg-gray-50 cursor-pointer'
@ -77,7 +75,7 @@ const Blocks = ({
type={BlockEnum.Tool}
toolIcon={toolWithProvider.icon}
/>
<div className='text-sm text-gray-900 truncate'>{tool.label[language]}</div>
<div className='text-sm text-gray-900 flex-1 min-w-0 truncate'>{tool.label[language]}</div>
</div>
</Tooltip>
))

View File

@ -24,7 +24,7 @@ import {
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { useStore as useAppStore } from '@/app/components/app/store'
import {
ClockPlay,
@ -100,7 +100,7 @@ const ViewHistory = ({
}
{
!withText && (
<TooltipPlus
<Tooltip
popupContent={t('workflow.common.viewRunHistory')}
>
<div
@ -112,7 +112,7 @@ const ViewHistory = ({
>
<ClockPlay className={cn('w-4 h-4 group-hover:text-components-button-secondary-accent-text', open ? 'text-components-button-secondary-accent-text' : 'text-components-button-ghost-text')} />
</div>
</TooltipPlus>
</Tooltip>
)
}
</PortalToFollowElemTrigger>

View File

@ -3,12 +3,11 @@ import type { FC } from 'react'
import React from 'react'
import {
RiArrowDownSLine,
RiQuestionLine,
} from '@remixicon/react'
import { useBoolean } from 'ahooks'
import type { DefaultTFuncReturn } from 'i18next'
import cn from '@/utils/classnames'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type Props = {
className?: string
@ -40,12 +39,11 @@ const Filed: FC<Props> = ({
<div className='flex items-center h-6'>
<div className='system-sm-semibold-uppercase text-text-secondary'>{title}</div>
{tooltip && (
<TooltipPlus popupContent={
<div className='w-[120px]'>
{tooltip}
</div>}>
<RiQuestionLine className='w-3.5 h-3.5 ml-0.5 text-text-quaternary' />
</TooltipPlus>
<Tooltip
popupContent={tooltip}
popupClassName='ml-1'
triggerClassName='w-4 h-4 ml-1'
/>
)}
</div>

View File

@ -2,7 +2,7 @@ import { memo } from 'react'
import { useTranslation } from 'react-i18next'
import { RiBookOpenLine } from '@remixicon/react'
import { useNodeHelpLink } from '../hooks/use-node-help-link'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import TooltipPlus from '@/app/components/base/tooltip'
import type { BlockEnum } from '@/app/components/workflow/types'
type HelpLinkProps = {
@ -15,7 +15,9 @@ const HelpLink = ({
const link = useNodeHelpLink(nodeType)
return (
<TooltipPlus popupContent={t('common.userProfile.helpCenter')}>
<TooltipPlus
popupContent={t('common.userProfile.helpCenter')}
>
<a
href={link}
target='_blank'

View File

@ -11,7 +11,7 @@ import type {
import { BlockEnum } from '@/app/components/workflow/types'
import PromptEditor from '@/app/components/base/prompt-editor'
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type Props = {
instanceId?: string
@ -109,13 +109,13 @@ const Editor: FC<Props> = ({
{readOnly && <div className='absolute inset-0 z-10'></div>}
{isFocus && (
<div className={cn('absolute z-10', insertVarTipToLeft ? 'top-1.5 left-[-12px]' : ' top-[-9px] right-1')}>
<TooltipPlus
<Tooltip
popupContent={`${t('workflow.common.insertVarTip')}`}
>
<div className='p-0.5 rounded-[5px] shadow-lg cursor-pointer bg-white hover:bg-gray-100 border-[0.5px] border-black/5'>
<Variable02 className='w-3.5 h-3.5 text-components-button-secondary-accent-text' />
</div>
</TooltipPlus>
</Tooltip>
</div>
)}
</>

View File

@ -19,7 +19,7 @@ import PanelOperator from './panel-operator'
import {
Stop,
} from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type NodeControlProps = Pick<Node, 'id' | 'data'>
const NodeControl: FC<NodeControlProps> = ({
@ -68,11 +68,12 @@ const NodeControl: FC<NodeControlProps> = ({
data._isSingleRun
? <Stop className='w-3 h-3' />
: (
<TooltipPlus
<Tooltip
popupContent={t('workflow.panel.runThisStep')}
asChild={false}
>
<RiPlayLargeLine className='w-3 h-3' />
</TooltipPlus>
</Tooltip>
)
}
</div>

View File

@ -3,9 +3,8 @@ import type { FC } from 'react'
import React, { useCallback } from 'react'
import type { VariantProps } from 'class-variance-authority'
import { cva } from 'class-variance-authority'
import { RiQuestionLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
const variants = cva([], {
variants: {
@ -59,13 +58,15 @@ const OptionCard: FC<Props> = ({
onClick={handleSelect}
>
<span>{title}</span>
{tooltip && <TooltipPlus
popupContent={<div className='w-[240px]'>
{tooltip}
</div>}
>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-text-quaternary' />
</TooltipPlus>}
{tooltip
&& <Tooltip
popupContent={
<div className='w-[240px]'>
{tooltip}
</div>
}
/>
}
</div>
)
}

View File

@ -31,7 +31,7 @@ import { useEventEmitterContextContext } from '@/context/event-emitter'
import { PROMPT_EDITOR_INSERT_QUICKLY } from '@/app/components/base/prompt-editor/plugins/update-block'
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
import ActionButton from '@/app/components/base/action-button'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars'
import Switch from '@/app/components/base/switch'
import { Jinja } from '@/app/components/base/icons/src/vender/workflow'
@ -141,14 +141,14 @@ const Editor: FC<Props> = ({
{/* Operations */}
<div className='flex items-center space-x-[2px]'>
{isSupportJinja && (
<TooltipPlus
<Tooltip
popupContent={
<div>
<div>{t('workflow.common.enableJinja')}</div>
<a className='text-[#155EEF]' target='_blank' href='https://jinja.palletsprojects.com/en/2.10.x/'>{t('workflow.common.learnMore')}</a>
</div>
}
hideArrow
needsDelay
>
<div className={cn(editionType === EditionType.jinja2 && 'border-black/5 bg-white', 'flex h-[22px] items-center px-1.5 rounded-[5px] border border-transparent hover:border-black/5 space-x-0.5')}>
<Jinja className='w-6 h-3 text-gray-300' />
@ -160,18 +160,17 @@ const Editor: FC<Props> = ({
}}
/>
</div>
</TooltipPlus>
</Tooltip>
)}
{!readOnly && (
<TooltipPlus
<Tooltip
popupContent={`${t('workflow.common.insertVarTip')}`}
asChild
>
<ActionButton onClick={handleInsertVariable}>
<Variable02 className='w-4 h-4' />
</ActionButton>
</TooltipPlus>
</Tooltip>
)}
{showRemove && (
<ActionButton onClick={onRemove}>

View File

@ -35,7 +35,7 @@ import {
useWorkflowHistory,
} from '@/app/components/workflow/hooks'
import { canRunBySingle } from '@/app/components/workflow/utils'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import type { Node } from '@/app/components/workflow/types'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useStore } from '@/app/components/workflow/store'
@ -127,8 +127,9 @@ const BasePanel: FC<BasePanelProps> = ({
<div className='shrink-0 flex items-center text-gray-500'>
{
canRunBySingle(data.type) && !nodesReadOnly && (
<TooltipPlus
<Tooltip
popupContent={t('workflow.panel.runThisStep')}
popupClassName='mr-1'
>
<div
className='flex items-center justify-center mr-1 w-6 h-6 rounded-md hover:bg-black/5 cursor-pointer'
@ -139,7 +140,7 @@ const BasePanel: FC<BasePanelProps> = ({
>
<RiPlayLargeLine className='w-4 h-4 text-text-tertiary' />
</div>
</TooltipPlus>
</Tooltip>
)
}
<HelpLink nodeType={data.type} />

View File

@ -29,7 +29,7 @@ import type {
import {
BlockEnum,
} from '@/app/components/workflow/types'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type AddBlockProps = {
iterationNodeId: string
@ -99,11 +99,11 @@ const AddBlock = ({
return (
<div className='absolute top-12 left-6 flex items-center h-8 z-10'>
<TooltipPlus popupContent={t('workflow.blocks.iteration-start')}>
<Tooltip popupContent={t('workflow.blocks.iteration-start')}>
<div className='flex items-center justify-center w-6 h-6 rounded-full border-[0.5px] border-black/[0.02] shadow-md bg-primary-500'>
<IterationStart className='w-4 h-4 text-white' />
</div>
</TooltipPlus>
</Tooltip>
<div className='group/insert relative w-16 h-0.5 bg-gray-300'>
{
iterationNodeData.startNodeType && (

View File

@ -3,13 +3,12 @@ import type { FC } from 'react'
import React, { useCallback, useEffect, useState } from 'react'
import { uniqueId } from 'lodash-es'
import { useTranslation } from 'react-i18next'
import { RiQuestionLine } from '@remixicon/react'
import type { ModelConfig, PromptItem, Variable } from '../../../types'
import { EditionType } from '../../../types'
import { useWorkflowStore } from '../../../store'
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { PromptRole } from '@/models/debug'
const i18nPrefix = 'workflow.nodes.llm'
@ -118,13 +117,12 @@ const ConfigPromptItem: FC<Props> = ({
/>
)}
<TooltipPlus
<Tooltip
popupContent={
<div className='max-w-[180px]'>{t(`${i18nPrefix}.roleDescription.${payload.role}`)}</div>
}
>
<RiQuestionLine className='w-3.5 h-3.5 text-gray-400' />
</TooltipPlus>
triggerClassName='w-4 h-4'
/>
</div>
}
value={payload.edition_type === EditionType.jinja2 ? (payload.jinja2_text || '') : payload.text}

View File

@ -1,7 +1,6 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { RiQuestionLine } from '@remixicon/react'
import MemoryConfig from '../_base/components/memory-config'
import VarReferencePicker from '../_base/components/variable/var-reference-picker'
import useConfig from './use-config'
@ -19,7 +18,7 @@ import { InputVarType, type NodePanelProps } from '@/app/components/workflow/typ
import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form'
import type { Props as FormProps } from '@/app/components/workflow/nodes/_base/components/before-run-form/form'
import ResultPanel from '@/app/components/workflow/run/result-panel'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
import Switch from '@/app/components/base/switch'
const i18nPrefix = 'workflow.nodes.llm'
@ -206,11 +205,10 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
<div className='flex justify-between items-center h-8 pl-3 pr-2 rounded-lg bg-gray-100'>
<div className='flex items-center space-x-1'>
<div className='text-xs font-semibold text-gray-700 uppercase'>{t('workflow.nodes.common.memories.title')}</div>
<TooltipPlus
<Tooltip
popupContent={t('workflow.nodes.common.memories.tip')}
>
<RiQuestionLine className='w-3.5 h-3.5 text-gray-400' />
</TooltipPlus>
triggerClassName='w-4 h-4'
/>
</div>
<div className='flex items-center h-[18px] px-1 rounded-[5px] border border-black/8 text-xs font-semibold text-gray-500 uppercase'>{t('workflow.nodes.common.memories.builtIn')}</div>
</div>
@ -219,13 +217,12 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
<Editor
title={<div className='flex items-center space-x-1'>
<div className='text-xs font-semibold text-gray-700 uppercase'>user</div>
<TooltipPlus
<Tooltip
popupContent={
<div className='max-w-[180px]'>{t('workflow.nodes.llm.roleDescription.user')}</div>
}
>
<RiQuestionLine className='w-3.5 h-3.5 text-gray-400' />
</TooltipPlus>
triggerClassName='w-4 h-4'
/>
</div>}
value={inputs.memory.query_prompt_template || '{{#sys.query#}}'}
onChange={handleSyeQueryChange}

View File

@ -1,9 +1,6 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import MemoryConfig from '../_base/components/memory-config'
import VarReferencePicker from '../_base/components/variable/var-reference-picker'
import Editor from '../_base/components/prompt/editor'
@ -19,7 +16,7 @@ import Split from '@/app/components/workflow/nodes/_base/components/split'
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars'
import { InputVarType, type NodePanelProps } from '@/app/components/workflow/types'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form'
import { VarType } from '@/app/components/workflow/types'
@ -126,12 +123,14 @@ const Panel: FC<NodePanelProps<ParameterExtractorNodeType>> = ({
title={
<div className='flex items-center space-x-1'>
<span className='uppercase'>{t(`${i18nPrefix}.instruction`)}</span>
<TooltipPlus popupContent={
<div className='w-[120px]'>
{t(`${i18nPrefix}.instructionTip`)}
</div>}>
<RiQuestionLine className='w-3.5 h-3.5 ml-0.5 text-gray-400' />
</TooltipPlus>
<Tooltip
popupContent={
<div className='w-[120px]'>
{t(`${i18nPrefix}.instructionTip`)}
</div>
}
triggerClassName='w-3.5 h-3.5 ml-0.5'
/>
</div>
}
value={inputs.instruction}

View File

@ -2,13 +2,10 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiQuestionLine,
} from '@remixicon/react'
import MemoryConfig from '../../_base/components/memory-config'
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
import type { Memory, Node, NodeOutPutVar } from '@/app/components/workflow/types'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
const i18nPrefix = 'workflow.nodes.questionClassifiers'
type Props = {
@ -50,12 +47,14 @@ const AdvancedSetting: FC<Props> = ({
title={
<div className='flex items-center space-x-1'>
<span className='uppercase'>{t(`${i18nPrefix}.instruction`)}</span>
<TooltipPlus popupContent={
<div className='w-[120px]'>
{t(`${i18nPrefix}.instructionTip`)}
</div>}>
<RiQuestionLine className='w-3.5 h-3.5 ml-0.5 text-gray-400' />
</TooltipPlus>
<Tooltip
popupContent={
<div className='w-[120px]'>
{t(`${i18nPrefix}.instructionTip`)}
</div>
}
triggerClassName='w-3.5 h-3.5 ml-0.5'
/>
</div>
}
value={instruction}

View File

@ -13,7 +13,7 @@ import {
import { useStore } from '../store'
import { useCommand } from './hooks'
import cn from '@/utils/classnames'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type CommandProps = {
type: 'bold' | 'italic' | 'strikethrough' | 'link' | 'bullet'
@ -60,7 +60,9 @@ const Command = ({
}, [type, t])
return (
<TooltipPlus popupContent={tip}>
<Tooltip
popupContent={tip}
>
<div
className={cn(
'flex items-center justify-center w-8 h-8 cursor-pointer rounded-md text-gray-500 hover:text-gray-800 hover:bg-black/5',
@ -74,7 +76,7 @@ const Command = ({
>
{icon}
</div>
</TooltipPlus>
</Tooltip>
)
}

View File

@ -1,6 +1,6 @@
import { memo } from 'react'
import ShortcutsName from '../shortcuts-name'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
type TipPopupProps = {
title: string
@ -13,9 +13,8 @@ const TipPopup = ({
shortcuts,
}: TipPopupProps) => {
return (
<TooltipPlus
<Tooltip
offset={4}
hideArrow
popupClassName='!p-0 !bg-gray-25'
popupContent={
<div className='flex items-center gap-1 px-2 h-6 text-xs font-medium text-gray-700 rounded-lg border-[0.5px] border-black/5'>
@ -27,7 +26,7 @@ const TipPopup = ({
}
>
{children}
</TooltipPlus>
</Tooltip>
)
}

View File

@ -18,7 +18,7 @@ import ChatWrapper from './chat-wrapper'
import cn from '@/utils/classnames'
import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
import { BubbleX } from '@/app/components/base/icons/src/vender/line/others'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
import { useStore } from '@/app/components/workflow/store'
@ -63,31 +63,31 @@ const DebugAndPreview = () => {
<div className='shrink-0 flex items-center justify-between px-4 pt-3 pb-2 text-text-primary system-xl-semibold'>
<div className='h-8'>{t('workflow.common.debugAndPreview').toLocaleUpperCase()}</div>
<div className='flex items-center gap-1'>
<TooltipPlus
<Tooltip
popupContent={t('common.operation.refresh')}
>
<ActionButton onClick={() => handleRestartChat()}>
<RefreshCcw01 className='w-4 h-4' />
</ActionButton>
</TooltipPlus>
</Tooltip>
{varList.length > 0 && (
<TooltipPlus
<Tooltip
popupContent={t('workflow.chatVariable.panelTitle')}
>
<ActionButton onClick={() => setShowConversationVariableModal(true)}>
<BubbleX className='w-4 h-4' />
</ActionButton>
</TooltipPlus>
</Tooltip>
)}
{variables.length > 0 && (
<div className='relative'>
<TooltipPlus
<Tooltip
popupContent={t('workflow.panel.userInputField')}
>
<ActionButton state={expanded ? ActionButtonState.Active : undefined} onClick={() => setExpanded(!expanded)}>
<RiEqualizer2Line className='w-4 h-4' />
</ActionButton>
</TooltipPlus>
</Tooltip>
{expanded && <div className='absolute z-10 bottom-[-17px] right-[5px] w-3 h-3 bg-components-panel-on-panel-item-bg border-l-[0.5px] border-t-[0.5px] border-components-panel-border-subtle rotate-45'/>}
</div>
)}

View File

@ -1,10 +1,10 @@
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { v4 as uuid4 } from 'uuid'
import { RiCloseLine, RiQuestionLine } from '@remixicon/react'
import { RiCloseLine } from '@remixicon/react'
import { useContext } from 'use-context-selector'
import Button from '@/app/components/base/button'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import Tooltip from '@/app/components/base/tooltip'
import { ToastContext } from '@/app/components/base/toast'
import { useStore } from '@/app/components/workflow/store'
import type { EnvironmentVariable } from '@/app/components/workflow/types'
@ -102,13 +102,14 @@ const VariableModal = ({
type === 'secret' && 'text-text-primary font-medium border-[1.5px] shadow-xs bg-components-option-card-option-selected-bg border-components-option-card-option-selected-border hover:border-components-option-card-option-selected-border',
)} onClick={() => setType('secret')}>
<span>Secret</span>
<TooltipPlus popupContent={
<div className='w-[240px]'>
{t('workflow.env.modal.secretTip')}
</div>
}>
<RiQuestionLine className='ml-0.5 w-[14px] h-[14px] text-text-quaternary' />
</TooltipPlus>
<Tooltip
popupContent={
<div className='w-[240px]'>
{t('workflow.env.modal.secretTip')}
</div>
}
triggerClassName='ml-0.5 w-3.5 h-3.5'
/>
</div>
</div>
</div>

View File

@ -6,8 +6,7 @@ import useSWR from 'swr'
import { useRouter } from 'next/navigation'
// import { useContext } from 'use-context-selector'
import Button from '@/app/components/base/button'
import Tooltip from '@/app/components/base/tooltip/index'
import Tooltip from '@/app/components/base/tooltip'
import { SimpleSelect } from '@/app/components/base/select'
import { timezones } from '@/utils/timezone'
import { LanguagesSupported, languages } from '@/i18n/language'
@ -88,9 +87,7 @@ const OneMoreStep = () => {
<label className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
{t('login.invitationCode')}
<Tooltip
clickable
selector='dont-have'
htmlContent={
popupContent={
<div className='w-[256px] text-xs font-medium'>
<div className='font-medium'>{t('login.sendUsMail')}</div>
<div className='text-xs font-medium cursor-pointer text-primary-600'>
@ -98,6 +95,7 @@ const OneMoreStep = () => {
</div>
</div>
}
needsDelay
>
<span className='cursor-pointer text-primary-600'>{t('login.donthave')}</span>
</Tooltip>