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
93 changed files with 640 additions and 758 deletions

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