mirror of
https://github.com/langgenius/dify.git
synced 2025-10-28 09:34:41 +00:00
publish as customized pipeline
This commit is contained in:
parent
eff8108f1c
commit
0564651f6f
@ -3,7 +3,7 @@ import { usePipelineTemplateList } from '@/service/use-pipeline'
|
|||||||
|
|
||||||
const CustomizedList = () => {
|
const CustomizedList = () => {
|
||||||
const { data: pipelineList, isLoading } = usePipelineTemplateList({ type: 'customized' })
|
const { data: pipelineList, isLoading } = usePipelineTemplateList({ type: 'customized' })
|
||||||
const list = pipelineList?.pipelines
|
const list = pipelineList?.pipeline_templates
|
||||||
|
|
||||||
if (isLoading || !list)
|
if (isLoading || !list)
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -0,0 +1,150 @@
|
|||||||
|
'use client'
|
||||||
|
import { useCallback, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { RiCloseLine } from '@remixicon/react'
|
||||||
|
import AppIconPicker from '@/app/components/base/app-icon-picker'
|
||||||
|
import type { AppIconSelection } from '@/app/components/base/app-icon-picker'
|
||||||
|
import Modal from '@/app/components/base/modal'
|
||||||
|
import Button from '@/app/components/base/button'
|
||||||
|
import Input from '@/app/components/base/input'
|
||||||
|
import Textarea from '@/app/components/base/textarea'
|
||||||
|
import AppIcon from '@/app/components/base/app-icon'
|
||||||
|
import { noop } from 'lodash-es'
|
||||||
|
import { useStore } from '@/app/components/workflow/store'
|
||||||
|
import type { IconInfo } from '@/models/datasets'
|
||||||
|
|
||||||
|
type PublishAsKnowledgePipelineModalProps = {
|
||||||
|
confirmDisabled?: boolean
|
||||||
|
onCancel: () => void
|
||||||
|
onConfirm: (
|
||||||
|
name: string,
|
||||||
|
icon: IconInfo,
|
||||||
|
description?: string,
|
||||||
|
) => Promise<void>
|
||||||
|
}
|
||||||
|
const PublishAsKnowledgePipelineModal = ({
|
||||||
|
confirmDisabled,
|
||||||
|
onCancel,
|
||||||
|
onConfirm,
|
||||||
|
}: PublishAsKnowledgePipelineModalProps) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const knowledgeName = useStore(s => s.knowledgeName)
|
||||||
|
const knowledgeIcon = useStore(s => s.knowledgeIcon)
|
||||||
|
const [pipelineName, setPipelineName] = useState(knowledgeName!)
|
||||||
|
const [pipelineIcon, setPipelineIcon] = useState(knowledgeIcon!)
|
||||||
|
const [description, setDescription] = useState('')
|
||||||
|
const [showAppIconPicker, setShowAppIconPicker] = useState(false)
|
||||||
|
|
||||||
|
const handleSelectIcon = useCallback((item: AppIconSelection) => {
|
||||||
|
if (item.type === 'image') {
|
||||||
|
setPipelineIcon({
|
||||||
|
icon_type: 'image',
|
||||||
|
icon_url: item.url,
|
||||||
|
icon_background: '',
|
||||||
|
icon: '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.type === 'emoji') {
|
||||||
|
setPipelineIcon({
|
||||||
|
icon_type: 'emoji',
|
||||||
|
icon: item.icon,
|
||||||
|
icon_background: item.background,
|
||||||
|
icon_url: '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setShowAppIconPicker(false)
|
||||||
|
}, [])
|
||||||
|
const handleCloseIconPicker = useCallback(() => {
|
||||||
|
setPipelineIcon({
|
||||||
|
icon_type: pipelineIcon.icon_type,
|
||||||
|
icon: pipelineIcon.icon,
|
||||||
|
icon_background: pipelineIcon.icon_background,
|
||||||
|
icon_url: pipelineIcon.icon_url,
|
||||||
|
})
|
||||||
|
setShowAppIconPicker(false)
|
||||||
|
}, [pipelineIcon])
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
if (confirmDisabled)
|
||||||
|
return
|
||||||
|
|
||||||
|
onConfirm(
|
||||||
|
pipelineName?.trim() || '',
|
||||||
|
pipelineIcon,
|
||||||
|
description?.trim(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Modal
|
||||||
|
isShow
|
||||||
|
onClose={noop}
|
||||||
|
className='relative !w-[520px] !p-0'
|
||||||
|
>
|
||||||
|
<div className='title-2xl-semi-bold relative flex items-center p-6 pb-3 pr-14 text-text-primary'>
|
||||||
|
{t('pipeline.common.publishAs')}
|
||||||
|
<div className='absolute right-5 top-5 flex h-8 w-8 cursor-pointer items-center justify-center' onClick={onCancel}>
|
||||||
|
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='px-6 py-3'>
|
||||||
|
<div className='mb-5 flex'>
|
||||||
|
<div className='mr-3 grow'>
|
||||||
|
<div className='system-sm-medium mb-1 flex h-6 items-center text-text-secondary'>
|
||||||
|
{t('pipeline.common.publishAsPipeline.name')}
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
value={pipelineName}
|
||||||
|
onChange={e => setPipelineName(e.target.value)}
|
||||||
|
placeholder={t('pipeline.common.publishAsPipeline.namePlaceholder') || ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<AppIcon
|
||||||
|
size='xxl'
|
||||||
|
onClick={() => { setShowAppIconPicker(true) }}
|
||||||
|
className='mt-2 shrink-0 cursor-pointer'
|
||||||
|
iconType={pipelineIcon?.icon_type}
|
||||||
|
icon={pipelineIcon?.icon}
|
||||||
|
background={pipelineIcon?.icon_background}
|
||||||
|
imageUrl={pipelineIcon?.icon_url}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className='system-sm-medium mb-1 flex h-6 items-center text-text-secondary '>
|
||||||
|
{t('pipeline.common.publishAsPipeline.description')}
|
||||||
|
</div>
|
||||||
|
<Textarea
|
||||||
|
className='resize-none'
|
||||||
|
placeholder={t('pipeline.common.publishAsPipeline.descriptionPlaceholder') || ''}
|
||||||
|
value={description}
|
||||||
|
onChange={e => setDescription(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center justify-end px-6 py-5'>
|
||||||
|
<Button
|
||||||
|
className='mr-2'
|
||||||
|
onClick={onCancel}
|
||||||
|
>
|
||||||
|
{t('common.operation.cancel')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
disabled={!pipelineName?.trim() || confirmDisabled}
|
||||||
|
variant='primary'
|
||||||
|
onClick={() => handleConfirm()}
|
||||||
|
>
|
||||||
|
{t('workflow.common.publish')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
{showAppIconPicker && <AppIconPicker
|
||||||
|
onSelect={handleSelectIcon}
|
||||||
|
onClose={handleCloseIconPicker}
|
||||||
|
/>}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PublishAsKnowledgePipelineModal
|
||||||
@ -36,6 +36,8 @@ import {
|
|||||||
usePublishAsCustomizedPipeline,
|
usePublishAsCustomizedPipeline,
|
||||||
} from '@/service/use-pipeline'
|
} from '@/service/use-pipeline'
|
||||||
import Confirm from '@/app/components/base/confirm'
|
import Confirm from '@/app/components/base/confirm'
|
||||||
|
import PublishAsKnowledgePipelineModal from '../../publish-as-knowledge-pipeline-modal'
|
||||||
|
import type { IconInfo } from '@/models/datasets'
|
||||||
|
|
||||||
const PUBLISH_SHORTCUT = ['⌘', '⇧', 'P']
|
const PUBLISH_SHORTCUT = ['⌘', '⇧', 'P']
|
||||||
|
|
||||||
@ -62,9 +64,16 @@ const Popup = () => {
|
|||||||
setTrue: showPublishing,
|
setTrue: showPublishing,
|
||||||
}] = useBoolean(false)
|
}] = useBoolean(false)
|
||||||
const {
|
const {
|
||||||
mutate: publishAsCustomizedPipeline,
|
mutateAsync: publishAsCustomizedPipeline,
|
||||||
isPending: isPublishingAsCustomizedPipeline,
|
|
||||||
} = usePublishAsCustomizedPipeline()
|
} = usePublishAsCustomizedPipeline()
|
||||||
|
const [showPublishAsKnowledgePipelineModal, {
|
||||||
|
setFalse: hidePublishAsKnowledgePipelineModal,
|
||||||
|
setTrue: setShowPublishAsKnowledgePipelineModal,
|
||||||
|
}] = useBoolean(false)
|
||||||
|
const [isPublishingAsCustomizedPipeline, {
|
||||||
|
setFalse: hidePublishingAsCustomizedPipeline,
|
||||||
|
setTrue: showPublishingAsCustomizedPipeline,
|
||||||
|
}] = useBoolean(false)
|
||||||
|
|
||||||
const invalidPublishedPipelineInfo = useInvalid([...publishedPipelineInfoQueryKeyPrefix, pipelineId])
|
const invalidPublishedPipelineInfo = useInvalid([...publishedPipelineInfoQueryKeyPrefix, pipelineId])
|
||||||
|
|
||||||
@ -117,6 +126,35 @@ const Popup = () => {
|
|||||||
push(`/datasets/${datasetId}/documents/create-from-pipeline`)
|
push(`/datasets/${datasetId}/documents/create-from-pipeline`)
|
||||||
}, [datasetId, push])
|
}, [datasetId, push])
|
||||||
|
|
||||||
|
const handlePublishAsKnowledgePipeline = useCallback(async (
|
||||||
|
name: string,
|
||||||
|
icon: IconInfo,
|
||||||
|
description?: string,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
showPublishingAsCustomizedPipeline()
|
||||||
|
await publishAsCustomizedPipeline({
|
||||||
|
pipelineId: pipelineId || '',
|
||||||
|
name,
|
||||||
|
icon_info: icon,
|
||||||
|
description,
|
||||||
|
})
|
||||||
|
notify({ type: 'success', message: t('common.api.actionSuccess') })
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
hidePublishingAsCustomizedPipeline()
|
||||||
|
hidePublishAsKnowledgePipelineModal()
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
pipelineId,
|
||||||
|
publishAsCustomizedPipeline,
|
||||||
|
showPublishingAsCustomizedPipeline,
|
||||||
|
hidePublishingAsCustomizedPipeline,
|
||||||
|
hidePublishAsKnowledgePipelineModal,
|
||||||
|
notify,
|
||||||
|
t,
|
||||||
|
])
|
||||||
|
|
||||||
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='w-[320px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5'>
|
||||||
<div className='p-4 pt-3'>
|
<div className='p-4 pt-3'>
|
||||||
@ -192,7 +230,7 @@ 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={() => publishAsCustomizedPipeline({ pipelineId: pipelineId || '' })}
|
onClick={setShowPublishAsKnowledgePipelineModal}
|
||||||
disabled={!publishedAt || isPublishingAsCustomizedPipeline}
|
disabled={!publishedAt || isPublishingAsCustomizedPipeline}
|
||||||
>
|
>
|
||||||
<div className='flex grow items-center'>
|
<div className='flex grow items-center'>
|
||||||
@ -213,6 +251,15 @@ const Popup = () => {
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
showPublishAsKnowledgePipelineModal && (
|
||||||
|
<PublishAsKnowledgePipelineModal
|
||||||
|
confirmDisabled={isPublishingAsCustomizedPipeline}
|
||||||
|
onConfirm={handlePublishAsKnowledgePipeline}
|
||||||
|
onCancel={hidePublishAsKnowledgePipelineModal}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,10 +25,11 @@ export const usePipelineInit = () => {
|
|||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
const datasetId = useDatasetDetailContextWithSelector(s => s.dataset)?.pipeline_id
|
const datasetId = useDatasetDetailContextWithSelector(s => s.dataset)?.pipeline_id
|
||||||
const knowledgeName = useDatasetDetailContextWithSelector(s => s.dataset)?.name
|
const knowledgeName = useDatasetDetailContextWithSelector(s => s.dataset)?.name
|
||||||
|
const knowledgeIcon = useDatasetDetailContextWithSelector(s => s.dataset)?.icon_info
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
workflowStore.setState({ pipelineId: datasetId, knowledgeName })
|
workflowStore.setState({ pipelineId: datasetId, knowledgeName, knowledgeIcon })
|
||||||
}, [datasetId, workflowStore, knowledgeName])
|
}, [datasetId, workflowStore, knowledgeName, knowledgeIcon])
|
||||||
|
|
||||||
usePipelineConfig()
|
usePipelineConfig()
|
||||||
|
|
||||||
|
|||||||
@ -5,10 +5,12 @@ import type {
|
|||||||
} from '@/app/components/workflow/types'
|
} from '@/app/components/workflow/types'
|
||||||
import type { DataSourceItem } from '@/app/components/workflow/block-selector/types'
|
import type { DataSourceItem } from '@/app/components/workflow/block-selector/types'
|
||||||
import { transformDataSourceToTool } from '@/app/components/workflow/block-selector/utils'
|
import { transformDataSourceToTool } from '@/app/components/workflow/block-selector/utils'
|
||||||
|
import type { IconInfo } from '@/models/datasets'
|
||||||
|
|
||||||
export type RagPipelineSliceShape = {
|
export type RagPipelineSliceShape = {
|
||||||
pipelineId: string
|
pipelineId: string
|
||||||
knowledgeName: string
|
knowledgeName: string
|
||||||
|
knowledgeIcon?: IconInfo
|
||||||
showInputFieldDialog: boolean
|
showInputFieldDialog: boolean
|
||||||
setShowInputFieldDialog: (showInputFieldPanel: boolean) => void
|
setShowInputFieldDialog: (showInputFieldPanel: boolean) => void
|
||||||
nodesDefaultConfigs: Record<string, any>
|
nodesDefaultConfigs: Record<string, any>
|
||||||
|
|||||||
@ -4,6 +4,12 @@ const translation = {
|
|||||||
publishAs: 'Publish as a Knowledge Pipeline',
|
publishAs: 'Publish as a Knowledge Pipeline',
|
||||||
confirmPublish: 'Confirm Publish',
|
confirmPublish: 'Confirm Publish',
|
||||||
confirmPublishContent: 'After successfully publishing the knowledge pipeline, the chunk structure of this knowledge base cannot be modified. Are you sure you want to publish it?',
|
confirmPublishContent: 'After successfully publishing the knowledge pipeline, the chunk structure of this knowledge base cannot be modified. Are you sure you want to publish it?',
|
||||||
|
publishAsPipeline: {
|
||||||
|
name: 'Pipeline name & icon',
|
||||||
|
namePlaceholder: 'Please enter the name of this Knowledge Pipeline. (Required) ',
|
||||||
|
description: 'Knowledge description',
|
||||||
|
descriptionPlaceholder: 'Please enter the description of this Knowledge Pipeline. (Optional) ',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,12 @@ const translation = {
|
|||||||
publishAs: '发布为知识管道',
|
publishAs: '发布为知识管道',
|
||||||
confirmPublish: '确认发布',
|
confirmPublish: '确认发布',
|
||||||
confirmPublishContent: '成功发布知识管道后,此知识库的分段结构将无法修改。您确定要发布吗?',
|
confirmPublishContent: '成功发布知识管道后,此知识库的分段结构将无法修改。您确定要发布吗?',
|
||||||
|
publishAsPipeline: {
|
||||||
|
name: 'Pipeline 名称和图标',
|
||||||
|
namePlaceholder: '请输入此 Pipeline 的名称。 (必填)',
|
||||||
|
description: 'Pipeline 描述',
|
||||||
|
descriptionPlaceholder: '请输入此 Pipeline 的描述。 (可选)',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export type PipelineTemplate = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PipelineTemplateListResponse = {
|
export type PipelineTemplateListResponse = {
|
||||||
pipelines: PipelineTemplate[]
|
pipeline_templates: PipelineTemplate[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PipelineTemplateByIdResponse = {
|
export type PipelineTemplateByIdResponse = {
|
||||||
|
|||||||
@ -28,12 +28,14 @@ import type {
|
|||||||
} from '@/models/pipeline'
|
} from '@/models/pipeline'
|
||||||
import type { DataSourceItem } from '@/app/components/workflow/block-selector/types'
|
import type { DataSourceItem } from '@/app/components/workflow/block-selector/types'
|
||||||
import type { ToolCredential } from '@/app/components/tools/types'
|
import type { ToolCredential } from '@/app/components/tools/types'
|
||||||
|
import type { IconInfo } from '@/models/datasets'
|
||||||
|
|
||||||
const NAME_SPACE = 'pipeline'
|
const NAME_SPACE = 'pipeline'
|
||||||
|
|
||||||
export const usePipelineTemplateList = (params: PipelineTemplateListParams) => {
|
export const usePipelineTemplateList = (params: PipelineTemplateListParams) => {
|
||||||
|
console.log('params', params)
|
||||||
return useQuery<PipelineTemplateListResponse>({
|
return useQuery<PipelineTemplateListResponse>({
|
||||||
queryKey: [NAME_SPACE, 'template', 'list'],
|
queryKey: [NAME_SPACE, 'template', 'list', params.type],
|
||||||
queryFn: () => {
|
queryFn: () => {
|
||||||
return get<PipelineTemplateListResponse>('/rag/pipeline/templates', { params })
|
return get<PipelineTemplateListResponse>('/rag/pipeline/templates', { params })
|
||||||
},
|
},
|
||||||
@ -348,8 +350,22 @@ export const usePublishAsCustomizedPipeline = () => {
|
|||||||
mutationKey: [NAME_SPACE, 'publish-as-customized-pipeline'],
|
mutationKey: [NAME_SPACE, 'publish-as-customized-pipeline'],
|
||||||
mutationFn: ({
|
mutationFn: ({
|
||||||
pipelineId,
|
pipelineId,
|
||||||
}: { pipelineId: string }) => {
|
name,
|
||||||
return post(`/rag/pipelines/${pipelineId}/customized/publish`)
|
icon_info,
|
||||||
|
description,
|
||||||
|
}: {
|
||||||
|
pipelineId: string,
|
||||||
|
name: string,
|
||||||
|
icon_info: IconInfo,
|
||||||
|
description?: string,
|
||||||
|
}) => {
|
||||||
|
return post(`/rag/pipelines/${pipelineId}/customized/publish`, {
|
||||||
|
body: {
|
||||||
|
name,
|
||||||
|
icon_info,
|
||||||
|
description,
|
||||||
|
},
|
||||||
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user