Browse Source

refactor: dag-menu refactor (#11965)

* refactor: dag-menu refactor

* feat: add i18n support for the dag-menu

* feat: add e2e class

Co-authored-by: devosend <devosend@gmail.com>
Co-authored-by: Tq <tianqitobethefirst@gmail.com>
labbomb
labbomb 2 years ago committed by GitHub
parent
commit
64f4cb4f3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/TaskTypeConfiguration.java
  2. 14
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/FavTaskServiceImpl.java
  3. 1
      dolphinscheduler-api/src/main/resources/task-type-config.yaml
  4. 6
      dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql
  5. 6
      dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql
  6. 2
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java
  7. 10
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java
  8. 9
      dolphinscheduler-ui/src/locales/en_US/project.ts
  9. 9
      dolphinscheduler-ui/src/locales/zh_CN/project.ts
  10. 39
      dolphinscheduler-ui/src/service/modules/dag-menu/index.ts
  11. 19
      dolphinscheduler-ui/src/store/project/index.ts
  12. 167
      dolphinscheduler-ui/src/store/project/task-type.ts
  13. 58
      dolphinscheduler-ui/src/store/project/types.ts
  14. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-java-task-main-jar.ts
  15. 87
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-java.ts
  16. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-task-type.ts
  17. 6
      dolphinscheduler-ui/src/views/projects/task/components/node/format-data.ts
  18. 6
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-java.ts
  19. 11
      dolphinscheduler-ui/src/views/projects/task/components/node/types.ts
  20. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/use-task.ts
  21. 2
      dolphinscheduler-ui/src/views/projects/task/definition/batch-task.tsx
  22. 472
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-sidebar.tsx
  23. 10
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag.module.scss
  24. 4
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/types.ts
  25. 4
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-cell-update.ts
  26. 8
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-custom-cell-builder.ts
  27. 2
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-dag-drag-drop.ts
  28. 2
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-task-edit.ts

30
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/TaskTypeConfiguration.java

@ -55,26 +55,18 @@ public class TaskTypeConfiguration {
private static final List<FavTaskDto> defaultTaskTypes = new ArrayList<>();
public List<FavTaskDto> getDefaultTaskTypes() {
if (defaultTaskTypes.size() <= 0) {
printDefaultTypes();
universal.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_UNIVERSAL)));
cloud.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_CLOUD)));
logic.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_LOGIC)));
dataIntegration.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_DATA_INTEGRATION)));
dataQuality.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_DATA_QUALITY)));
machineLearning.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_MACHINE_LEARNING)));
other.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_OTHER)));
if (!defaultTaskTypes.isEmpty()) {
return defaultTaskTypes;
}
List<FavTaskDto> result = new ArrayList<>();
defaultTaskTypes.forEach(e -> {
try {
result.add((FavTaskDto) e.clone());
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
});
return result;
printDefaultTypes();
universal.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_UNIVERSAL)));
cloud.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_CLOUD)));
logic.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_LOGIC)));
dataIntegration.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_DATA_INTEGRATION)));
dataQuality.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_DATA_QUALITY)));
machineLearning.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_MACHINE_LEARNING)));
other.forEach(task -> defaultTaskTypes.add(new FavTaskDto(task, false, Constants.TYPE_OTHER)));
return defaultTaskTypes;
}
public void printDefaultTypes() {

14
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/FavTaskServiceImpl.java

@ -43,12 +43,20 @@ public class FavTaskServiceImpl extends BaseServiceImpl implements FavTaskServic
Set<String> userFavTaskTypes = favMapper.getUserFavTaskTypes(loginUser.getId());
List<FavTaskDto> defaultTaskTypes = taskTypeConfiguration.getDefaultTaskTypes();
List<FavTaskDto> result = new ArrayList<>();
// clone default list and modify fav task type flag
defaultTaskTypes.forEach(e -> {
if (userFavTaskTypes.contains(e.getTaskName())) {
e.setCollection(true);
try {
FavTaskDto clone = (FavTaskDto) e.clone();
if (userFavTaskTypes.contains(clone.getTaskName())) {
clone.setCollection(true);
}
result.add(clone);
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
});
return defaultTaskTypes;
return result;
}
@Override

1
dolphinscheduler-api/src/main/resources/task-type-config.yaml

@ -18,6 +18,7 @@
task:
universal:
- 'SHELL'
- 'JAVA'
- 'PYTHON'
- 'PROCEDURE'
- 'SQL'

6
dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql

@ -2003,10 +2003,10 @@ INSERT INTO `t_ds_cluster`
VALUES (100, 0, 'ds_null_k8s', '{"k8s":"ds_null_k8s"}', 'test', 1, '2021-03-03 11:31:24.0', '2021-03-03 11:31:24.0');
--
-- Table structure for t_ds_fav
-- Table structure for t_ds_fav_task
--
DROP TABLE IF EXISTS t_ds_fav CASCADE;
CREATE TABLE t_ds_fav
DROP TABLE IF EXISTS t_ds_fav_task CASCADE;
CREATE TABLE t_ds_fav_task
(
id bigint(20) NOT NULL AUTO_INCREMENT,
task_name varchar(64) NOT NULL,

6
dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql

@ -1958,11 +1958,11 @@ CREATE TABLE t_ds_cluster(
);
--
-- Table structure for t_ds_fav
-- Table structure for t_ds_fav_task
--
DROP TABLE IF EXISTS t_ds_fav;
CREATE TABLE t_ds_fav
DROP TABLE IF EXISTS t_ds_fav_task;
CREATE TABLE t_ds_fav_task
(
id serial NOT NULL,
task_name varchar(64) NOT NULL,

2
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java

@ -142,7 +142,7 @@ class WorkflowE2ETest {
.goToTab(WorkflowDefinitionTab.class);
workflowDefinitionPage
.createWorkflow()
.createSubProcessWorkflow()
.<SubWorkflowTaskForm> addTask(TaskType.SUB_PROCESS)
.childNode("test-workflow-1")

10
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java

@ -59,6 +59,9 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
@FindBy(className = "items")
private List<WebElement> workflowList;
@FindBy(className = "task-cate-logic")
private WebElement subProcessList;
public WorkflowDefinitionTab(RemoteWebDriver driver) {
super(driver);
}
@ -69,6 +72,13 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
return new WorkflowForm(driver);
}
public WorkflowForm createSubProcessWorkflow() {
buttonCreateProcess().click();
subProcessList().click();
return new WorkflowForm(driver);
}
public WorkflowDefinitionTab publish(String workflow) {
workflowList()
.stream()

9
dolphinscheduler-ui/src/locales/en_US/project.ts

@ -785,5 +785,14 @@ export default {
pytorch_conda_python_version: 'Python Version',
pytorch_conda_python_version_tips:
'Please enter the version number, such as 3.6, 3.7, 3.x'
},
menu: {
fav: 'Favorites',
universal: 'Universal',
cloud: 'Cloud',
logic: 'Logic',
di: 'Data Integration',
dq: 'Data Quality',
other: 'Other',
}
}

9
dolphinscheduler-ui/src/locales/zh_CN/project.ts

@ -765,5 +765,14 @@ export default {
pytorch_requirements: '依赖文件',
pytorch_conda_python_version: 'python版本',
pytorch_conda_python_version_tips: '请输入版本号,如 3.6, 3.7, 3.x等'
},
menu: {
fav: '收藏组件',
universal: '通用组件',
cloud: '云',
logic: '逻辑节点',
di: '数据集成',
dq: '数据质量',
other: '其他',
}
}

39
dolphinscheduler-ui/src/service/modules/dag-menu/index.ts

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { axios } from '@/service/service'
export function getDagMenu(): any {
return axios({
url: '/favourite/taskTypes',
method: 'get'
})
}
export function Collection(taskName: string): any {
return axios({
url: `/favourite/${taskName}`,
method: 'post'
})
}
export function CancelCollection(taskName: string): any {
return axios({
url: `/favourite/${taskName}`,
method: 'delete'
})
}

19
dolphinscheduler-ui/src/store/project/index.ts

@ -0,0 +1,19 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './task-node'
export * from './task-type'

167
dolphinscheduler-ui/src/store/project/task-type.ts

@ -0,0 +1,167 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { defineStore } from 'pinia'
import type {
TaskTypeState,
TaskType,
ITaskTypeItem,
TaskExecuteType
} from './types'
export const TASK_TYPES_MAP = {
JAVA: {
alias: 'JAVA'
},
SHELL: {
alias: 'SHELL'
},
SUB_PROCESS: {
alias: 'SUB_PROCESS'
},
PROCEDURE: {
alias: 'PROCEDURE'
},
SQL: {
alias: 'SQL'
},
SPARK: {
alias: 'SPARK'
},
FLINK: {
alias: 'FLINK'
},
MR: {
alias: 'MapReduce',
helperLinkDisable: true
},
PYTHON: {
alias: 'PYTHON'
},
DEPENDENT: {
alias: 'DEPENDENT'
},
HTTP: {
alias: 'HTTP'
},
DATAX: {
alias: 'DataX'
},
PIGEON: {
alias: 'PIGEON'
},
SQOOP: {
alias: 'SQOOP',
helperLinkDisable: true
},
CONDITIONS: {
alias: 'CONDITIONS'
},
DATA_QUALITY: {
alias: 'DATA_QUALITY',
helperLinkDisable: true
},
SWITCH: {
alias: 'SWITCH'
},
SEATUNNEL: {
alias: 'SeaTunnel',
helperLinkDisable: true
},
EMR: {
alias: 'AmazonEMR',
helperLinkDisable: true
},
ZEPPELIN: {
alias: 'ZEPPELIN',
helperLinkDisable: true
},
JUPYTER: {
alias: 'JUPYTER',
helperLinkDisable: true
},
K8S: {
alias: 'K8S',
helperLinkDisable: true
},
MLFLOW: {
alias: 'MLFLOW',
helperLinkDisable: true
},
OPENMLDB: {
alias: 'OPENMLDB',
helperLinkDisable: true
},
DVC: {
alias: 'DVC',
helperLinkDisable: true
},
DINKY: {
alias: 'DINKY',
helperLinkDisable: true
},
SAGEMAKER: {
alias: 'SageMaker',
helperLinkDisable: true
},
CHUNJUN: {
alias: 'CHUNJUN',
helperLinkDisable: true
},
FLINK_STREAM: {
alias: 'FLINK_STREAM',
helperLinkDisable: true,
taskExecuteType: 'STREAM'
},
PYTORCH: {
alias: 'Pytorch',
helperLinkDisable: true
},
HIVECLI: {
alias: 'HIVECLI',
helperLinkDisable: true
}
} as {
[key in TaskType]: {
alias: string
helperLinkDisable?: boolean
taskExecuteType?: TaskExecuteType
}
}
export const useTaskTypeStore = defineStore({
id: 'project-task-type',
state: (): TaskTypeState => ({
types: []
}),
persist: true,
getters: {
getTaskType(): ITaskTypeItem[] {
return this.types
}
},
actions: {
setTaskTypes(types: TaskType[]): void {
try {
this.types = types
.filter((type) => !!TASK_TYPES_MAP[type])
.map((type) => ({ ...TASK_TYPES_MAP[type], type }))
} catch (err) {
this.types = []
}
}
}
})

58
dolphinscheduler-ui/src/store/project/types.ts

@ -18,7 +18,42 @@
import type { EditWorkflowDefinition } from '@/views/projects/workflow/components/dag/types'
import type { IOption } from '@/components/form/types'
type ProgramType = 'JAVA' | 'SCALA' | 'PYTHON' | 'SQL'
type TaskExecuteType = 'STREAM' | 'BATCH'
type TaskType =
| 'SHELL'
| 'SUB_PROCESS'
| 'PROCEDURE'
| 'SQL'
| 'SPARK'
| 'FLINK'
| 'MR'
| 'PYTHON'
| 'DEPENDENT'
| 'HTTP'
| 'DATAX'
| 'PIGEON'
| 'SQOOP'
| 'CONDITIONS'
| 'DATA_QUALITY'
| 'SWITCH'
| 'SEATUNNEL'
| 'EMR'
| 'ZEPPELIN'
| 'K8S'
| 'JUPYTER'
| 'MLFLOW'
| 'OPENMLDB'
| 'DVC'
| 'JAVA'
| 'DINKY'
| 'SAGEMAKER'
| 'CHUNJUN'
| 'FLINK_STREAM'
| 'PYTORCH'
| 'HIVECLI'
type ProgramType = 'JAVA' | 'SCALA' | 'PYTHON'
type DependentResultType = {
[key: string]: 'SUCCESS' | 'WAITING_THREAD' | 'FAILURE'
}
@ -45,6 +80,20 @@ interface TaskNodeState {
name: string
dependentResult: DependentResultType
}
interface ITaskType {
alias: string
helperLinkDisable?: boolean
taskDefinitionDisable?: boolean
taskExecuteType?: TaskExecuteType
}
interface ITaskTypeItem extends ITaskType {
type: TaskType
}
interface TaskTypeState {
types: ITaskTypeItem[]
}
export {
TaskNodeState,
EditWorkflowDefinition,
@ -53,5 +102,10 @@ export {
ProgramType,
DependentResultType,
BDependentResultType,
IMainJar
IMainJar,
TaskType,
ITaskType,
ITaskTypeItem,
TaskTypeState,
TaskExecuteType
}

2
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-java-task-main-jar.ts

@ -49,7 +49,7 @@ export function useJavaTaskMainJar(model: { [field: string]: any }): IJsonItem {
watch(
() => model.programType,
(value) => {
getMainJars(value)
getMainJars(value)
}
)

87
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-java.ts

@ -16,7 +16,7 @@
*/
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useCustomParams, useResources ,useJavaTaskMainJar} from '.'
import { useCustomParams, useResources, useJavaTaskMainJar } from '.'
import type { IJsonItem } from '../types'
export function useJava(model: { [field: string]: any }): IJsonItem[] {
@ -24,39 +24,39 @@ export function useJava(model: { [field: string]: any }): IJsonItem[] {
const rawScriptSpan = computed(() => (model.runType === 'JAR' ? 0 : 24))
return [
{
type: 'select',
field: 'runType',
span: 12,
name: t('project.node.run_type'),
options: RUN_TYPES,
value: model.runType
},
{
type: 'switch',
field: 'isModulePath',
span: 24,
name: t('project.node.is_module_path'),
value: model.isModulePath
},
{
type: 'input',
field: 'mainArgs',
name: t('project.node.main_arguments'),
props: {
type: 'textarea',
placeholder: t('project.node.main_arguments_tips')
}
},
{
type: 'input',
field: 'jvmArgs',
name: t('project.node.jvm_args'),
props: {
type: 'textarea',
placeholder: t('project.node.jvm_args_tips')
}
},
useJavaTaskMainJar(model),
type: 'select',
field: 'runType',
span: 12,
name: t('project.node.run_type'),
options: RUN_TYPES,
value: model.runType
},
{
type: 'switch',
field: 'isModulePath',
span: 24,
name: t('project.node.is_module_path'),
value: model.isModulePath
},
{
type: 'input',
field: 'mainArgs',
name: t('project.node.main_arguments'),
props: {
type: 'textarea',
placeholder: t('project.node.main_arguments_tips')
}
},
{
type: 'input',
field: 'jvmArgs',
name: t('project.node.jvm_args'),
props: {
type: 'textarea',
placeholder: t('project.node.jvm_args_tips')
}
},
useJavaTaskMainJar(model),
{
type: 'editor',
field: 'rawScript',
@ -74,13 +74,12 @@ export function useJava(model: { [field: string]: any }): IJsonItem[] {
}
export const RUN_TYPES = [
{
label: 'JAVA',
value: 'JAVA'
},
{
label: 'JAR',
value: 'JAR'
}
]
{
label: 'JAVA',
value: 'JAVA'
},
{
label: 'JAR',
value: 'JAR'
}
]

2
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-task-type.ts

@ -16,7 +16,7 @@
*/
import { useI18n } from 'vue-i18n'
import { TASK_TYPES_MAP } from '@/views/projects/task/constants/task-type'
import { TASK_TYPES_MAP } from '@/store/project/task-type'
import type { IJsonItem } from '../types'
export function useTaskType(

6
dolphinscheduler-ui/src/views/projects/task/components/node/format-data.ts

@ -36,13 +36,13 @@ export function formatParams(data: INodeData): {
taskParams.processDefinitionCode = data.processDefinitionCode
}
if(data.taskType === 'JAVA'){
if (data.taskType === 'JAVA') {
taskParams.runType = data.runType
taskParams.mainArgs = data.mainArgs
taskParams.jvmArgs = data.jvmArgs
taskParams.isModulePath = data.isModulePath
if(data.runType === 'JAR' && data.mainJar){
taskParams.mainJar = {id: data.mainJar};
if (data.runType === 'JAR' && data.mainJar) {
taskParams.mainJar = { id: data.mainJar }
}
}

6
dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-java.ts

@ -48,9 +48,9 @@ export function useJava({
timeoutNotifyStrategy: ['WARN'],
timeout: 30,
mainJar: undefined,
runType:'JAVA',
mainArgs:'',
jvmArgs:'',
runType: 'JAVA',
mainArgs: '',
jvmArgs: '',
programType: 'JAVA'
} as unknown as INodeData)

11
dolphinscheduler-ui/src/views/projects/task/components/node/types.ts

@ -17,10 +17,7 @@
import { VNode } from 'vue'
import type { SelectOption } from 'naive-ui'
import type {
TaskExecuteType,
TaskType
} from '@/views/projects/task/constants/task-type'
import type { TaskExecuteType, TaskType } from '@/store/project/types'
import type { IDataBase } from '@/service/modules/data-source/types'
import type {
IFormItem,
@ -223,9 +220,9 @@ interface ITaskParams {
resourceList?: ISourceItem[]
mainJar?: ISourceItem
localParams?: ILocalParam[]
runType?:string
jvmArgs?:string
isModulePath?:boolean
runType?: string
jvmArgs?: string
isModulePath?: boolean
rawScript?: string
initScript?: string
programType?: string

2
dolphinscheduler-ui/src/views/projects/task/components/node/use-task.ts

@ -18,7 +18,7 @@ import { ref, Ref, unref } from 'vue'
import nodes from './tasks'
import getElementByJson from '@/components/form/get-elements-by-json'
import { useTaskNodeStore } from '@/store/project/task-node'
import { TASK_TYPES_MAP } from '../../constants/task-type'
import { TASK_TYPES_MAP } from '@/store/project/task-type'
import type {
IFormItem,
IJsonItem,

2
dolphinscheduler-ui/src/views/projects/task/definition/batch-task.tsx

@ -36,7 +36,7 @@ import { SearchOutlined } from '@vicons/antd'
import { useI18n } from 'vue-i18n'
import { useTable } from './use-table'
import { useTask } from './use-task'
import { TASK_TYPES_MAP } from '@/views/projects/task/constants/task-type'
import { TASK_TYPES_MAP } from '@/store/project/task-type'
import Card from '@/components/card'
import VersionModal from './components/version-modal'
import MoveModal from './components/move-modal'

472
dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-sidebar.tsx

@ -15,42 +15,458 @@
* limitations under the License.
*/
import { defineComponent } from 'vue'
import {
TaskType,
TASK_TYPES_MAP
} from '@/views/projects/task/constants/task-type'
import { defineComponent, onMounted, reactive } from 'vue'
import styles from './dag.module.scss'
import type { TaskType } from './types'
import { NCollapse, NCollapseItem, NIcon } from 'naive-ui'
import { StarFilled, StarOutlined } from '@vicons/antd'
import {
CancelCollection,
Collection,
getDagMenu
} from '@/service/modules/dag-menu'
import { useI18n } from 'vue-i18n'
export default defineComponent({
name: 'workflow-dag-sidebar',
emits: ['dragStart'],
setup(props, context) {
const allTaskTypes = Object.keys(TASK_TYPES_MAP).map((type) => ({
type,
...TASK_TYPES_MAP[type as TaskType]
}))
const variables = reactive({
dataList: [],
universal: [],
cloud: [],
logic: [],
di: [],
dq: [],
other: [],
fav: []
})
const { t } = useI18n()
const handleDagMenu = () => {
getDagMenu().then((res: any) => {
variables.dataList = res.map((item: any) => {
return {
...item,
starHover: false,
type: item.taskName
}
})
variables.universal = variables.dataList.filter(
(item: any) => item.taskType === 'Universal'
)
variables.cloud = variables.dataList.filter(
(item: any) => item.taskType === 'Cloud'
)
variables.logic = variables.dataList.filter(
(item: any) => item.taskType === 'Logic'
)
variables.di = variables.dataList.filter(
(item: any) => item.taskType === 'DataIntegration'
)
variables.dq = variables.dataList.filter(
(item: any) => item.taskType === 'DataQuality'
)
variables.other = variables.dataList.filter(
(item: any) => item.taskType === 'Other'
)
variables.fav = variables.dataList.filter(
(item: any) => item.collection === true
)
})
}
const handleCollection = (item: any) => {
item.collection
? CancelCollection(item.taskName).then(() => {
handleDagMenu()
})
: Collection(item.taskName).then(() => {
handleDagMenu()
})
item.collection = !item.collection
}
onMounted(() => {
handleDagMenu()
})
return () => (
return () =>
<div class={styles.sidebar}>
{allTaskTypes.map((task) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.alias}</span>
</div>
))}
<NCollapse default-expanded-names='1' accordion>
{variables.fav.length > 0 && (
<NCollapseItem
title={t('project.menu.fav')}
name='0'
class='task-cate-fav'
v-slots={{
default: () => {
return variables.fav.map((task: any) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.taskName}</span>
<div
class={styles.stars}
onMouseenter={() => {
task.starHover = true
}}
onMouseleave={() => {
task.starHover = false
}}
onClick={() => handleCollection(task)}
>
<NIcon
size='20'
color={
task.collection || task.starHover
? '#288FFF'
: '#ccc'
}
>
{task.collection ? (
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon>
</div>
</div>
))
}
}}
></NCollapseItem>
)}
{variables.universal.length > 0 && (
<NCollapseItem
title={t('project.menu.universal')}
name='1'
class='task-cate-universal'
v-slots={{
default: () => {
return variables.universal.map((task: any) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.taskName}</span>
<div
class={styles.stars}
onMouseenter={() => {
task.starHover = true
}}
onMouseleave={() => {
task.starHover = false
}}
onClick={() => handleCollection(task)}
>
<NIcon
size='20'
color={
task.collection || task.starHover
? '#288FFF'
: '#ccc'
}
>
{task.collection ? (
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon>
</div>
</div>
))
}
}}
></NCollapseItem>
)}
{variables.cloud.length > 0 && (
<NCollapseItem
title={t('project.menu.cloud')}
name='2'
class='task-cate-cloud'
v-slots={{
default: () => {
return variables.cloud.map((task: any) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.taskName}</span>
<div
class={styles.stars}
onMouseenter={() => {
task.starHover = true
}}
onMouseleave={() => {
task.starHover = false
}}
onClick={() => handleCollection(task)}
>
<NIcon
size='20'
color={
task.collection || task.starHover
? '#288FFF'
: '#ccc'
}
>
{task.collection ? (
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon>
</div>
</div>
))
}
}}
></NCollapseItem>
)}
{variables.logic.length > 0 && (
<NCollapseItem
title={t('project.menu.logic')}
name='3'
class='task-cate-logic'
v-slots={{
default: () => {
return variables.logic.map((task: any) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.taskName}</span>
<div
class={styles.stars}
onMouseenter={() => {
task.starHover = true
}}
onMouseleave={() => {
task.starHover = false
}}
onClick={() => handleCollection(task)}
>
<NIcon
size='20'
color={
task.collection || task.starHover
? '#288FFF'
: '#ccc'
}
>
{task.collection ? (
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon>
</div>
</div>
))
}
}}
></NCollapseItem>
)}
{variables.di.length > 0 && (
<NCollapseItem
title={t('project.menu.di')}
name='4'
class='task-cate-di'
v-slots={{
default: () => {
return variables.di.map((task: any) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.taskName}</span>
<div
class={styles.stars}
onMouseenter={() => {
task.starHover = true
}}
onMouseleave={() => {
task.starHover = false
}}
onClick={() => handleCollection(task)}
>
<NIcon
size='20'
color={
task.collection || task.starHover
? '#288FFF'
: '#ccc'
}
>
{task.collection ? (
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon>
</div>
</div>
))
}
}}
></NCollapseItem>
)}
{variables.dq.length > 0 && (
<NCollapseItem
title={t('project.menu.dq')}
name='5'
class='task-cate-dq'
v-slots={{
default: () => {
return variables.dq.map((task: any) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.taskName}</span>
<div
class={styles.stars}
onMouseenter={() => {
task.starHover = true
}}
onMouseleave={() => {
task.starHover = false
}}
onClick={() => handleCollection(task)}
>
<NIcon
size='20'
color={
task.collection || task.starHover
? '#288FFF'
: '#ccc'
}
>
{task.collection ? (
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon>
</div>
</div>
))
}
}}
></NCollapseItem>
)}
{variables.other.length > 0 && (
<NCollapseItem
title={t('project.menu.other')}
name='6'
class='task-cate-other'
v-slots={{
default: () => {
return variables.other.map((task: any) => (
<div
class={[styles.draggable, `task-item-${task.type}`]}
draggable='true'
onDragstart={(e) => {
context.emit('dragStart', e, task.type as TaskType)
}}
>
<em
class={[
styles['sidebar-icon'],
styles['icon-' + task.type.toLocaleLowerCase()]
]}
/>
<span>{task.taskName}</span>
<div
class={styles.stars}
onMouseenter={() => {
task.starHover = true
}}
onMouseleave={() => {
task.starHover = false
}}
onClick={() => handleCollection(task)}
>
<NIcon
size='20'
color={
task.collection || task.starHover
? '#288FFF'
: '#ccc'
}
>
{task.collection ? (
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon>
</div>
</div>
))
}
}}
></NCollapseItem>
)}
</NCollapse>
</div>
)
}
})

10
dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag.module.scss

@ -289,6 +289,16 @@ $bgLight: #ffffff;
}
}
}
span {
display: flex;
flex: 1;
}
.stars {
display: flex;
cursor: pointer;
}
}
.dag-dark .draggable {

4
dolphinscheduler-ui/src/views/projects/workflow/components/dag/types.ts

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { TaskType } from '@/views/projects/task/constants/task-type'
import type { TaskType } from '@/store/project/types'
export type { ITaskState } from '@/common/types'
export interface ProcessDefinition {
@ -172,3 +172,5 @@ export interface IWorkflowTaskInstance {
taskCode: number
taskType: string
}
export { TaskType }

4
dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-cell-update.ts

@ -17,9 +17,9 @@
import type { Ref } from 'vue'
import type { Graph } from '@antv/x6'
import type { TaskType } from '@/views/projects/task/constants/task-type'
import type { TaskType } from '@/store/project/types'
import type { Coordinate } from './types'
import { TASK_TYPES_MAP } from '@/views/projects/task/constants/task-type'
import { TASK_TYPES_MAP } from '@/store/project/task-type'
import { useCustomCellBuilder } from './dag-hooks'
import utils from '@/utils'
import type { Edge } from '@antv/x6'

8
dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-custom-cell-builder.ts

@ -18,10 +18,8 @@
import type { Node, Edge } from '@antv/x6'
import { X6_NODE_NAME, X6_EDGE_NAME } from './dag-config'
import utils from '@/utils'
import {
TASK_TYPES_MAP,
TaskType
} from '@/views/projects/task/constants/task-type'
import { TaskType } from '@/store/project/types'
import { TASK_TYPES_MAP } from '@/store/project/task-type'
import { WorkflowDefinition, Coordinate } from './types'
export function useCustomCellBuilder() {
@ -96,7 +94,7 @@ export function useCustomCellBuilder() {
// Use href instead of xlink:href, you may lose the icon when downloadPNG
'xlink:href': `${
import.meta.env.BASE_URL
}images/task-icons/${(type !== 'FLINK_STREAM'
}images/task-icons/${(type !== ('FLINK_STREAM' as TaskType)
? type
: 'FLINK'
).toLocaleLowerCase()}.png`

2
dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-dag-drag-drop.ts

@ -20,7 +20,7 @@ import type { Ref } from 'vue'
import type { Graph } from '@antv/x6'
import { genTaskCodeList } from '@/service/modules/task-definition'
import { Coordinate, Dragged } from './types'
import { TaskType } from '@/views/projects/task/constants/task-type'
import { TaskType } from '@/store/project/types'
import { useRoute } from 'vue-router'
interface Options {

2
dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-task-edit.ts

@ -17,7 +17,7 @@
import { ref, onMounted, watch } from 'vue'
import { remove, cloneDeep } from 'lodash'
import { TaskType } from '@/views/projects/task/constants/task-type'
import { TaskType } from '@/store/project/types'
import { formatParams } from '@/views/projects/task/components/node/format-data'
import { useCellUpdate } from './dag-hooks'
import type { Ref } from 'vue'

Loading…
Cancel
Save