feat: SaaS price plan frontend (#1683)
Co-authored-by: StyleZhang <jasonapring2015@outlook.com>
This commit is contained in:
@@ -15,6 +15,10 @@ import { formatNumber } from '@/utils/format'
|
||||
import { fetchIndexingStatusBatch as doFetchIndexingStatus, fetchIndexingEstimateBatch, fetchProcessRule } from '@/service/datasets'
|
||||
import { DataSourceType } from '@/models/datasets'
|
||||
import NotionIcon from '@/app/components/base/notion-icon'
|
||||
import PriorityLabel from '@/app/components/billing/priority-label'
|
||||
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'
|
||||
|
||||
type Props = {
|
||||
datasetId: string
|
||||
@@ -78,6 +82,7 @@ const RuleDetail: FC<{ sourceData?: ProcessRuleResponse }> = ({ sourceData }) =>
|
||||
|
||||
const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], indexingType }) => {
|
||||
const { t } = useTranslation()
|
||||
const { enableBilling } = useProviderContext()
|
||||
|
||||
const getFirstDocument = documents[0]
|
||||
|
||||
@@ -115,14 +120,14 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
|
||||
}, [])
|
||||
|
||||
// get rule
|
||||
const { data: ruleDetail, error: ruleError } = useSWR({
|
||||
const { data: ruleDetail } = useSWR({
|
||||
action: 'fetchProcessRule',
|
||||
params: { documentId: getFirstDocument.id },
|
||||
}, apiParams => fetchProcessRule(omit(apiParams, 'action')), {
|
||||
revalidateOnFocus: false,
|
||||
})
|
||||
// get cost
|
||||
const { data: indexingEstimateDetail, error: indexingEstimateErr } = useSWR({
|
||||
const { data: indexingEstimateDetail } = useSWR({
|
||||
action: 'fetchIndexingEstimateBatch',
|
||||
datasetId,
|
||||
batchId,
|
||||
@@ -175,7 +180,7 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
|
||||
{isEmbeddingCompleted && t('datasetDocuments.embedding.completed')}
|
||||
</div>
|
||||
<div className={s.cost}>
|
||||
{indexingType === 'high_quaility' && (
|
||||
{indexingType === 'high_quality' && (
|
||||
<div className='flex items-center'>
|
||||
<div className={cn(s.commonIcon, s.highIcon)} />
|
||||
{t('datasetDocuments.embedding.highQuality')} · {t('datasetDocuments.embedding.estimate')}
|
||||
@@ -192,6 +197,19 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
enableBilling && (
|
||||
<div className='flex items-center mb-3 p-3 h-14 bg-white border-[0.5px] border-black/5 shadow-md rounded-xl'>
|
||||
<div className='shrink-0 flex items-center justify-center w-8 h-8 bg-[#FFF6ED] rounded-lg'>
|
||||
<ZapFast className='w-4 h-4 text-[#FB6514]' />
|
||||
</div>
|
||||
<div className='grow mx-3 text-[13px] font-medium text-gray-700'>
|
||||
{t('billing.plansCommon.documentProcessingPriorityUpgrade')}
|
||||
</div>
|
||||
<UpgradeBtn />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<div className={s.progressContainer}>
|
||||
{indexingStatusBatchDetail.map(indexingStatusDetail => (
|
||||
<div key={indexingStatusDetail.id} className={cn(
|
||||
@@ -202,7 +220,7 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
|
||||
{isSourceEmbedding(indexingStatusDetail) && (
|
||||
<div className={s.progressbar} style={{ width: `${getSourcePercent(indexingStatusDetail)}%` }}/>
|
||||
)}
|
||||
<div className={s.info}>
|
||||
<div className={`${s.info} grow`}>
|
||||
{getSourceType(indexingStatusDetail.id) === DataSourceType.FILE && (
|
||||
<div className={cn(s.fileIcon, s[getFileType(getSourceName(indexingStatusDetail.id))])}/>
|
||||
)}
|
||||
@@ -213,7 +231,12 @@ const EmbeddingProcess: FC<Props> = ({ datasetId, batchId, documents = [], index
|
||||
src={getIcon(indexingStatusDetail.id)}
|
||||
/>
|
||||
)}
|
||||
<div className={s.name}>{getSourceName(indexingStatusDetail.id)}</div>
|
||||
<div className={`${s.name} truncate`} title={getSourceName(indexingStatusDetail.id)}>{getSourceName(indexingStatusDetail.id)}</div>
|
||||
{
|
||||
enableBilling && (
|
||||
<PriorityLabel />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className='shrink-0'>
|
||||
{isSourceEmbedding(indexingStatusDetail) && (
|
||||
|
@@ -15,6 +15,8 @@ import Button from '@/app/components/base/button'
|
||||
import { NotionPageSelector } from '@/app/components/base/notion-page-selector'
|
||||
import { useDatasetDetailContext } from '@/context/dataset-detail'
|
||||
import { fetchDocumentsLimit } from '@/service/common'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import VectorSpaceFull from '@/app/components/billing/vector-space-full'
|
||||
|
||||
type IStepOneProps = {
|
||||
datasetId?: string
|
||||
@@ -88,11 +90,20 @@ const StepOne = ({
|
||||
|
||||
const shouldShowDataSourceTypeList = !datasetId || (datasetId && !dataset?.data_source_type)
|
||||
|
||||
const { plan, enableBilling } = useProviderContext()
|
||||
const allFileLoaded = (files.length > 0 && files.every(file => file.file.id))
|
||||
const hasNotin = notionPages.length > 0
|
||||
const isVectorSpaceFull = plan.usage.vectorSpace >= plan.total.vectorSpace
|
||||
const isShowVectorSpaceFull = (allFileLoaded || hasNotin) && isVectorSpaceFull && enableBilling
|
||||
|
||||
const nextDisabled = useMemo(() => {
|
||||
if (!files.length)
|
||||
return true
|
||||
if (files.some(file => !file.file.id))
|
||||
return true
|
||||
if (isShowVectorSpaceFull)
|
||||
return true
|
||||
|
||||
return false
|
||||
}, [files])
|
||||
return (
|
||||
@@ -164,6 +175,11 @@ const StepOne = ({
|
||||
countLimit={limitsData.documents_limit}
|
||||
countUsed={limitsData.documents_count}
|
||||
/>
|
||||
{isShowVectorSpaceFull && (
|
||||
<div className='max-w-[640px] mb-4'>
|
||||
<VectorSpaceFull />
|
||||
</div>
|
||||
)}
|
||||
<Button disabled={nextDisabled} className={s.submitButton} type='primary' onClick={onStepChange}>{t('datasetCreation.stepOne.button')}</Button>
|
||||
</>
|
||||
)}
|
||||
@@ -181,7 +197,12 @@ const StepOne = ({
|
||||
countUsed={limitsData.documents_count}
|
||||
/>
|
||||
</div>
|
||||
<Button disabled={!notionPages.length} className={s.submitButton} type='primary' onClick={onStepChange}>{t('datasetCreation.stepOne.button')}</Button>
|
||||
{isShowVectorSpaceFull && (
|
||||
<div className='max-w-[640px] mb-4'>
|
||||
<VectorSpaceFull />
|
||||
</div>
|
||||
)}
|
||||
<Button disabled={isShowVectorSpaceFull || !notionPages.length} className={s.submitButton} type='primary' onClick={onStepChange}>{t('datasetCreation.stepOne.button')}</Button>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
Reference in New Issue
Block a user