Commit d6620bc0 authored by DarkForst's avatar DarkForst

core UI change

parent eef3f0aa
.pos_end{
display: flex;
align-items: center;
justify-content: flex-end;
}
export const algoData = [
{
id: 'recentlyUsed',
name: '最近使用',
isDir: true,
children: [
{
id: 10,
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_1',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: '算法组件1',
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_1',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '算法组件1',
id: 10,
},
},
{
id: 11,
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_2',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: '算法组件2',
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_2',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '算法组件2',
id: 11,
},
},
{
id: 12,
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_3',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: '算法组件3',
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_3',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '算法组件3',
id: 12,
},
},
],
},
{
name: '数据读写',
id: 21,
category: 'source',
isDir: true,
children: [
{
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'odps_source',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: '读数据表',
id: 100,
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'odps_source',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '读数据表',
id: 100,
},
},
],
isBranch: true,
isExpanded: false,
codeName: 'source',
parentId: 'platformAlgo',
},
{
name: '统计分析',
id: 22,
category: 'analytics',
isDir: true,
children: [],
isBranch: true,
isExpanded: false,
codeName: 'analytics',
parentId: 'platformAlgo',
},
{
name: '算法',
id: 23,
category: 'ai_algo',
isDir: true,
children: [],
isBranch: true,
isExpanded: false,
codeName: 'algorithm',
parentId: 'platformAlgo',
},
{
name: '预测',
id: 24,
category: 'predict',
isDir: true,
children: [],
isBranch: true,
isExpanded: false,
codeName: 'predict',
parentId: 'platformAlgo',
},
{
name: '评估',
id: 25,
category: 'evaluation',
isDir: true,
children: [],
isBranch: true,
isExpanded: false,
codeName: 'evaluation',
parentId: 'platformAlgo',
},
]
export const searchByKeyword = async (keyword: string) => {
return Array(10)
.fill(null)
.map((i, idx) => {
return {
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDir: false,
isDisabled: false,
author: 'demo author',
codeName: `${keyword}${idx}`,
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: `${keyword}__${idx}`,
id: idx,
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
name: `${keyword}-${idx}`,
codeName: `${keyword}${idx}`,
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
id: idx,
},
}
})
}
import random from 'lodash/random'
interface NodeParams {
name: string
x: number
y: number
}
export const copyNode = ({ name, x, y }: NodeParams) => {
const id = `${Date.now()}`
return {
id,
name,
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: id + 100000,
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: id + 200000,
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: id + 300000,
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: id + 400000,
},
],
positionX: x + 200 + random(20, false),
positionY: y + random(10, false),
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
}
}
export const addNode = ({ name, x, y }: NodeParams) => {
const id = `${Date.now()}`
return {
id,
name,
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: id + '_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: id + '_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: id + '_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: id + '_out_2',
},
],
positionX: x,
positionY: y,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
}
}
export const queryGraph = (id: string) => {
return {
lang: 'zh_CN',
success: true,
data: initData,
Lang: 'zh_CN',
}
}
export const addNodeGroup = async (groupName: string) => {
return {
success: true,
data: {
group: {
name: groupName,
id: Date.now(),
},
},
}
}
const initData = {
nodes: [
{
id: '1603716783816',
name: '算法组件1',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716783816_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716783816_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716783816_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716783816_out_2',
},
],
positionX: -200,
positionY: -300,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716786205',
name: '算法组件2',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716786205_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716786205_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716786205_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716786205_out_2',
},
],
positionX: -369,
positionY: -161,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716788394',
name: '算法组件2',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716788394_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716788394_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716788394_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716788394_out_2',
},
],
positionX: -154,
positionY: -161,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716792826',
name: '算法组件3',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716792826_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716792826_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716792826_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716792826_out_2',
},
],
positionX: -520,
positionY: -30,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716795011',
name: '算法组件2',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716795011_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716795011_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716795011_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716795011_out_2',
},
],
positionX: 74,
positionY: -160,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716814719',
name: '算法组件3',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716814719_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716814719_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716814719_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716814719_out_2',
},
],
positionX: -310,
positionY: -30,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716822805',
name: '算法组件3',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716822805_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716822805_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716822805_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716822805_out_2',
},
],
positionX: -50,
positionY: -30,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716828657',
name: '算法组件3',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716828657_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716828657_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716828657_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716828657_out_2',
},
],
positionX: 160,
positionY: -30,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716834901',
name: '算法组件2',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716834901_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716834901_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716834901_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716834901_out_2',
},
],
positionX: -390,
positionY: 90,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716844054',
name: '算法组件2',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716844054_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716844054_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716844054_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716844054_out_2',
},
],
positionX: -170,
positionY: 90,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716854368',
name: '算法组件2',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716854368_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716854368_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716854368_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716854368_out_2',
},
],
positionX: 40,
positionY: 90,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716858435',
name: '算法组件3',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716858435_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716858435_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716858435_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716858435_out_2',
},
],
positionX: -310,
positionY: 230,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
{
id: '1603716868041',
name: '算法组件2',
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: '1603716868041_in_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: '1603716868041_in_2',
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: '1603716868041_out_1',
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: '1603716868041_out_2',
},
],
positionX: -100,
positionY: 230,
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
},
],
links: [
{
source: '1603716783816',
target: '1603716786205',
outputPortId: '1603716783816_out_1',
inputPortId: '1603716786205_in_1',
},
{
source: '1603716783816',
target: '1603716788394',
outputPortId: '1603716783816_out_2',
inputPortId: '1603716788394_in_1',
},
{
source: '1603716783816',
target: '1603716795011',
outputPortId: '1603716783816_out_2',
inputPortId: '1603716795011_in_1',
},
{
source: '1603716786205',
target: '1603716792826',
outputPortId: '1603716786205_out_1',
inputPortId: '1603716792826_in_1',
},
{
source: '1603716788394',
target: '1603716814719',
outputPortId: '1603716788394_out_1',
inputPortId: '1603716814719_in_1',
},
{
source: '1603716795011',
target: '1603716822805',
outputPortId: '1603716795011_out_1',
inputPortId: '1603716822805_in_1',
},
{
source: '1603716795011',
target: '1603716828657',
outputPortId: '1603716795011_out_2',
inputPortId: '1603716828657_in_2',
},
{
source: '1603716792826',
target: '1603716834901',
outputPortId: '1603716792826_out_1',
inputPortId: '1603716834901_in_1',
},
{
source: '1603716814719',
target: '1603716844054',
outputPortId: '1603716814719_out_1',
inputPortId: '1603716844054_in_1',
},
{
source: '1603716822805',
target: '1603716854368',
outputPortId: '1603716822805_out_1',
inputPortId: '1603716854368_in_1',
},
{
source: '1603716834901',
target: '1603716858435',
outputPortId: '1603716834901_out_1',
inputPortId: '1603716858435_in_1',
},
{
source: '1603716844054',
target: '1603716858435',
outputPortId: '1603716844054_out_1',
inputPortId: '1603716858435_in_2',
},
{
source: '1603716854368',
target: '1603716868041',
outputPortId: '1603716854368_out_1',
inputPortId: '1603716868041_in_1',
},
],
}
/* eslint-disable no-param-reassign */
import { useCallback, useState } from 'react'
import { algoData, searchByKeyword } from '@/mock/algo'
import { algoData, searchByKeyword } from '@/services/algo'
export namespace Res {
export interface Data {
......@@ -70,16 +70,16 @@ function dfs(
export default () => {
const [keyword, setKeyword] = useState<string>('') // 搜索关键字
const [loading, setLoading] = useState<boolean>(false) // 加载状态
const [componentTreeNodes, setComponentTreeNodes] = useState<any[]>([])
const [componentApplications, setComponentApplications] = useState<any[]>([])
const [searchList, setSearchList] = useState<any[]>([]) // 搜索结果列表
// 加载组件
const loadComponentNodes = useCallback(() => {
const loadComponentApplications = useCallback(() => {
setLoading(true)
const load = async () => {
try {
if (algoData) {
setComponentTreeNodes(algoData)
setComponentApplications(algoData)
}
} finally {
setLoading(false)
......@@ -112,12 +112,12 @@ export default () => {
// 状态
keyword,
loading,
componentTreeNodes,
componentApplications,
searchList,
// 方法
setKeyword,
loadComponentNodes,
loadComponentApplications, // 应用组件
search,
}
}
export const COMMONLY_USED = {
VARIATE: 'COMMONLY_USED_VARIATE', // 变量
} // 通用组件
export const SCENE_DISPLAY = {
EQUIPMENT: 'SCENE_DISPLAY_EQUIPMENT', // 设备触发
TIME: 'SCENE_DISPLAY_TIME', // 时间触发
MANUAL: 'SCENE_DISPLAY_MANUAL', // 手动触发
} // 场景触发
export const SIGN_OPERATION = {
RELATION: 'SIGN_OPERATION_RELATION', // 关系运算
LOGICAL: 'SIGN_OPERATION_LOGICAL', // 逻辑运算
CONDITION: 'SIGN_OPERATION_CONDITION', // 条件判断
} // 运算符号
export const MOTION_OPERATION = {
EQUIPMENT: 'MOTION_OPERATION_EQUIPMENT', // 设备触发
TIME: 'MOTION_OPERATION_TIME', // 时间触发
MANUAL: 'MOTION_OPERATION_MANUAL', // 手动触发
} // 运动符号
export const COMPONENTS_TYPE = {
COMMONLY_USED: 'COMMONLY_USED', // 通用组件
SCENE_DISPLAY: 'SCENE_DISPLAY', // 场景触发
SIGN_OPERATION: 'SIGN_OPERATION', // 运算符号
MOTION_OPERATION: 'MOTION_OPERATION', // 运动符号
APPLICATION: 'APPLICATION' // 应用组件
}
import { useMemo } from 'react'
import {} from '../components-type'
interface NodeParams {
name: string
x: number
y: number
}
const useCreateNode = ({ name, x, y }: NodeParams) => {
const id = `${Date.now()}`
return {
id,
name,
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入',
id: id + '_in',
}
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出',
id: id + '_out',
}
],
positionX: x,
positionY: y,
category: 'source',
groupId: 0,
}
}
export default useCreateNode
import {
COMPONENTS_TYPE,
COMMONLY_USED,
SCENE_DISPLAY,
SIGN_OPERATION,
MOTION_OPERATION
} from '@/pages/common/components-type'
export const componentsData = [
{
id: COMPONENTS_TYPE.COMMONLY_USED,
name: '通用组件',
isDir: true,
children: [
{
id: COMMONLY_USED.VARIATE,
name: '变量',
}
],
},
{
id: COMPONENTS_TYPE.SCENE_DISPLAY,
name: '场景触发',
isDir: true,
children: [
{
id: SCENE_DISPLAY.EQUIPMENT,
name: '设备触发',
},
{
id: SCENE_DISPLAY.TIME,
name: '时间触发',
},
{
id: SCENE_DISPLAY.MANUAL,
name: '手动按钮',
}
],
},
{
id: COMPONENTS_TYPE.SIGN_OPERATION,
name: '运算符号',
isDir: true,
children: [
{
id: SIGN_OPERATION.RELATION,
name: '关系运算',
},
{
id: SIGN_OPERATION.LOGICAL,
name: '逻辑运算',
},
{
id: SIGN_OPERATION.CONDITION,
name: '条件判断',
}
],
},
{
id: COMPONENTS_TYPE.MOTION_OPERATION,
name: '运动符号',
isDir: true,
children: [
{
id: MOTION_OPERATION.EQUIPMENT,
name: '设备触发',
},
{
id: MOTION_OPERATION.TIME,
name: '时间触发',
},
{
id: MOTION_OPERATION.MANUAL,
name: '手动触发',
}
],
},
{
id: COMPONENTS_TYPE.APPLICATION,
name: '应用组件',
isDir: true,
children: [],
}
]
export const applicationTemplate = () => {
return {
id: 10,
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
author: 'demo author',
codeName: 'algo_1',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
owner: 'system',
description: '组件描述信息',
name: '算法组件1',
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
author: 'demo author',
codeName: 'algo_1',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '算法组件1',
id: 10,
},
}
}
......@@ -38,6 +38,13 @@
flex-grow: 1;
}
}
.@{ant-prefix}-tree-switcher {
width: 10px;
}
.@{ant-prefix}-tree-switcher .@{ant-prefix}-tree-switcher-icon{
display: none;
}
}
}
......
import React, { useCallback } from 'react'
import React, { useCallback, useMemo } from 'react'
import { useModel } from 'umi'
import { Tree } from 'antd'
import { FolderFilled, FolderOpenFilled } from '@ant-design/icons'
import { NodeTitle } from './node-title'
import styles from './index.less'
import { componentsData, applicationTemplate } from './componentTreeNodes'
const { DirectoryTree, TreeNode } = Tree
......@@ -12,13 +13,13 @@ const FolderIcon = ({ expanded }: { expanded: boolean }) => {
}
export const CategoryTree = () => {
const { componentTreeNodes } = useModel('guide-algo-component')
const { componentApplications } = useModel('guide-algo-component')
const renderTree = useCallback(
(treeList: any[] = [], searchKey: string = '') => {
return treeList.map((item) => {
const { isDir, id, children } = item
const key = id.toString()
const key = id.toString();
const title = <NodeTitle node={item} searchKey={searchKey} />
if (isDir) {
......@@ -48,18 +49,23 @@ export const CategoryTree = () => {
[],
)
const treeList = componentTreeNodes.filter((node) => node.status !== 4)
const applicationsTreeData = useMemo(() => {
// 根据模板生成应用组件数据格式
const applicationsData = componentApplications?.map(applicationTemplate /* 模板方法 */);
return componentApplications?.map(applicationTemplate);
}, [componentApplications])
// console.log('componentsData', componentsData, renderTree(componentsData))
return (
<div className={styles.list}>
<DirectoryTree
showIcon={true}
selectable={false}
autoExpandParent={true}
defaultExpandAll
className={styles.tree}
defaultExpandedKeys={['recentlyUsed']}
>
{renderTree(treeList)}
{renderTree(componentsData)}
</DirectoryTree>
</div>
)
......
......@@ -35,7 +35,7 @@
.node {
display: flex;
height: 30px;
padding-left: 20px;
padding-left: 10px;
font-size: 12px;
line-height: 30px;
......
......@@ -6,6 +6,7 @@ import { DatabaseFilled, ReadOutlined } from '@ant-design/icons'
import marked from 'marked'
import { useSafeSetHTML } from '@/pages/common/hooks/useSafeSetHtml'
import { DRAGGABLE_ALGO_COMPONENT } from '@/constants/graph'
import {COMPONENTS_TYPE} from './componentTreeNodes'
import styles from './node-title.less'
marked.setOptions({
......@@ -61,13 +62,13 @@ const InnerNodeTitle = (props: Props) => {
connectDragSource,
} = props
const { name = '', isDir } = node
const [visible, setVisible] = useState<boolean>(false)
const onMouseIn = useCallback(() => {
setVisible(true)
}, [])
const onMouseOut = useCallback(() => {
setVisible(false)
}, [])
// const [visible, setVisible] = useState<boolean>(false)
// const onMouseIn = useCallback(() => {
// setVisible(true)
// }, [])
// const onMouseOut = useCallback(() => {
// setVisible(false)
// }, [])
// 文件夹
if (isDir) {
......@@ -98,8 +99,8 @@ const InnerNodeTitle = (props: Props) => {
return (
<div
className={styles.nodeTitleWrapper}
onMouseEnter={onMouseIn}
onMouseLeave={onMouseOut}
// onMouseEnter={onMouseIn}
// onMouseLeave={onMouseOut}
>
{connectDragPreview(
connectDragSource(
......@@ -109,19 +110,19 @@ const InnerNodeTitle = (props: Props) => {
</div>,
),
)}
{visible && (
<Popover
visible={true}
title={name}
placement="right"
content={<Document node={node} />}
key="description"
>
<a className={styles.doc}>
<ReadOutlined /> 文档
</a>
</Popover>
)}
{/*{visible && (*/}
{/* <Popover*/}
{/* visible={true}*/}
{/* title={name}*/}
{/* placement="right"*/}
{/* content={<Document node={node} />}*/}
{/* key="description"*/}
{/* >*/}
{/* <a className={styles.doc}>*/}
{/* <ReadOutlined /> 文档*/}
{/* </a>*/}
{/* </Popover>*/}
{/*)}*/}
</div>
)
}
......
......@@ -6,10 +6,10 @@ import { SearchResultList } from './search-result-list'
import styles from './index.less'
export const ComponentTree = () => {
const { keyword, loadComponentNodes } = useModel('guide-algo-component')
const { keyword, loadComponentApplications } = useModel('guide-algo-component')
useMount(() => {
loadComponentNodes()
loadComponentApplications()
})
return (
......
......@@ -13,7 +13,7 @@ export const ComponentSourceTree: React.FC<Props> = (props) => {
return (
<div className={classNames(className, styles.componentSourceTree)}>
<div className={styles.component}>
<SearchInput />
{/*<SearchInput />*/}
<ComponentTree />
</div>
</div>
......
......@@ -16,18 +16,18 @@ export const ComponentTreePanel: React.FC<Props> = (props) => {
return (
<div className={classNames(className, styles.nodeSourceTreeContainer)}>
<div className={styles.tabWrapper}>
<div
className={classNames(styles.tab, {
[styles.active]: activeTab === 'component',
})}
onClick={() => {
setActiveTab('component')
}}
>
组件库
</div>
</div>
{/*<div className={styles.tabWrapper}>*/}
{/* <div*/}
{/* className={classNames(styles.tab, {*/}
{/* [styles.active]: activeTab === 'component',*/}
{/* })}*/}
{/* onClick={() => {*/}
{/* setActiveTab('component')*/}
{/* }}*/}
{/* >*/}
{/* 组件库*/}
{/* </div>*/}
{/*</div>*/}
<div className={styles.tabContentWrapper}>
<ComponentSourceTree
className={classNames({ [styles.hide]: activeTab !== 'component' })}
......
import React from 'react'
import CN from 'classnames'
import commonStyle from '@/common/style.less'
import styles from './style.less'
import { Button } from 'antd'
const Index = () => {
return (
<div className={CN(commonStyle.pos_end, styles.canvas_action)}>
<Button size="small">sss</Button>
<Button size="small">sssss</Button>
<Button size="small">sssss</Button>
<Button size="small">sssss</Button>
</div>
)
}
export default Index
.canvas_action{
padding-right: 10px;
}
@import (reference) '~antd/es/style/themes/default.less';
.bottomToolbar {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: 199;
height: 40px;
font-size: 12px;
background-color: #fff;
box-shadow: 0 0 16px -5px rgba(0, 0, 0, 0.2);
user-select: none;
.itemList {
color: rgba(0, 0, 0, 0.65);
text-align: center;
list-style-type: none;
.item {
display: inline-flex;
align-items: center;
height: 40px;
margin: 0 10px;
padding: 0;
line-height: 40px;
cursor: pointer;
a {
display: inline-flex;
align-items: center;
color: rgba(0, 0, 0, 0.65);
&:hover {
text-decoration: none;
}
&:focus {
text-decoration: none;
outline: none;
}
}
&.disabled {
color: #ccc;
cursor: default;
a {
color: #ccc;
cursor: default;
}
}
&:hover {
color: #1890ff;
a {
color: #1890ff;
}
}
:global {
& .anticon {
margin-right: 4px;
font-size: 16px;
}
}
}
}
}
.menu {
padding: 4px 0;
:global {
.@{ant-prefix}-menu-item {
min-width: 110px;
height: 32px;
margin: 0 !important;
padding: 0 12px;
font-size: 12px;
line-height: 32px;
a::before {
display: none;
}
&-selected {
color: rgba(0, 0, 0, 0.65);
background-color: #fff !important;
}
&:hover {
color: rgba(0, 0, 0, 0.65);
background-color: #f5f5f5;
}
:local {
.label {
display: flex;
align-items: center;
justify-content: space-between;
&:hover {
color: rgba(0, 0, 0, 0.65);
}
.icon {
margin: 0;
color: rgba(0, 0, 0, 0.65);
&:hover {
color: #1890ff;
}
}
}
}
}
}
}
.menuPopover {
:global {
.@{ant-prefix}-popover-inner {
background-color: transparent;
box-shadow: none;
&-content {
padding: 0 4px;
}
}
}
}
.popover {
:global {
.@{ant-prefix}-popover-inner-content {
padding: 5px 12px;
font-size: 12px;
}
}
}
import React, { useCallback, useEffect, useState } from 'react'
import { Popover } from 'antd'
import {
CloudUploadOutlined,
LogoutOutlined,
PlayCircleOutlined,
} from '@ant-design/icons'
import classNames from 'classnames'
import { useObservableState } from '@/common/hooks/useObservableState'
import { useExperimentGraph } from '@/pages/rx-models/experiment-graph'
import styles from './bottom-toolbar.less'
interface Props {
experimentId: string
}
export const BottomToolbar: React.FC<Props> = (props) => {
const { experimentId } = props
const expGraph = useExperimentGraph(experimentId)
const [running] = useObservableState(expGraph.running$)
const [preparingRun, setPreparingRun] = useState(false)
const [preparingStop, setPreparingStop] = useState(false)
// running 的值发生变化,说明运行或停止按钮的操作产生了作用
useEffect(() => {
setPreparingRun(false)
setPreparingStop(false)
}, [running])
// 运行实验
const onRunExperiment = useCallback(() => {
setPreparingRun(true)
expGraph.runGraph().then((res: any) => {
if (!res.success) {
setPreparingRun(false)
}
})
}, [expGraph])
// 停止运行
const onStopRunExperiment = useCallback(() => {
setPreparingStop(true)
expGraph.stopRunGraph().then((res: any) => {
if (!res.success) {
setPreparingStop(false)
}
})
}, [expGraph])
const runningConfigs = [
{
content: '运行',
tip: '依次运行本实验的每个组件',
icon: PlayCircleOutlined,
disabled: preparingRun,
clickHandler: onRunExperiment,
},
{
content: '停止',
tip: '停止运行实验',
icon: LogoutOutlined,
disabled: preparingStop,
clickHandler: onStopRunExperiment,
},
]
const runningConfig = runningConfigs[Number(!!running)]
const RunningIcon = runningConfig.icon
return (
<div className={styles.bottomToolbar}>
<ul className={styles.itemList}>
{/* 部署 */}
<li className={styles.item}>
<CloudUploadOutlined />
<span>部署</span>
</li>
{/* 运行/停止 */}
<Popover content={runningConfig.tip} overlayClassName={styles.popover}>
<li
className={classNames(styles.item, {
[styles.disabled]: runningConfig.disabled,
})}
onClick={runningConfig.clickHandler}
>
<RunningIcon />
<span>{runningConfig.content}</span>
</li>
</Popover>
</ul>
</div>
)
}
......@@ -31,6 +31,7 @@ export const CanvasContent: React.FC<Props> = (props) => {
const [, dropRef] = useDrop({
accept: [DRAGGABLE_ALGO_COMPONENT, DRAGGABLE_MODEL],
drop: (item: any, monitor) => {
console.log('drop', item, monitor)
const currentMouseOffset = monitor.getClientOffset()
const sourceMouseOffset = monitor.getInitialClientOffset()
const sourceElementOffset = monitor.getInitialSourceClientOffset()
......@@ -75,6 +76,8 @@ export const CanvasContent: React.FC<Props> = (props) => {
[expGraph],
)
console.log('expGraph', expGraph)
return (
<div
ref={(elem) => {
......
......@@ -2,6 +2,8 @@
@import (reference) '../common/style/x6-overwrite';
.canvasToolbar {
display: flex;
justify-content: space-between;
background-color: #f7f9fb;
.x6-toolbar-overwrite();
......@@ -66,4 +68,5 @@
}
}
}
}
......@@ -10,11 +10,12 @@ import {
import { useObservableState } from '@/common/hooks/useObservableState'
import { RxInput } from '@/component/rx-component/rx-input'
import { showModal } from '@/component/modal'
import { addNodeGroup } from '@/mock/graph'
import { addNodeGroup } from '@/services/graph'
import { BehaviorSubject } from 'rxjs'
import { useExperimentGraph } from '@/pages/rx-models/experiment-graph'
import { formatGroupInfoToNodeMeta } from '@/pages/rx-models/graph-util'
import styles from './canvas-toolbar.less'
import CanvasAction from '@/pages/components/canvas-action'
const { Item, Group } = Toolbar
interface Props {
......@@ -49,9 +50,9 @@ export const CanvasToolbar: React.FC<Props> = (props) => {
expGraph.toggleSelectionEnabled()
setSelectionEnabled((enabled) => !enabled)
break
case Operations.RUN_SELECTED:
expGraph.runGraph()
break
// case Operations.RUN_SELECTED:
// expGraph.runGraph()
// break
case Operations.NEW_GROUP: {
const value$ = new BehaviorSubject('')
const modal = showModal({
......@@ -154,15 +155,16 @@ export const CanvasToolbar: React.FC<Props> = (props) => {
icon={<UngroupOutlined />}
/>
</Group>
<Group>
<Item
name={Operations.RUN_SELECTED}
disabled={!activeNodeInstance}
tooltip="执行选择节点"
icon={<PlaySquareOutlined />}
/>
</Group>
{/*<Group>*/}
{/* <Item*/}
{/* name={Operations.RUN_SELECTED}*/}
{/* disabled={!activeNodeInstance}*/}
{/* tooltip="执行选择节点"*/}
{/* icon={<PlaySquareOutlined />}*/}
{/* />*/}
{/*</Group>*/}
</Toolbar>
<CanvasAction/>
</div>
)
}
......@@ -56,13 +56,13 @@ export const NodeContextMenu: React.FC<Props> = (props) => {
<Menu hasIcon={true}>
<Menu.Item onClick={onNodeCopy} icon={<CopyOutlined />} text="复制" />
<Menu.Item onClick={onNodeDel} icon={<DeleteOutlined />} text="删除" />
<Menu.Item disabled={true} icon={<EditOutlined />} text="重命名" />
<Menu.Divider />
<Menu.Item
onClick={onGraphRun}
icon={<PlaySquareOutlined />}
text="执行"
/>
{/*<Menu.Item disabled={true} icon={<EditOutlined />} text="重命名" />*/}
{/*<Menu.Divider />*/}
{/*<Menu.Item*/}
{/* onClick={onGraphRun}*/}
{/* icon={<PlaySquareOutlined />}*/}
{/* text="执行"*/}
{/*/>*/}
</Menu>
</div>
)
......
......@@ -6,7 +6,6 @@ import {
} from '@/pages/rx-models/experiment-graph'
import { CanvasContent } from './canvas-content'
import { CanvasToolbar } from './canvas-toolbar'
import { BottomToolbar } from './bottom-toolbar'
import styles from './index.less'
......@@ -32,12 +31,11 @@ export const DAGCanvas: React.FC<Props> = (props) => {
return (
<div className={classNames(styles.dagContainer, className)}>
{/*<CanvasToolbar experimentId={experimentId} />*/}
<CanvasToolbar experimentId={experimentId} />
<CanvasContent
experimentId={experimentId}
className={styles.canvasContent}
/>
{/*<BottomToolbar experimentId={experimentId} />*/}
</div>
)
}
......@@ -28,8 +28,8 @@ import {
formatGraphData,
formatNodeInfoToNodeMeta,
} from './graph-util'
import { queryGraph, addNode, copyNode } from '@/mock/graph'
import { queryGraphStatus, runGraph, stopGraphRun } from '@/mock/status'
import { queryGraph, addNode, copyNode } from '@/services/graph'
import { queryGraphStatus, runGraph, stopGraphRun } from '@/services/status'
export function parseStatus(data: NExecutionStatus.ExecutionStatus) {
const { execInfo, instStatus } = data
......@@ -448,7 +448,7 @@ class ExperimentGraph extends GraphCore<BaseNode, BaseEdge> {
onSelectNodes(nodes: BaseNode[]) {
const selectedNodes: X6DemoNode[] = nodes.filter(
(cell) => cell.isNode() && !cell.isGroup(),
(cell) => cell.isNode() && !cell?.isGroup(),
) as X6DemoNode[]
const selectedGroups: X6DemoGroupNode[] = nodes.filter(
(cell) => cell.isNode() && cell.isGroup(),
......@@ -689,7 +689,8 @@ class ExperimentGraph extends GraphCore<BaseNode, BaseEdge> {
const pos = graph.clientToLocal(clientX, clientY)
const nodeRes = await addNode({ ...nodeMeta, ...pos })
this.updateExperimentGraph([nodeRes])
const newNode = formatNodeInfoToNodeMeta(nodeRes as any)
const newNode = formatNodeInfoToNodeMeta(nodeRes as any);
console.log('newNode', newNode)
this.addNode(newNode)
return { success: true }
}
......
......@@ -34,16 +34,15 @@ export namespace NExperimentGraph {
export interface Node {
outPorts: OutPort[]
inPorts: InPort[]
catId: number
positionX: number
positionY: number
codeName: string
category: string
codeName?: string
category?: string
name: string
id: string
nodeInstanceId?: number
groupId: number
status: number
groupId?: number
status?: number
}
export interface Port {
......
export const algoData = [
{
id: 10,
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_1',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: '算法组件1',
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_1',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '算法组件1',
id: 10,
},
},
{
id: 11,
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_2',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: '算法组件2',
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_2',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '算法组件2',
id: 11,
},
},
{
id: 12,
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_3',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: '算法组件3',
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
codeName: 'algo_3',
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
name: '算法组件3',
id: 12,
},
},
]
export const searchByKeyword = async (keyword: string) => {
return Array(10)
.fill(null)
.map((i, idx) => {
return {
defSource: 2,
docUrl: '',
ioType: 0,
up: 148,
down: 11,
iconType: 1,
isDir: false,
isDisabled: false,
author: 'demo author',
codeName: `${keyword}${idx}`,
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
engineType: 0,
isComposite: false,
sequence: 0,
owner: 'system',
description: '组件描述信息',
name: `${keyword}__${idx}`,
id: idx,
parentId: 'recentlyUsed',
isBranch: false,
social: {
defSource: 2,
isEnabled: true,
docUrl: '#',
iconType: 1,
isDisabled: false,
author: 'demo author',
name: `${keyword}-${idx}`,
codeName: `${keyword}${idx}`,
catId: 1,
lastModifyTime: '2020-08-25 15:43:39',
createdTime: '2015-04-16 13:38:11',
owner: 'system',
description: '组件描述信息',
id: idx,
},
}
})
}
import random from 'lodash/random'
interface NodeParams {
name: string
x: number
y: number
}
export const copyNode = ({ name, x, y }: NodeParams) => {
const id = `${Date.now()}`
return {
id,
name,
inPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输入1',
id: id + 100000,
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输入2',
id: id + 200000,
},
],
outPorts: [
{
tableName: 'germany_credit_data',
sequence: 1,
description: '输出表1',
id: id + 300000,
},
{
tableName: 'germany_credit_data',
sequence: 2,
description: '输出表2',
id: id + 400000,
},
],
positionX: x + 200 + random(20, false),
positionY: y + random(10, false),
codeName: 'source_11111',
catId: 1,
nodeDefId: 111111,
category: 'source',
status: 3,
groupId: 0,
}
}
export const addNode = ({ name, x, y }: NodeParams) => {
const id = `${Date.now()}`
return {
id,
name,
inPorts: [
{
sequence: 1,
description: '输入',
id: id + '_in_1',
}
],
outPorts: [
{
sequence: 1,
description: '输出',
id: id + '_out_1',
}
],
positionX: x,
positionY: y,
}
}
export const queryGraph = (id: string) => {
return {
lang: 'zh_CN',
success: true,
data: initData,
Lang: 'zh_CN',
}
}
export const addNodeGroup = async (groupName: string) => {
return {
success: true,
data: {
group: {
name: groupName,
id: Date.now(),
},
},
}
}
const initData = {
nodes: [],
links: [],
}
......@@ -10,7 +10,7 @@
"baseUrl": "./",
"strict": true,
"paths": {
"@/*": ["src/*"],
"@/*": ["./src/*"],
"@@/*": ["src/.umi/*"]
},
"allowSyntheticDefaultImports": true
......
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