mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 10:28:10 +08:00
feat: workflow preview
This commit is contained in:
@ -1,17 +1,36 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
import Loading from '@/app/components/base/loading'
|
||||||
|
import { useGetTryAppFlowPreview } from '@/service/use-try-app'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import WorkflowPreview from '@/app/components/workflow/workflow-preview'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
appId: string
|
appId: string
|
||||||
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const FlowAppPreview: FC<Props> = ({
|
const FlowAppPreview: FC<Props> = ({
|
||||||
appId,
|
appId,
|
||||||
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { data, isLoading } = useGetTryAppFlowPreview(appId)
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <div className='flex h-full items-center justify-center'>
|
||||||
|
<Loading type='area' />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
if(!data)
|
||||||
|
return null
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{appId}
|
<WorkflowPreview
|
||||||
|
{...data.graph}
|
||||||
|
className={cn(className)}
|
||||||
|
miniMapToRight
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,6 @@ const Preview: FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
return isBasicApp ? <BasicAppPreview appId={appId} /> : <FlowAppPreview appId={appId} />
|
return isBasicApp ? <BasicAppPreview appId={appId} /> : <FlowAppPreview appId={appId} className='h-[80vh]' />
|
||||||
}
|
}
|
||||||
export default React.memo(Preview)
|
export default React.memo(Preview)
|
||||||
|
|||||||
@ -61,12 +61,14 @@ type WorkflowPreviewProps = {
|
|||||||
edges: Edge[]
|
edges: Edge[]
|
||||||
viewport: Viewport
|
viewport: Viewport
|
||||||
className?: string
|
className?: string
|
||||||
|
miniMapToRight?: boolean
|
||||||
}
|
}
|
||||||
const WorkflowPreview = ({
|
const WorkflowPreview = ({
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
viewport,
|
viewport,
|
||||||
className,
|
className,
|
||||||
|
miniMapToRight,
|
||||||
}: WorkflowPreviewProps) => {
|
}: WorkflowPreviewProps) => {
|
||||||
const [nodesData, setNodesData] = useState(() => initialNodes(nodes, edges))
|
const [nodesData, setNodesData] = useState(() => initialNodes(nodes, edges))
|
||||||
const [edgesData, setEdgesData] = useState(() => initialEdges(edges, nodes))
|
const [edgesData, setEdgesData] = useState(() => initialEdges(edges, nodes))
|
||||||
@ -97,8 +99,9 @@ const WorkflowPreview = ({
|
|||||||
height: 72,
|
height: 72,
|
||||||
}}
|
}}
|
||||||
maskColor='var(--color-workflow-minimap-bg)'
|
maskColor='var(--color-workflow-minimap-bg)'
|
||||||
className='!absolute !bottom-14 !left-4 z-[9] !m-0 !h-[72px] !w-[102px] !rounded-lg !border-[0.5px]
|
className={cn('!absolute !bottom-14 z-[9] !m-0 !h-[72px] !w-[102px] !rounded-lg !border-[0.5px] !border-divider-subtle !bg-background-default-subtle !shadow-md !shadow-shadow-shadow-5',
|
||||||
!border-divider-subtle !bg-background-default-subtle !shadow-md !shadow-shadow-shadow-5'
|
miniMapToRight ? '!right-4' : '!left-4',
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<div className='absolute bottom-4 left-4 z-[9] mt-1 flex items-center gap-2'>
|
<div className='absolute bottom-4 left-4 z-[9] mt-1 flex items-center gap-2'>
|
||||||
<ZoomInOut />
|
<ZoomInOut />
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import type {
|
|||||||
import type { ModelConfig } from '@/types/app'
|
import type { ModelConfig } from '@/types/app'
|
||||||
import qs from 'qs'
|
import qs from 'qs'
|
||||||
import type { DataSetListResponse } from '@/models/datasets'
|
import type { DataSetListResponse } from '@/models/datasets'
|
||||||
|
import type { Edge, Node } from '@/app/components/workflow/types'
|
||||||
|
import type { Viewport } from 'reactflow'
|
||||||
|
|
||||||
type TryAppInfo = {
|
type TryAppInfo = {
|
||||||
name: string
|
name: string
|
||||||
@ -25,3 +27,15 @@ export const fetchTryAppDatasets = (appId: string, ids: string[]) => {
|
|||||||
const urlParams = qs.stringify({ ids }, { indices: false })
|
const urlParams = qs.stringify({ ids }, { indices: false })
|
||||||
return get<DataSetListResponse>(`/trial-apps/${appId}/datasets?${urlParams}`)
|
return get<DataSetListResponse>(`/trial-apps/${appId}/datasets?${urlParams}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TryAppFlowPreview = {
|
||||||
|
graph: {
|
||||||
|
nodes: Node[]
|
||||||
|
edges: Edge[]
|
||||||
|
viewport: Viewport
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const fetchTryAppFlowPreview = (appId: string) => {
|
||||||
|
return get<TryAppFlowPreview>(`/trial-apps/${appId}/workflows`)
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import { fetchTryAppDatasets, fetchTryAppInfo } from './try-app'
|
import { fetchTryAppDatasets, fetchTryAppFlowPreview, fetchTryAppInfo } from './try-app'
|
||||||
import { AppSourceType, fetchAppParams } from './share'
|
import { AppSourceType, fetchAppParams } from './share'
|
||||||
import type { DataSetListResponse } from '@/models/datasets'
|
import type { DataSetListResponse } from '@/models/datasets'
|
||||||
|
|
||||||
@ -32,3 +32,12 @@ export const useGetTryAppDataSets = (appId: string, ids: string[]) => {
|
|||||||
enabled: ids.length > 0,
|
enabled: ids.length > 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useGetTryAppFlowPreview = (appId: string) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [NAME_SPACE, 'preview', appId],
|
||||||
|
queryFn: () => {
|
||||||
|
return fetchTryAppFlowPreview(appId)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user