feat: add knowledge pipeline publishing feature and update billing context; refactor popup component for conditional rendering

This commit is contained in:
twwu 2025-08-15 18:06:15 +08:00
parent fb10706c20
commit 8cf98ba0ce
5 changed files with 41 additions and 6 deletions

View File

@ -9,7 +9,7 @@ const Cloud = ({
return ( return (
<svg xmlns='http://www.w3.org/2000/svg' width='16' height='17' viewBox='0 0 16 17' fill='none'> <svg xmlns='http://www.w3.org/2000/svg' width='16' height='17' viewBox='0 0 16 17' fill='none'>
<g clip-path='url(#clip0_1_4630)'> <g clipPath='url(#clip0_1_4630)'>
<rect y='0.5' width='4' height='4' rx='2' fill={color} /> <rect y='0.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='6' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' /> <rect opacity='0.18' x='6' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='12' y='0.5' width='4' height='4' rx='2' fill={color} /> <rect x='12' y='0.5' width='4' height='4' rx='2' fill={color} />

View File

@ -9,7 +9,7 @@ const SelfHosted = ({
return ( return (
<svg xmlns='http://www.w3.org/2000/svg' width='16' height='17' viewBox='0 0 16 17' fill='none'> <svg xmlns='http://www.w3.org/2000/svg' width='16' height='17' viewBox='0 0 16 17' fill='none'>
<g clip-path='url(#clip0_1_4644)'> <g clipPath='url(#clip0_1_4644)'>
<rect opacity='0.18' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' /> <rect opacity='0.18' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />
<rect x='6' y='0.5' width='4' height='4' rx='2' fill={color} /> <rect x='6' y='0.5' width='4' height='4' rx='2' fill={color} />
<rect opacity='0.18' x='12' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' /> <rect opacity='0.18' x='12' y='0.5' width='4' height='4' rx='2' fill='var(--color-text-quaternary)' />

View File

@ -101,6 +101,9 @@ export type CurrentPlanInfoBackend = {
limit: number limit: number
}, },
is_allow_transfer_workspace: boolean is_allow_transfer_workspace: boolean
knowledge_pipeline: {
publish_enabled: boolean
},
} }
export type SubscriptionItem = { export type SubscriptionItem = {

View File

@ -39,6 +39,11 @@ import Confirm from '@/app/components/base/confirm'
import PublishAsKnowledgePipelineModal from '../../publish-as-knowledge-pipeline-modal' import PublishAsKnowledgePipelineModal from '../../publish-as-knowledge-pipeline-modal'
import type { IconInfo } from '@/models/datasets' import type { IconInfo } from '@/models/datasets'
import { useResetDatasetList } from '@/service/knowledge/use-dataset' import { useResetDatasetList } from '@/service/knowledge/use-dataset'
import { useProviderContext } from '@/context/provider-context'
import classNames from '@/utils/classnames'
import PremiumBadge from '@/app/components/base/premium-badge'
import { SparklesSoft } from '@/app/components/base/icons/src/public/common'
import { useModalContextSelector } from '@/context/modal-context'
const PUBLISH_SHORTCUT = ['ctrl', '⇧', 'P'] const PUBLISH_SHORTCUT = ['ctrl', '⇧', 'P']
@ -56,6 +61,9 @@ const Popup = () => {
const { mutateAsync: publishWorkflow } = usePublishWorkflow() const { mutateAsync: publishWorkflow } = usePublishWorkflow()
const { notify } = useToastContext() const { notify } = useToastContext()
const workflowStore = useWorkflowStore() const workflowStore = useWorkflowStore()
const { isAllowPublishAsKnowledgePipeline } = useProviderContext()
const setShowPricingModal = useModalContextSelector(s => s.setShowPricingModal)
const [confirmVisible, { const [confirmVisible, {
setFalse: hideConfirm, setFalse: hideConfirm,
setTrue: showConfirm, setTrue: showConfirm,
@ -158,8 +166,18 @@ const Popup = () => {
t, t,
]) ])
const handleClickPublishAsKnowledgePipeline = useCallback(() => {
if (!isAllowPublishAsKnowledgePipeline)
setShowPricingModal()
else
setShowPublishAsKnowledgePipelineModal()
}, [isAllowPublishAsKnowledgePipeline, setShowPublishAsKnowledgePipelineModal, setShowPricingModal])
return ( return (
<div className='w-[320px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5'> <div className={classNames(
'rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5',
isAllowPublishAsKnowledgePipeline ? 'w-[320px] ' : 'w-[360px]',
)}>
<div className='p-4 pt-3'> <div className='p-4 pt-3'>
<div className='system-xs-medium-uppercase flex h-6 items-center text-text-tertiary'> <div className='system-xs-medium-uppercase flex h-6 items-center text-text-tertiary'>
{publishedAt ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')} {publishedAt ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')}
@ -233,12 +251,20 @@ const Popup = () => {
<Button <Button
className='w-full hover:bg-state-accent-hover hover:text-text-accent' className='w-full hover:bg-state-accent-hover hover:text-text-accent'
variant='tertiary' variant='tertiary'
onClick={setShowPublishAsKnowledgePipelineModal} onClick={handleClickPublishAsKnowledgePipeline}
disabled={!publishedAt || isPublishingAsCustomizedPipeline} disabled={!publishedAt || isPublishingAsCustomizedPipeline}
> >
<div className='flex grow items-center'> <div className='flex grow items-center gap-x-2'>
<RiHammerLine className='mr-2 h-4 w-4' /> <RiHammerLine className='h-4 w-4' />
{t('pipeline.common.publishAs')} {t('pipeline.common.publishAs')}
{!isAllowPublishAsKnowledgePipeline && (
<PremiumBadge className='cursor-pointer select-none' size='s' color='indigo'>
<SparklesSoft className='flex size-3 items-center text-components-premium-badge-indigo-text-stop-0' />
<span className='system-2xs-medium p-0.5'>
{t('billing.upgradeBtn.encourageShort')}
</span>
</PremiumBadge>
)}
</div> </div>
</Button> </Button>
</div> </div>

View File

@ -57,6 +57,7 @@ type ProviderContextState = {
}, },
refreshLicenseLimit: () => void refreshLicenseLimit: () => void
isAllowTransferWorkspace: boolean isAllowTransferWorkspace: boolean
isAllowPublishAsKnowledgePipeline: boolean
} }
const ProviderContext = createContext<ProviderContextState>({ const ProviderContext = createContext<ProviderContextState>({
modelProviders: [], modelProviders: [],
@ -99,6 +100,7 @@ const ProviderContext = createContext<ProviderContextState>({
}, },
refreshLicenseLimit: noop, refreshLicenseLimit: noop,
isAllowTransferWorkspace: false, isAllowTransferWorkspace: false,
isAllowPublishAsKnowledgePipeline: false,
}) })
export const useProviderContext = () => useContext(ProviderContext) export const useProviderContext = () => useContext(ProviderContext)
@ -137,6 +139,7 @@ export const ProviderContextProvider = ({
const [isEducationWorkspace, setIsEducationWorkspace] = useState(false) const [isEducationWorkspace, setIsEducationWorkspace] = useState(false)
const { data: isEducationAccount } = useEducationStatus(!enableEducationPlan) const { data: isEducationAccount } = useEducationStatus(!enableEducationPlan)
const [isAllowTransferWorkspace, setIsAllowTransferWorkspace] = useState(false) const [isAllowTransferWorkspace, setIsAllowTransferWorkspace] = useState(false)
const [isAllowPublishAsKnowledgePipeline, setIsAllowPublishAsKnowledgePipeline] = useState(false)
const fetchPlan = async () => { const fetchPlan = async () => {
try { try {
@ -167,6 +170,8 @@ export const ProviderContextProvider = ({
setLicenseLimit({ workspace_members: data.workspace_members }) setLicenseLimit({ workspace_members: data.workspace_members })
if (data.is_allow_transfer_workspace) if (data.is_allow_transfer_workspace)
setIsAllowTransferWorkspace(data.is_allow_transfer_workspace) setIsAllowTransferWorkspace(data.is_allow_transfer_workspace)
if (data.knowledge_pipeline?.publish_enabled)
setIsAllowPublishAsKnowledgePipeline(data.knowledge_pipeline?.publish_enabled)
} }
catch (error) { catch (error) {
console.error('Failed to fetch plan info:', error) console.error('Failed to fetch plan info:', error)
@ -228,6 +233,7 @@ export const ProviderContextProvider = ({
licenseLimit, licenseLimit,
refreshLicenseLimit: fetchPlan, refreshLicenseLimit: fetchPlan,
isAllowTransferWorkspace, isAllowTransferWorkspace,
isAllowPublishAsKnowledgePipeline,
}}> }}>
{children} {children}
</ProviderContext.Provider> </ProviderContext.Provider>