mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
chore(web): new lint setup (#30020)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
This commit is contained in:
@ -1,18 +1,19 @@
|
||||
import type { Option } from './types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
GeneralChunk,
|
||||
ParentChildChunk,
|
||||
QuestionAndAnswer,
|
||||
} from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import { EffectColor, type Option } from './types'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { EffectColor } from './types'
|
||||
|
||||
export const useChunkStructure = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const GeneralOption: Option = {
|
||||
id: ChunkingMode.text,
|
||||
icon: <GeneralChunk className='size-[18px]' />,
|
||||
icon: <GeneralChunk className="size-[18px]" />,
|
||||
iconActiveColor: 'text-util-colors-indigo-indigo-600',
|
||||
title: 'General',
|
||||
description: t('datasetCreation.stepTwo.generalTip'),
|
||||
@ -21,7 +22,7 @@ export const useChunkStructure = () => {
|
||||
}
|
||||
const ParentChildOption: Option = {
|
||||
id: ChunkingMode.parentChild,
|
||||
icon: <ParentChildChunk className='size-[18px]' />,
|
||||
icon: <ParentChildChunk className="size-[18px]" />,
|
||||
iconActiveColor: 'text-util-colors-blue-light-blue-light-500',
|
||||
title: 'Parent-Child',
|
||||
description: t('datasetCreation.stepTwo.parentChildTip'),
|
||||
@ -30,7 +31,7 @@ export const useChunkStructure = () => {
|
||||
}
|
||||
const QuestionAnswerOption: Option = {
|
||||
id: ChunkingMode.qa,
|
||||
icon: <QuestionAndAnswer className='size-[18px]' />,
|
||||
icon: <QuestionAndAnswer className="size-[18px]" />,
|
||||
title: 'Q&A',
|
||||
description: t('datasetCreation.stepTwo.qaTip'),
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { ChunkingMode } from '@/models/datasets'
|
||||
import React from 'react'
|
||||
import { useChunkStructure } from './hooks'
|
||||
import OptionCard from '../option-card'
|
||||
import { useChunkStructure } from './hooks'
|
||||
|
||||
type ChunkStructureProps = {
|
||||
chunkStructure: ChunkingMode
|
||||
@ -15,7 +15,7 @@ const ChunkStructure = ({
|
||||
} = useChunkStructure()
|
||||
|
||||
return (
|
||||
<div className='flex flex-col gap-y-1'>
|
||||
<div className="flex flex-col gap-y-1">
|
||||
{
|
||||
options.map(option => (
|
||||
<OptionCard
|
||||
@ -28,7 +28,7 @@ const ChunkStructure = ({
|
||||
isActive={chunkStructure === option.id}
|
||||
effectColor={option.effectColor}
|
||||
showEffectColor
|
||||
className='gap-x-1.5 p-3 pr-4'
|
||||
className="gap-x-1.5 p-3 pr-4"
|
||||
disabled
|
||||
/>
|
||||
))
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
'use client'
|
||||
import type { AppIconSelection } from '@/app/components/base/app-icon-picker'
|
||||
import type { DefaultModel } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { Member } from '@/models/common'
|
||||
import type { IconInfo } from '@/models/datasets'
|
||||
import type { AppIconType, RetrievalConfig } from '@/types/app'
|
||||
import { RiAlertFill } from '@remixicon/react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import PermissionSelector from '../permission-selector'
|
||||
import IndexMethod from '../index-method'
|
||||
import RetrievalSettings from '../../external-knowledge-base/create/RetrievalSettings'
|
||||
import { IndexingType } from '../../create/step-two'
|
||||
import RetrievalMethodConfig from '@/app/components/datasets/common/retrieval-method-config'
|
||||
import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/economical-retrieval-method-config'
|
||||
import AppIcon from '@/app/components/base/app-icon'
|
||||
import AppIconPicker from '@/app/components/base/app-icon-picker'
|
||||
import Button from '@/app/components/base/button'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import { ApiConnectionMod } from '@/app/components/base/icons/src/vender/solid/development'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Textarea from '@/app/components/base/textarea'
|
||||
import { ApiConnectionMod } from '@/app/components/base/icons/src/vender/solid/development'
|
||||
import { updateDatasetSetting } from '@/service/datasets'
|
||||
import type { IconInfo } from '@/models/datasets'
|
||||
import { ChunkingMode, DatasetPermission } from '@/models/datasets'
|
||||
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
|
||||
import type { AppIconType, RetrievalConfig } from '@/types/app'
|
||||
import { useSelector as useAppContextWithSelector } from '@/context/app-context'
|
||||
import { isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
import { useModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import type { DefaultModel } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { Member } from '@/models/common'
|
||||
import AppIcon from '@/app/components/base/app-icon'
|
||||
import type { AppIconSelection } from '@/app/components/base/app-icon-picker'
|
||||
import AppIconPicker from '@/app/components/base/app-icon-picker'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import ChunkStructure from '../chunk-structure'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { RiAlertFill } from '@remixicon/react'
|
||||
import { isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model'
|
||||
import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/economical-retrieval-method-config'
|
||||
import RetrievalMethodConfig from '@/app/components/datasets/common/retrieval-method-config'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
import { useSelector as useAppContextWithSelector } from '@/context/app-context'
|
||||
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
|
||||
import { useDocLink } from '@/context/i18n'
|
||||
import { ChunkingMode, DatasetPermission } from '@/models/datasets'
|
||||
import { updateDatasetSetting } from '@/service/datasets'
|
||||
import { useInvalidDatasetList } from '@/service/knowledge/use-dataset'
|
||||
import { useMembers } from '@/service/use-common'
|
||||
import { IndexingType } from '../../create/step-two'
|
||||
import RetrievalSettings from '../../external-knowledge-base/create/RetrievalSettings'
|
||||
import ChunkStructure from '../chunk-structure'
|
||||
import IndexMethod from '../index-method'
|
||||
import PermissionSelector from '../permission-selector'
|
||||
import { checkShowMultiModalTip } from '../utils'
|
||||
|
||||
const rowClass = 'flex gap-x-1'
|
||||
@ -68,13 +68,13 @@ const Form = () => {
|
||||
const [embeddingModel, setEmbeddingModel] = useState<DefaultModel>(
|
||||
currentDataset?.embedding_model
|
||||
? {
|
||||
provider: currentDataset.embedding_model_provider,
|
||||
model: currentDataset.embedding_model,
|
||||
}
|
||||
provider: currentDataset.embedding_model_provider,
|
||||
model: currentDataset.embedding_model,
|
||||
}
|
||||
: {
|
||||
provider: '',
|
||||
model: '',
|
||||
},
|
||||
provider: '',
|
||||
model: '',
|
||||
},
|
||||
)
|
||||
const { data: rerankModelList } = useModelList(ModelTypeEnum.rerank)
|
||||
const { data: embeddingModelList } = useModelList(ModelTypeEnum.textEmbedding)
|
||||
@ -102,7 +102,7 @@ const Form = () => {
|
||||
setShowAppIconPicker(false)
|
||||
}, [])
|
||||
|
||||
const handleSettingsChange = useCallback((data: { top_k?: number; score_threshold?: number; score_threshold_enabled?: boolean }) => {
|
||||
const handleSettingsChange = useCallback((data: { top_k?: number, score_threshold?: number, score_threshold_enabled?: boolean }) => {
|
||||
if (data.top_k !== undefined)
|
||||
setTopK(data.top_k)
|
||||
if (data.score_threshold !== undefined)
|
||||
@ -209,17 +209,17 @@ const Form = () => {
|
||||
}, [embeddingModel, rerankModelList, retrievalConfig.reranking_enable, retrievalConfig.reranking_model, embeddingModelList, indexMethod])
|
||||
|
||||
return (
|
||||
<div className='flex w-full flex-col gap-y-4 px-20 py-8 sm:w-[960px]'>
|
||||
<div className="flex w-full flex-col gap-y-4 px-20 py-8 sm:w-[960px]">
|
||||
{/* Dataset name and icon */}
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.nameAndIcon')}</div>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('datasetSettings.form.nameAndIcon')}</div>
|
||||
</div>
|
||||
<div className='flex grow items-center gap-x-2'>
|
||||
<div className="flex grow items-center gap-x-2">
|
||||
<AppIcon
|
||||
size='small'
|
||||
size="small"
|
||||
onClick={handleOpenAppIconPicker}
|
||||
className='cursor-pointer'
|
||||
className="cursor-pointer"
|
||||
iconType={iconInfo.icon_type as AppIconType}
|
||||
icon={iconInfo.icon}
|
||||
background={iconInfo.icon_background}
|
||||
@ -236,12 +236,12 @@ const Form = () => {
|
||||
{/* Dataset description */}
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.desc')}</div>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('datasetSettings.form.desc')}</div>
|
||||
</div>
|
||||
<div className='grow'>
|
||||
<div className="grow">
|
||||
<Textarea
|
||||
disabled={!currentDataset?.embedding_available}
|
||||
className='resize-none'
|
||||
className="resize-none"
|
||||
placeholder={t('datasetSettings.form.descPlaceholder') || ''}
|
||||
value={description}
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
@ -251,9 +251,9 @@ const Form = () => {
|
||||
{/* Permissions */}
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.permissions')}</div>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('datasetSettings.form.permissions')}</div>
|
||||
</div>
|
||||
<div className='grow'>
|
||||
<div className="grow">
|
||||
<PermissionSelector
|
||||
disabled={!currentDataset?.embedding_available || isCurrentWorkspaceDatasetOperator}
|
||||
permission={permission}
|
||||
@ -268,28 +268,28 @@ const Form = () => {
|
||||
currentDataset?.doc_form && (
|
||||
<>
|
||||
<Divider
|
||||
type='horizontal'
|
||||
className='my-1 h-px bg-divider-subtle'
|
||||
type="horizontal"
|
||||
className="my-1 h-px bg-divider-subtle"
|
||||
/>
|
||||
{/* Chunk Structure */}
|
||||
<div className={rowClass}>
|
||||
<div className='flex w-[180px] shrink-0 flex-col'>
|
||||
<div className='system-sm-semibold flex h-8 items-center text-text-secondary'>
|
||||
<div className="flex w-[180px] shrink-0 flex-col">
|
||||
<div className="system-sm-semibold flex h-8 items-center text-text-secondary">
|
||||
{t('datasetSettings.form.chunkStructure.title')}
|
||||
</div>
|
||||
<div className='body-xs-regular text-text-tertiary'>
|
||||
<div className="body-xs-regular text-text-tertiary">
|
||||
<a
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={docLink('/guides/knowledge-base/create-knowledge-and-upload-documents/chunking-and-cleaning-text')}
|
||||
className='text-text-accent'
|
||||
className="text-text-accent"
|
||||
>
|
||||
{t('datasetSettings.form.chunkStructure.learnMore')}
|
||||
</a>
|
||||
{t('datasetSettings.form.chunkStructure.description')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='grow'>
|
||||
<div className="grow">
|
||||
<ChunkStructure
|
||||
chunkStructure={currentDataset?.doc_form}
|
||||
/>
|
||||
@ -300,16 +300,16 @@ const Form = () => {
|
||||
}
|
||||
{(isShowIndexMethod || indexMethod === 'high_quality') && (
|
||||
<Divider
|
||||
type='horizontal'
|
||||
className='my-1 h-px bg-divider-subtle'
|
||||
type="horizontal"
|
||||
className="my-1 h-px bg-divider-subtle"
|
||||
/>
|
||||
)}
|
||||
{isShowIndexMethod && (
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.indexMethod')}</div>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('datasetSettings.form.indexMethod')}</div>
|
||||
</div>
|
||||
<div className='grow'>
|
||||
<div className="grow">
|
||||
<IndexMethod
|
||||
value={indexMethod}
|
||||
disabled={!currentDataset?.embedding_available}
|
||||
@ -319,12 +319,12 @@ const Form = () => {
|
||||
onKeywordNumberChange={setKeywordNumber}
|
||||
/>
|
||||
{currentDataset.indexing_technique === IndexingType.ECONOMICAL && indexMethod === IndexingType.QUALIFIED && (
|
||||
<div className='relative mt-2 flex h-10 items-center gap-x-0.5 overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur px-2 shadow-xs shadow-shadow-shadow-3'>
|
||||
<div className='absolute left-0 top-0 flex h-full w-full items-center bg-toast-warning-bg opacity-40' />
|
||||
<div className='p-1'>
|
||||
<RiAlertFill className='size-4 text-text-warning-secondary' />
|
||||
<div className="relative mt-2 flex h-10 items-center gap-x-0.5 overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur px-2 shadow-xs shadow-shadow-shadow-3">
|
||||
<div className="absolute left-0 top-0 flex h-full w-full items-center bg-toast-warning-bg opacity-40" />
|
||||
<div className="p-1">
|
||||
<RiAlertFill className="size-4 text-text-warning-secondary" />
|
||||
</div>
|
||||
<span className='system-xs-medium text-text-primary'>
|
||||
<span className="system-xs-medium text-text-primary">
|
||||
{t('datasetSettings.form.upgradeHighQualityTip')}
|
||||
</span>
|
||||
</div>
|
||||
@ -335,11 +335,11 @@ const Form = () => {
|
||||
{indexMethod === IndexingType.QUALIFIED && (
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>
|
||||
<div className="system-sm-semibold text-text-secondary">
|
||||
{t('datasetSettings.form.embeddingModel')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='grow'>
|
||||
<div className="grow">
|
||||
<ModelSelector
|
||||
defaultModel={embeddingModel}
|
||||
modelList={embeddingModelList}
|
||||
@ -351,119 +351,118 @@ const Form = () => {
|
||||
{/* Retrieval Method Config */}
|
||||
{currentDataset?.provider === 'external'
|
||||
? (
|
||||
<>
|
||||
<Divider
|
||||
type='horizontal'
|
||||
className='my-1 h-px bg-divider-subtle'
|
||||
/>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.retrievalSetting.title')}</div>
|
||||
</div>
|
||||
<RetrievalSettings
|
||||
topK={topK}
|
||||
scoreThreshold={scoreThreshold}
|
||||
scoreThresholdEnabled={scoreThresholdEnabled}
|
||||
onChange={handleSettingsChange}
|
||||
isInRetrievalSetting={true}
|
||||
/>
|
||||
</div>
|
||||
<Divider
|
||||
type='horizontal'
|
||||
className='my-1 h-px bg-divider-subtle'
|
||||
/>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.externalKnowledgeAPI')}</div>
|
||||
</div>
|
||||
<div className='w-full'>
|
||||
<div className='flex h-full items-center gap-1 rounded-lg bg-components-input-bg-normal px-3 py-2'>
|
||||
<ApiConnectionMod className='h-4 w-4 text-text-secondary' />
|
||||
<div className='system-sm-medium overflow-hidden text-ellipsis text-text-secondary'>
|
||||
{currentDataset?.external_knowledge_info.external_knowledge_api_name}
|
||||
</div>
|
||||
<div className='system-xs-regular text-text-tertiary'>·</div>
|
||||
<div className='system-xs-regular text-text-tertiary'>
|
||||
{currentDataset?.external_knowledge_info.external_knowledge_api_endpoint}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.externalKnowledgeID')}</div>
|
||||
</div>
|
||||
<div className='w-full'>
|
||||
<div className='flex h-full items-center gap-1 rounded-lg bg-components-input-bg-normal px-3 py-2'>
|
||||
<div className='system-xs-regular text-text-tertiary'>
|
||||
{currentDataset?.external_knowledge_info.external_knowledge_id}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
// eslint-disable-next-line sonarjs/no-nested-conditional
|
||||
: indexMethod
|
||||
? (
|
||||
<>
|
||||
<Divider
|
||||
type='horizontal'
|
||||
className='my-1 h-px bg-divider-subtle'
|
||||
type="horizontal"
|
||||
className="my-1 h-px bg-divider-subtle"
|
||||
/>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className='flex w-[180px] shrink-0 flex-col'>
|
||||
<div className='system-sm-semibold flex h-7 items-center pt-1 text-text-secondary'>
|
||||
{t('datasetSettings.form.retrievalSetting.title')}
|
||||
<div className="system-sm-semibold text-text-secondary">{t('datasetSettings.form.retrievalSetting.title')}</div>
|
||||
</div>
|
||||
<RetrievalSettings
|
||||
topK={topK}
|
||||
scoreThreshold={scoreThreshold}
|
||||
scoreThresholdEnabled={scoreThresholdEnabled}
|
||||
onChange={handleSettingsChange}
|
||||
isInRetrievalSetting={true}
|
||||
/>
|
||||
</div>
|
||||
<Divider
|
||||
type="horizontal"
|
||||
className="my-1 h-px bg-divider-subtle"
|
||||
/>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('datasetSettings.form.externalKnowledgeAPI')}</div>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="flex h-full items-center gap-1 rounded-lg bg-components-input-bg-normal px-3 py-2">
|
||||
<ApiConnectionMod className="h-4 w-4 text-text-secondary" />
|
||||
<div className="system-sm-medium overflow-hidden text-ellipsis text-text-secondary">
|
||||
{currentDataset?.external_knowledge_info.external_knowledge_api_name}
|
||||
</div>
|
||||
<div className='body-xs-regular text-text-tertiary'>
|
||||
<a
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
href={docLink('/guides/knowledge-base/create-knowledge-and-upload-documents/setting-indexing-methods#setting-the-retrieval-setting', {
|
||||
'zh-Hans': '/guides/knowledge-base/create-knowledge-and-upload-documents/setting-indexing-methods#指定检索方式',
|
||||
'ja-JP': '/guides/knowledge-base/create-knowledge-and-upload-documents/setting-indexing-methods#検索方法の指定',
|
||||
})}
|
||||
className='text-text-accent'
|
||||
>
|
||||
{t('datasetSettings.form.retrievalSetting.learnMore')}
|
||||
</a>
|
||||
{t('datasetSettings.form.retrievalSetting.description')}
|
||||
<div className="system-xs-regular text-text-tertiary">·</div>
|
||||
<div className="system-xs-regular text-text-tertiary">
|
||||
{currentDataset?.external_knowledge_info.external_knowledge_api_endpoint}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='grow'>
|
||||
{indexMethod === IndexingType.QUALIFIED
|
||||
? (
|
||||
<RetrievalMethodConfig
|
||||
value={retrievalConfig}
|
||||
onChange={setRetrievalConfig}
|
||||
showMultiModalTip={showMultiModalTip}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<EconomicalRetrievalMethodConfig
|
||||
value={retrievalConfig}
|
||||
onChange={setRetrievalConfig}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className="system-sm-semibold text-text-secondary">{t('datasetSettings.form.externalKnowledgeID')}</div>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="flex h-full items-center gap-1 rounded-lg bg-components-input-bg-normal px-3 py-2">
|
||||
<div className="system-xs-regular text-text-tertiary">
|
||||
{currentDataset?.external_knowledge_info.external_knowledge_id}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
: null
|
||||
}
|
||||
// eslint-disable-next-line sonarjs/no-nested-conditional
|
||||
: indexMethod
|
||||
? (
|
||||
<>
|
||||
<Divider
|
||||
type="horizontal"
|
||||
className="my-1 h-px bg-divider-subtle"
|
||||
/>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass}>
|
||||
<div className="flex w-[180px] shrink-0 flex-col">
|
||||
<div className="system-sm-semibold flex h-7 items-center pt-1 text-text-secondary">
|
||||
{t('datasetSettings.form.retrievalSetting.title')}
|
||||
</div>
|
||||
<div className="body-xs-regular text-text-tertiary">
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={docLink('/guides/knowledge-base/create-knowledge-and-upload-documents/setting-indexing-methods#setting-the-retrieval-setting', {
|
||||
'zh-Hans': '/guides/knowledge-base/create-knowledge-and-upload-documents/setting-indexing-methods#指定检索方式',
|
||||
'ja-JP': '/guides/knowledge-base/create-knowledge-and-upload-documents/setting-indexing-methods#検索方法の指定',
|
||||
})}
|
||||
className="text-text-accent"
|
||||
>
|
||||
{t('datasetSettings.form.retrievalSetting.learnMore')}
|
||||
</a>
|
||||
{t('datasetSettings.form.retrievalSetting.description')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grow">
|
||||
{indexMethod === IndexingType.QUALIFIED
|
||||
? (
|
||||
<RetrievalMethodConfig
|
||||
value={retrievalConfig}
|
||||
onChange={setRetrievalConfig}
|
||||
showMultiModalTip={showMultiModalTip}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<EconomicalRetrievalMethodConfig
|
||||
value={retrievalConfig}
|
||||
onChange={setRetrievalConfig}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
: null}
|
||||
<Divider
|
||||
type='horizontal'
|
||||
className='my-1 h-px bg-divider-subtle'
|
||||
type="horizontal"
|
||||
className="my-1 h-px bg-divider-subtle"
|
||||
/>
|
||||
<div className={rowClass}>
|
||||
<div className={labelClass} />
|
||||
<div className='grow'>
|
||||
<div className="grow">
|
||||
<Button
|
||||
className='min-w-24'
|
||||
variant='primary'
|
||||
className="min-w-24"
|
||||
variant="primary"
|
||||
loading={loading}
|
||||
disabled={loading}
|
||||
onClick={handleSave}
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
'use client'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useRef } from 'react'
|
||||
import { useHover } from 'ahooks'
|
||||
import { IndexingType } from '../../create/step-two'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Economic, HighQuality } from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import {
|
||||
PortalToFollowElem,
|
||||
PortalToFollowElemContent,
|
||||
PortalToFollowElemTrigger,
|
||||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
import { Economic, HighQuality } from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { IndexingType } from '../../create/step-two'
|
||||
import { EffectColor } from '../chunk-structure/types'
|
||||
import OptionCard from '../option-card'
|
||||
import KeywordNumber from './keyword-number'
|
||||
@ -43,21 +43,21 @@ const IndexMethod = ({
|
||||
id={IndexingType.QUALIFIED}
|
||||
isActive={value === IndexingType.QUALIFIED}
|
||||
onClick={onChange}
|
||||
icon={<HighQuality className='size-[18px]' />}
|
||||
iconActiveColor='text-util-colors-orange-orange-500'
|
||||
icon={<HighQuality className="size-[18px]" />}
|
||||
iconActiveColor="text-util-colors-orange-orange-500"
|
||||
title={t('datasetCreation.stepTwo.qualified')}
|
||||
description={t('datasetSettings.form.indexMethodHighQualityTip')}
|
||||
disabled={disabled}
|
||||
isRecommended
|
||||
effectColor={EffectColor.orange}
|
||||
showEffectColor
|
||||
className='gap-x-2'
|
||||
className="gap-x-2"
|
||||
/>
|
||||
{/* Economy */}
|
||||
<PortalToFollowElem
|
||||
open={isHoveringEconomy}
|
||||
offset={4}
|
||||
placement={'right'}
|
||||
placement="right"
|
||||
>
|
||||
<PortalToFollowElemTrigger>
|
||||
<OptionCard
|
||||
@ -65,15 +65,15 @@ const IndexMethod = ({
|
||||
id={IndexingType.ECONOMICAL}
|
||||
isActive={value === IndexingType.ECONOMICAL}
|
||||
onClick={onChange}
|
||||
icon={<Economic className='size-[18px]' />}
|
||||
iconActiveColor='text-util-colors-indigo-indigo-600'
|
||||
icon={<Economic className="size-[18px]" />}
|
||||
iconActiveColor="text-util-colors-indigo-indigo-600"
|
||||
title={t('datasetSettings.form.indexMethodEconomy')}
|
||||
description={t('datasetSettings.form.indexMethodEconomyTip', { count: keywordNumber })}
|
||||
disabled={disabled || isEconomyDisabled}
|
||||
effectColor={EffectColor.indigo}
|
||||
showEffectColor
|
||||
showChildren
|
||||
className='gap-x-2'
|
||||
className="gap-x-2"
|
||||
>
|
||||
<KeywordNumber
|
||||
keywordNumber={keywordNumber}
|
||||
@ -82,7 +82,7 @@ const IndexMethod = ({
|
||||
</OptionCard>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent style={{ zIndex: 60 }}>
|
||||
<div className='rounded-lg border-components-panel-border bg-components-tooltip-bg p-3 text-xs font-medium text-text-secondary shadow-lg'>
|
||||
<div className="rounded-lg border-components-panel-border bg-components-tooltip-bg p-3 text-xs font-medium text-text-secondary shadow-lg">
|
||||
{t('datasetSettings.form.indexMethodChangeToEconomyDisabledTip')}
|
||||
</div>
|
||||
</PortalToFollowElemContent>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { InputNumber } from '@/app/components/base/input-number'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import { RiQuestionLine } from '@remixicon/react'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { InputNumber } from '@/app/components/base/input-number'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
|
||||
type KeyWordNumberProps = {
|
||||
keywordNumber: number
|
||||
@ -22,26 +22,26 @@ const KeyWordNumber = ({
|
||||
}, [onKeywordNumberChange])
|
||||
|
||||
return (
|
||||
<div className='flex items-center gap-x-1'>
|
||||
<div className='flex grow items-center gap-x-0.5'>
|
||||
<div className='system-xs-medium truncate text-text-secondary'>
|
||||
<div className="flex items-center gap-x-1">
|
||||
<div className="flex grow items-center gap-x-0.5">
|
||||
<div className="system-xs-medium truncate text-text-secondary">
|
||||
{t('datasetSettings.form.numberOfKeywords')}
|
||||
</div>
|
||||
<Tooltip
|
||||
popupContent='number of keywords'
|
||||
popupContent="number of keywords"
|
||||
>
|
||||
<RiQuestionLine className='h-3.5 w-3.5 text-text-quaternary' />
|
||||
<RiQuestionLine className="h-3.5 w-3.5 text-text-quaternary" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Slider
|
||||
className='mr-3 w-[206px] shrink-0'
|
||||
className="mr-3 w-[206px] shrink-0"
|
||||
value={keywordNumber}
|
||||
max={50}
|
||||
onChange={onKeywordNumberChange}
|
||||
/>
|
||||
<InputNumber
|
||||
wrapperClassName='shrink-0 w-12'
|
||||
type='number'
|
||||
wrapperClassName="shrink-0 w-12"
|
||||
type="number"
|
||||
value={keywordNumber}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import React from 'react'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import Badge from '@/app/components/base/badge'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { EffectColor } from './chunk-structure/types'
|
||||
import Badge from '@/app/components/base/badge'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { ArrowShape } from '../../base/icons/src/vender/knowledge'
|
||||
import { EffectColor } from './chunk-structure/types'
|
||||
|
||||
const HEADER_EFFECT_MAP: Record<EffectColor, string> = {
|
||||
[EffectColor.indigo]: 'bg-util-colors-indigo-indigo-600 opacity-50',
|
||||
@ -57,20 +57,23 @@ const OptionCard = <T,>({
|
||||
disabled && 'cursor-not-allowed opacity-50',
|
||||
)}
|
||||
onClick={() => {
|
||||
if (isActive || disabled) return
|
||||
if (isActive || disabled)
|
||||
return
|
||||
onClick?.(id)
|
||||
}}
|
||||
>
|
||||
<div className={cn(
|
||||
'relative flex rounded-t-xl p-2',
|
||||
className,
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
{
|
||||
effectColor && showEffectColor && (
|
||||
<div className={cn(
|
||||
'absolute left-[-2px] top-[-2px] h-14 w-14 rounded-full blur-[80px]',
|
||||
`${HEADER_EFFECT_MAP[effectColor]}`,
|
||||
)} />
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
@ -78,19 +81,20 @@ const OptionCard = <T,>({
|
||||
<div className={cn(
|
||||
'flex size-6 shrink-0 items-center justify-center text-text-tertiary',
|
||||
isActive && iconActiveColor,
|
||||
)}>
|
||||
)}
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<div className='flex grow flex-col gap-y-0.5 py-px'>
|
||||
<div className='flex items-center gap-x-1'>
|
||||
<span className='system-sm-medium text-text-secondary'>
|
||||
<div className="flex grow flex-col gap-y-0.5 py-px">
|
||||
<div className="flex items-center gap-x-1">
|
||||
<span className="system-sm-medium text-text-secondary">
|
||||
{title}
|
||||
</span>
|
||||
{
|
||||
isRecommended && (
|
||||
<Badge className='h-[18px] border-text-accent-secondary text-text-accent-secondary'>
|
||||
<Badge className="h-[18px] border-text-accent-secondary text-text-accent-secondary">
|
||||
{t('datasetCreation.stepTwo.recommend')}
|
||||
</Badge>
|
||||
)
|
||||
@ -98,7 +102,7 @@ const OptionCard = <T,>({
|
||||
</div>
|
||||
{
|
||||
description && (
|
||||
<div className='system-xs-regular text-text-tertiary'>
|
||||
<div className="system-xs-regular text-text-tertiary">
|
||||
{description}
|
||||
</div>
|
||||
)
|
||||
@ -107,8 +111,8 @@ const OptionCard = <T,>({
|
||||
</div>
|
||||
{
|
||||
children && showChildren && (
|
||||
<div className='relative rounded-b-xl bg-components-panel-bg p-4'>
|
||||
<ArrowShape className='absolute left-[14px] top-[-11px] size-4 text-components-panel-bg' />
|
||||
<div className="relative rounded-b-xl bg-components-panel-bg p-4">
|
||||
<ArrowShape className="absolute left-[14px] top-[-11px] size-4 text-components-panel-bg" />
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import React, { useCallback, useMemo, useState } from 'react'
|
||||
import { useDebounceFn } from 'ahooks'
|
||||
import type { Member } from '@/models/common'
|
||||
import { RiArrowDownSLine, RiGroup2Line, RiLock2Line } from '@remixicon/react'
|
||||
import { useDebounceFn } from 'ahooks'
|
||||
import React, { useCallback, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Avatar from '@/app/components/base/avatar'
|
||||
import Input from '@/app/components/base/input'
|
||||
import {
|
||||
PortalToFollowElem,
|
||||
PortalToFollowElemContent,
|
||||
PortalToFollowElemTrigger,
|
||||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
import Avatar from '@/app/components/base/avatar'
|
||||
import Input from '@/app/components/base/input'
|
||||
import { DatasetPermission } from '@/models/datasets'
|
||||
import { useSelector as useAppContextWithSelector } from '@/context/app-context'
|
||||
import type { Member } from '@/models/common'
|
||||
import Item from './permission-item'
|
||||
import { DatasetPermission } from '@/models/datasets'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import MemberItem from './member-item'
|
||||
import Item from './permission-item'
|
||||
|
||||
export type RoleSelectorProps = {
|
||||
disabled?: boolean
|
||||
@ -92,25 +92,22 @@ const PermissionSelector = ({
|
||||
<PortalToFollowElem
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
placement='bottom-start'
|
||||
placement="bottom-start"
|
||||
offset={4}
|
||||
>
|
||||
<div className='relative'>
|
||||
<div className="relative">
|
||||
<PortalToFollowElemTrigger
|
||||
onClick={() => !disabled && setOpen(v => !v)}
|
||||
className='block'
|
||||
className="block"
|
||||
>
|
||||
<div className={cn('flex cursor-pointer items-center gap-x-0.5 rounded-lg bg-components-input-bg-normal px-2 py-1 hover:bg-state-base-hover-alt',
|
||||
open && 'bg-state-base-hover-alt',
|
||||
disabled && '!cursor-not-allowed !bg-components-input-bg-disabled hover:!bg-components-input-bg-disabled',
|
||||
)}>
|
||||
<div className={cn('flex cursor-pointer items-center gap-x-0.5 rounded-lg bg-components-input-bg-normal px-2 py-1 hover:bg-state-base-hover-alt', open && 'bg-state-base-hover-alt', disabled && '!cursor-not-allowed !bg-components-input-bg-disabled hover:!bg-components-input-bg-disabled')}>
|
||||
{
|
||||
isOnlyMe && (
|
||||
<>
|
||||
<div className='flex size-6 shrink-0 items-center justify-center'>
|
||||
<div className="flex size-6 shrink-0 items-center justify-center">
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={20} />
|
||||
</div>
|
||||
<div className='system-sm-regular grow p-1 text-components-input-text-filled'>
|
||||
<div className="system-sm-regular grow p-1 text-components-input-text-filled">
|
||||
{t('datasetSettings.form.permissionsOnlyMe')}
|
||||
</div>
|
||||
</>
|
||||
@ -119,10 +116,10 @@ const PermissionSelector = ({
|
||||
{
|
||||
isAllTeamMembers && (
|
||||
<>
|
||||
<div className='flex size-6 shrink-0 items-center justify-center'>
|
||||
<RiGroup2Line className='size-4 text-text-secondary' />
|
||||
<div className="flex size-6 shrink-0 items-center justify-center">
|
||||
<RiGroup2Line className="size-4 text-text-secondary" />
|
||||
</div>
|
||||
<div className='system-sm-regular grow p-1 text-components-input-text-filled'>
|
||||
<div className="system-sm-regular grow p-1 text-components-input-text-filled">
|
||||
{t('datasetSettings.form.permissionsAllMember')}
|
||||
</div>
|
||||
</>
|
||||
@ -131,7 +128,7 @@ const PermissionSelector = ({
|
||||
{
|
||||
isPartialMembers && (
|
||||
<>
|
||||
<div className='relative flex size-6 shrink-0 items-center justify-center'>
|
||||
<div className="relative flex size-6 shrink-0 items-center justify-center">
|
||||
{
|
||||
selectedMembers.length === 1 && (
|
||||
<Avatar
|
||||
@ -147,13 +144,13 @@ const PermissionSelector = ({
|
||||
<Avatar
|
||||
avatar={selectedMembers[0].avatar_url}
|
||||
name={selectedMembers[0].name}
|
||||
className='absolute left-0 top-0 z-0'
|
||||
className="absolute left-0 top-0 z-0"
|
||||
size={16}
|
||||
/>
|
||||
<Avatar
|
||||
avatar={selectedMembers[1].avatar_url}
|
||||
name={selectedMembers[1].name}
|
||||
className='absolute bottom-0 right-0 z-10'
|
||||
className="absolute bottom-0 right-0 z-10"
|
||||
size={16}
|
||||
/>
|
||||
</>
|
||||
@ -162,7 +159,7 @@ const PermissionSelector = ({
|
||||
</div>
|
||||
<div
|
||||
title={selectedMemberNames}
|
||||
className='system-sm-regular grow truncate p-1 text-components-input-text-filled'
|
||||
className="system-sm-regular grow truncate p-1 text-components-input-text-filled"
|
||||
>
|
||||
{selectedMemberNames}
|
||||
</div>
|
||||
@ -178,13 +175,13 @@ const PermissionSelector = ({
|
||||
/>
|
||||
</div>
|
||||
</PortalToFollowElemTrigger>
|
||||
<PortalToFollowElemContent className='z-[1002]'>
|
||||
<div className='relative w-[480px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg shadow-shadow-shadow-5'>
|
||||
<div className='p-1'>
|
||||
<PortalToFollowElemContent className="z-[1002]">
|
||||
<div className="relative w-[480px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg shadow-shadow-shadow-5">
|
||||
<div className="p-1">
|
||||
{/* Only me */}
|
||||
<Item
|
||||
leftIcon={
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='shrink-0' size={24} />
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className="shrink-0" size={24} />
|
||||
}
|
||||
text={t('datasetSettings.form.permissionsOnlyMe')}
|
||||
onClick={onSelectOnlyMe}
|
||||
@ -192,30 +189,30 @@ const PermissionSelector = ({
|
||||
/>
|
||||
{/* All team members */}
|
||||
<Item
|
||||
leftIcon={
|
||||
<div className='flex size-6 shrink-0 items-center justify-center'>
|
||||
<RiGroup2Line className='size-4 text-text-secondary' />
|
||||
leftIcon={(
|
||||
<div className="flex size-6 shrink-0 items-center justify-center">
|
||||
<RiGroup2Line className="size-4 text-text-secondary" />
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
text={t('datasetSettings.form.permissionsAllMember')}
|
||||
onClick={onSelectAllMembers}
|
||||
isSelected={isAllTeamMembers}
|
||||
/>
|
||||
{/* Partial members */}
|
||||
<Item
|
||||
leftIcon={
|
||||
<div className='flex size-6 shrink-0 items-center justify-center'>
|
||||
<RiLock2Line className='size-4 text-text-secondary' />
|
||||
leftIcon={(
|
||||
<div className="flex size-6 shrink-0 items-center justify-center">
|
||||
<RiLock2Line className="size-4 text-text-secondary" />
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
text={t('datasetSettings.form.permissionsInvitedMembers')}
|
||||
onClick={onSelectPartialMembers}
|
||||
isSelected={isPartialMembers}
|
||||
/>
|
||||
</div>
|
||||
{isPartialMembers && (
|
||||
<div className='max-h-[360px] overflow-y-auto border-t-[1px] border-divider-regular pb-1 pl-1 pr-1'>
|
||||
<div className='sticky left-0 top-0 z-10 bg-components-panel-on-panel-item-bg p-2 pb-1'>
|
||||
<div className="max-h-[360px] overflow-y-auto border-t-[1px] border-divider-regular pb-1 pl-1 pr-1">
|
||||
<div className="sticky left-0 top-0 z-10 bg-components-panel-on-panel-item-bg p-2 pb-1">
|
||||
<Input
|
||||
showLeftIcon
|
||||
showClearIcon
|
||||
@ -224,11 +221,11 @@ const PermissionSelector = ({
|
||||
onClear={() => handleKeywordsChange('')}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex flex-col p-1'>
|
||||
<div className="flex flex-col p-1">
|
||||
{showMe && (
|
||||
<MemberItem
|
||||
leftIcon={
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className='shrink-0' size={24} />
|
||||
<Avatar avatar={userProfile.avatar_url} name={userProfile.name} className="shrink-0" size={24} />
|
||||
}
|
||||
name={userProfile.name}
|
||||
email={userProfile.email}
|
||||
@ -239,7 +236,7 @@ const PermissionSelector = ({
|
||||
{filteredMemberList.map(member => (
|
||||
<MemberItem
|
||||
leftIcon={
|
||||
<Avatar avatar={member.avatar_url} name={member.name} className='shrink-0' size={24} />
|
||||
<Avatar avatar={member.avatar_url} name={member.name} className="shrink-0" size={24} />
|
||||
}
|
||||
name={member.name}
|
||||
email={member.email}
|
||||
@ -249,7 +246,7 @@ const PermissionSelector = ({
|
||||
))}
|
||||
{
|
||||
!showMe && filteredMemberList.length === 0 && (
|
||||
<div className='system-xs-regular flex items-center justify-center whitespace-pre-wrap px-1 py-6 text-center text-text-tertiary'>
|
||||
<div className="system-xs-regular flex items-center justify-center whitespace-pre-wrap px-1 py-6 text-center text-text-tertiary">
|
||||
{t('datasetSettings.form.onSearchResults')}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { RiCheckLine } from '@remixicon/react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
type MemberItemProps = {
|
||||
leftIcon: React.ReactNode
|
||||
@ -24,18 +24,20 @@ const MemberItem = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className='flex cursor-pointer items-center gap-2 rounded-lg py-1 pl-2 pr-[10px] hover:bg-state-base-hover'
|
||||
className="flex cursor-pointer items-center gap-2 rounded-lg py-1 pl-2 pr-[10px] hover:bg-state-base-hover"
|
||||
onClick={onClick}
|
||||
>
|
||||
{leftIcon}
|
||||
<div className='grow'>
|
||||
<div className='system-sm-medium truncate text-text-secondary'>
|
||||
<div className="grow">
|
||||
<div className="system-sm-medium truncate text-text-secondary">
|
||||
{name}
|
||||
{isMe && <span className='system-xs-regular text-text-tertiary'>
|
||||
{t('datasetSettings.form.me')}
|
||||
</span>}
|
||||
{isMe && (
|
||||
<span className="system-xs-regular text-text-tertiary">
|
||||
{t('datasetSettings.form.me')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className='system-xs-regular truncate text-text-tertiary'>{email}</div>
|
||||
<div className="system-xs-regular truncate text-text-tertiary">{email}</div>
|
||||
</div>
|
||||
{isSelected && <RiCheckLine className={cn('size-4 shrink-0 text-text-accent', isMe && 'opacity-30')} />}
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { RiCheckLine } from '@remixicon/react'
|
||||
import React from 'react'
|
||||
|
||||
type PermissionItemProps = {
|
||||
leftIcon: React.ReactNode
|
||||
@ -16,14 +16,14 @@ const PermissionItem = ({
|
||||
}: PermissionItemProps) => {
|
||||
return (
|
||||
<div
|
||||
className='flex cursor-pointer items-center gap-x-1 rounded-lg px-2 py-1 hover:bg-state-base-hover'
|
||||
className="flex cursor-pointer items-center gap-x-1 rounded-lg px-2 py-1 hover:bg-state-base-hover"
|
||||
onClick={onClick}
|
||||
>
|
||||
{leftIcon}
|
||||
<div className='system-md-regular grow px-1 text-text-secondary'>
|
||||
<div className="system-md-regular grow px-1 text-text-secondary">
|
||||
{text}
|
||||
</div>
|
||||
{isSelected && <RiCheckLine className='size-4 text-text-accent' />}
|
||||
{isSelected && <RiCheckLine className="size-4 text-text-accent" />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { type DefaultModel, type Model, ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { DefaultModel, Model } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { IndexingType } from '../../create/step-two'
|
||||
|
||||
type ShowMultiModalTipProps = {
|
||||
|
||||
Reference in New Issue
Block a user