| @@ -6,11 +6,8 @@ import { | |||
| } from '../type' | |||
| import cn from '@/utils/classnames' | |||
| import { useProviderContext } from '@/context/provider-context' | |||
| import { | |||
| ZapFast, | |||
| ZapNarrow, | |||
| } from '@/app/components/base/icons/src/vender/solid/general' | |||
| import Tooltip from '@/app/components/base/tooltip' | |||
| import { RiAedFill } from '@remixicon/react' | |||
| type PriorityLabelProps = { | |||
| className?: string | |||
| @@ -34,30 +31,26 @@ const PriorityLabel = ({ className }: PriorityLabelProps) => { | |||
| return ( | |||
| <Tooltip popupContent={ | |||
| <div> | |||
| <div className='mb-1 text-xs font-semibold text-gray-700'>{`${t('billing.plansCommon.documentProcessingPriority')}: ${t(`billing.plansCommon.priority.${priority}`)}`}</div> | |||
| <div className='mb-1 text-xs font-semibold text-text-primary'>{`${t('billing.plansCommon.documentProcessingPriority')}: ${t(`billing.plansCommon.priority.${priority}`)}`}</div> | |||
| { | |||
| priority !== DocumentProcessingPriority.topPriority && ( | |||
| <div className='text-xs text-gray-500'>{t('billing.plansCommon.documentProcessingPriorityTip')}</div> | |||
| <div className='text-xs text-text-secondary'>{t('billing.plansCommon.documentProcessingPriorityTip')}</div> | |||
| ) | |||
| } | |||
| </div> | |||
| }> | |||
| <span className={cn(` | |||
| ml-1 flex h-[18px] shrink-0 items-center rounded-[5px] border border-text-accent-secondary px-1 | |||
| text-2xs font-medium text-text-accent-secondary | |||
| `, className)}> | |||
| <div | |||
| className={cn( | |||
| 'system-2xs-medium ml-1 inline-flex h-[18px] shrink-0 items-center rounded-[5px] border border-text-accent-secondary bg-components-badge-bg-dimm px-[5px] text-text-accent-secondary', | |||
| className, | |||
| )}> | |||
| { | |||
| plan.type === Plan.professional && ( | |||
| <ZapNarrow className='mr-0.5 size-3' /> | |||
| (plan.type === Plan.professional || plan.type === Plan.team || plan.type === Plan.enterprise) && ( | |||
| <RiAedFill className='mr-0.5 size-3' /> | |||
| ) | |||
| } | |||
| { | |||
| (plan.type === Plan.team || plan.type === Plan.enterprise) && ( | |||
| <ZapFast className='mr-0.5 size-3' /> | |||
| ) | |||
| } | |||
| {t(`billing.plansCommon.priority.${priority}`)} | |||
| </span> | |||
| <span>{t(`billing.plansCommon.priority.${priority}`)}</span> | |||
| </div> | |||
| </Tooltip> | |||
| ) | |||
| } | |||
| @@ -4,8 +4,8 @@ import useSWR from 'swr' | |||
| import { useRouter } from 'next/navigation' | |||
| import { useTranslation } from 'react-i18next' | |||
| import { omit } from 'lodash-es' | |||
| import { ArrowRightIcon } from '@heroicons/react/24/solid' | |||
| import { | |||
| RiArrowRightLine, | |||
| RiCheckboxCircleFill, | |||
| RiErrorWarningFill, | |||
| RiLoader2Fill, | |||
| @@ -31,6 +31,7 @@ import { sleep } from '@/utils' | |||
| import { RETRIEVE_METHOD } from '@/types/app' | |||
| import Tooltip from '@/app/components/base/tooltip' | |||
| import { useInvalidDocumentList } from '@/service/knowledge/use-document' | |||
| import Divider from '@/app/components/base/divider' | |||
| type Props = { | |||
| datasetId: string | |||
| @@ -252,102 +253,112 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index | |||
| return ( | |||
| <> | |||
| <div className="mb-3 flex h-5 items-center"> | |||
| <div className="mr-2 flex items-center justify-between text-sm font-medium text-text-secondary"> | |||
| {isEmbedding && <div className='flex items-center'> | |||
| <RiLoader2Fill className='mr-1 size-4 animate-spin text-text-secondary' /> | |||
| {t('datasetDocuments.embedding.processing')} | |||
| </div>} | |||
| <div className='flex flex-col gap-y-3'> | |||
| <div className='system-md-semibold-uppercase flex items-center gap-x-1 text-text-secondary'> | |||
| {isEmbedding && ( | |||
| <> | |||
| <RiLoader2Fill className='size-4 animate-spin' /> | |||
| <span>{t('datasetDocuments.embedding.processing')}</span> | |||
| </> | |||
| )} | |||
| {isEmbeddingCompleted && t('datasetDocuments.embedding.completed')} | |||
| </div> | |||
| </div> | |||
| { | |||
| enableBilling && plan.type !== Plan.team && ( | |||
| <div className='mb-3 flex h-14 items-center rounded-xl border-[0.5px] border-black/5 bg-white p-3 shadow-md'> | |||
| <div className='flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[#FFF6ED]'> | |||
| <ZapFast className='h-4 w-4 text-[#FB6514]' /> | |||
| </div> | |||
| <div className='mx-3 grow text-[13px] font-medium text-gray-700'> | |||
| {t('billing.plansCommon.documentProcessingPriorityUpgrade')} | |||
| { | |||
| enableBilling && plan.type !== Plan.team && ( | |||
| <div className='flex h-14 items-center rounded-xl border-[0.5px] border-black/5 bg-white p-3 shadow-md'> | |||
| <div className='flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[#FFF6ED]'> | |||
| <ZapFast className='h-4 w-4 text-[#FB6514]' /> | |||
| </div> | |||
| <div className='mx-3 grow text-[13px] font-medium text-gray-700'> | |||
| {t('billing.plansCommon.documentProcessingPriorityUpgrade')} | |||
| </div> | |||
| <UpgradeBtn loc='knowledge-speed-up' /> | |||
| </div> | |||
| <UpgradeBtn loc='knowledge-speed-up' /> | |||
| </div> | |||
| ) | |||
| } | |||
| <div className="flex flex-col gap-0.5 pb-2"> | |||
| {indexingStatusBatchDetail.map(indexingStatusDetail => ( | |||
| <div key={indexingStatusDetail.id} className={cn( | |||
| 'relative h-[26px] overflow-hidden rounded-md bg-components-progress-bar-bg', | |||
| indexingStatusDetail.indexing_status === 'error' && 'bg-state-destructive-hover-alt', | |||
| // indexingStatusDetail.indexing_status === 'completed' && 's.success', | |||
| )}> | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div className="absolute left-0 top-0 h-full min-w-0.5 border-r-[2px] border-r-components-progress-bar-progress-highlight bg-components-progress-bar-progress" style={{ width: `${getSourcePercent(indexingStatusDetail)}%` }} /> | |||
| )} | |||
| <div className="z-[1] flex h-full items-center gap-1 pl-[6px] pr-2"> | |||
| {getSourceType(indexingStatusDetail.id) === DataSourceType.FILE && ( | |||
| // <div className={cn( | |||
| // 'shrink-0 marker:size-4 bg-center bg-no-repeat bg-contain', | |||
| // s[getFileType(getSourceName(indexingStatusDetail.id))] || s.unknownFileIcon, | |||
| // )} /> | |||
| <DocumentFileIcon | |||
| className="size-4 shrink-0" | |||
| name={getSourceName(indexingStatusDetail.id)} | |||
| extension={getFileType(getSourceName(indexingStatusDetail.id))} | |||
| /> | |||
| ) | |||
| } | |||
| <div className='flex flex-col gap-0.5 pb-2'> | |||
| {indexingStatusBatchDetail.map(indexingStatusDetail => ( | |||
| <div | |||
| key={indexingStatusDetail.id} | |||
| className={cn( | |||
| 'relative h-[26px] overflow-hidden rounded-md bg-components-progress-bar-bg', | |||
| indexingStatusDetail.indexing_status === 'error' && 'bg-state-destructive-hover-alt', | |||
| )} | |||
| {getSourceType(indexingStatusDetail.id) === DataSourceType.NOTION && ( | |||
| <NotionIcon | |||
| className='shrink-0' | |||
| type='page' | |||
| src={getIcon(indexingStatusDetail.id)} | |||
| > | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div | |||
| className='absolute left-0 top-0 h-full min-w-0.5 border-r-[2px] border-r-components-progress-bar-progress-highlight bg-components-progress-bar-progress' | |||
| style={{ width: `${getSourcePercent(indexingStatusDetail)}%` }} | |||
| /> | |||
| )} | |||
| <div className="flex w-0 grow items-center gap-1" title={getSourceName(indexingStatusDetail.id)}> | |||
| <div className="system-xs-medium truncate text-text-secondary"> | |||
| {getSourceName(indexingStatusDetail.id)} | |||
| <div className='z-[1] flex h-full items-center gap-1 pl-[6px] pr-2'> | |||
| {getSourceType(indexingStatusDetail.id) === DataSourceType.FILE && ( | |||
| <DocumentFileIcon | |||
| className='size-4 shrink-0' | |||
| name={getSourceName(indexingStatusDetail.id)} | |||
| extension={getFileType(getSourceName(indexingStatusDetail.id))} | |||
| /> | |||
| )} | |||
| {getSourceType(indexingStatusDetail.id) === DataSourceType.NOTION && ( | |||
| <NotionIcon | |||
| className='shrink-0' | |||
| type='page' | |||
| src={getIcon(indexingStatusDetail.id)} | |||
| /> | |||
| )} | |||
| <div className='flex w-0 grow items-center gap-1' title={getSourceName(indexingStatusDetail.id)}> | |||
| <div className='system-xs-medium truncate text-text-secondary'> | |||
| {getSourceName(indexingStatusDetail.id)} | |||
| </div> | |||
| { | |||
| enableBilling && ( | |||
| <PriorityLabel className='ml-0' /> | |||
| ) | |||
| } | |||
| </div> | |||
| { | |||
| enableBilling && ( | |||
| <PriorityLabel className='ml-0' /> | |||
| ) | |||
| } | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div className='shrink-0 text-xs text-text-secondary'>{`${getSourcePercent(indexingStatusDetail)}%`}</div> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'error' && ( | |||
| <Tooltip | |||
| popupClassName='px-4 py-[14px] max-w-60 body-xs-regular text-text-secondary border-[0.5px] border-components-panel-border rounded-xl' | |||
| offset={4} | |||
| popupContent={indexingStatusDetail.error} | |||
| > | |||
| <span> | |||
| <RiErrorWarningFill className='size-4 shrink-0 text-text-destructive' /> | |||
| </span> | |||
| </Tooltip> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'completed' && ( | |||
| <RiCheckboxCircleFill className='size-4 shrink-0 text-text-success' /> | |||
| )} | |||
| </div> | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div className="shrink-0 text-xs text-text-secondary">{`${getSourcePercent(indexingStatusDetail)}%`}</div> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'error' && ( | |||
| <Tooltip | |||
| popupClassName='px-4 py-[14px] max-w-60 text-sm leading-4 text-text-secondary border-[0.5px] border-components-panel-border rounded-xl' | |||
| offset={4} | |||
| popupContent={indexingStatusDetail.error} | |||
| > | |||
| <span> | |||
| <RiErrorWarningFill className='size-4 shrink-0 text-text-destructive' /> | |||
| </span> | |||
| </Tooltip> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'completed' && ( | |||
| <RiCheckboxCircleFill className='size-4 shrink-0 text-text-success' /> | |||
| )} | |||
| </div> | |||
| </div> | |||
| ))} | |||
| ))} | |||
| </div> | |||
| <Divider type='horizontal' className='my-0 bg-divider-subtle' /> | |||
| <RuleDetail | |||
| sourceData={ruleDetail} | |||
| indexingType={indexingType} | |||
| retrievalMethod={retrievalMethod} | |||
| /> | |||
| </div> | |||
| <hr className="my-3 h-[1px] border-0 bg-divider-subtle" /> | |||
| <RuleDetail | |||
| sourceData={ruleDetail} | |||
| indexingType={indexingType} | |||
| retrievalMethod={retrievalMethod} | |||
| /> | |||
| <div className='my-10 flex items-center gap-2'> | |||
| <Button className='w-fit' onClick={navToApiDocs}> | |||
| <RiTerminalBoxLine className='mr-2 size-4' /> | |||
| <span>Access the API</span> | |||
| <div className='mt-6 flex items-center gap-x-2 py-2'> | |||
| <Button | |||
| className='w-fit gap-x-0.5 px-3' | |||
| onClick={navToApiDocs} | |||
| > | |||
| <RiTerminalBoxLine className='size-4' /> | |||
| <span className='px-0.5'>Access the API</span> | |||
| </Button> | |||
| <Button className='w-fit' variant='primary' onClick={navToDocumentList}> | |||
| <span>{t('datasetCreation.stepThree.navTo')}</span> | |||
| <ArrowRightIcon className='ml-2 size-4 stroke-current stroke-1' /> | |||
| <Button | |||
| className='w-fit gap-x-0.5 px-3' | |||
| variant='primary' | |||
| onClick={navToDocumentList} | |||
| > | |||
| <span className='px-0.5'>{t('datasetCreation.stepThree.navTo')}</span> | |||
| <RiArrowRightLine className='size-4 stroke-current stroke-1' /> | |||
| </Button> | |||
| </div> | |||
| </> | |||
| @@ -7,6 +7,7 @@ import EmbeddingProcess from '../embedding-process' | |||
| import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' | |||
| import type { FullDocumentDetail, createDocumentResponse } from '@/models/datasets' | |||
| import AppIcon from '@/app/components/base/app-icon' | |||
| import Divider from '@/app/components/base/divider' | |||
| type StepThreeProps = { | |||
| datasetId?: string | |||
| @@ -21,31 +22,48 @@ const StepThree = ({ datasetId, datasetName, indexingType, creationCache, retrie | |||
| const media = useBreakpoints() | |||
| const isMobile = media === MediaType.mobile | |||
| const iconInfo = creationCache?.dataset?.icon_info || { | |||
| icon: '📙', | |||
| icon_type: 'emoji', | |||
| icon_background: '#FFF4ED', | |||
| icon_url: '', | |||
| } | |||
| return ( | |||
| <div className="flex h-full max-h-full w-full justify-center overflow-y-auto"> | |||
| <div className="h-full max-w-[960px] shrink-0 grow overflow-y-auto px-14 sm:px-16"> | |||
| <div className="mx-auto max-w-[640px]"> | |||
| <div className='flex h-full max-h-full w-full justify-center overflow-y-auto'> | |||
| <div className='h-full max-w-[960px] shrink-0 grow overflow-y-auto px-14 sm:px-16'> | |||
| <div className='mx-auto max-w-[640px] pb-8 pt-10'> | |||
| {!datasetId && ( | |||
| <> | |||
| <div className="pt-10"> | |||
| <div className="mb-1 text-xl font-semibold leading-[22px] text-text-primary">{t('datasetCreation.stepThree.creationTitle')}</div> | |||
| <div className="mb-7 text-[13px] leading-4 text-text-tertiary">{t('datasetCreation.stepThree.creationContent')}</div> | |||
| <div className="flex gap-4"> | |||
| <AppIcon {...creationCache?.dataset} className="size-14 self-center text-2xl" /> | |||
| <div className="flex grow flex-col gap-1"> | |||
| <div className="text-[13px] font-semibold leading-6 text-text-secondary">{t('datasetCreation.stepThree.label')}</div> | |||
| <div className="w-full truncate rounded-lg bg-components-input-bg-normal px-3 py-2 text-[13px] leading-4 text-components-input-text-filled">{datasetName || creationCache?.dataset?.name}</div> | |||
| <div className='flex flex-col gap-y-1 pb-3'> | |||
| <div className='title-2xl-semi-bold text-text-primary'>{t('datasetCreation.stepThree.creationTitle')}</div> | |||
| <div className='system-sm-regular text-text-tertiary'>{t('datasetCreation.stepThree.creationContent')}</div> | |||
| </div> | |||
| <div className='flex gap-4'> | |||
| <AppIcon | |||
| size='xxl' | |||
| iconType={iconInfo.icon_type} | |||
| icon={iconInfo.icon} | |||
| background={iconInfo.icon_background} | |||
| imageUrl={iconInfo.icon_url} | |||
| className='shrink-0' | |||
| /> | |||
| <div className='flex grow flex-col gap-y-1'> | |||
| <div className='system-sm-semibold flex h-6 items-center text-text-secondary'> | |||
| {t('datasetCreation.stepThree.label')} | |||
| </div> | |||
| <div className='system-sm-regular w-full truncate rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled'> | |||
| <span className='px-1'>{datasetName || creationCache?.dataset?.name}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <hr className="my-6 h-[1px] border-0 bg-divider-subtle" /> | |||
| <Divider type='horizontal' className='my-6 bg-divider-subtle' /> | |||
| </> | |||
| )} | |||
| {datasetId && ( | |||
| <div className="pt-10"> | |||
| <div className="mb-1 text-xl font-semibold leading-[22px] text-text-primary">{t('datasetCreation.stepThree.additionTitle')}</div> | |||
| <div className="mb-7 text-[13px] leading-4 text-text-tertiary">{`${t('datasetCreation.stepThree.additionP1')} ${datasetName || creationCache?.dataset?.name} ${t('datasetCreation.stepThree.additionP2')}`}</div> | |||
| <div className='flex flex-col gap-y-1 pb-3'> | |||
| <div className='title-2xl-semi-bold text-text-primary'>{t('datasetCreation.stepThree.additionTitle')}</div> | |||
| <div className='system-sm-regular text-text-tertiary'>{`${t('datasetCreation.stepThree.additionP1')} ${datasetName || creationCache?.dataset?.name} ${t('datasetCreation.stepThree.additionP2')}`}</div> | |||
| </div> | |||
| )} | |||
| <EmbeddingProcess | |||
| @@ -58,13 +76,13 @@ const StepThree = ({ datasetId, datasetName, indexingType, creationCache, retrie | |||
| </div> | |||
| </div> | |||
| {!isMobile && ( | |||
| <div className="shrink-0 pr-8 pt-[88px] text-xs"> | |||
| <div className="flex w-[328px] flex-col gap-3 rounded-xl bg-background-section p-6 text-text-tertiary"> | |||
| <div className="flex size-10 items-center justify-center rounded-[10px] bg-components-card-bg shadow-lg"> | |||
| <RiBookOpenLine className="size-5 text-text-accent" /> | |||
| <div className='shrink-0 pr-8 pt-[88px] text-xs'> | |||
| <div className='flex w-[328px] flex-col gap-3 rounded-xl bg-background-section p-6 text-text-tertiary'> | |||
| <div className='flex size-10 items-center justify-center rounded-[10px] bg-components-card-bg shadow-lg'> | |||
| <RiBookOpenLine className='size-5 text-text-accent' /> | |||
| </div> | |||
| <div className="text-base font-semibold text-text-secondary">{t('datasetCreation.stepThree.sideTipTitle')}</div> | |||
| <div className="text-text-tertiary">{t('datasetCreation.stepThree.sideTipContent')}</div> | |||
| <div className='text-base font-semibold text-text-secondary'>{t('datasetCreation.stepThree.sideTipTitle')}</div> | |||
| <div className='text-text-tertiary'>{t('datasetCreation.stepThree.sideTipContent')}</div> | |||
| </div> | |||
| </div> | |||
| )} | |||
| @@ -1,8 +1,9 @@ | |||
| import React, { useEffect, useMemo, useState } from 'react' | |||
| import { useRouter } from 'next/navigation' | |||
| import { useTranslation } from 'react-i18next' | |||
| import { ArrowRightIcon } from '@heroicons/react/24/solid' | |||
| import { | |||
| RiAedFill, | |||
| RiArrowRightLine, | |||
| RiCheckboxCircleFill, | |||
| RiErrorWarningFill, | |||
| RiLoader2Fill, | |||
| @@ -14,7 +15,6 @@ import type { IndexingStatusResponse } from '@/models/datasets' | |||
| import NotionIcon from '@/app/components/base/notion-icon' | |||
| import PriorityLabel from '@/app/components/billing/priority-label' | |||
| 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 Tooltip from '@/app/components/base/tooltip' | |||
| @@ -25,6 +25,7 @@ import type { IndexingType } from '@/app/components/datasets/create/step-two' | |||
| import type { RETRIEVE_METHOD } from '@/types/app' | |||
| import { DatasourceType, type InitialDocumentDetail } from '@/models/pipeline' | |||
| import { useIndexingStatusBatch, useProcessRule } from '@/service/knowledge/use-dataset' | |||
| import Divider from '@/app/components/base/divider' | |||
| type EmbeddingProcessProps = { | |||
| datasetId: string | |||
| @@ -122,100 +123,112 @@ const EmbeddingProcess = ({ | |||
| return ( | |||
| <> | |||
| <div className='mb-3 flex h-5 items-center'> | |||
| <div className='mr-2 flex items-center justify-between text-sm font-medium text-text-secondary'> | |||
| {isEmbedding && <div className='flex items-center'> | |||
| <RiLoader2Fill className='mr-1 size-4 animate-spin text-text-secondary' /> | |||
| {t('datasetDocuments.embedding.processing')} | |||
| </div>} | |||
| <div className='flex flex-col gap-y-3'> | |||
| <div className='system-md-semibold-uppercase flex items-center gap-x-1 text-text-secondary'> | |||
| {isEmbedding && ( | |||
| <> | |||
| <RiLoader2Fill className='size-4 animate-spin' /> | |||
| <span>{t('datasetDocuments.embedding.processing')}</span> | |||
| </> | |||
| )} | |||
| {isEmbeddingCompleted && t('datasetDocuments.embedding.completed')} | |||
| </div> | |||
| </div> | |||
| { | |||
| enableBilling && plan.type !== Plan.team && ( | |||
| <div className='mb-3 flex h-14 items-center rounded-xl border-[0.5px] border-black/5 bg-white p-3 shadow-md'> | |||
| <div className='flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[#FFF6ED]'> | |||
| <ZapFast className='h-4 w-4 text-[#FB6514]' /> | |||
| </div> | |||
| <div className='mx-3 grow text-[13px] font-medium text-gray-700'> | |||
| {t('billing.plansCommon.documentProcessingPriorityUpgrade')} | |||
| { | |||
| enableBilling && plan.type !== Plan.team && ( | |||
| <div className='flex h-[52px] items-center gap-x-2 rounded-xl border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg p-2.5 pl-3 shadow-xs shadow-shadow-shadow-3'> | |||
| <div className='flex shrink-0 items-center justify-center rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-blue-brand-blue-brand-500 shadow-md shadow-shadow-shadow-5'> | |||
| <RiAedFill className='size-4 text-text-primary-on-surface' /> | |||
| </div> | |||
| <div className='system-md-medium grow text-text-primary'> | |||
| {t('billing.plansCommon.documentProcessingPriorityUpgrade')} | |||
| </div> | |||
| <UpgradeBtn loc='knowledge-speed-up' /> | |||
| </div> | |||
| <UpgradeBtn loc='knowledge-speed-up' /> | |||
| </div> | |||
| ) | |||
| } | |||
| <div className='flex flex-col gap-0.5 pb-2'> | |||
| {indexingStatusBatchDetail.map(indexingStatusDetail => ( | |||
| <div key={indexingStatusDetail.id} className={cn( | |||
| 'relative h-[26px] overflow-hidden rounded-md bg-components-progress-bar-bg', | |||
| indexingStatusDetail.indexing_status === 'error' && 'bg-state-destructive-hover-alt', | |||
| )}> | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div | |||
| className='absolute left-0 top-0 h-full min-w-0.5 border-r-[2px] border-r-components-progress-bar-progress-highlight bg-components-progress-bar-progress' | |||
| style={{ width: `${getSourcePercent(indexingStatusDetail)}%` }} | |||
| /> | |||
| )} | |||
| <div className='z-[1] flex h-full items-center gap-1 pl-[6px] pr-2'> | |||
| {getSourceType(indexingStatusDetail.id) === DatasourceType.localFile && ( | |||
| <DocumentFileIcon | |||
| className='size-4 shrink-0' | |||
| name={getSourceName(indexingStatusDetail.id)} | |||
| extension={getFileType(getSourceName(indexingStatusDetail.id))} | |||
| /> | |||
| ) | |||
| } | |||
| <div className='flex flex-col gap-0.5 pb-2'> | |||
| {indexingStatusBatchDetail.map(indexingStatusDetail => ( | |||
| <div | |||
| key={indexingStatusDetail.id} | |||
| className={cn( | |||
| 'relative h-[26px] overflow-hidden rounded-md bg-components-progress-bar-bg', | |||
| indexingStatusDetail.indexing_status === 'error' && 'bg-state-destructive-hover-alt', | |||
| )} | |||
| {getSourceType(indexingStatusDetail.id) === DatasourceType.onlineDocument && ( | |||
| <NotionIcon | |||
| className='shrink-0' | |||
| type='page' | |||
| src={getIcon(indexingStatusDetail.id)} | |||
| > | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div | |||
| className='absolute left-0 top-0 h-full min-w-0.5 border-r-[2px] border-r-components-progress-bar-progress-highlight bg-components-progress-bar-progress' | |||
| style={{ width: `${getSourcePercent(indexingStatusDetail)}%` }} | |||
| /> | |||
| )} | |||
| <div className='flex w-0 grow items-center gap-1' title={getSourceName(indexingStatusDetail.id)}> | |||
| <div className='system-xs-medium truncate text-text-secondary'> | |||
| {getSourceName(indexingStatusDetail.id)} | |||
| <div className='z-[1] flex h-full items-center gap-1 pl-[6px] pr-2'> | |||
| {getSourceType(indexingStatusDetail.id) === DatasourceType.localFile && ( | |||
| <DocumentFileIcon | |||
| className='size-4 shrink-0' | |||
| name={getSourceName(indexingStatusDetail.id)} | |||
| extension={getFileType(getSourceName(indexingStatusDetail.id))} | |||
| /> | |||
| )} | |||
| {getSourceType(indexingStatusDetail.id) === DatasourceType.onlineDocument && ( | |||
| <NotionIcon | |||
| className='shrink-0' | |||
| type='page' | |||
| src={getIcon(indexingStatusDetail.id)} | |||
| /> | |||
| )} | |||
| <div className='flex w-0 grow items-center gap-1' title={getSourceName(indexingStatusDetail.id)}> | |||
| <div className='system-xs-medium truncate text-text-secondary'> | |||
| {getSourceName(indexingStatusDetail.id)} | |||
| </div> | |||
| { | |||
| enableBilling && ( | |||
| <PriorityLabel className='ml-0' /> | |||
| ) | |||
| } | |||
| </div> | |||
| { | |||
| enableBilling && ( | |||
| <PriorityLabel className='ml-0' /> | |||
| ) | |||
| } | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div className='shrink-0 text-xs text-text-secondary'>{`${getSourcePercent(indexingStatusDetail)}%`}</div> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'error' && ( | |||
| <Tooltip | |||
| popupClassName='px-4 py-[14px] max-w-60 body-xs-regular text-text-secondary border-[0.5px] border-components-panel-border rounded-xl' | |||
| offset={4} | |||
| popupContent={indexingStatusDetail.error} | |||
| > | |||
| <span> | |||
| <RiErrorWarningFill className='size-4 shrink-0 text-text-destructive' /> | |||
| </span> | |||
| </Tooltip> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'completed' && ( | |||
| <RiCheckboxCircleFill className='size-4 shrink-0 text-text-success' /> | |||
| )} | |||
| </div> | |||
| {isSourceEmbedding(indexingStatusDetail) && ( | |||
| <div className='shrink-0 text-xs text-text-secondary'>{`${getSourcePercent(indexingStatusDetail)}%`}</div> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'error' && ( | |||
| <Tooltip | |||
| popupClassName='px-4 py-[14px] max-w-60 text-sm leading-4 text-text-secondary border-[0.5px] border-components-panel-border rounded-xl' | |||
| offset={4} | |||
| popupContent={indexingStatusDetail.error} | |||
| > | |||
| <span> | |||
| <RiErrorWarningFill className='size-4 shrink-0 text-text-destructive' /> | |||
| </span> | |||
| </Tooltip> | |||
| )} | |||
| {indexingStatusDetail.indexing_status === 'completed' && ( | |||
| <RiCheckboxCircleFill className='size-4 shrink-0 text-text-success' /> | |||
| )} | |||
| </div> | |||
| </div> | |||
| ))} | |||
| ))} | |||
| </div> | |||
| <Divider type='horizontal' className='my-0 bg-divider-subtle' /> | |||
| <RuleDetail | |||
| sourceData={ruleDetail} | |||
| indexingType={indexingType} | |||
| retrievalMethod={retrievalMethod} | |||
| /> | |||
| </div> | |||
| <hr className='my-3 h-[1px] border-0 bg-divider-subtle' /> | |||
| <RuleDetail | |||
| sourceData={ruleDetail} | |||
| indexingType={indexingType} | |||
| retrievalMethod={retrievalMethod} | |||
| /> | |||
| <div className='my-10 flex items-center gap-2'> | |||
| <Button className='w-fit' onClick={navToApiDocs}> | |||
| <RiTerminalBoxLine className='mr-2 size-4' /> | |||
| <span>Access the API</span> | |||
| <div className='mt-6 flex items-center gap-x-2 py-2'> | |||
| <Button | |||
| className='w-fit gap-x-0.5 px-3' | |||
| onClick={navToApiDocs} | |||
| > | |||
| <RiTerminalBoxLine className='size-4' /> | |||
| <span className='px-0.5'>Access the API</span> | |||
| </Button> | |||
| <Button className='w-fit' variant='primary' onClick={navToDocumentList}> | |||
| <span>{t('datasetCreation.stepThree.navTo')}</span> | |||
| <ArrowRightIcon className='ml-2 size-4 stroke-current stroke-1' /> | |||
| <Button | |||
| className='w-fit gap-x-0.5 px-3' | |||
| variant='primary' | |||
| onClick={navToDocumentList} | |||
| > | |||
| <span className='px-0.5'>{t('datasetCreation.stepThree.navTo')}</span> | |||
| <RiArrowRightLine className='size-4 stroke-current stroke-1' /> | |||
| </Button> | |||
| </div> | |||
| </> | |||