Commit a3d4befa authored by StyleZhang's avatar StyleZhang

service

parent 2f13d277
......@@ -29,10 +29,10 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const detailParams = { url: '/apps', id: appId }
const { data: response } = useSWR(detailParams, fetchAppDetail)
// redirection
if ((response?.mode === 'workflow' || response?.mode === 'advanced-chat') && (pathname).endsWith('configuration'))
// redirections
if (response && (response?.mode === 'workflow' || response?.mode === 'advanced-chat') && (pathname).endsWith('configuration'))
router.replace(`/app/${appId}/workflow`)
if ((response?.mode !== 'workflow' && response?.mode !== 'advanced-chat') && (pathname).endsWith('workflow'))
if (response && (response?.mode !== 'workflow' && response?.mode !== 'advanced-chat') && (pathname).endsWith('workflow'))
router.replace(`/app/${appId}/configuration`)
const appModeName = (() => {
......@@ -89,11 +89,12 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
}, [response])
if (!response)
return null
return (
<div className={cn(s.app, 'flex', 'overflow-hidden')}>
<AppSideBar title={response.name} icon={response.icon} icon_background={response.icon_background} desc={appModeName} navigation={navigation} />
<div className="bg-white grow overflow-hidden">
{React.cloneElement(children as React.ReactElement<any>, { appMode: response.mode })}
{children}
</div>
</div>
)
......
'use client'
import type { FC } from 'react'
import { memo } from 'react'
import Workflow from '@/app/components/workflow'
const initialNodes = [
{
id: '1',
type: 'custom',
position: { x: 180, y: 180 },
data: { type: 'start' },
},
// {
// id: '2',
// type: 'custom',
// position: { x: 0, y: 0 },
// data: {
// type: 'if-else',
// branches: [
// {
// id: 'if-true',
// name: 'IS TRUE',
// },
// {
// id: 'if-false',
// name: 'IS FALSE',
// },
// ],
// },
// },
// {
// id: '3',
// type: 'custom',
// position: { x: 0, y: 0 },
// data: { type: 'question-classifier', sortIndexInBranches: 0 },
// },
// {
// id: '4',
// type: 'custom',
// position: { x: 0, y: 0 },
// data: {
// type: 'if-else',
// sortIndexInBranches: 1,
// branches: [
// {
// id: 'if-true',
// name: 'IS TRUE',
// },
// {
// id: 'if-false',
// name: 'IS FALSE',
// },
// ],
// },
// },
]
const initialEdges = [
// {
// id: '0',
// type: 'custom',
// source: '1',
// sourceHandle: 'source',
// target: '2',
// targetHandle: 'target',
// },
// {
// id: '1',
// type: 'custom',
// source: '2',
// sourceHandle: 'if-true',
// target: '3',
// targetHandle: 'target',
// },
// {
// id: '2',
// type: 'custom',
// source: '2',
// sourceHandle: 'if-false',
// target: '4',
// targetHandle: 'target',
// },
]
const Page: FC = () => {
const Page = () => {
return (
<div className='min-w-[720px] w-full h-full overflow-x-auto'>
<Workflow
nodes={initialNodes}
edges={initialEdges}
nodes={[]}
edges={[]}
/>
</div>
)
}
export default memo(Page)
'use client'
import type { FC } from 'react'
import { memo } from 'react'
import Workflow from '@/app/components/workflow'
const initialNodes = [
{
id: '1',
type: 'custom',
position: { x: 180, y: 180 },
data: { type: 'start' },
},
// {
// id: '2',
// type: 'custom',
// position: { x: 0, y: 0 },
// data: {
// type: 'if-else',
// branches: [
// {
// id: 'if-true',
// name: 'IS TRUE',
// },
// {
// id: 'if-false',
// name: 'IS FALSE',
// },
// ],
// },
// },
// {
// id: '3',
// type: 'custom',
// position: { x: 0, y: 0 },
// data: { type: 'question-classifier', sortIndexInBranches: 0 },
// },
// {
// id: '4',
// type: 'custom',
// position: { x: 0, y: 0 },
// data: {
// type: 'if-else',
// sortIndexInBranches: 1,
// branches: [
// {
// id: 'if-true',
// name: 'IS TRUE',
// },
// {
// id: 'if-false',
// name: 'IS FALSE',
// },
// ],
// },
// },
]
const initialEdges = [
// {
// id: '0',
// type: 'custom',
// source: '1',
// sourceHandle: 'source',
// target: '2',
// targetHandle: 'target',
// },
// {
// id: '1',
// type: 'custom',
// source: '2',
// sourceHandle: 'if-true',
// target: '3',
// targetHandle: 'target',
// },
// {
// id: '2',
// type: 'custom',
// source: '2',
// sourceHandle: 'if-false',
// target: '4',
// targetHandle: 'target',
// },
]
const Page: FC = () => {
return (
<div className='min-w-[720px] w-full h-full overflow-x-auto'>
<Workflow
nodes={initialNodes}
edges={initialEdges}
/>
</div>
)
}
export default memo(Page)
......@@ -3,6 +3,8 @@ import {
memo,
// useEffect,
} from 'react'
import { useParams } from 'next/navigation'
import useSWR from 'swr'
import { useKeyPress } from 'ahooks'
import ReactFlow, {
Background,
......@@ -26,6 +28,12 @@ import CustomConnectionLine from './custom-connection-line'
import Panel from './panel'
import Features from './features'
import { useStore } from './store'
import { NodeInitialData } from './constants'
import {
fetchWorkflowDraft,
syncWorkflowDraft,
} from '@/service/workflow'
import Loading from '@/app/components/base/loading'
const nodeTypes = {
custom: CustomNode,
......@@ -112,6 +120,36 @@ const WorkflowWrap: FC<WorkflowProps> = ({
nodes,
edges,
}) => {
const appId = useParams().appId
const { data, isLoading, error } = useSWR(`/apps/${appId}/workflows/draft`, fetchWorkflowDraft)
// const { data: configsData } = useSWR(`/apps/${appId}/workflows/default-workflow-block-configs`, fetchNodesDefaultConfigs)
if (error) {
syncWorkflowDraft({
url: `/apps/${appId}/workflows/draft`,
params: {
graph: {
nodes: [{
id: `${Date.now()}`,
data: NodeInitialData.start,
position: {
x: 100,
y: 100,
},
}],
edges: [],
},
features: {},
},
})
}
if (isLoading) {
return (
<Loading />
)
}
return (
<ReactFlowProvider>
<Workflow
......
......@@ -44,6 +44,7 @@ type IOtherOptions = {
bodyStringify?: boolean
needAllResponseContent?: boolean
deleteContentType?: boolean
silent?: boolean
onData?: IOnData // for stream
onThought?: IOnThought
onFile?: IOnFile
......@@ -176,6 +177,7 @@ const baseFetch = <T>(
needAllResponseContent,
deleteContentType,
getAbortController,
silent,
}: IOtherOptions,
): Promise<T> => {
const options: typeof baseOptions & FetchOptionType = Object.assign({}, baseOptions, fetchOptions)
......@@ -250,13 +252,14 @@ const baseFetch = <T>(
case 401: {
if (isPublicAPI) {
return bodyJson.then((data: ResponseError) => {
if (!silent)
Toast.notify({ type: 'error', message: data.message })
return Promise.reject(data)
})
}
const loginUrl = `${globalThis.location.origin}/signin`
bodyJson.then((data: ResponseError) => {
if (data.code === 'init_validate_failed' && IS_CE_EDITION)
if (data.code === 'init_validate_failed' && IS_CE_EDITION && !silent)
Toast.notify({ type: 'error', message: data.message, duration: 4000 })
else if (data.code === 'not_init_validated' && IS_CE_EDITION)
globalThis.location.href = `${globalThis.location.origin}/init`
......@@ -264,7 +267,7 @@ const baseFetch = <T>(
globalThis.location.href = `${globalThis.location.origin}/install`
else if (location.pathname !== '/signin' || !IS_CE_EDITION)
globalThis.location.href = loginUrl
else
else if (!silent)
Toast.notify({ type: 'error', message: data.message })
}).catch(() => {
// Handle any other errors
......@@ -275,6 +278,7 @@ const baseFetch = <T>(
}
case 403:
bodyJson.then((data: ResponseError) => {
if (!silent)
Toast.notify({ type: 'error', message: data.message })
if (data.code === 'already_setup')
globalThis.location.href = `${globalThis.location.origin}/signin`
......@@ -283,6 +287,7 @@ const baseFetch = <T>(
// fall through
default:
bodyJson.then((data: ResponseError) => {
if (!silent)
Toast.notify({ type: 'error', message: data.message })
})
}
......@@ -301,6 +306,7 @@ const baseFetch = <T>(
resolve(needAllResponseContent ? resClone : data)
})
.catch((err) => {
if (!silent)
Toast.notify({ type: 'error', message: err })
reject(err)
})
......
import type { Fetcher } from 'swr'
import { get, post } from './base'
import type { CommonResponse } from '@/models/common'
import type {
FetchWorkflowDraftResponse,
} from '@/types/workflow'
export const fetchWorkflowDraft: Fetcher<FetchWorkflowDraftResponse, string> = (url) => {
return get<FetchWorkflowDraftResponse>(url, {}, { silent: true })
}
export const syncWorkflowDraft: Fetcher<CommonResponse, { url: string; params: Pick<FetchWorkflowDraftResponse, 'graph' | 'features'> }> = ({ url, params }) => {
return post<CommonResponse>(url, { body: params })
}
export const fetchNodesDefaultConfigs: Fetcher<any, string> = (url) => {
return get<any>(url)
}
import type {
Edge,
Node,
} from '@/app/components/workflow/types'
export type FetchWorkflowDraftResponse = {
id: string
graph: {
nodes: Node[]
edges: Edge[]
}
features?: any
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment