diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/application.yaml b/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/application.yaml
index 6fbcc04feb..8f76fcddfd 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/application.yaml
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/application.yaml
@@ -77,18 +77,16 @@ alert:
sender-parallelism: 100
registry:
- type: zookeeper
- zookeeper:
- namespace: dolphinscheduler
- connect-string: localhost:2181
- retry-policy:
- base-sleep-time: 60ms
- max-sleep: 300ms
- max-retries: 5
- session-timeout: 30s
- connection-timeout: 9s
- block-until-connected: 600ms
- digest: ~
+ type: jdbc
+ term-refresh-interval: 2s
+ term-expire-times: 3
+ hikari-config:
+ jdbc-url: jdbc:postgresql://localhost:5432/dolphinscheduler
+ username: root
+ password: root
+ maximum-pool-size: 5
+ connection-timeout: 9000
+ idle-timeout: 600000
metrics:
enabled: true
diff --git a/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/logback-spring.xml b/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/logback-spring.xml
index 81c8042bc5..db58b54373 100644
--- a/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/logback-spring.xml
+++ b/dolphinscheduler-alert/dolphinscheduler-alert-server/src/main/resources/logback-spring.xml
@@ -46,11 +46,7 @@
-
-
-
-
-
+
diff --git a/dolphinscheduler-api/pom.xml b/dolphinscheduler-api/pom.xml
index 40d556a17e..5d62253175 100644
--- a/dolphinscheduler-api/pom.xml
+++ b/dolphinscheduler-api/pom.xml
@@ -77,6 +77,11 @@
dolphinscheduler-task-all
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-all
+
+
org.apache.dolphinscheduler
dolphinscheduler-ui
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
index f8b705179a..cf0e28f8b1 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
@@ -28,6 +28,7 @@ import org.apache.dolphinscheduler.plugin.datasource.api.plugin.DataSourceProces
import org.apache.dolphinscheduler.plugin.storage.api.StorageConfiguration;
import org.apache.dolphinscheduler.plugin.task.api.TaskChannelFactory;
import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerPluginManager;
import org.apache.dolphinscheduler.registry.api.RegistryConfiguration;
import org.apache.dolphinscheduler.service.ServiceConfiguration;
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer;
@@ -70,6 +71,7 @@ public class ApiApplicationServer {
log.info("Received spring application context ready event will load taskPlugin and write to DB");
// install task plugin
TaskPluginManager.loadPlugin();
+ TriggerPluginManager.loadPlugin();
DataSourceProcessorProvider.initialize();
for (Map.Entry entry : TaskPluginManager.getTaskChannelFactoryMap().entrySet()) {
String taskPluginName = entry.getKey();
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TriggerController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TriggerController.java
new file mode 100644
index 0000000000..280d3b14ba
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TriggerController.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.api.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dolphinscheduler.api.audit.OperatorLog;
+import org.apache.dolphinscheduler.api.audit.enums.AuditType;
+import org.apache.dolphinscheduler.api.exceptions.ApiException;
+import org.apache.dolphinscheduler.api.service.ExecutorService;
+import org.apache.dolphinscheduler.api.service.TriggerDefinitionService;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.constants.Constants;
+import org.apache.dolphinscheduler.common.enums.*;
+import org.apache.dolphinscheduler.dao.entity.User;
+import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+import static org.apache.dolphinscheduler.api.enums.Status.*;
+
+/**
+ * trigger definition controller
+ */
+@Tag(name = "TRIGGER_DEFINITION_TAG")
+@RestController
+@RequestMapping("projects/{projectCode}/trigger-definition")
+@Slf4j
+public class TriggerController extends BaseController {
+
+ @Autowired
+ private ExecutorService execService;
+
+ @Autowired
+ private TriggerDefinitionService triggerDefinitionService;
+
+ /**
+ * create trigger definition
+ *
+ * @param loginUser login user
+ * @param projectCode project code
+ * @param triggerDefinitionJson trigger definition json
+ * @return create result code
+ */
+ @Operation(summary = "save", description = "CREATE_TRIGGER_DEFINITION_NOTES")
+ @Parameters({
+ @Parameter(name = "projectCode", description = "PROJECT_CODE", required = true, schema = @Schema(implementation = long.class)),
+ @Parameter(name = "triggerDefinitionJson", description = "TRIGGER_DEFINITION_JSON", required = true, schema = @Schema(implementation = String.class))
+ })
+ @PostMapping()
+ @ResponseStatus(HttpStatus.CREATED)
+ // change error code
+ @ApiException(CREATE_TASK_DEFINITION_ERROR)
+ // change audit type
+ @OperatorLog(auditType = AuditType.TASK_CREATE)
+ public Result createTriggerDefinition(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
+ @RequestParam(value = "triggerDefinitionJson", required = true) String triggerDefinitionJson) {
+ Map result =
+ triggerDefinitionService.createTriggerDefinition(loginUser, projectCode, triggerDefinitionJson);
+ return returnDataList(result);
+ }
+
+ /**
+ * query task definition list paging
+ *
+ * @param loginUser login user
+ * @param projectCode project code
+ * @param searchTriggerName searchTaskName
+ * @param triggerType taskType
+ * @param pageNo page number
+ * @param pageSize page size
+ * @return task definition page
+ */
+ @Operation(summary = "queryTaskDefinitionListPaging", description = "QUERY_TASK_DEFINITION_LIST_PAGING_NOTES")
+ @Parameters({
+ @Parameter(name = "projectCode", description = "PROJECT_CODE", required = false, schema = @Schema(implementation = long.class)),
+ @Parameter(name = "searchWorkflowName", description = "SEARCH_WORKFLOW_NAME", required = false, schema = @Schema(implementation = String.class)),
+ @Parameter(name = "searchTaskName", description = "SEARCH_TASK_NAME", required = false, schema = @Schema(implementation = String.class)),
+ @Parameter(name = "taskType", description = "TASK_TYPE", required = false, schema = @Schema(implementation = String.class, example = "SHELL")),
+ @Parameter(name = "taskExecuteType", description = "TASK_EXECUTE_TYPE", required = false, schema = @Schema(implementation = TaskExecuteType.class, example = "STREAM")),
+ @Parameter(name = "pageNo", description = "PAGE_NO", required = true, schema = @Schema(implementation = int.class, example = "1")),
+ @Parameter(name = "pageSize", description = "PAGE_SIZE", required = true, schema = @Schema(implementation = int.class, example = "10"))
+ })
+ @GetMapping()
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(QUERY_TASK_DEFINITION_LIST_PAGING_ERROR)
+ public Result queryTaskDefinitionListPaging(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
+ @RequestParam(value = "searchTriggerName", required = false) String searchTriggerName,
+ @RequestParam(value = "triggerType", required = false) String triggerType,
+ @RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize) {
+ checkPageParams(pageNo, pageSize);
+ searchTriggerName = ParameterUtils.handleEscapes(searchTriggerName);
+ return triggerDefinitionService.queryTriggerDefinitionListPaging(loginUser, projectCode,
+ searchTriggerName, triggerType, pageNo, pageSize);
+ }
+}
+
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TriggerDefinitionService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TriggerDefinitionService.java
new file mode 100644
index 0000000000..bdea04b983
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TriggerDefinitionService.java
@@ -0,0 +1,24 @@
+package org.apache.dolphinscheduler.api.service;
+
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
+import org.apache.dolphinscheduler.dao.entity.User;
+
+import java.util.Map;
+
+/**
+ * trigger definition service
+ */
+public interface TriggerDefinitionService {
+
+ Map createTriggerDefinition(User loginUser,
+ long projectCode,
+ String triggerDefinitionJson);
+
+ Result queryTriggerDefinitionListPaging(User loginUser,
+ long projectCode,
+ String searchTriggerName,
+ String triggerType,
+ Integer pageNo,
+ Integer pageSize);
+}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TriggerDefinitionServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TriggerDefinitionServiceImpl.java
new file mode 100644
index 0000000000..f511f31d00
--- /dev/null
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TriggerDefinitionServiceImpl.java
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.api.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.dolphinscheduler.api.dto.task.TaskCreateRequest;
+import org.apache.dolphinscheduler.api.dto.task.TaskFilterRequest;
+import org.apache.dolphinscheduler.api.dto.task.TaskUpdateRequest;
+import org.apache.dolphinscheduler.api.dto.taskRelation.TaskRelationUpdateUpstreamRequest;
+import org.apache.dolphinscheduler.api.dto.workflow.WorkflowUpdateRequest;
+import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.exceptions.ServiceException;
+import org.apache.dolphinscheduler.api.permission.PermissionCheck;
+import org.apache.dolphinscheduler.api.service.*;
+import org.apache.dolphinscheduler.api.utils.PageInfo;
+import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.api.vo.TaskDefinitionVO;
+import org.apache.dolphinscheduler.common.constants.Constants;
+import org.apache.dolphinscheduler.common.enums.*;
+import org.apache.dolphinscheduler.common.utils.CodeGenerateUtils;
+import org.apache.dolphinscheduler.common.utils.JSONUtils;
+import org.apache.dolphinscheduler.dao.entity.*;
+import org.apache.dolphinscheduler.dao.mapper.*;
+import org.apache.dolphinscheduler.dao.repository.ProcessTaskRelationLogDao;
+import org.apache.dolphinscheduler.dao.repository.TaskDefinitionDao;
+import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager;
+import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode;
+import org.apache.dolphinscheduler.service.process.ProcessService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.*;
+import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_DEFINITION;
+
+/**
+ * tenant service impl
+ */
+@Service
+@Slf4j
+public class TriggerDefinitionServiceImpl extends BaseServiceImpl implements TriggerDefinitionService {
+
+ @Autowired
+ private ProjectMapper projectMapper;
+
+ @Autowired
+ private ProjectService projectService;
+
+ @Autowired
+ private TaskDefinitionMapper taskDefinitionMapper;
+
+ @Autowired
+ private TriggerDefinitionMapper triggerDefinitionMapper;
+
+ @Autowired
+ private TaskDefinitionDao taskDefinitionDao;
+
+ @Autowired
+ private TaskDefinitionLogMapper taskDefinitionLogMapper;
+
+ @Autowired
+ private ProcessTaskRelationMapper processTaskRelationMapper;
+
+ @Autowired
+ private ProcessTaskRelationLogDao processTaskRelationLogDao;
+
+ @Autowired
+ private ProcessTaskRelationService processTaskRelationService;
+
+ @Autowired
+ private ProcessDefinitionMapper processDefinitionMapper;
+
+ @Autowired
+ private ProcessService processService;
+
+ @Autowired
+ private ProcessDefinitionService processDefinitionService;
+
+ @Autowired
+ private ProcessDefinitionLogMapper processDefinitionLogMapper;
+
+
+ @Transactional
+ @Override
+ public Map createTriggerDefinition(User loginUser,
+ long projectCode,
+ String triggerDefinitionJson) {
+ Project project = projectMapper.queryByCode(projectCode);
+ // check if user have write perm for project
+ Map result = new HashMap<>();
+ return result;
+ }
+
+ @Override
+ public Result queryTriggerDefinitionListPaging(User loginUser,
+ long projectCode,
+ String searchTriggerName,
+ String triggerType,
+ Integer pageNo,
+ Integer pageSize) {
+ Result result = new Result();
+ Project project = projectMapper.queryByCode(projectCode);
+ // check user access for project
+ Map checkResult =
+ projectService.checkProjectAndAuth(loginUser, project, projectCode, TASK_DEFINITION);
+ Status resultStatus = (Status) checkResult.get(Constants.STATUS);
+ if (resultStatus != Status.SUCCESS) {
+ putMsg(result, resultStatus);
+ return result;
+ }
+ triggerType = triggerType == null ? StringUtils.EMPTY : triggerType;
+ Page page = new Page<>(pageNo, pageSize);
+ // first, query trigger code by page size
+ IPage taskMainInfoIPage = triggerDefinitionMapper.queryDefinitionListPaging(page, projectCode,
+ searchTriggerName, triggerType);
+ PageInfo pageInfo = new PageInfo<>(pageNo, pageSize);
+ pageInfo.setTotal((int) taskMainInfoIPage.getTotal());
+// pageInfo.setTotalList(taskMainInfoIPage.getRecords());
+ result.setData(pageInfo);
+ putMsg(result, Status.SUCCESS);
+ return result;
+ }
+}
+
diff --git a/dolphinscheduler-api/src/main/resources/application.yaml b/dolphinscheduler-api/src/main/resources/application.yaml
index e38d0c5a8e..e6f1fb03a6 100644
--- a/dolphinscheduler-api/src/main/resources/application.yaml
+++ b/dolphinscheduler-api/src/main/resources/application.yaml
@@ -113,18 +113,16 @@ management:
application: ${spring.application.name}
registry:
- type: zookeeper
- zookeeper:
- namespace: dolphinscheduler
- connect-string: localhost:2181
- retry-policy:
- base-sleep-time: 60ms
- max-sleep: 300ms
- max-retries: 5
- session-timeout: 60s
- connection-timeout: 15s
- block-until-connected: 15s
- digest: ~
+ type: jdbc
+ term-refresh-interval: 2s
+ term-expire-times: 3
+ hikari-config:
+ jdbc-url: jdbc:postgresql://localhost:5432/dolphinscheduler
+ username: root
+ password: root
+ maximum-pool-size: 5
+ connection-timeout: 9000
+ idle-timeout: 600000
api:
audit-enable: false
diff --git a/dolphinscheduler-api/src/main/resources/logback-spring.xml b/dolphinscheduler-api/src/main/resources/logback-spring.xml
index 1982d6de5b..97173c25c9 100644
--- a/dolphinscheduler-api/src/main/resources/logback-spring.xml
+++ b/dolphinscheduler-api/src/main/resources/logback-spring.xml
@@ -51,11 +51,7 @@
-
-
-
-
-
+
diff --git a/dolphinscheduler-authentication/dolphinscheduler-aws-authentication/src/main/resources/aws.yaml b/dolphinscheduler-authentication/dolphinscheduler-aws-authentication/src/main/resources/aws.yaml
index 6d453bb78a..bb9b4d29f3 100644
--- a/dolphinscheduler-authentication/dolphinscheduler-aws-authentication/src/main/resources/aws.yaml
+++ b/dolphinscheduler-authentication/dolphinscheduler-aws-authentication/src/main/resources/aws.yaml
@@ -21,11 +21,11 @@ aws:
# AWSStaticCredentialsProvider: use the access key and secret key to authenticate
# InstanceProfileCredentialsProvider: use the IAM role to authenticate
credentials.provider.type: AWSStaticCredentialsProvider
- access.key.id: accessKey123
- access.key.secret: secretKey123
+ access.key.id: minioadmin
+ access.key.secret: minioadmin
region: us-east-1
bucket.name: dolphinscheduler
- endpoint: http://s3:9000
+ endpoint: http://localhost:9000
emr:
# The AWS credentials provider type. support: AWSStaticCredentialsProvider, InstanceProfileCredentialsProvider
# AWSStaticCredentialsProvider: use the access key and secret key to authenticate
diff --git a/dolphinscheduler-common/src/main/resources/common.properties b/dolphinscheduler-common/src/main/resources/common.properties
index cf1723700e..36d1ca1544 100644
--- a/dolphinscheduler-common/src/main/resources/common.properties
+++ b/dolphinscheduler-common/src/main/resources/common.properties
@@ -24,7 +24,7 @@ data.basedir.path=/tmp/dolphinscheduler
# resource storage type: LOCAL, HDFS, S3, OSS, GCS, ABS, OBS. LOCAL type is default type, and it's a specific type of HDFS with "resource.hdfs.fs.defaultFS = file:///" configuration
# please notice that LOCAL mode does not support reading and writing in distributed mode, which mean you can only use your resource in one machine, unless
# use shared file mount point
-resource.storage.type=LOCAL
+resource.storage.type=S3
# resource store on HDFS/S3 path, resource file will store to this base path, self configuration, please make sure the directory exists on hdfs and have read write permissions. "/dolphinscheduler" is recommended
resource.storage.upload.base.path=/dolphinscheduler
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerDefinition.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerDefinition.java
new file mode 100644
index 0000000000..26f8bfb636
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerDefinition.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.entity;
+
+import java.util.Date;
+import java.util.Objects;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+@Data
+@TableName("t_ds_trigger_definition")
+public class TriggerDefinition {
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ /**
+ * code
+ */
+ private long code;
+
+ /**
+ * name
+ */
+ private String name;
+
+ /**
+ * description
+ */
+ private String description;
+
+ /**
+ * project code
+ */
+ private long projectCode;
+
+ /**
+ * trigger user id
+ */
+ private int userId;
+
+ /**
+ * trigger type
+ */
+ private String triggerType;
+
+ /**
+ * create time
+ */
+ private Date createTime;
+
+ /**
+ * update time
+ */
+ private Date updateTime;
+
+ public TriggerDefinition() {
+ }
+
+ public TriggerDefinition(long code) {
+ this.code = code;
+ }
+
+ public boolean equals(Object o) {
+ if (o == null) {
+ return false;
+ }
+ TriggerDefinition that = (TriggerDefinition) o;
+ return Objects.equals(name, that.name)
+ && Objects.equals(description, that.description);
+ }
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerInstance.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerInstance.java
new file mode 100644
index 0000000000..186b59475d
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerInstance.java
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.core.type.TypeReference;
+import lombok.Data;
+
+import org.apache.dolphinscheduler.common.constants.Constants;
+import org.apache.dolphinscheduler.common.enums.Flag;
+import org.apache.dolphinscheduler.common.enums.Priority;
+import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
+import org.apache.dolphinscheduler.common.utils.DateUtils;
+import org.apache.dolphinscheduler.common.utils.JSONUtils;
+import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus;
+import org.apache.dolphinscheduler.plugin.task.api.parameters.DependentParameters;
+import org.apache.dolphinscheduler.plugin.task.api.parameters.SwitchParameters;
+
+import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.*;
+import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.TASK_TYPE_BLOCKING;
+
+@Data
+@TableName("t_ds_trigger_instance")
+public class TriggerInstance implements Serializable {
+
+ /**
+ * id
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ /**
+ * task name
+ */
+ private String name;
+
+ /**
+ * task type
+ */
+ private String triggerType;
+
+ private int processInstanceId;
+
+ private String processInstanceName;
+
+ private Long projectCode;
+
+ private long triggerCode;
+
+ @TableField(exist = false)
+ private String processDefinitionName;
+
+ /**
+ * state
+ */
+ private TaskExecutionStatus state;
+
+ /**
+ * task first submit time.
+ */
+ private Date firstSubmitTime;
+
+ /**
+ * task submit time
+ */
+ private Date submitTime;
+
+ /**
+ * task start time
+ */
+ private Date startTime;
+
+ /**
+ * task end time
+ */
+ private Date endTime;
+}
+
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerMainInfo.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerMainInfo.java
new file mode 100644
index 0000000000..67446e5094
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerMainInfo.java
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.entity;
+
+import org.apache.dolphinscheduler.common.enums.ReleaseState;
+
+import java.util.Date;
+import java.util.Map;
+
+import lombok.Data;
+
+/**
+ * task main info
+ */
+@Data
+public class TriggerMainInfo {
+ private long id;
+
+ /**
+ * task name
+ */
+ private String taskName;
+
+ /**
+ * task code
+ */
+ private long taskCode;
+
+ /**
+ * task version
+ */
+ private int taskVersion;
+
+ /**
+ * task type
+ */
+ private String taskType;
+
+ /**
+ * create time
+ */
+ private Date taskCreateTime;
+
+ /**
+ * update time
+ */
+ private Date taskUpdateTime;
+
+ /**
+ * projectCode
+ */
+ private long projectCode;
+
+ /**
+ * processDefinitionCode
+ */
+ private long processDefinitionCode;
+
+ /**
+ * processDefinitionVersion
+ */
+ private int processDefinitionVersion;
+
+ /**
+ * processDefinitionName
+ */
+ private String processDefinitionName;
+
+ /**
+ * processReleaseState
+ */
+ private ReleaseState processReleaseState;
+
+ /**
+ * upstreamTaskMap(k:code,v:name)
+ */
+ private Map upstreamTaskMap;
+
+ /**
+ * upstreamTaskCode
+ */
+ private long upstreamTaskCode;
+
+ /**
+ * upstreamTaskName
+ */
+ private String upstreamTaskName;
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerOffset.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerOffset.java
new file mode 100644
index 0000000000..a8c450b416
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TriggerOffset.java
@@ -0,0 +1,26 @@
+package org.apache.dolphinscheduler.dao.entity;
+
+import lombok.Data;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+@Data
+@TableName("t_ds_trigger_offset")
+public class TriggerOffset {
+ /**
+ * id
+ */
+ private Integer id;
+
+ /**
+ * code
+ */
+ private long code;
+
+ public TriggerOffset() {
+ }
+
+ public TriggerOffset(long code) {
+ this.code = code;
+ }
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapper.java
new file mode 100644
index 0000000000..5f5254073a
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapper.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.mapper;
+
+import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
+import org.apache.dolphinscheduler.dao.entity.*;
+import org.apache.dolphinscheduler.dao.model.WorkflowDefinitionCountDto;
+
+import org.apache.ibatis.annotations.MapKey;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * trigger definition mapper interface
+ */
+
+public interface TriggerDefinitionMapper extends BaseMapper {
+
+ /**
+ * query trigger definition by name
+ *
+ * @param projectCode projectCode
+ * @param processCode processCode
+ * @param name name
+ * @return trigger definition
+ */
+ TriggerDefinition queryByName(@Param("projectCode") long projectCode,
+ @Param("processCode") long processCode,
+ @Param("name") String name);
+
+ /**
+ * query trigger definition by code
+ *
+ * @param code taskDefinitionCode
+ * @return trigger definition
+ */
+ TriggerDefinition queryByCode(@Param("code") long code);
+
+ /**
+ * query all trigger definition list
+ *
+ * @param projectCode projectCode
+ * @return trigger definition list
+ */
+ List queryAllDefinitionList(@Param("projectCode") long projectCode);
+
+ /**
+ * task main info page
+ *
+ * @param page page
+ * @param projectCode projectCode
+ * @param searchTriggerName searchTriggerName
+ * @param triggerType triggerType
+ * @return task main info IPage
+ */
+ IPage queryDefinitionListPaging(IPage page,
+ @Param("projectCode") long projectCode,
+ @Param("searchTaskName") String searchTriggerName,
+ @Param("taskType") String triggerType);
+
+ /**
+ * delete trigger definition by code
+ *
+ * @param code code
+ * @return int
+ */
+ int deleteByCode(@Param("code") long code);
+}
+
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerInstanceMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerInstanceMapper.java
new file mode 100644
index 0000000000..b79bc9d010
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerInstanceMapper.java
@@ -0,0 +1,20 @@
+package org.apache.dolphinscheduler.dao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
+import org.apache.dolphinscheduler.dao.entity.*;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.*;
+
+public interface TriggerInstanceMapper extends BaseMapper {
+
+ /**
+ * query trigger definition by code
+ *
+ * @param code taskDefinitionCode
+ * @return trigger definition
+ */
+ TriggerInstance queryByCode(@Param("code") long code);
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerOffsetMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerOffsetMapper.java
new file mode 100644
index 0000000000..a56a371b72
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TriggerOffsetMapper.java
@@ -0,0 +1,16 @@
+package org.apache.dolphinscheduler.dao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.dolphinscheduler.dao.entity.*;
+import org.apache.ibatis.annotations.Param;
+
+public interface TriggerOffsetMapper extends BaseMapper {
+
+ /**
+ * query trigger definition by code
+ *
+ * @param code taskDefinitionCode
+ * @return trigger definition
+ */
+ TriggerOffset queryByCode(@Param("code") long code);
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/TriggerDefinitionDao.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/TriggerDefinitionDao.java
new file mode 100644
index 0000000000..4c59692a9b
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/TriggerDefinitionDao.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.repository;
+
+import org.apache.dolphinscheduler.dao.entity.TriggerDefinition;
+
+/**
+ * Trigger Definition DAO
+ */
+public interface TriggerDefinitionDao extends IDao {
+ TriggerDefinition queryByCode(long triggerCode);
+}
\ No newline at end of file
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/TriggerInstanceDao.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/TriggerInstanceDao.java
new file mode 100644
index 0000000000..4a359d0e06
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/TriggerInstanceDao.java
@@ -0,0 +1,10 @@
+package org.apache.dolphinscheduler.dao.repository;
+
+import org.apache.dolphinscheduler.dao.entity.TriggerInstance;
+
+/**
+ * Trigger Instance DAO
+ */
+public interface TriggerInstanceDao extends IDao {
+ TriggerInstance queryByCode(long triggerCode);
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/TriggerDefinitionDaoImpl.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/TriggerDefinitionDaoImpl.java
new file mode 100644
index 0000000000..dd795b908a
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/TriggerDefinitionDaoImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.repository.impl;
+
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dolphinscheduler.dao.entity.*;
+import org.apache.dolphinscheduler.dao.mapper.*;
+import org.apache.dolphinscheduler.dao.repository.BaseDao;
+import org.apache.dolphinscheduler.dao.repository.TriggerDefinitionDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@Slf4j
+public class TriggerDefinitionDaoImpl extends BaseDao implements TriggerDefinitionDao {
+
+ @Autowired
+ private ProcessDefinitionMapper processDefinitionMapper;
+
+ @Autowired
+ private ProcessTaskRelationLogMapper processTaskRelationLogMapper;
+
+ @Autowired
+ private TaskDefinitionLogMapper taskDefinitionLogMapper;
+
+ public TriggerDefinitionDaoImpl(@NonNull TriggerDefinitionMapper triggerDefinitionMapper) {
+ super(triggerDefinitionMapper);
+ }
+
+ @Override
+ public TriggerDefinition queryByCode(long triggerCode) {
+ return mybatisMapper.queryByCode(triggerCode);
+ }
+}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/TriggerInstanceDaoImpl.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/TriggerInstanceDaoImpl.java
new file mode 100644
index 0000000000..b6cbe6ab14
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/TriggerInstanceDaoImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.repository.impl;
+
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dolphinscheduler.dao.entity.*;
+import org.apache.dolphinscheduler.dao.mapper.*;
+import org.apache.dolphinscheduler.dao.repository.BaseDao;
+import org.apache.dolphinscheduler.dao.repository.TriggerInstanceDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@Slf4j
+public class TriggerInstanceDaoImpl extends BaseDao implements TriggerInstanceDao {
+
+ @Autowired
+ private ProcessDefinitionMapper processDefinitionMapper;
+
+ @Autowired
+ private ProcessTaskRelationLogMapper processTaskRelationLogMapper;
+
+ @Autowired
+ private TaskDefinitionLogMapper taskDefinitionLogMapper;
+
+ public TriggerInstanceDaoImpl(@NonNull TriggerInstanceMapper triggerInstanceMapper) {
+ super(triggerInstanceMapper);
+ }
+
+ @Override
+ public TriggerInstance queryByCode(long triggerCode) {
+ return mybatisMapper.queryByCode(triggerCode);
+ }
+}
\ No newline at end of file
diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapper.xml
new file mode 100644
index 0000000000..abf01fc543
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapper.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
diff --git a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql
index a907ec69a1..d788a72127 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_h2.sql
@@ -499,6 +499,57 @@ CREATE TABLE t_ds_task_definition
PRIMARY KEY (id, code)
);
+-- ----------------------------
+-- Table structure for t_ds_trigger_offset
+-- ----------------------------
+DROP TABLE IF EXISTS t_ds_trigger_offset CASCADE;
+CREATE TABLE t_ds_trigger_offset
+(
+ id int(11) NOT NULL,
+ code bigint(20) NOT NULL,
+ PRIMARY KEY (id, code)
+);
+
+-- ----------------------------
+-- Table structure for t_ds_trigger_definition
+-- ----------------------------
+DROP TABLE IF EXISTS t_ds_trigger_definition CASCADE;
+CREATE TABLE t_ds_trigger_definition
+(
+ id int(11) NOT NULL AUTO_INCREMENT,
+ code bigint(20) NOT NULL,
+ name varchar(255) DEFAULT NULL,
+ description text,
+ project_code bigint(20) NOT NULL,
+ user_id int(11) DEFAULT NULL,
+ trigger_type varchar(50) NOT NULL,
+ trigger_params longtext,
+ create_time datetime NOT NULL,
+ update_time datetime DEFAULT NULL,
+ PRIMARY KEY (id, code)
+);
+
+-- ----------------------------
+-- Table structure for t_ds_trigger_instance
+-- ----------------------------
+DROP TABLE IF EXISTS t_ds_trigger_instance CASCADE;
+CREATE TABLE t_ds_trigger_instance
+(
+ id int(11) NOT NULL AUTO_INCREMENT,
+ name varchar(255) DEFAULT NULL,
+ trigger_type varchar(50) NOT NULL,
+ trigger_code bigint(20) NOT NULL,
+ process_instance_id int(11) DEFAULT NULL,
+ process_instance_name varchar(255) DEFAULT NULL,
+ project_code bigint(20) DEFAULT NULL,
+ state tinyint(4) DEFAULT NULL,
+ submit_time datetime DEFAULT NULL,
+ start_time datetime DEFAULT NULL,
+ end_time datetime DEFAULT NULL,
+ trigger_params longtext,
+ PRIMARY KEY (id)
+);
+
-- ----------------------------
-- Table structure for t_ds_task_definition_log
-- ----------------------------
@@ -2154,7 +2205,6 @@ CREATE TABLE t_ds_trigger_relation
UNIQUE KEY t_ds_trigger_relation_UN(trigger_type,job_id,trigger_code)
);
-
DROP TABLE IF EXISTS t_ds_relation_sub_workflow;
CREATE TABLE t_ds_relation_sub_workflow (
id BIGINT AUTO_INCREMENT NOT NULL,
diff --git a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql
index 3a4f17a357..3ff0408d75 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_mysql.sql
@@ -939,6 +939,68 @@ CREATE TABLE `t_ds_task_instance` (
-- Records of t_ds_task_instance
-- ----------------------------
+-- ----------------------------
+-- Table structure for t_ds_trigger_offset
+-- ----------------------------
+DROP TABLE IF EXISTS `t_ds_trigger_offset`;
+CREATE TABLE `t_ds_trigger_offset` (
+ `id` int(11) NOT NULL COMMENT 'self-increasing id',
+ `code` bigint(20) NOT NULL COMMENT 'encoding',
+ PRIMARY KEY (`id`,`code`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE = utf8_bin;
+
+-- ----------------------------
+-- Records of t_ds_trigger_offset
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for t_ds_trigger_definition
+-- ----------------------------
+DROP TABLE IF EXISTS `t_ds_trigger_definition`;
+CREATE TABLE `t_ds_trigger_definition` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'self-increasing id',
+ `code` bigint(20) NOT NULL COMMENT 'encoding',
+ `name` varchar(255) DEFAULT NULL COMMENT 'trigger definition name',
+ `description` text COMMENT 'description',
+ `project_code` bigint(20) NOT NULL COMMENT 'project code',
+ `user_id` int(11) DEFAULT NULL COMMENT 'trigger definition creator id',
+ `trigger_type` varchar(50) NOT NULL COMMENT 'trigger type',
+ `trigger_params` longtext COMMENT 'job custom parameters',
+ `create_time` datetime NOT NULL COMMENT 'create time',
+ `update_time` datetime NOT NULL COMMENT 'update time',
+ PRIMARY KEY (`id`,`code`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE = utf8_bin;
+
+-- ----------------------------
+-- Records of t_ds_trigger_definition
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for t_ds_trigger_instance
+-- ----------------------------
+DROP TABLE IF EXISTS `t_ds_trigger_instance`;
+CREATE TABLE `t_ds_trigger_instance` (
+ `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'key',
+ `name` varchar(255) DEFAULT NULL COMMENT 'trigger name',
+ `trigger_type` varchar(50) NOT NULL COMMENT 'trigger type',
+ `trigger_code` bigint(20) NOT NULL COMMENT 'trigger definition code',
+ `process_instance_id` int(11) DEFAULT NULL COMMENT 'process instance id',
+ `process_instance_name` varchar(255) DEFAULT NULL COMMENT 'process instance name',
+ `project_code` bigint(20) DEFAULT NULL COMMENT 'project code',
+ `state` tinyint(4) DEFAULT NULL COMMENT 'Status: 0 commit succeeded, 1 running, 2 prepare to pause, 3 pause, 4 prepare to stop, 5 stop, 6 fail, 7 succeed, 8 need fault tolerance, 9 kill, 10 wait for thread, 11 wait for dependency to complete',
+ `submit_time` datetime DEFAULT NULL COMMENT 'trigger submit time',
+ `start_time` datetime DEFAULT NULL COMMENT 'trigger start time',
+ `end_time` datetime DEFAULT NULL COMMENT 'trigger end time',
+ `trigger_params` longtext COMMENT 'job custom parameters',
+ PRIMARY KEY (`id`),
+ KEY `process_instance_id` (`process_instance_id`) USING BTREE,
+ KEY `idx_code_version` (`task_code`, `task_definition_version`) USING BTREE,
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE = utf8_bin;
+
+-- ----------------------------
+-- Records of t_ds_trigger_instance
+-- ----------------------------
+
-- ----------------------------
-- Table structure for t_ds_tenant
-- ----------------------------
diff --git a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql
index d314c6ef09..f955dfd9de 100644
--- a/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql
+++ b/dolphinscheduler-dao/src/main/resources/sql/dolphinscheduler_postgresql.sql
@@ -419,6 +419,61 @@ CREATE TABLE t_ds_task_definition (
create index task_definition_index on t_ds_task_definition (project_code,id);
+--
+-- Table structure for table t_ds_trigger_offset
+--
+
+DROP TABLE IF EXISTS t_ds_trigger_offset;
+CREATE TABLE t_ds_trigger_offset (
+ id int NOT NULL ,
+ code bigint NOT NULL,
+ PRIMARY KEY (id)
+) ;
+
+--
+-- Table structure for table t_ds_trigger_definition
+--
+
+DROP TABLE IF EXISTS t_ds_trigger_definition;
+CREATE TABLE t_ds_trigger_definition (
+ id int NOT NULL ,
+ code bigint NOT NULL,
+ name varchar(255) DEFAULT NULL ,
+ description text ,
+ project_code bigint DEFAULT NULL ,
+ user_id int DEFAULT NULL ,
+ trigger_type varchar(50) DEFAULT NULL ,
+ trigger_params text ,
+ create_time timestamp DEFAULT NULL ,
+ update_time timestamp DEFAULT NULL ,
+ PRIMARY KEY (id)
+) ;
+
+create index trigger_definition_index on t_ds_trigger_definition (project_code,id);
+
+--
+-- Table structure for table t_ds_trigger_instance
+--
+
+DROP TABLE IF EXISTS t_ds_trigger_instance;
+CREATE TABLE t_ds_trigger_instance (
+ id int NOT NULL ,
+ name varchar(255) DEFAULT NULL ,
+ trigger_type varchar(50) DEFAULT NULL ,
+ trigger_code bigint NOT NULL,
+ process_instance_id int DEFAULT NULL ,
+ process_instance_name varchar(255) DEFAULT NULL,
+ project_code bigint DEFAULT NULL,
+ state int DEFAULT NULL ,
+ submit_time timestamp DEFAULT NULL ,
+ start_time timestamp DEFAULT NULL ,
+ end_time timestamp DEFAULT NULL ,
+ trigger_params text ,
+ PRIMARY KEY (id)
+) ;
+
+create index idx_trigger_instance_code_version on t_ds_trigger_instance (task_code, task_definition_version);
+
--
-- Table structure for table t_ds_task_definition_log
--
@@ -838,6 +893,8 @@ CREATE TABLE t_ds_task_instance (
create index idx_task_instance_code_version on t_ds_task_instance (task_code, task_definition_version);
create index idx_cache_key on t_ds_task_instance (cache_key);
+
+
--
-- Table structure for table t_ds_tenant
--
diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapperTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapperTest.java
new file mode 100644
index 0000000000..99e3dec47f
--- /dev/null
+++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerDefinitionMapperTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+package org.apache.dolphinscheduler.dao.mapper;
+
+import java.util.Date;
+
+import org.apache.dolphinscheduler.dao.BaseDaoTest;
+import org.apache.dolphinscheduler.dao.entity.TaskDefinition;
+import org.apache.dolphinscheduler.dao.entity.TriggerDefinition;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class TriggerDefinitionMapperTest extends BaseDaoTest {
+ @Autowired
+ private TriggerDefinitionMapper triggerDefinitionMapper;
+
+ public TriggerDefinition insertOne() {
+ return insertOne(99);
+ }
+
+ public TriggerDefinition insertOne(int userId) {
+ TriggerDefinition triggerDefinition = new TriggerDefinition();
+ triggerDefinition.setCode(888888L);
+ triggerDefinition.setName("unit-test");
+ triggerDefinition.setProjectCode(1L);
+ triggerDefinition.setUserId(userId);
+ triggerDefinition.setCreateTime(new Date());
+ triggerDefinition.setUpdateTime(new Date());
+ triggerDefinition.setTriggerType("unit-test");
+ triggerDefinitionMapper.insert(triggerDefinition);
+ return triggerDefinition;
+ }
+
+ @Test
+ public void testInsert() {
+ TriggerDefinition triggerDefinition = insertOne();
+ Assertions.assertNotEquals(0, triggerDefinition.getId().intValue());
+ }
+}
diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerInstanceMapperTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerInstanceMapperTest.java
new file mode 100644
index 0000000000..28cfb9cfdd
--- /dev/null
+++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerInstanceMapperTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.dao.mapper;
+
+import java.util.Date;
+
+import org.apache.dolphinscheduler.common.enums.WorkflowExecutionStatus;
+import org.apache.dolphinscheduler.dao.BaseDaoTest;
+import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
+import org.apache.dolphinscheduler.dao.entity.TriggerInstance;
+import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class TriggerInstanceMapperTest extends BaseDaoTest {
+
+ @Autowired
+ private ProcessDefinitionMapper processDefinitionMapper;
+
+ @Autowired
+ private ProcessInstanceMapper processInstanceMapper;
+
+ @Autowired
+ private TriggerInstanceMapper triggerInstanceMapper;
+
+ /**
+ * insert
+ *
+ * @return ProcessInstance
+ */
+ private ProcessInstance insertProcessInstance() {
+ ProcessInstance processInstance = new ProcessInstance();
+ processInstance.setId(1);
+ processInstance.setName("taskName");
+ processInstance.setState(WorkflowExecutionStatus.RUNNING_EXECUTION);
+ processInstance.setStartTime(new Date());
+ processInstance.setEndTime(new Date());
+ processInstance.setProcessDefinitionCode(1L);
+ processInstance.setProjectCode(1L);
+ processInstance.setTestFlag(0);
+ processInstanceMapper.insert(processInstance);
+ return processInstance;
+ }
+
+ /**
+ * construct a task instance and then insert
+ */
+ private TriggerInstance insertTriggerInstance(int processInstanceId) {
+ TriggerInstance taskInstance = new TriggerInstance();
+ taskInstance.setName("us task");
+ taskInstance.setState(TaskExecutionStatus.RUNNING_EXECUTION);
+ taskInstance.setStartTime(new Date());
+ taskInstance.setEndTime(new Date());
+ taskInstance.setTriggerType("asd");
+ taskInstance.setProcessInstanceId(processInstanceId);
+ taskInstance.setProjectCode(1L);
+ triggerInstanceMapper.insert(taskInstance);
+ return taskInstance;
+ }
+
+ /**
+ * test update
+ */
+ @Test
+ public void testUpdate() {
+ // insert ProcessInstance
+ ProcessInstance processInstance = insertProcessInstance();
+
+ // insert taskInstance
+ TriggerInstance triggerInstance = insertTriggerInstance(processInstance.getId());
+ }
+}
diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerOffsetMapperTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerOffsetMapperTest.java
new file mode 100644
index 0000000000..88c2f13881
--- /dev/null
+++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/TriggerOffsetMapperTest.java
@@ -0,0 +1,31 @@
+package org.apache.dolphinscheduler.dao.mapper;
+
+import org.apache.dolphinscheduler.dao.BaseDaoTest;
+import org.apache.dolphinscheduler.dao.entity.TriggerOffset;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
+
+public class TriggerOffsetMapperTest extends BaseDaoTest {
+ @Autowired
+ private TriggerOffsetMapper triggerOffsetMapper;
+
+ public TriggerOffset insertOne() {
+ return insertOne(99);
+ }
+
+ public TriggerOffset insertOne(int userId) {
+ TriggerOffset triggerOffset = new TriggerOffset();
+ triggerOffset.setId(1);
+ triggerOffset.setCode(888888L);
+ return triggerOffset;
+ }
+
+ @Test
+ public void testInsert() {
+ TriggerOffset triggerDefinition = insertOne();
+ Assertions.assertNotEquals(0, triggerDefinition.getId().intValue());
+ }
+}
diff --git a/dolphinscheduler-master/pom.xml b/dolphinscheduler-master/pom.xml
index 1b99dd97f3..7eb9de4ef7 100644
--- a/dolphinscheduler-master/pom.xml
+++ b/dolphinscheduler-master/pom.xml
@@ -69,6 +69,11 @@
dolphinscheduler-task-all
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-all
+
+
org.apache.dolphinscheduler
dolphinscheduler-storage-all
diff --git a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java
index 9b507500b9..14ae216872 100644
--- a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java
+++ b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java
@@ -29,6 +29,7 @@ import org.apache.dolphinscheduler.meter.metrics.SystemMetrics;
import org.apache.dolphinscheduler.plugin.datasource.api.plugin.DataSourceProcessorProvider;
import org.apache.dolphinscheduler.plugin.storage.api.StorageConfiguration;
import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerPluginManager;
import org.apache.dolphinscheduler.registry.api.RegistryConfiguration;
import org.apache.dolphinscheduler.scheduler.api.SchedulerApi;
import org.apache.dolphinscheduler.server.master.metrics.MasterServerMetrics;
@@ -38,6 +39,7 @@ import org.apache.dolphinscheduler.server.master.rpc.MasterRpcServer;
import org.apache.dolphinscheduler.server.master.runner.EventExecuteService;
import org.apache.dolphinscheduler.server.master.runner.FailoverExecuteThread;
import org.apache.dolphinscheduler.server.master.runner.MasterSchedulerBootstrap;
+import org.apache.dolphinscheduler.server.master.runner.MasterTriggerBootstrap;
import org.apache.dolphinscheduler.server.master.runner.taskgroup.TaskGroupCoordinator;
import org.apache.dolphinscheduler.service.ServiceConfiguration;
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
@@ -70,6 +72,9 @@ public class MasterServer implements IStoppable {
@Autowired
private MasterSchedulerBootstrap masterSchedulerBootstrap;
+ @Autowired
+ private MasterTriggerBootstrap masterTriggerBootstrap;
+
@Autowired
private SchedulerApi schedulerApi;
@@ -109,6 +114,7 @@ public class MasterServer implements IStoppable {
// install task plugin
TaskPluginManager.loadPlugin();
+ TriggerPluginManager.loadPlugin();
DataSourceProcessorProvider.initialize();
this.masterSlotManager.start();
@@ -119,6 +125,8 @@ public class MasterServer implements IStoppable {
this.masterSchedulerBootstrap.start();
+ this.masterTriggerBootstrap.start();
+
this.eventExecuteService.start();
this.failoverExecuteThread.start();
@@ -162,6 +170,7 @@ public class MasterServer implements IStoppable {
try (
SchedulerApi closedSchedulerApi = schedulerApi;
MasterSchedulerBootstrap closedSchedulerBootstrap = masterSchedulerBootstrap;
+ MasterTriggerBootstrap closedTriggerBootstrap = masterTriggerBootstrap;
MasterRpcServer closedRpcServer = masterRPCServer;
MasterRegistryClient closedMasterRegistryClient = masterRegistryClient;
// close spring Context and will invoke method with @PreDestroy annotation to destroy beans.
diff --git a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/MasterTriggerBootstrap.java b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/MasterTriggerBootstrap.java
new file mode 100644
index 0000000000..297cb3c4fe
--- /dev/null
+++ b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/MasterTriggerBootstrap.java
@@ -0,0 +1,151 @@
+package org.apache.dolphinscheduler.server.master.runner;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.dolphinscheduler.common.constants.Constants;
+import org.apache.dolphinscheduler.common.lifecycle.ServerLifeCycleManager;
+import org.apache.dolphinscheduler.common.thread.BaseDaemonThread;
+import org.apache.dolphinscheduler.common.thread.ThreadUtils;
+import org.apache.dolphinscheduler.dao.entity.Command;
+import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
+import org.apache.dolphinscheduler.meter.metrics.MetricsProvider;
+import org.apache.dolphinscheduler.meter.metrics.SystemMetrics;
+import org.apache.dolphinscheduler.server.master.cache.ProcessInstanceExecCacheManager;
+import org.apache.dolphinscheduler.server.master.command.ICommandFetcher;
+import org.apache.dolphinscheduler.server.master.config.MasterConfig;
+import org.apache.dolphinscheduler.server.master.config.MasterServerLoadProtection;
+import org.apache.dolphinscheduler.server.master.event.WorkflowEvent;
+import org.apache.dolphinscheduler.server.master.event.WorkflowEventQueue;
+import org.apache.dolphinscheduler.server.master.event.WorkflowEventType;
+import org.apache.dolphinscheduler.server.master.exception.WorkflowCreateException;
+import org.apache.dolphinscheduler.server.master.metrics.MasterServerMetrics;
+import org.apache.dolphinscheduler.service.command.CommandService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@Slf4j
+public class MasterTriggerBootstrap extends BaseDaemonThread implements AutoCloseable {
+
+ @Autowired
+ private ICommandFetcher commandFetcher;
+
+ @Autowired
+ private CommandService commandService;
+
+ @Autowired
+ private MasterConfig masterConfig;
+
+ @Autowired
+ private ProcessInstanceExecCacheManager processInstanceExecCacheManager;
+
+ @Autowired
+ private WorkflowExecuteRunnableFactory workflowExecuteRunnableFactory;
+
+ @Autowired
+ private WorkflowEventQueue workflowEventQueue;
+
+ @Autowired
+ private WorkflowEventLooper workflowEventLooper;
+
+ @Autowired
+ private MasterTaskExecutorBootstrap masterTaskExecutorBootstrap;
+
+ @Autowired
+ private MetricsProvider metricsProvider;
+
+ protected MasterTriggerBootstrap() {
+ super("MasterTriggerBootstrap");
+ }
+
+ @Override
+ public synchronized void start() {
+ log.info("MasterTriggerBootstrap starting..");
+ super.start();
+// workflowEventLooper.start();
+// masterTaskExecutorBootstrap.start();
+ log.info("MasterTriggerBootstrap started...");
+ }
+
+ @Override
+ public void close() throws Exception {
+ log.info("MasterTriggerBootstrap stopping...");
+// try (
+// final WorkflowEventLooper workflowEventLooper1 = workflowEventLooper;
+// final MasterTaskExecutorBootstrap masterTaskExecutorBootstrap1 = masterTaskExecutorBootstrap) {
+// // closed the resource
+// }
+ log.info("MasterTriggerBootstrap stopped...");
+ }
+
+ @Override
+ public void run() {
+ MasterServerLoadProtection serverLoadProtection = masterConfig.getServerLoadProtection();
+ while (!ServerLifeCycleManager.isStopped()) {
+ try {
+ if (!ServerLifeCycleManager.isRunning()) {
+ // the current server is not at running status, cannot consume command.
+ log.warn("The current server is not at running status, cannot consumes commands.");
+ Thread.sleep(Constants.SLEEP_TIME_MILLIS);
+ }
+
+ // todo: if the workflow event queue is much, we need to handle the back pressure
+ SystemMetrics systemMetrics = metricsProvider.getSystemMetrics();
+ if (serverLoadProtection.isOverload(systemMetrics)) {
+ log.warn("The current server is overload, cannot consumes commands.");
+ MasterServerMetrics.incMasterOverload();
+ Thread.sleep(Constants.SLEEP_TIME_MILLIS);
+ continue;
+ }
+
+
+ List commands = commandFetcher.fetchCommands();
+ if (CollectionUtils.isEmpty(commands)) {
+ // indicate that no command ,sleep for 1s
+ Thread.sleep(Constants.SLEEP_TIME_MILLIS);
+ continue;
+ }
+//
+// commands.parallelStream()
+// .forEach(command -> {
+// try {
+// Optional workflowExecuteRunnableOptional =
+// workflowExecuteRunnableFactory.createWorkflowExecuteRunnable(command);
+// if (!workflowExecuteRunnableOptional.isPresent()) {
+// log.warn(
+// "The command execute success, will not trigger a WorkflowExecuteRunnable, this workflowInstance might be in serial mode");
+// return;
+// }
+// WorkflowExecuteRunnable workflowExecuteRunnable = workflowExecuteRunnableOptional.get();
+// ProcessInstance processInstance = workflowExecuteRunnable
+// .getWorkflowExecuteContext().getWorkflowInstance();
+// if (processInstanceExecCacheManager.contains(processInstance.getId())) {
+// log.error(
+// "The workflow instance is already been cached, this case shouldn't be happened");
+// }
+// processInstanceExecCacheManager.cache(processInstance.getId(), workflowExecuteRunnable);
+// workflowEventQueue.addEvent(
+// new WorkflowEvent(WorkflowEventType.START_WORKFLOW, processInstance.getId()));
+// } catch (WorkflowCreateException workflowCreateException) {
+// log.error("Master handle command {} error ", command.getId(), workflowCreateException);
+// commandService.moveToErrorCommand(command, workflowCreateException.toString());
+// }
+// });
+// MasterServerMetrics.incMasterConsumeCommand(commands.size());
+ } catch (InterruptedException interruptedException) {
+ log.warn("MasterTriggerBootstrap interrupted, close the loop", interruptedException);
+ Thread.currentThread().interrupt();
+ break;
+ } catch (Exception e) {
+ log.error("MasterTriggerBootstrap error", e);
+ // sleep for 1s here to avoid the database down cause the exception boom
+ ThreadUtils.sleep(Constants.SLEEP_TIME_MILLIS);
+ }
+ }
+ }
+
+}
+
diff --git a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/TriggerExecuteRunnable.java b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/TriggerExecuteRunnable.java
new file mode 100644
index 0000000000..0d372dd63c
--- /dev/null
+++ b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/TriggerExecuteRunnable.java
@@ -0,0 +1,139 @@
+package org.apache.dolphinscheduler.server.master.runner;
+
+import org.apache.dolphinscheduler.plugin.task.api.*;
+import org.apache.dolphinscheduler.plugin.task.api.log.TaskInstanceLogHeader;
+import org.apache.dolphinscheduler.plugin.task.api.utils.LogUtils;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerCallBack;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.annotation.Nullable;
+
+@Slf4j
+public abstract class TriggerExecuteRunnable implements Runnable {
+
+
+ protected @Nullable AbstractTask task;
+
+ protected TriggerExecuteRunnable() {
+ }
+
+ protected void executeTrigger(TriggerCallBack triggerCallBack) {
+ if (task == null) {
+ throw new IllegalArgumentException("The task plugin instance is not initialized");
+ }
+// task.handle(taskCallBack);
+ }
+
+ protected void afterExecute() throws TaskException {
+// if (task == null) {
+// throw new TaskException("The current task instance is null");
+// }
+// sendAlertIfNeeded();
+//
+// sendTaskResult();
+//
+// WorkerTaskExecutorHolder.remove(taskExecutionContext.getTaskInstanceId());
+// log.info("Remove the current task execute context from worker cache");
+// clearTaskExecPathIfNeeded();
+ }
+
+ protected void afterThrowing(Throwable throwable) throws TaskException {
+// if (cancelTask()) {
+// log.info("Cancel the task successfully");
+// }
+// WorkerTaskExecutorHolder.remove(taskExecutionContext.getTaskInstanceId());
+// taskExecutionContext.setCurrentExecutionStatus(TaskExecutionStatus.FAILURE);
+// taskExecutionContext.setEndTime(System.currentTimeMillis());
+// workerMessageSender.sendMessageWithRetry(taskExecutionContext,
+// ITaskInstanceExecutionEvent.TaskInstanceExecutionEventType.FINISH);
+// log.info("Get a exception when execute the task, will send the task status: {} to master: {}",
+// TaskExecutionStatus.FAILURE.name(), taskExecutionContext.getHost());
+
+ }
+
+ protected boolean cancelTask() {
+ // cancel the task
+ if (task == null) {
+ return true;
+ }
+ try {
+ task.cancel();
+// ProcessUtils.cancelApplication(taskExecutionContext);
+ return true;
+ } catch (Exception e) {
+ log.error("Cancel task failed, this will not affect the taskInstance status, but you need to check manual",
+ e);
+ return false;
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ TaskInstanceLogHeader.printInitializeTaskContextHeader();
+ initializeTask();
+
+ TaskInstanceLogHeader.printLoadTaskInstancePluginHeader();
+ beforeExecute();
+
+// TaskCallBack taskCallBack = TaskCallbackImpl.builder()
+// .workerMessageSender(workerMessageSender)
+// .taskExecutionContext(taskExecutionContext)
+// .build();
+
+ TaskInstanceLogHeader.printExecuteTaskHeader();
+// executeTrigger(taskCallBack);
+
+ TaskInstanceLogHeader.printFinalizeTaskHeader();
+ afterExecute();
+ closeLogAppender();
+ } catch (Throwable ex) {
+ log.error("Task execute failed, due to meet an exception", ex);
+ afterThrowing(ex);
+ closeLogAppender();
+ } finally {
+ LogUtils.removeWorkflowAndTaskInstanceIdMDC();
+ LogUtils.removeTaskInstanceLogFullPathMDC();
+ }
+ }
+
+ protected void initializeTask() {
+ log.info("Begin to initialize task");
+
+ long taskStartTime = System.currentTimeMillis();
+// taskExecutionContext.setStartTime(taskStartTime);
+ log.info("Set task startTime: {}", taskStartTime);
+
+// String taskAppId = String.format("%s_%s", taskExecutionContext.getProcessInstanceId(),
+// taskExecutionContext.getTaskInstanceId());
+// taskExecutionContext.setTaskAppId(taskAppId);
+// log.info("Set task appId: {}", taskAppId);
+
+// log.info("End initialize task {}", JSONUtils.toPrettyJsonString(taskExecutionContext));
+ }
+
+ protected void beforeExecute() {
+ }
+
+ protected void sendAlertIfNeeded() {
+
+ }
+
+ protected void sendTaskResult() {
+
+ }
+
+ protected void clearTaskExecPathIfNeeded() {
+
+ }
+
+ protected void closeLogAppender() {
+
+ }
+
+ public @Nullable AbstractTask getTask() {
+ return task;
+ }
+
+}
diff --git a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/TriggerExecuteThreadPool.java b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/TriggerExecuteThreadPool.java
new file mode 100644
index 0000000000..9cd5a678f1
--- /dev/null
+++ b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/runner/TriggerExecuteThreadPool.java
@@ -0,0 +1,58 @@
+package org.apache.dolphinscheduler.server.master.runner;
+
+import org.apache.dolphinscheduler.plugin.task.api.utils.LogUtils;
+import org.apache.dolphinscheduler.server.master.cache.ProcessInstanceExecCacheManager;
+import org.apache.dolphinscheduler.server.master.config.MasterConfig;
+import org.apache.dolphinscheduler.server.master.event.StateEvent;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.PostConstruct;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+import org.springframework.util.concurrent.ListenableFuture;
+import org.springframework.util.concurrent.ListenableFutureCallback;
+
+@Component
+@Slf4j
+public class TriggerExecuteThreadPool extends ThreadPoolTaskExecutor {
+
+ @Autowired
+ private MasterConfig masterConfig;
+
+ @PostConstruct
+ private void init() {
+ this.setDaemon(true);
+ this.setThreadNamePrefix("StreamTaskExecuteThread-");
+ this.setMaxPoolSize(masterConfig.getExecThreads());
+ this.setCorePoolSize(masterConfig.getExecThreads());
+ }
+
+ public void executeEvent(final TriggerExecuteRunnable triggerExecuteRunnable) {
+// if (!streamTaskExecuteRunnable.isStart() || streamTaskExecuteRunnable.eventSize() == 0) {
+// return;
+// }
+// int taskInstanceId = streamTaskExecuteRunnable.getTaskInstance().getId();
+// ListenableFuture> future = this.submitListenable(streamTaskExecuteRunnable::handleEvents);
+// future.addCallback(new ListenableFutureCallback() {
+//
+// @Override
+// public void onFailure(Throwable ex) {
+// LogUtils.setTaskInstanceIdMDC(taskInstanceId);
+// log.error("Stream task instance events handle failed", ex);
+// LogUtils.removeTaskInstanceIdMDC();
+// }
+//
+// @Override
+// public void onSuccess(Object result) {
+// LogUtils.setTaskInstanceIdMDC(taskInstanceId);
+// log.info("Stream task instance is finished.");
+// LogUtils.removeTaskInstanceIdMDC();
+// }
+// });
+ }
+}
diff --git a/dolphinscheduler-master/src/main/resources/application.yaml b/dolphinscheduler-master/src/main/resources/application.yaml
index 17b1e41a71..ea03bcde05 100644
--- a/dolphinscheduler-master/src/main/resources/application.yaml
+++ b/dolphinscheduler-master/src/main/resources/application.yaml
@@ -68,18 +68,16 @@ mybatis-plus:
registry:
- type: zookeeper
- zookeeper:
- namespace: dolphinscheduler
- connect-string: localhost:2181
- retry-policy:
- base-sleep-time: 60ms
- max-sleep: 300ms
- max-retries: 5
- session-timeout: 30s
- connection-timeout: 9s
- block-until-connected: 600ms
- digest: ~
+ type: jdbc
+ term-refresh-interval: 2s
+ term-expire-times: 3
+ hikari-config:
+ jdbc-url: jdbc:postgresql://localhost:5432/dolphinscheduler
+ username: root
+ password: root
+ maximum-pool-size: 5
+ connection-timeout: 9000
+ idle-timeout: 600000
master:
listen-port: 5678
diff --git a/dolphinscheduler-master/src/main/resources/logback-spring.xml b/dolphinscheduler-master/src/main/resources/logback-spring.xml
index efc5a513c6..e50f711a72 100644
--- a/dolphinscheduler-master/src/main/resources/logback-spring.xml
+++ b/dolphinscheduler-master/src/main/resources/logback-spring.xml
@@ -67,12 +67,8 @@
-
-
-
-
-
-
+
+
diff --git a/dolphinscheduler-service/pom.xml b/dolphinscheduler-service/pom.xml
index 0bca706c3b..d7fddd66a2 100644
--- a/dolphinscheduler-service/pom.xml
+++ b/dolphinscheduler-service/pom.xml
@@ -58,6 +58,10 @@
org.apache.dolphinscheduler
dolphinscheduler-task-api
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-api
+
org.apache.dolphinscheduler
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml b/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml
index 5e4c74b27a..9719960a60 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml
@@ -222,6 +222,11 @@
dolphinscheduler-task-remoteshell
${project.version}
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-task-trigger
+ ${project.version}
+
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java
index afc2edc586..1fec85f334 100644
--- a/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/shell/BaseLinuxShellInterceptorBuilder.java
@@ -48,6 +48,11 @@ public abstract class BaseLinuxShellInterceptorBuilder
+
+
+ 4.0.0
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-task-plugin
+ dev-SNAPSHOT
+
+
+ dolphinscheduler-task-trigger
+ jar
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-spi
+ provided
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-task-api
+ provided
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-common
+ provided
+
+
+
+
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerException.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerException.java
new file mode 100644
index 0000000000..189204023d
--- /dev/null
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerException.java
@@ -0,0 +1,18 @@
+package org.apache.dolphinscheduler.plugin.task.trigger;
+
+public class TriggerException extends RuntimeException {
+
+ private static final long serialVersionUID = 8155449302457294758L;
+
+ public TriggerException() {
+ super();
+ }
+
+ public TriggerException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ public TriggerException(String msg) {
+ super(msg);
+ }
+}
\ No newline at end of file
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerParameters.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerParameters.java
new file mode 100644
index 0000000000..187fd916c1
--- /dev/null
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerParameters.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.task.trigger;
+
+import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters;
+
+import org.apache.commons.lang3.StringUtils;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Setter
+@Getter
+@NoArgsConstructor
+@ToString
+public class TriggerParameters extends AbstractParameters {
+
+ private String factoryName;
+ private String resourceGroupName;
+ private String pipelineName;
+ private String runId;
+
+ @Override
+ public boolean checkParameters() {
+ return StringUtils.isNotEmpty(factoryName) && StringUtils.isNotEmpty(resourceGroupName)
+ && StringUtils.isNotEmpty(pipelineName);
+ }
+}
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerStatus.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerStatus.java
new file mode 100644
index 0000000000..1f58e945e2
--- /dev/null
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerStatus.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.task.trigger;
+
+public enum TriggerStatus {
+
+ Queued,
+ InProgress,
+ Succeeded,
+ Failed,
+ Canceling,
+ Cancelled,
+ ;
+
+ /**
+ * Gets the status property: The status of a pipeline run. Possible values: Queued, InProgress, Succeeded, Failed,
+ * Canceling, Cancelled.
+ *
+ * @return the status value.
+ */
+ TriggerStatus() {
+ }
+}
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTask.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTask.java
new file mode 100644
index 0000000000..f38f519d0a
--- /dev/null
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTask.java
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.task.trigger;
+
+import org.apache.dolphinscheduler.common.utils.JSONUtils;
+import org.apache.dolphinscheduler.plugin.task.api.AbstractRemoteTask;
+import org.apache.dolphinscheduler.plugin.task.api.TaskConstants;
+import org.apache.dolphinscheduler.plugin.task.api.TaskException;
+import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
+
+import java.util.Collections;
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@Setter
+@Getter
+@Slf4j
+public class TriggerTask extends AbstractRemoteTask {
+
+ private final TaskExecutionContext taskExecutionContext;
+ private TriggerParameters parameters;
+
+ public TriggerTask(TaskExecutionContext taskExecutionContext) {
+ super(taskExecutionContext);
+ this.taskExecutionContext = taskExecutionContext;
+ }
+
+ @Override
+ public List getApplicationIds() throws TaskException {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void init() {
+ parameters = JSONUtils.parseObject(taskExecutionContext.getTaskParams(), TriggerParameters.class);
+ log.info("Initialize Datafactory task params {}", JSONUtils.toPrettyJsonString(parameters));
+ }
+
+ @Override
+ public void submitApplication() throws TaskException {
+ try {
+ // start task
+ exitStatusCode = startDatafactoryTask();
+ setExitStatusCode(exitStatusCode);
+ } catch (Exception e) {
+ setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE);
+ throw new TaskException("data factory start task error", e);
+ }
+ // set runId to the appIds if start success
+ setAppIds(parameters.getRunId());
+ }
+
+ @Override
+ public void cancelApplication() throws TaskException {
+ checkApplicationId();
+ exitStatusCode = TaskConstants.EXIT_CODE_KILL;
+ }
+
+ @Override
+ public void trackApplicationStatus() throws TaskException {
+ checkApplicationId();
+ Boolean isFinishedSuccessfully = false;
+ if (!isFinishedSuccessfully) {
+ exitStatusCode = TaskConstants.EXIT_CODE_FAILURE;
+ } else {
+ exitStatusCode = TaskConstants.EXIT_CODE_SUCCESS;
+ }
+ }
+
+ /**
+ * check datafactory applicationId or get it from appId
+ */
+ private void checkApplicationId() {
+ }
+
+ public int startDatafactoryTask() {
+ return 0;
+ }
+
+ @Override
+ public TriggerParameters getParameters() {
+ return parameters;
+ }
+
+}
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskChannel.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskChannel.java
new file mode 100644
index 0000000000..3abcf68f8c
--- /dev/null
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskChannel.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.task.trigger;
+
+import org.apache.dolphinscheduler.common.utils.JSONUtils;
+import org.apache.dolphinscheduler.plugin.task.api.TaskChannel;
+import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
+import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters;
+import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode;
+import org.apache.dolphinscheduler.plugin.task.api.parameters.resource.ResourceParametersHelper;
+
+public class TriggerTaskChannel implements TaskChannel {
+
+ @Override
+ public void cancelApplication(boolean status) {
+ }
+
+ @Override
+ public TriggerTask createTask(TaskExecutionContext taskRequest) {
+ return new TriggerTask(taskRequest);
+ }
+
+ @Override
+ public AbstractParameters parseParameters(ParametersNode parametersNode) {
+ return JSONUtils.parseObject(parametersNode.getTaskParams(), TriggerParameters.class);
+ }
+
+ @Override
+ public ResourceParametersHelper getResources(String parameters) {
+ return null;
+ }
+}
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskChannelFactory.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskChannelFactory.java
new file mode 100644
index 0000000000..e95d6825f5
--- /dev/null
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/main/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskChannelFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.task.trigger;
+
+import org.apache.dolphinscheduler.plugin.task.api.TaskChannel;
+import org.apache.dolphinscheduler.plugin.task.api.TaskChannelFactory;
+import org.apache.dolphinscheduler.spi.params.base.PluginParams;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(TaskChannelFactory.class)
+public class TriggerTaskChannelFactory implements TaskChannelFactory {
+
+ @Override
+ public TaskChannel create() {
+ return new TriggerTaskChannel();
+ }
+
+ @Override
+ public String getName() {
+ return "TRIGGER";
+ }
+
+ @Override
+ public List getParams() {
+ return Collections.emptyList();
+ }
+}
diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/test/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskTest.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/test/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskTest.java
new file mode 100644
index 0000000000..7405663f34
--- /dev/null
+++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-trigger/src/test/java/org/apache/dolphinscheduler/plugin/task/trigger/TriggerTaskTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.task.trigger;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class TriggerTaskTest {
+
+
+}
diff --git a/dolphinscheduler-task-plugin/pom.xml b/dolphinscheduler-task-plugin/pom.xml
index f4c1573226..92c420425a 100644
--- a/dolphinscheduler-task-plugin/pom.xml
+++ b/dolphinscheduler-task-plugin/pom.xml
@@ -63,6 +63,7 @@
dolphinscheduler-task-linkis
dolphinscheduler-task-datafactory
dolphinscheduler-task-remoteshell
+ dolphinscheduler-task-trigger
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-all/pom.xml b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-all/pom.xml
new file mode 100644
index 0000000000..872d66eab0
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-all/pom.xml
@@ -0,0 +1,22 @@
+
+
+ 4.0.0
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-plugin
+ dev-SNAPSHOT
+
+
+ dolphinscheduler-trigger-all
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-simple
+ ${project.version}
+
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/pom.xml b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/pom.xml
new file mode 100644
index 0000000000..66425496fd
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/pom.xml
@@ -0,0 +1,29 @@
+
+
+ 4.0.0
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-plugin
+ dev-SNAPSHOT
+
+
+ dolphinscheduler-trigger-api
+ jar
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-common
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-spi
+
+
+ com.baomidou
+ mybatis-plus-annotation
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/AbstractTrigger.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/AbstractTrigger.java
new file mode 100644
index 0000000000..d64ff8819d
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/AbstractTrigger.java
@@ -0,0 +1,45 @@
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dolphinscheduler.plugin.trigger.api.enums.TriggerExecutionStatus;
+import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
+
+import java.util.Map;
+import java.util.StringJoiner;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Slf4j
+public abstract class AbstractTrigger {
+ @Getter
+ @Setter
+ protected Map taskOutputParams;
+
+ /**
+ * taskExecutionContext
+ **/
+ protected TriggerExecutionContext triggerExecutionContext;
+
+ protected AbstractTrigger(TriggerExecutionContext triggerExecutionContext) {
+ this.triggerExecutionContext = triggerExecutionContext;
+ }
+
+ public void init() {
+ }
+
+ public abstract void handle(TriggerCallBack taskCallBack) throws TriggerException;
+
+ public abstract void cancel() throws TriggerException;
+
+ /**
+ * get task parameters
+ *
+ * @return AbstractParameters
+ */
+ public abstract AbstractParameters getParameters();
+
+
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerCallBack.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerCallBack.java
new file mode 100644
index 0000000000..02083da772
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerCallBack.java
@@ -0,0 +1,4 @@
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+public interface TriggerCallBack {
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerChannel.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerChannel.java
new file mode 100644
index 0000000000..d1fb616705
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerChannel.java
@@ -0,0 +1,7 @@
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+public interface TriggerChannel {
+ void cancelApplication(boolean status);
+
+ AbstractTrigger createTrigger(TriggerExecutionContext taskRequest);
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerChannelFactory.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerChannelFactory.java
new file mode 100644
index 0000000000..365d16df97
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerChannelFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+import org.apache.dolphinscheduler.spi.common.UiChannelFactory;
+import org.apache.dolphinscheduler.spi.plugin.PrioritySPI;
+import org.apache.dolphinscheduler.spi.plugin.SPIIdentify;
+
+public interface TriggerChannelFactory extends UiChannelFactory, PrioritySPI {
+
+ TriggerChannel create();
+
+ default SPIIdentify getIdentify() {
+ return SPIIdentify.builder().name(getName()).build();
+ }
+
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerConstants.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerConstants.java
new file mode 100644
index 0000000000..aea0bd7d25
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerConstants.java
@@ -0,0 +1,425 @@
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+import com.google.common.collect.Sets;
+import org.apache.dolphinscheduler.common.constants.DateConstants;
+
+import java.time.Duration;
+import java.util.Set;
+
+public class TriggerConstants {
+
+ private TriggerConstants() {
+ throw new IllegalStateException("Utility class");
+ }
+
+ public static final String YARN_APPLICATION_REGEX = "application_\\d+_\\d+";
+
+ public static final String FLINK_APPLICATION_REGEX = "JobID \\w+";
+
+ /**
+ * exit code kill
+ */
+ public static final int EXIT_CODE_KILL = 137;
+ public static final String PID = "pid";
+
+ /**
+ * QUESTION ?
+ */
+ public static final String QUESTION = "?";
+
+ /**
+ * comma ,
+ */
+ public static final String COMMA = ",";
+
+ /**
+ * hyphen
+ */
+ public static final String HYPHEN = "-";
+
+ /**
+ * slash /
+ */
+ public static final String SLASH = "/";
+
+ /**
+ * COLON :
+ */
+ public static final String COLON = ":";
+
+ /**
+ * SPACE " "
+ */
+ public static final String SPACE = " ";
+
+ /**
+ * SINGLE_SLASH /
+ */
+ public static final String SINGLE_SLASH = "/";
+
+ /**
+ * DOUBLE_SLASH //
+ */
+ public static final String DOUBLE_SLASH = "//";
+
+ /**
+ * SINGLE_QUOTES "'"
+ */
+ public static final String SINGLE_QUOTES = "'";
+ /**
+ * DOUBLE_QUOTES "\""
+ */
+ public static final String DOUBLE_QUOTES = "\"";
+
+ /**
+ * SEMICOLON ;
+ */
+ public static final String SEMICOLON = ";";
+
+ /**
+ * EQUAL SIGN
+ */
+ public static final String EQUAL_SIGN = "=";
+ /**
+ * AT SIGN
+ */
+ public static final String AT_SIGN = "@";
+ /**
+ * UNDERLINE
+ */
+ public static final String UNDERLINE = "_";
+
+ /**
+ * sleep time
+ */
+ public static final int SLEEP_TIME_MILLIS = 1000;
+
+ /**
+ * exit code failure
+ */
+ public static final int EXIT_CODE_FAILURE = -1;
+
+ /**
+ * exit code success
+ */
+ public static final int EXIT_CODE_SUCCESS = 0;
+ /**
+ * running code
+ */
+ public static final int RUNNING_CODE = 1;
+
+ public static final String SH = "sh";
+
+ /**
+ * log flush interval?output when reach the interval
+ */
+ public static final int DEFAULT_LOG_FLUSH_INTERVAL = 1000;
+
+ /**
+ * pstree, get pud and sub pid
+ */
+ public static final String PSTREE = "pstree";
+
+ public static final String RWXR_XR_X = "rwxr-xr-x";
+
+ /**
+ * date format of yyyyMMddHHmmss
+ */
+ public static final String PARAMETER_FORMAT_TIME = "yyyyMMddHHmmss";
+
+ /**
+ * new
+ * schedule time
+ */
+ public static final String PARAMETER_SHECDULE_TIME = "schedule.time";
+
+ /**
+ * system date(yyyyMMddHHmmss)
+ */
+ public static final String PARAMETER_DATETIME = DateConstants.PARAMETER_DATETIME;
+
+ /**
+ * system date(yyyymmdd) today
+ */
+ public static final String PARAMETER_CURRENT_DATE = DateConstants.PARAMETER_CURRENT_DATE;
+
+ /**
+ * system date(yyyymmdd) yesterday
+ */
+ public static final String PARAMETER_BUSINESS_DATE = DateConstants.PARAMETER_BUSINESS_DATE;
+
+ /**
+ * the absolute path of current executing task
+ */
+ public static final String PARAMETER_TASK_EXECUTE_PATH = "system.task.execute.path";
+
+ /**
+ * the instance id of current task
+ */
+ public static final String PARAMETER_TASK_INSTANCE_ID = "system.task.instance.id";
+
+ /**
+ * the definition code of current task
+ */
+ public static final String PARAMETER_TASK_DEFINITION_CODE = "system.task.definition.code";
+
+ /**
+ * the definition name of current task
+ */
+ public static final String PARAMETER_TASK_DEFINITION_NAME = "system.task.definition.name";
+
+ /**
+ * the instance id of the workflow to which current task belongs
+ */
+ public static final String PARAMETER_WORKFLOW_INSTANCE_ID = "system.workflow.instance.id";
+
+ /**
+ * the definition code of the workflow to which current task belongs
+ */
+ public static final String PARAMETER_WORKFLOW_DEFINITION_CODE = "system.workflow.definition.code";
+
+ /**
+ * the definition name of the workflow to which current task belongs
+ */
+ public static final String PARAMETER_WORKFLOW_DEFINITION_NAME = "system.workflow.definition.name";
+
+ /**
+ * the code of the project to which current task belongs
+ */
+ public static final String PARAMETER_PROJECT_CODE = "system.project.code";
+
+ /**
+ * the name of the project to which current task belongs
+ */
+ public static final String PARAMETER_PROJECT_NAME = "system.project.name";
+ /**
+ * month_begin
+ */
+ public static final String MONTH_BEGIN = "month_begin";
+ /**
+ * add_months
+ */
+ public static final String ADD_MONTHS = "add_months";
+ /**
+ * month_end
+ */
+ public static final String MONTH_END = "month_end";
+ /**
+ * week_begin
+ */
+ public static final String WEEK_BEGIN = "week_begin";
+ /**
+ * week_end
+ */
+ public static final String WEEK_END = "week_end";
+ /**
+ * this_day
+ */
+ public static final String THIS_DAY = "this_day";
+ /**
+ * last_day
+ */
+ public static final String LAST_DAY = "last_day";
+
+ /**
+ * month_first_day
+ */
+ public static final String MONTH_FIRST_DAY = "month_first_day";
+
+ /**
+ * month_last_day
+ */
+ public static final String MONTH_LAST_DAY = "month_last_day";
+
+ /**
+ * week_first_day
+ */
+ public static final String WEEK_FIRST_DAY = "week_first_day";
+
+ /**
+ * week_last_day
+ */
+ public static final String WEEK_LAST_DAY = "week_last_day";
+
+ /**
+ * year_week
+ */
+ public static final String YEAR_WEEK = "year_week";
+ /**
+ * timestamp
+ */
+ public static final String TIMESTAMP = "timestamp";
+ public static final char SUBTRACT_CHAR = '-';
+ public static final char ADD_CHAR = '+';
+ public static final char MULTIPLY_CHAR = '*';
+ public static final char DIVISION_CHAR = '/';
+ public static final char LEFT_BRACE_CHAR = '(';
+ public static final char RIGHT_BRACE_CHAR = ')';
+ public static final String ADD_STRING = "+";
+ public static final String MULTIPLY_STRING = "*";
+ public static final String DIVISION_STRING = "/";
+ public static final String LEFT_BRACE_STRING = "(";
+ public static final char P = 'P';
+ public static final char N = 'N';
+ public static final String SUBTRACT_STRING = "-";
+ public static final String LOCAL_PARAMS_LIST = "localParamsList";
+ public static final String TASK_TYPE = "taskType";
+ public static final String QUEUE = "queue";
+ /**
+ * default display rows
+ */
+ public static final int DEFAULT_DISPLAY_ROWS = 10;
+
+ /**
+ * jar
+ */
+ public static final String JAR = "jar";
+
+ /**
+ * hadoop
+ */
+ public static final String HADOOP = "hadoop";
+
+ /**
+ * -D =
+ */
+ public static final String D = "-D";
+
+ /**
+ * datasource encryption salt
+ */
+ public static final String DATASOURCE_ENCRYPTION_SALT_DEFAULT = "!@#$%^&*";
+ public static final String DATASOURCE_ENCRYPTION_ENABLE = "datasource.encryption.enable";
+ public static final String DATASOURCE_ENCRYPTION_SALT = "datasource.encryption.salt";
+
+ /**
+ * kerberos
+ */
+ public static final String KERBEROS = "kerberos";
+
+ /**
+ * kerberos expire time
+ */
+ public static final String KERBEROS_EXPIRE_TIME = "kerberos.expire.time";
+
+ /**
+ * java.security.krb5.conf
+ */
+ public static final String JAVA_SECURITY_KRB5_CONF = "java.security.krb5.conf";
+
+ /**
+ * java.security.krb5.conf.path
+ */
+ public static final String JAVA_SECURITY_KRB5_CONF_PATH = "java.security.krb5.conf.path";
+
+ /**
+ * loginUserFromKeytab user
+ */
+ public static final String LOGIN_USER_KEY_TAB_USERNAME = "login.user.keytab.username";
+
+ /**
+ * loginUserFromKeytab path
+ */
+ public static final String LOGIN_USER_KEY_TAB_PATH = "login.user.keytab.path";
+
+ /**
+ * hadoop.security.authentication
+ */
+ public static final String HADOOP_SECURITY_AUTHENTICATION = "hadoop.security.authentication";
+
+ /**
+ * hadoop.security.authentication
+ */
+ public static final String HADOOP_SECURITY_AUTHENTICATION_STARTUP_STATE =
+ "hadoop.security.authentication.startup.state";
+
+ /**
+ * hdfs/s3 configuration
+ * resource.storage.upload.base.path
+ */
+ public static final String RESOURCE_UPLOAD_PATH = "resource.storage.upload.base.path";
+
+ /**
+ * data.quality.jar.dir
+ */
+ public static final String DATA_QUALITY_JAR_DIR = "data-quality.jar.dir";
+
+ public static final String TASK_TYPE_CONDITIONS = "CONDITIONS";
+
+ public static final String TASK_TYPE_SWITCH = "SWITCH";
+
+ public static final String TASK_TYPE_SUB_PROCESS = "SUB_PROCESS";
+
+ public static final String TASK_TYPE_DYNAMIC = "DYNAMIC";
+
+ public static final String TASK_TYPE_DEPENDENT = "DEPENDENT";
+
+ public static final String TASK_TYPE_SQL = "SQL";
+
+ public static final String TASK_TYPE_DATA_QUALITY = "DATA_QUALITY";
+
+ public static final Set TASK_TYPE_SET_K8S = Sets.newHashSet("K8S", "KUBEFLOW");
+
+ public static final String TASK_TYPE_BLOCKING = "BLOCKING";
+
+ /**
+ * azure config
+ */
+ public static final String AZURE_CLIENT_ID = "resource.azure.client.id";
+ public static final String AZURE_CLIENT_SECRET = "resource.azure.client.secret";
+ public static final String AZURE_ACCESS_SUB_ID = "resource.azure.subId";
+ public static final String AZURE_SECRET_TENANT_ID = "resource.azure.tenant.id";
+ public static final String QUERY_INTERVAL = "resource.query.interval";
+
+ /**
+ * aws config
+ */
+ public static final String AWS_ACCESS_KEY_ID = "resource.aws.access.key.id";
+ public static final String AWS_SECRET_ACCESS_KEY = "resource.aws.secret.access.key";
+ public static final String AWS_REGION = "resource.aws.region";
+
+ /**
+ * alibaba cloud config
+ */
+ public static final String ALIBABA_CLOUD_ACCESS_KEY_ID = "resource.alibaba.cloud.access.key.id";
+ public static final String ALIBABA_CLOUD_ACCESS_KEY_SECRET = "resource.alibaba.cloud.access.key.secret";
+ public static final String ALIBABA_CLOUD_REGION = "resource.alibaba.cloud.region";
+
+ /**
+ * huawei cloud config
+ */
+ public static final String HUAWEI_CLOUD_ACCESS_KEY_ID = "resource.huawei.cloud.access.key.id";
+ public static final String HUAWEI_CLOUD_ACCESS_KEY_SECRET = "resource.huawei.cloud.access.key.secret";
+
+ /**
+ * use for k8s task
+ */
+ public static final String API_VERSION = "batch/v1";
+ public static final String RESTART_POLICY = "Never";
+ public static final String MEMORY = "memory";
+ public static final String CPU = "cpu";
+ public static final String LAYER_LABEL = "k8s.cn/layer";
+ public static final String LAYER_LABEL_VALUE = "batch";
+ public static final String NAME_LABEL = "k8s.cn/name";
+ public static final String TASK_INSTANCE_ID = "taskInstanceId";
+ public static final String MI = "Mi";
+ public static final int JOB_TTL_SECONDS = 300;
+ public static final int LOG_LINES = 500;
+ public static final String NAMESPACE_NAME = "name";
+ public static final String CLUSTER = "cluster";
+
+ /**
+ * spark / flink on k8s label name
+ */
+ public static final String UNIQUE_LABEL_NAME = "dolphinscheduler-label";
+
+ /**
+ * conda config used by jupyter task plugin
+ */
+ public static final String CONDA_PATH = "conda.path";
+
+ // Loop task constants
+ public static final Duration DEFAULT_LOOP_STATUS_INTERVAL = Duration.ofSeconds(5L);
+
+}
+
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerException.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerException.java
new file mode 100644
index 0000000000..c41175e0c8
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerException.java
@@ -0,0 +1,18 @@
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+public class TriggerException extends RuntimeException {
+
+ private static final long serialVersionUID = 8155449302457294758L;
+
+ public TriggerException() {
+ super();
+ }
+
+ public TriggerException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ public TriggerException(String msg) {
+ super(msg);
+ }
+}
\ No newline at end of file
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerExecutionContext.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerExecutionContext.java
new file mode 100644
index 0000000000..c5793ec81a
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerExecutionContext.java
@@ -0,0 +1,128 @@
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * to master/worker task transport
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TriggerExecutionContext implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /**
+ * trigger id
+ */
+ private int triggerInstanceId;
+
+ /**
+ * trigger name
+ */
+ private String triggerName;
+
+ /**
+ * trigger first submit time.
+ */
+ private long firstSubmitTime;
+
+ /**
+ * trigger start time
+ */
+ private long startTime;
+
+ /**
+ * trigger type
+ */
+ private String triggerType;
+
+ /**
+ * trigger json
+ */
+ private String triggerJson;
+
+ /**
+ * processId
+ */
+ private int processId;
+
+ /**
+ * processCode
+ */
+ private Long processDefineCode;
+
+ /**
+ * processVersion
+ */
+ private int processDefineVersion;
+
+ /**
+ * appIds
+ */
+ private String appIds;
+
+ /**
+ * process instance id
+ */
+ private int processInstanceId;
+
+ /**
+ * process instance schedule time
+ */
+ private long scheduleTime;
+
+ /**
+ * process instance global parameters
+ */
+ private String globalParams;
+
+ /**
+ * execute user id
+ */
+ private int executorId;
+
+ /**
+ * command type if complement
+ */
+ private int cmdTypeIfComplement;
+
+ /**
+ * tenant code
+ */
+ private String tenantCode;
+
+ /**
+ * process define id
+ */
+ private int processDefineId;
+
+ /**
+ * project id
+ */
+ private int projectId;
+
+ /**
+ * project code
+ */
+ private long projectCode;
+
+ /**
+ * taskParams
+ */
+ private String taskParams;
+
+ /**
+ * environmentConfig
+ */
+ private String environmentConfig;
+}
+
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerPluginManager.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerPluginManager.java
new file mode 100644
index 0000000000..4891dced38
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/TriggerPluginManager.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.plugin.trigger.api;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dolphinscheduler.common.utils.JSONUtils;
+import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
+import org.apache.dolphinscheduler.plugin.trigger.api.parameters.ParametersNode;
+import org.apache.dolphinscheduler.spi.plugin.PrioritySPIFactory;
+
+@Slf4j
+public class TriggerPluginManager {
+ private static final Map taskChannelFactoryMap = new HashMap<>();
+ private static final Map taskChannelMap = new HashMap<>();
+
+ private static final AtomicBoolean loadedFlag = new AtomicBoolean(false);
+
+ /**
+ * Load task plugins from classpath.
+ */
+ public static void loadPlugin() {
+ if (!loadedFlag.compareAndSet(false, true)) {
+ log.warn("The trigger plugin has already been loaded");
+ return;
+ }
+ PrioritySPIFactory prioritySPIFactory = new PrioritySPIFactory<>(TriggerChannelFactory.class);
+ for (Map.Entry entry : prioritySPIFactory.getSPIMap().entrySet()) {
+ String factoryName = entry.getKey();
+ TriggerChannelFactory factory = entry.getValue();
+
+ log.info("Registering trigger plugin: {} - {}", factoryName, factory.getClass().getSimpleName());
+
+ taskChannelFactoryMap.put(factoryName, factory);
+ taskChannelMap.put(factoryName, factory.create());
+
+ log.info("Registered trigger plugin: {} - {}", factoryName, factory.getClass().getSimpleName());
+ }
+
+ }
+
+ public static Map getTaskChannelMap() {
+ return Collections.unmodifiableMap(taskChannelMap);
+ }
+
+ public static Map getTaskChannelFactoryMap() {
+ return Collections.unmodifiableMap(taskChannelFactoryMap);
+ }
+
+ public static TriggerChannel getTaskChannel(String type) {
+ return getTaskChannelMap().get(type);
+ }
+
+ public static boolean checkTaskParameters(ParametersNode parametersNode) {
+ AbstractParameters abstractParameters = getParameters(parametersNode);
+ return abstractParameters != null;
+ }
+
+ public static AbstractParameters getParameters(ParametersNode parametersNode) {
+ String taskType = parametersNode.getTaskType();
+ if (Objects.isNull(taskType)) {
+ return null;
+ }
+ return null;
+ }
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/enums/TriggerExecutionStatus.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/enums/TriggerExecutionStatus.java
new file mode 100644
index 0000000000..42c0678381
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/enums/TriggerExecutionStatus.java
@@ -0,0 +1,109 @@
+package org.apache.dolphinscheduler.plugin.trigger.api.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum TriggerExecutionStatus {
+
+ SUBMITTED_SUCCESS(0, "submit success"),
+ RUNNING_EXECUTION(1, "running"),
+ PAUSE(3, "pause"),
+ STOP(5, "stop"),
+ FAILURE(6, "failure"),
+ SUCCESS(7, "success"),
+ NEED_FAULT_TOLERANCE(8, "need fault tolerance"),
+ KILL(9, "kill"),
+ DELAY_EXECUTION(12, "delay execution"),
+ FORCED_SUCCESS(13, "forced success"),
+ DISPATCH(17, "dispatch"),
+
+ ;
+
+ private static final Map CODE_MAP = new HashMap<>();
+
+ static {
+ for (TriggerExecutionStatus executionStatus : TriggerExecutionStatus.values()) {
+ CODE_MAP.put(executionStatus.getCode(), executionStatus);
+ }
+ }
+
+ /**
+ * Get TaskExecutionStatus by code, if the code is invalidated will throw {@link IllegalArgumentException}.
+ */
+ public static TriggerExecutionStatus of(int code) {
+ TriggerExecutionStatus taskExecutionStatus = CODE_MAP.get(code);
+ if (taskExecutionStatus == null) {
+ throw new IllegalArgumentException(String.format("The task execution status code: %s is invalidated",
+ code));
+ }
+ return taskExecutionStatus;
+ }
+
+ public boolean isRunning() {
+ return this == RUNNING_EXECUTION;
+ }
+
+ public boolean isSuccess() {
+ return this == TriggerExecutionStatus.SUCCESS;
+ }
+
+ public boolean isForceSuccess() {
+ return this == TriggerExecutionStatus.FORCED_SUCCESS;
+ }
+
+ public boolean isKill() {
+ return this == TriggerExecutionStatus.KILL;
+ }
+
+ public boolean isFailure() {
+ return this == TriggerExecutionStatus.FAILURE || this == NEED_FAULT_TOLERANCE;
+ }
+
+ public boolean isPause() {
+ return this == TriggerExecutionStatus.PAUSE;
+ }
+
+ public boolean isStop() {
+ return this == TriggerExecutionStatus.STOP;
+ }
+
+ public boolean isFinished() {
+ return isSuccess() || isKill() || isFailure() || isPause() || isStop() || isForceSuccess();
+ }
+
+ public boolean isNeedFaultTolerance() {
+ return this == NEED_FAULT_TOLERANCE;
+ }
+
+ public boolean shouldFailover() {
+ return SUBMITTED_SUCCESS == this
+ || DISPATCH == this
+ || RUNNING_EXECUTION == this
+ || DELAY_EXECUTION == this;
+ }
+
+ @EnumValue
+ private final int code;
+ private final String desc;
+
+ TriggerExecutionStatus(int code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ @Override
+ public String toString() {
+ return "TaskExecutionStatus{" + "code=" + code + ", desc='" + desc + '\'' + '}';
+ }
+
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/AbstractParameters.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/AbstractParameters.java
new file mode 100644
index 0000000000..4ca713f16c
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/AbstractParameters.java
@@ -0,0 +1,28 @@
+package org.apache.dolphinscheduler.plugin.trigger.api.parameters;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.collect.Lists;
+import org.apache.dolphinscheduler.common.utils.JSONUtils;
+
+@Getter
+@Slf4j
+public class AbstractParameters implements IParameters {
+
+
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/IParameters.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/IParameters.java
new file mode 100644
index 0000000000..0f1ff1b9f6
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/IParameters.java
@@ -0,0 +1,4 @@
+package org.apache.dolphinscheduler.plugin.trigger.api.parameters;
+
+public interface IParameters {
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/ParametersNode.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/ParametersNode.java
new file mode 100644
index 0000000000..7ae8b2c1c3
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-api/src/main/java/org/apache/dolphinscheduler/plugin/trigger/api/parameters/ParametersNode.java
@@ -0,0 +1,95 @@
+package org.apache.dolphinscheduler.plugin.trigger.api.parameters;
+
+public class ParametersNode {
+
+ private String taskType;
+
+ private String taskParams;
+
+ private String dependence;
+
+ private String switchResult;
+
+ public static ParametersNode.ParametersNodeBuilder builder() {
+ return new ParametersNode.ParametersNodeBuilder();
+ }
+
+ public static class ParametersNodeBuilder {
+
+ private String taskType;
+
+ private String taskParams;
+
+ private String dependence;
+
+ private String switchResult;
+
+ public ParametersNodeBuilder taskType(String taskType) {
+ this.taskType = taskType;
+ return this;
+ }
+
+ public ParametersNodeBuilder taskParams(String taskParams) {
+ this.taskParams = taskParams;
+ return this;
+ }
+
+ public ParametersNodeBuilder dependence(String dependence) {
+ this.dependence = dependence;
+ return this;
+ }
+
+ public ParametersNodeBuilder switchResult(String switchResult) {
+ this.switchResult = switchResult;
+ return this;
+ }
+
+ public ParametersNode build() {
+ return new ParametersNode(this.taskType, this.taskParams, this.dependence, this.switchResult);
+ }
+
+ }
+
+ public ParametersNode() {
+
+ }
+
+ public ParametersNode(String taskType, String taskParams, String dependence, String switchResult) {
+ this.taskType = taskType;
+ this.taskParams = taskParams;
+ this.dependence = dependence;
+ this.switchResult = switchResult;
+ }
+
+ public String getTaskType() {
+ return taskType;
+ }
+
+ public void setTaskType(String taskType) {
+ this.taskType = taskType;
+ }
+
+ public String getTaskParams() {
+ return taskParams;
+ }
+
+ public void setTaskParams(String taskParams) {
+ this.taskParams = taskParams;
+ }
+
+ public String getDependence() {
+ return dependence;
+ }
+
+ public void setDependence(String dependence) {
+ this.dependence = dependence;
+ }
+
+ public String getSwitchResult() {
+ return switchResult;
+ }
+
+ public void setSwitchResult(String switchResult) {
+ this.switchResult = switchResult;
+ }
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/pom.xml b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/pom.xml
new file mode 100644
index 0000000000..84ff596759
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/pom.xml
@@ -0,0 +1,27 @@
+
+
+ 4.0.0
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-plugin
+ dev-SNAPSHOT
+
+
+ dolphinscheduler-trigger-simple
+ jar
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-spi
+ provided
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-api
+ ${project.version}
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTrigger.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTrigger.java
new file mode 100644
index 0000000000..c95098e8ac
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTrigger.java
@@ -0,0 +1,51 @@
+package org.apache.dolphinscheduler.plugin.trigger.simple;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dolphinscheduler.plugin.trigger.api.AbstractTrigger;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerCallBack;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerException;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerExecutionContext;
+import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
+
+@Slf4j
+public class SimpleTrigger extends AbstractTrigger {
+
+ private SimpleTriggerPatameters simpleTriggerPatameters;
+
+ private TriggerExecutionContext triggerExecutionContext;
+
+ public SimpleTrigger(TriggerExecutionContext triggerExecutionContext) {
+ super(triggerExecutionContext);
+
+ this.triggerExecutionContext = triggerExecutionContext;
+ }
+
+ @Override
+ public void init() {
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void handle(TriggerCallBack triggerCallBack) throws TriggerException {
+ try {
+
+ } catch (Exception e) {
+ log.error("shell task error", e);
+ throw new TriggerException("Execute shell task error", e);
+ }
+ }
+
+ @Override
+ public void cancel() throws TriggerException {
+ // cancel process
+ try {
+ } catch (Exception e) {
+ throw new TriggerException("cancel application error", e);
+ }
+ }
+
+ public AbstractParameters getParameters() {
+ return simpleTriggerPatameters;
+ }
+
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerChannel.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerChannel.java
new file mode 100644
index 0000000000..eb0a9bd9c5
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerChannel.java
@@ -0,0 +1,20 @@
+package org.apache.dolphinscheduler.plugin.trigger.simple;
+
+import org.apache.dolphinscheduler.common.utils.JSONUtils;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerChannel;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerExecutionContext;
+import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
+import org.apache.dolphinscheduler.plugin.trigger.api.parameters.ParametersNode;
+
+public class SimpleTriggerChannel implements TriggerChannel {
+
+ @Override
+ public void cancelApplication(boolean status) {
+
+ }
+
+ @Override
+ public SimpleTrigger createTrigger(TriggerExecutionContext taskRequest) {
+ return new SimpleTrigger(taskRequest);
+ }
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerChannelFactory.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerChannelFactory.java
new file mode 100644
index 0000000000..2a2fcb317f
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerChannelFactory.java
@@ -0,0 +1,48 @@
+package org.apache.dolphinscheduler.plugin.trigger.simple;
+
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerChannel;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerChannelFactory;
+import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
+import org.apache.dolphinscheduler.spi.params.base.PluginParams;
+import org.apache.dolphinscheduler.spi.params.base.Validate;
+import org.apache.dolphinscheduler.spi.params.input.InputParam;
+import org.apache.dolphinscheduler.spi.params.radio.RadioParam;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(TriggerChannelFactory.class)
+public class SimpleTriggerChannelFactory implements TriggerChannelFactory {
+
+ @Override
+ public TriggerChannel create() {
+ return new SimpleTriggerChannel();
+ }
+
+ @Override
+ public String getName() {
+ return "SIMPLE";
+ }
+
+ @Override
+ public List getParams() {
+ List paramsList = new ArrayList<>();
+
+ InputParam nodeName = InputParam.newBuilder("name", "$t('Node name')")
+ .addValidate(Validate.newBuilder()
+ .setRequired(true)
+ .build())
+ .build();
+
+ RadioParam runFlag = RadioParam.newBuilder("runFlag", "RUN_FLAG")
+ .addParamsOptions(new ParamsOptions("NORMAL", "NORMAL", false))
+ .addParamsOptions(new ParamsOptions("FORBIDDEN", "FORBIDDEN", false))
+ .build();
+
+ paramsList.add(nodeName);
+ paramsList.add(runFlag);
+ return paramsList;
+ }
+}
diff --git a/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerPatameters.java b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerPatameters.java
new file mode 100644
index 0000000000..9cfd0de87b
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/dolphinscheduler-trigger-simple/src/main/java/org/apache/dolphinscheduler/plugin/trigger/simple/SimpleTriggerPatameters.java
@@ -0,0 +1,11 @@
+package org.apache.dolphinscheduler.plugin.trigger.simple;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
+
+@Getter
+@Setter
+public class SimpleTriggerPatameters extends AbstractParameters {
+
+}
\ No newline at end of file
diff --git a/dolphinscheduler-trigger-plugin/pom.xml b/dolphinscheduler-trigger-plugin/pom.xml
new file mode 100644
index 0000000000..f6d0a9514e
--- /dev/null
+++ b/dolphinscheduler-trigger-plugin/pom.xml
@@ -0,0 +1,32 @@
+
+
+ 4.0.0
+
+ org.apache.dolphinscheduler
+ dolphinscheduler
+ dev-SNAPSHOT
+
+
+ dolphinscheduler-trigger-plugin
+ pom
+
+
+ dolphinscheduler-trigger-all
+ dolphinscheduler-trigger-api
+ dolphinscheduler-trigger-simple
+
+
+
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-bom
+ ${project.version}
+ pom
+ import
+
+
+
+
\ No newline at end of file
diff --git a/dolphinscheduler-ui/pnpm-lock.yaml b/dolphinscheduler-ui/pnpm-lock.yaml
index 5621ef47ec..38ce00babc 100644
--- a/dolphinscheduler-ui/pnpm-lock.yaml
+++ b/dolphinscheduler-ui/pnpm-lock.yaml
@@ -1,20 +1,4 @@
-# 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.
-lockfileVersion: 5.4
+lockfileVersion: 5.3
specifiers:
'@antv/layout': 0.1.31
diff --git a/dolphinscheduler-ui/src/layouts/content/components/sidebar/index.tsx b/dolphinscheduler-ui/src/layouts/content/components/sidebar/index.tsx
index 782b966609..d9300d94d3 100644
--- a/dolphinscheduler-ui/src/layouts/content/components/sidebar/index.tsx
+++ b/dolphinscheduler-ui/src/layouts/content/components/sidebar/index.tsx
@@ -36,6 +36,7 @@ const Sidebar = defineComponent({
const defaultExpandedKeys = [
'workflow',
'task',
+ 'trigger',
'udf-manage',
'service-manage',
'statistical-manage',
diff --git a/dolphinscheduler-ui/src/layouts/content/use-dataList.ts b/dolphinscheduler-ui/src/layouts/content/use-dataList.ts
index facf521db8..3156228eb0 100644
--- a/dolphinscheduler-ui/src/layouts/content/use-dataList.ts
+++ b/dolphinscheduler-ui/src/layouts/content/use-dataList.ts
@@ -167,6 +167,23 @@ export function useDataList() {
payload: { projectName: projectName }
}
]
+ },
+ {
+ label: t('menu.trigger'),
+ key: 'trigger',
+ icon: renderIcon(SettingOutlined),
+ children: [
+ {
+ label: t('menu.trigger_definition'),
+ key: `/projects/${projectCode}/trigger/definitions`,
+ payload: { projectName: projectName }
+ },
+ {
+ label: t('menu.trigger_instance'),
+ key: `/projects/${projectCode}/trigger/instances`,
+ payload: { projectName: projectName }
+ }
+ ]
}
]
},
diff --git a/dolphinscheduler-ui/src/locales/en_US/menu.ts b/dolphinscheduler-ui/src/locales/en_US/menu.ts
index d71f382ec0..c7cafdd362 100644
--- a/dolphinscheduler-ui/src/locales/en_US/menu.ts
+++ b/dolphinscheduler-ui/src/locales/en_US/menu.ts
@@ -33,6 +33,9 @@ export default {
task: 'Task',
task_instance: 'Task Instance',
task_definition: 'Task Definition',
+ trigger: 'Trigger',
+ trigger_instance: 'Trigger Instance',
+ trigger_definition: 'Trigger Definition',
file_manage: 'File Manage',
udf_manage: 'UDF Manage',
resource_manage: 'Resource Manage',
diff --git a/dolphinscheduler-ui/src/locales/en_US/project.ts b/dolphinscheduler-ui/src/locales/en_US/project.ts
index 68eb7b3102..dbe3c7b8c1 100644
--- a/dolphinscheduler-ui/src/locales/en_US/project.ts
+++ b/dolphinscheduler-ui/src/locales/en_US/project.ts
@@ -76,6 +76,7 @@ export default {
modify_user: 'Modify User',
operation: 'Operation',
edit: 'Edit',
+ trigger: '触发',
confirm: 'Confirm',
cancel: 'Cancel',
start: 'Start',
@@ -323,6 +324,12 @@ export default {
delete_validate_dependent_tasks_desc:
'The downstream dependent tasks exists. You can not delete the task.'
},
+ trigger: {
+ trigger: 'Trigger',
+ create_trigger: 'Create Trigger',
+ trigger_definition: 'Trigger Definition',
+ trigger_name: 'Trigger Name'
+ },
dag: {
create: 'Create Workflow',
search: 'Search',
diff --git a/dolphinscheduler-ui/src/locales/zh_CN/menu.ts b/dolphinscheduler-ui/src/locales/zh_CN/menu.ts
index 257541f3ad..1fe104911c 100644
--- a/dolphinscheduler-ui/src/locales/zh_CN/menu.ts
+++ b/dolphinscheduler-ui/src/locales/zh_CN/menu.ts
@@ -34,6 +34,9 @@ export default {
task: '任务',
task_instance: '任务实例',
task_definition: '任务定义',
+ trigger: '触发器',
+ trigger_instance: '触发器实例',
+ trigger_definition: '触发器定义',
file_manage: '文件管理',
udf_manage: 'UDF管理',
resource_manage: '资源管理',
diff --git a/dolphinscheduler-ui/src/locales/zh_CN/project.ts b/dolphinscheduler-ui/src/locales/zh_CN/project.ts
index e1bfd6f672..c7401a231f 100644
--- a/dolphinscheduler-ui/src/locales/zh_CN/project.ts
+++ b/dolphinscheduler-ui/src/locales/zh_CN/project.ts
@@ -76,6 +76,7 @@ export default {
modify_user: '修改用户',
operation: '操作',
edit: '编辑',
+ trigger: '触发',
confirm: '确定',
cancel: '取消',
start: '运行',
@@ -319,6 +320,12 @@ export default {
remove_task_cache: '清除缓存',
delete_validate_dependent_tasks_desc: '下游存在依赖,你不能删除该任务定义'
},
+ trigger: {
+ trigger: '触发器',
+ create_trigger: '创建触发器',
+ trigger_definition: '触发器定义',
+ trigger_name: '触发器名称'
+ },
dag: {
create: '创建工作流',
search: '搜索',
diff --git a/dolphinscheduler-ui/src/router/modules/projects.ts b/dolphinscheduler-ui/src/router/modules/projects.ts
index 8412f5904f..0af7ed465f 100644
--- a/dolphinscheduler-ui/src/router/modules/projects.ts
+++ b/dolphinscheduler-ui/src/router/modules/projects.ts
@@ -201,6 +201,28 @@ export default {
auth: []
}
},
+ {
+ path: '/projects/:projectCode/trigger/definitions',
+ name: 'trigger-definition',
+ component: components['projects-trigger-definition'],
+ meta: {
+ title: '触发器定义',
+ activeMenu: 'projects',
+ showSide: true,
+ auth: []
+ }
+ },
+ {
+ path: '/projects/:projectCode/trigger/instances',
+ name: 'trigger-instance',
+ component: components['projects-trigger-instance'],
+ meta: {
+ title: '触发器实例',
+ activeMenu: 'projects',
+ showSide: true,
+ auth: []
+ }
+ },
{
path: '/projects/:projectCode/workflow-definition/tree/:definitionCode',
name: 'workflow-definition-tree',
diff --git a/dolphinscheduler-ui/src/service/modules/trigger-definition/index.ts b/dolphinscheduler-ui/src/service/modules/trigger-definition/index.ts
new file mode 100644
index 0000000000..8774154d32
--- /dev/null
+++ b/dolphinscheduler-ui/src/service/modules/trigger-definition/index.ts
@@ -0,0 +1,172 @@
+/*
+ * 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'
+import {
+ PageReq,
+ ProjectCodeReq,
+ TaskDefinitionListReq,
+ TaskDefinitionJsonReq,
+ CodeReq,
+ TaskDefinitionJsonObjReq,
+ ReleaseStateReq,
+ VersionReq,
+ ISingleSaveReq,
+ TaskDefinitionReq
+} from './types'
+
+export function queryTriggerDefinitionListPaging(
+ params: TaskDefinitionListReq,
+ projectCode: ProjectCodeReq
+): any {
+ return axios({
+ url: `/projects/${projectCode.projectCode}/task-definition`,
+ method: 'get',
+ params
+ })
+}
+
+export function save(
+ data: TaskDefinitionJsonReq,
+ projectCode: ProjectCodeReq
+): any {
+ return axios({
+ url: `/projects/${projectCode}/task-definition`,
+ method: 'post',
+ data
+ })
+}
+
+export function genTaskCodeList(num: number, projectCode: number) {
+ return axios.request({
+ url: `/projects/${projectCode}/task-definition/gen-task-codes`,
+ method: 'get',
+ params: {
+ genNum: num
+ }
+ })
+}
+
+export function queryTriggerDefinitionByCode(
+ code: number,
+ projectCode: number
+): any {
+ return axios({
+ url: `/projects/${projectCode}/task-definition/${code}`,
+ method: 'get'
+ })
+}
+
+export function updateTrigger(
+ projectCode: number,
+ code: number,
+ data: TaskDefinitionJsonObjReq
+): any {
+ return axios({
+ url: `/projects/${projectCode}/task-definition/${code}`,
+ method: 'put',
+ data
+ })
+}
+
+export function deleteTriggerDefinition(
+ code: CodeReq,
+ projectCode: ProjectCodeReq
+): any {
+ return axios({
+ url: `/projects/${projectCode.projectCode}/task-definition/${code.code}`,
+ method: 'delete'
+ })
+}
+
+export function releaseTaskDefinition(
+ data: ReleaseStateReq,
+ code: number,
+ projectCode: number
+): any {
+ return axios({
+ url: `/projects/${projectCode}/task-definition/${code}/release`,
+ method: 'post',
+ data
+ })
+}
+
+export function queryTaskVersions(
+ params: PageReq,
+ code: CodeReq,
+ projectCode: ProjectCodeReq
+): any {
+ return axios({
+ url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions`,
+ method: 'get',
+ params
+ })
+}
+
+export function switchVersion(
+ version: VersionReq,
+ code: CodeReq,
+ projectCode: ProjectCodeReq
+): any {
+ return axios({
+ url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`,
+ method: 'get'
+ })
+}
+
+export function deleteVersion(
+ version: VersionReq,
+ code: CodeReq,
+ projectCode: ProjectCodeReq
+): any {
+ return axios({
+ url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`,
+ method: 'delete'
+ })
+}
+
+export function saveSingle(projectCode: number, data: ISingleSaveReq) {
+ return axios({
+ url: `/projects/${projectCode}/task-definition/save-single`,
+ method: 'post',
+ data
+ })
+}
+
+export function updateWithUpstream(
+ projectCode: number,
+ code: number,
+ data: ISingleSaveReq
+) {
+ return axios({
+ url: `/projects/${projectCode}/task-definition/${code}/with-upstream`,
+ method: 'put',
+ data
+ })
+}
+
+export function startTaskDefinition(
+ projectCode: number,
+ code: number,
+ data: TaskDefinitionReq
+) {
+ return axios({
+ url: `projects/${projectCode}/executors/task-instance/${code}/start`,
+ method: 'post',
+ data
+ })
+}
diff --git a/dolphinscheduler-ui/src/service/modules/trigger-definition/types.ts b/dolphinscheduler-ui/src/service/modules/trigger-definition/types.ts
new file mode 100644
index 0000000000..3f90b42762
--- /dev/null
+++ b/dolphinscheduler-ui/src/service/modules/trigger-definition/types.ts
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+interface PageReq {
+ pageNo: number
+ pageSize: number
+}
+
+interface ListReq extends PageReq {
+ searchVal?: string
+}
+
+interface ProjectCodeReq {
+ projectCode: number
+}
+
+interface TaskDefinitionListReq extends ListReq {
+ taskType?: string
+ userId?: number
+ taskExecuteType?: 'BATCH' | 'STREAM'
+}
+
+interface TaskDefinitionJsonReq {
+ taskDefinitionJson: string
+}
+
+interface CodeReq {
+ code: any
+}
+
+interface TaskDefinitionJsonObjReq {
+ taskDefinitionJsonObj: string
+ taskExecuteType?: string
+}
+
+interface ReleaseStateReq {
+ releaseState: 'OFFLINE' | 'ONLINE'
+}
+
+interface VersionReq {
+ version: number
+}
+
+interface TaskDefinitionItem {
+ taskName: string
+ taskCode: any
+ taskVersion: number
+ taskType: string
+ taskCreateTime: string
+ taskUpdateTime: string
+ processDefinitionCode: any
+ processDefinitionVersion: number
+ processDefinitionName: string
+ processReleaseState: string
+ upstreamTaskMap: any
+ upstreamTaskCode: number
+ upstreamTaskName: string
+}
+
+interface TaskDefinitionRes {
+ totalList: TaskDefinitionItem[]
+ total: number
+ totalPage: number
+ pageSize: number
+ currentPage: number
+ start: number
+}
+
+interface TaskDefinitionVersionItem {
+ id: number
+ code: number
+ name: string
+ version: number
+ description: string
+ projectCode: number
+ userId: number
+ taskType: string
+ taskParams: any
+ taskParamList: any[]
+ taskParamMap: any
+ flag: string
+ taskPriority: string
+ userName?: any
+ projectName?: any
+ workerGroup: string
+ environmentCode: number
+ failRetryTimes: number
+ failRetryInterval: number
+ timeoutFlag: string
+ timeoutNotifyStrategy?: any
+ timeout: number
+ delayTime: number
+ resourceIds: string
+ createTime: string
+ updateTime: string
+ modifyBy?: any
+ taskGroupId: number
+ taskGroupPriority: number
+ operator: number
+ operateTime: string
+ dependence: string
+}
+
+interface TaskDefinitionVersionRes {
+ totalList: TaskDefinitionVersionItem[]
+ total: number
+ totalPage: number
+ pageSize: number
+ currentPage: number
+ start: number
+}
+
+interface ISingleSaveReq {
+ processDefinitionCode?: string
+ upstreamCodes: string
+ taskDefinitionJsonObj: string
+}
+
+interface TaskDefinitionReq {
+ version: number
+ warningType: string
+ warningGroupId: number
+ workerGroup?: string
+ environmentCode?: number
+ startParams?: string
+ dryRun?: number
+}
+
+export {
+ PageReq,
+ ListReq,
+ ProjectCodeReq,
+ TaskDefinitionListReq,
+ TaskDefinitionJsonReq,
+ CodeReq,
+ TaskDefinitionJsonObjReq,
+ ReleaseStateReq,
+ VersionReq,
+ TaskDefinitionItem,
+ TaskDefinitionRes,
+ TaskDefinitionVersionItem,
+ TaskDefinitionVersionRes,
+ ISingleSaveReq,
+ TaskDefinitionReq
+}
diff --git a/dolphinscheduler-ui/src/store/project/types.ts b/dolphinscheduler-ui/src/store/project/types.ts
index e486bd9c5c..dbb9c1d2ee 100644
--- a/dolphinscheduler-ui/src/store/project/types.ts
+++ b/dolphinscheduler-ui/src/store/project/types.ts
@@ -60,6 +60,8 @@ type TaskType =
| 'DATA_FACTORY'
| 'REMOTESHELL'
+type TriggerType = 'SIMPLE' | 'TIMER' | 'KAFKA'
+
type ProgramType = 'JAVA' | 'SCALA' | 'PYTHON'
type DependentResultType = {
@@ -113,6 +115,7 @@ export {
BDependentResultType,
IMainJar,
TaskType,
+ TriggerType,
ITaskType,
ITaskTypeItem,
TaskTypeState,
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/detail-modal.tsx b/dolphinscheduler-ui/src/views/projects/trigger/components/node/detail-modal.tsx
new file mode 100644
index 0000000000..b2659b3095
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/detail-modal.tsx
@@ -0,0 +1,270 @@
+/*
+ * 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 {
+ defineComponent,
+ PropType,
+ ref,
+ watch,
+ nextTick,
+ provide,
+ computed,
+ h,
+ Ref,
+ onMounted
+} from 'vue'
+import { useI18n } from 'vue-i18n'
+import Modal from '@/components/modal'
+import Detail from './detail'
+import { formatModel } from './format-data'
+import {
+ HistoryOutlined,
+ ProfileOutlined,
+ QuestionCircleTwotone,
+ BranchesOutlined
+} from '@vicons/antd'
+import { NIcon } from 'naive-ui'
+import { Router, useRouter } from 'vue-router'
+import { querySubProcessInstanceByTaskCode } from '@/service/modules/process-instances'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import type {
+ ITriggerData,
+ ITriggerType,
+ EditWorkflowDefinition,
+ IWorkflowTaskInstance,
+ WorkflowInstance
+} from './types'
+import { queryProjectPreferenceByProjectCode } from '@/service/modules/projects-preference'
+import { INodeData } from './types'
+
+const props = {
+ show: {
+ type: Boolean as PropType,
+ default: false
+ },
+ data: {
+ type: Object as PropType,
+ default: { code: 0, taskType: 'SHELL', name: '' }
+ },
+ projectCode: {
+ type: Number as PropType,
+ required: true,
+ default: 0
+ },
+ readonly: {
+ type: Boolean as PropType,
+ default: false
+ },
+ from: {
+ type: Number as PropType,
+ default: 0
+ },
+ definition: {
+ type: Object as PropType[>
+ },
+ processInstance: {
+ type: Object as PropType
+ },
+ taskInstance: {
+ type: Object as PropType
+ },
+ saving: {
+ type: Boolean,
+ default: false
+ }
+}
+
+const NodeDetailModal = defineComponent({
+ name: 'NodeDetailModal',
+ props,
+ emits: ['cancel', 'submit', 'viewLog'],
+ setup(props, { emit }) {
+ const { t, locale } = useI18n()
+ const router: Router = useRouter()
+ const taskStore = useTaskNodeStore()
+
+ const renderIcon = (icon: any) => {
+ return () => h(NIcon, null, { default: () => h(icon) })
+ }
+ const detailRef = ref()
+
+ const onConfirm = async () => {
+ await detailRef.value.value.validate()
+ emit('submit', { data: detailRef.value.value.getValues() })
+ }
+ const onCancel = () => {
+ emit('cancel')
+ }
+
+ const headerLinks = ref([] as any)
+ const projectPreferences = ref({} as any)
+
+ const handleViewLog = () => {
+ if (props.taskInstance) {
+ emit('viewLog', props.taskInstance.id, props.taskInstance.taskType)
+ }
+ }
+
+ const initProjectPreferences = (projectCode: number) => {
+ queryProjectPreferenceByProjectCode(projectCode).then((result: any) => {
+ if (result?.preferences && result.state === 1) {
+ projectPreferences.value = JSON.parse(result.preferences)
+ }
+ })
+ }
+
+ const restructureNodeData = (data: INodeData) => {
+ if (!data?.id) {
+ for (const item in projectPreferences.value) {
+ if (projectPreferences.value[item] !== null && item in data) {
+ Object.assign(data, { item: projectPreferences.value[item] })
+ }
+ }
+ }
+ }
+
+ const initHeaderLinks = (processInstance: any, taskType?: ITriggerType) => {
+ headerLinks.value = [
+ {
+ text: t('project.node.instructions'),
+ show: !!(taskType),
+ action: () => {
+ let linkedTaskType = taskType?.toLowerCase().replace('_', '-')
+ if (taskType === 'PROCEDURE') linkedTaskType = 'stored-procedure'
+ const helpUrl =
+ 'https://dolphinscheduler.apache.org/' +
+ locale.value.toLowerCase().replace('_', '-') +
+ '/docs/latest/user_doc/guide/task/' +
+ linkedTaskType +
+ '.html'
+ window.open(helpUrl)
+ },
+ icon: renderIcon(QuestionCircleTwotone)
+ },
+ {
+ text: t('project.node.view_history'),
+ show: !!props.taskInstance,
+ action: () => {
+ router.push({
+ name: 'task-instance',
+ query: {
+ taskCode: props.data.code
+ }
+ })
+ },
+ icon: renderIcon(HistoryOutlined)
+ },
+ {
+ text: t('project.node.view_log'),
+ show: !!props.taskInstance,
+ action: () => {
+ handleViewLog()
+ },
+ icon: renderIcon(ProfileOutlined)
+ },
+ {
+ text: t('project.node.enter_this_child_node'),
+ show:
+ props.data.taskType === 'SUB_PROCESS' ||
+ props.data.taskType === 'DYNAMIC',
+ disabled:
+ !props.data.id ||
+ (router.currentRoute.value.name === 'workflow-instance-detail' &&
+ !props.taskInstance),
+ action: () => {
+ if (router.currentRoute.value.name === 'workflow-instance-detail') {
+ querySubProcessInstanceByTaskCode(
+ { taskId: props.taskInstance?.id },
+ { projectCode: props.projectCode }
+ ).then((res: any) => {
+ router.push({
+ name: 'workflow-instance-detail',
+ params: { id: res.subProcessInstanceId },
+ query: { code: props.data.taskParams?.processDefinitionCode }
+ })
+ })
+ } else {
+ router.push({
+ name: 'workflow-definition-detail',
+ params: { code: props.data.taskParams?.processDefinitionCode }
+ })
+ }
+ },
+ icon: renderIcon(BranchesOutlined)
+ }
+ ]
+ }
+
+ const onTaskTypeChange = (taskType: ITriggerType) => {
+ // eslint-disable-next-line vue/no-mutating-props
+ props.data.taskType = taskType
+ initHeaderLinks(props.processInstance, props.data.taskType)
+ }
+
+ provide(
+ 'data',
+ computed(() => ({
+ projectCode: props.projectCode,
+ data: props.data,
+ from: props.from,
+ readonly: props.readonly,
+ definition: props.definition
+ }))
+ )
+
+ onMounted(() => {
+ initProjectPreferences(props.projectCode)
+ })
+
+ watch(
+ () => [props.show, props.data],
+ async () => {
+ if (!props.show) return
+ initHeaderLinks(props.processInstance, props.data.taskType)
+ taskStore.init()
+ const nodeData = formatModel(props.data)
+ await nextTick()
+ restructureNodeData(nodeData)
+ detailRef.value.value.setValues(nodeData)
+ }
+ )
+
+ return () => (
+
+
+
+ )
+ }
+})
+
+export default NodeDetailModal
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/detail.tsx b/dolphinscheduler-ui/src/views/projects/trigger/components/node/detail.tsx
new file mode 100644
index 0000000000..ab8282e88c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/detail.tsx
@@ -0,0 +1,84 @@
+/*
+ * 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 { defineComponent, ref, watch, inject, Ref, unref } from 'vue'
+import Form from '@/components/form'
+import { useTask } from './use-task'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import type { ITaskData, EditWorkflowDefinition } from './types'
+
+interface IDetailPanel {
+ projectCode: number
+ data: ITaskData
+ readonly: false
+ from: number
+ detailRef?: Ref
+ definition?: EditWorkflowDefinition
+}
+
+const NodeDetail = defineComponent({
+ name: 'NodeDetail',
+ emits: ['taskTypeChange'],
+ setup(props, { expose, emit }) {
+ const taskStore = useTaskNodeStore()
+
+ const formRef = ref()
+ const detailData: IDetailPanel = inject('data') || {
+ projectCode: 0,
+ data: {
+ taskType: 'SHELL'
+ },
+ readonly: false,
+ from: 0
+ }
+ const { data, projectCode, from, readonly, definition } = unref(detailData)
+
+ const { elementsRef, rulesRef, model } = useTask({
+ data,
+ projectCode,
+ from,
+ readonly,
+ definition
+ })
+ watch(
+ () => model.taskType,
+ async (taskType) => {
+ taskStore.updateName(model.name || '')
+ emit('taskTypeChange', taskType)
+ }
+ )
+
+ expose(formRef)
+
+ return () => (
+
+ )
+ }
+})
+
+export default NodeDetail
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/index.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/index.ts
new file mode 100644
index 0000000000..57d168867e
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/index.ts
@@ -0,0 +1,93 @@
+/*
+ * 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 { useName } from './use-name'
+export { useRunFlag } from './use-run-flag'
+export { useCache } from './use-cache'
+export { useDescription } from './use-description'
+export { useTaskPriority } from './use-task-priority'
+export { useWorkerGroup } from './use-worker-group'
+export { useEnvironmentName } from './use-environment-name'
+export { useTaskGroup } from './use-task-group'
+export { useFailed } from './use-failed'
+export { useResourceLimit } from './use-resource-limit'
+export { useDelayTime } from './use-delay-time'
+export { useTimeoutAlarm } from './use-timeout-alarm'
+export { usePreTasks } from './use-pre-tasks'
+export { useTaskType } from './use-task-type'
+export { useProcessName } from './use-process-name'
+export { useChildNode } from './use-child-node'
+export { useTargetTaskName } from './use-target-task-name'
+export { useDatasource } from './use-datasource'
+export { useSqlType } from './use-sql-type'
+export { useProcedure } from './use-procedure'
+export { useCustomParams } from './use-custom-params'
+export { useCustomLabels } from './use-custom-labels'
+export { useNodeSelectors } from './use-node-selectors'
+export { useSourceType } from './use-sqoop-source-type'
+export { useTargetType } from './use-sqoop-target-type'
+export { useRelationCustomParams } from './use-relation-custom-params'
+export { useDependentTimeout } from './use-dependent-timeout'
+export { useRules } from './use-rules'
+export { useDeployMode } from './use-deploy-mode'
+export { useDriverCores } from './use-driver-cores'
+export { useDriverMemory } from './use-driver-memory'
+export { useExecutorNumber } from './use-executor-number'
+export { useExecutorMemory } from './use-executor-memory'
+export { useExecutorCores } from './use-executor-cores'
+export { useMainJar } from './use-main-jar'
+export { useResources } from './use-resources'
+export { useTaskDefinition } from './use-task-definition'
+export { useJavaTaskMainJar } from './use-java-task-main-jar'
+
+export { useShell } from './use-shell'
+export { useSpark } from './use-spark'
+export { useMr } from './use-mr'
+export { useFlink } from './use-flink'
+export { useHttp } from './use-http'
+export { useSql } from './use-sql'
+export { useSqoop } from './use-sqoop'
+export { useSeaTunnel } from './use-sea-tunnel'
+export { useSwitch } from './use-switch'
+export { useDataX } from './use-datax'
+export { useConditions } from './use-conditions'
+export { useDependent } from './use-dependent'
+export { useEmr } from './use-emr'
+export { useZeppelin } from './use-zeppelin'
+export { useNamespace } from './use-namespace'
+export { useK8s } from './use-k8s'
+export { useJupyter } from './use-jupyter'
+export { useMlflow } from './use-mlflow'
+export { useMlflowProjects } from './use-mlflow-projects'
+export { useMlflowModels } from './use-mlflow-models'
+export { useOpenmldb } from './use-openmldb'
+export { useDvc } from './use-dvc'
+export { useDinky } from './use-dinky'
+export { useSagemaker } from './use-sagemaker'
+export { useJava } from './use-java'
+export { useChunjun } from './use-chunjun'
+export { useChunjunDeployMode } from './use-chunjun-deploy-mode'
+export { usePytorch } from './use-pytorch'
+export { useHiveCli } from './use-hive-cli'
+export { useDms } from './use-dms'
+export { useDatasync } from './use-datasync'
+export { useKubeflow } from './use-kubeflow'
+export { useLinkis } from './use-linkis'
+export { useDataFactory } from './use-data-factory'
+export { useRemoteShell } from './use-remote-shell'
+export { useDynamic } from './use-dynamic'
+export { useYarnQueue } from './use-queue'
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-cache.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-cache.ts
new file mode 100644
index 0000000000..fd7e90431c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-cache.ts
@@ -0,0 +1,29 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useCache(): IJsonItem {
+ const { t } = useI18n()
+ return {
+ type: 'switch',
+ field: 'isCache',
+ name: t('project.node.is_cache'),
+ span: 12
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-child-node.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-child-node.ts
new file mode 100644
index 0000000000..98b232f271
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-child-node.ts
@@ -0,0 +1,90 @@
+/*
+ * 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 { ref, onMounted } from 'vue'
+import { useI18n } from 'vue-i18n'
+import {
+ querySimpleList,
+ queryProcessDefinitionByCode
+} from '@/service/modules/process-definition'
+import type { IJsonItem } from '../types'
+
+export function useChildNode({
+ model,
+ projectCode,
+ from,
+ processName,
+ code
+}: {
+ model: { [field: string]: any }
+ projectCode: number
+ from?: number
+ processName?: number
+ code?: number
+}): IJsonItem {
+ const { t } = useI18n()
+
+ const options = ref([] as { label: string; value: string }[])
+ const loading = ref(false)
+
+ const getProcessList = async () => {
+ if (loading.value) return
+ loading.value = true
+ const res = await querySimpleList(projectCode)
+ options.value = res
+ .filter((option: { name: string; code: number }) => option.code !== code)
+ .map((option: { name: string; code: number }) => ({
+ label: option.name,
+ value: option.code
+ }))
+ loading.value = false
+ }
+ const getProcessListByCode = async (processCode: number) => {
+ if (!processCode) return
+ const res = await queryProcessDefinitionByCode(processCode, projectCode)
+ model.definition = res
+ }
+
+ onMounted(() => {
+ if (from === 1 && processName) {
+ getProcessListByCode(processName)
+ }
+ getProcessList()
+ })
+
+ return {
+ type: 'select',
+ field: 'processDefinitionCode',
+ span: 24,
+ name: t('project.node.child_node'),
+ props: {
+ loading: loading,
+ filterable: true
+ },
+ options: options,
+ class: 'select-child-node',
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(unuse: any, value: number) {
+ if (!value) {
+ return Error(t('project.node.child_node_tips'))
+ }
+ }
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-chunjun-deploy-mode.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-chunjun-deploy-mode.ts
new file mode 100644
index 0000000000..9cd5083a9c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-chunjun-deploy-mode.ts
@@ -0,0 +1,49 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useChunjunDeployMode(span = 24): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'radio',
+ field: 'deployMode',
+ name: t('project.node.deploy_mode'),
+ options: DEPLOY_MODES,
+ span
+ }
+}
+
+export const DEPLOY_MODES = [
+ {
+ label: 'local',
+ value: 'local'
+ },
+ {
+ label: 'standlone',
+ value: 'standlone'
+ },
+ {
+ label: 'yarn-session',
+ value: 'yarn-session'
+ },
+ {
+ label: 'yarn-per-job',
+ value: 'yarn-per-job'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-chunjun.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-chunjun.ts
new file mode 100644
index 0000000000..617a8e5145
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-chunjun.ts
@@ -0,0 +1,103 @@
+/*
+ * 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 { ref, onMounted } from 'vue'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+import { useChunjunDeployMode } from './'
+
+export function useChunjun(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const jsonEditorSpan = ref(0)
+ const customParameterSpan = ref(0)
+
+ const initConstants = () => {
+ jsonEditorSpan.value = 24
+ customParameterSpan.value = 24
+ }
+
+ onMounted(() => {
+ initConstants()
+ })
+
+ return [
+ {
+ type: 'editor',
+ field: 'json',
+ name: t('project.node.chunjun_json_template'),
+ span: jsonEditorSpan,
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.sql_empty_tips')
+ }
+ },
+ {
+ type: 'custom-parameters',
+ field: 'localParams',
+ name: t('project.node.custom_parameters'),
+ span: customParameterSpan,
+ children: [
+ {
+ type: 'input',
+ field: 'prop',
+ span: 10,
+ props: {
+ placeholder: t('project.node.prop_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.prop_tips'))
+ }
+
+ const sameItems = model.localParams.filter(
+ (item: { prop: string }) => item.prop === value
+ )
+
+ if (sameItems.length > 1) {
+ return new Error(t('project.node.prop_repeat'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'value',
+ span: 10,
+ props: {
+ placeholder: t('project.node.value_tips'),
+ maxLength: 256
+ }
+ }
+ ]
+ },
+ useChunjunDeployMode(24),
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.option_parameters'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.option_parameters_tips')
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-conditions.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-conditions.ts
new file mode 100644
index 0000000000..53df0bba75
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-conditions.ts
@@ -0,0 +1,127 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import { useRelationCustomParams, useTimeoutAlarm } from '.'
+import type { IJsonItem } from '../types'
+
+export function useConditions(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const taskStore = useTaskNodeStore()
+
+ const preTaskOptions = taskStore.preTaskOptions.filter((option) =>
+ taskStore.preTasks.includes(Number(option.value))
+ )
+ const stateOptions = [
+ { label: t('project.node.success'), value: 'success' },
+ { label: t('project.node.failed'), value: 'failed' }
+ ]
+
+ return [
+ {
+ type: 'select',
+ field: 'successNode',
+ name: t('project.node.state'),
+ span: 12,
+ props: {
+ disabled: true
+ },
+ options: stateOptions
+ },
+ {
+ type: 'select',
+ field: 'successBranch',
+ name: t('project.node.branch_flow'),
+ span: 12,
+ props: {
+ clearable: true
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ validator: (unuse, value) => {
+ if (value && value === model.failedBranch) {
+ return new Error(t('project.node.branch_tips'))
+ }
+ }
+ },
+ options: taskStore.getPostTaskOptions
+ },
+ {
+ type: 'select',
+ field: 'failedNode',
+ name: t('project.node.state'),
+ span: 12,
+ props: {
+ disabled: true
+ },
+ options: stateOptions
+ },
+ {
+ type: 'select',
+ field: 'failedBranch',
+ name: t('project.node.branch_flow'),
+ span: 12,
+ props: {
+ clearable: true
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ validator: (unuse, value) => {
+ if (value && value === model.successBranch) {
+ return new Error(t('project.node.branch_tips'))
+ }
+ }
+ },
+ options: taskStore.getPostTaskOptions
+ },
+ ...useTimeoutAlarm(model),
+ ...useRelationCustomParams({
+ model,
+ children: {
+ type: 'custom-parameters',
+ field: 'dependItemList',
+ span: 18,
+ children: [
+ {
+ type: 'select',
+ field: 'depTaskCode',
+ span: 10,
+ options: preTaskOptions
+ },
+ {
+ type: 'select',
+ field: 'status',
+ span: 10,
+ options: [
+ {
+ value: 'SUCCESS',
+ label: t('project.node.success')
+ },
+ {
+ value: 'FAILURE',
+ label: t('project.node.failed')
+ }
+ ]
+ }
+ ]
+ },
+ childrenField: 'dependItemList',
+ name: 'add_pre_task_check_condition'
+ })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-custom-labels.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-custom-labels.ts
new file mode 100644
index 0000000000..915fcceab9
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-custom-labels.ts
@@ -0,0 +1,82 @@
+/*
+ * 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 { Ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useCustomLabels({
+ model,
+ field,
+ name = 'custom_labels',
+ span = 24
+}: {
+ model: { [field: string]: any }
+ field: string
+ name?: string
+ span?: Ref | number
+}): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'custom-parameters',
+ field: field,
+ name: t(`project.node.${name}`),
+ class: 'btn-custom-parameters',
+ span,
+ children: [
+ {
+ type: 'input',
+ field: 'label',
+ span: 8,
+ class: 'customized-label-name',
+ props: {
+ placeholder: t('project.node.label_name_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.label_name_tips'))
+ }
+
+ const sameItems = model[field].filter(
+ (item: { label: string }) => item.label === value
+ )
+
+ if (sameItems.length > 1) {
+ return new Error(t('project.node.label_repeat'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'value',
+ span: 14,
+ class: 'customized-label-value',
+ props: {
+ placeholder: t('project.node.label_value_tips'),
+ maxLength: 256
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-custom-params.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-custom-params.ts
new file mode 100644
index 0000000000..2052f524fe
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-custom-params.ts
@@ -0,0 +1,162 @@
+/*
+ * 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 { Ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useCustomParams({
+ model,
+ field,
+ isSimple,
+ name = 'custom_parameters',
+ span = 24
+}: {
+ model: { [field: string]: any }
+ field: string
+ isSimple: boolean
+ name?: string
+ span?: Ref | number
+}): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'custom-parameters',
+ field: field,
+ name: t(`project.node.${name}`),
+ class: 'btn-custom-parameters',
+ span,
+ children: [
+ {
+ type: 'input',
+ field: 'prop',
+ span: 6,
+ class: 'input-param-key',
+ props: {
+ placeholder: t('project.node.prop_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.prop_tips'))
+ }
+
+ const sameItems = model[field].filter(
+ (item: { prop: string }) => item.prop === value
+ )
+
+ if (sameItems.length > 1) {
+ return new Error(t('project.node.prop_repeat'))
+ }
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'direct',
+ span: 4,
+ options: DIRECT_LIST,
+ value: 'IN',
+ props: {
+ disabled: isSimple
+ }
+ },
+ {
+ type: 'select',
+ field: 'type',
+ span: 6,
+ options: TYPE_LIST,
+ value: 'VARCHAR',
+ props: {
+ disabled: isSimple
+ }
+ },
+ {
+ type: 'input',
+ field: 'value',
+ span: 6,
+ class: 'input-param-value',
+ props: {
+ placeholder: t('project.node.value_tips'),
+ maxLength: 256
+ }
+ }
+ ]
+ }
+ ]
+}
+
+export const TYPE_LIST = [
+ {
+ value: 'VARCHAR',
+ label: 'VARCHAR'
+ },
+ {
+ value: 'INTEGER',
+ label: 'INTEGER'
+ },
+ {
+ value: 'LONG',
+ label: 'LONG'
+ },
+ {
+ value: 'FLOAT',
+ label: 'FLOAT'
+ },
+ {
+ value: 'DOUBLE',
+ label: 'DOUBLE'
+ },
+ {
+ value: 'DATE',
+ label: 'DATE'
+ },
+ {
+ value: 'TIME',
+ label: 'TIME'
+ },
+ {
+ value: 'TIMESTAMP',
+ label: 'TIMESTAMP'
+ },
+ {
+ value: 'BOOLEAN',
+ label: 'BOOLEAN'
+ },
+ {
+ value: 'LIST',
+ label: 'LIST'
+ },
+ {
+ value: 'FILE',
+ label: 'FILE'
+ }
+]
+
+export const DIRECT_LIST = [
+ {
+ value: 'IN',
+ label: 'IN'
+ },
+ {
+ value: 'OUT',
+ label: 'OUT'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-data-factory.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-data-factory.ts
new file mode 100644
index 0000000000..8dc6f5213c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-data-factory.ts
@@ -0,0 +1,152 @@
+/*
+ * 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 {
+ queryDataFactoryFactories,
+ queryDataFactoryPipelines,
+ queryDataFactoryResourceGroups
+} from '@/service/modules/azure'
+import { onMounted, ref, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useDataFactory(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const factoryLoading = ref(false)
+ const resourceGroupLoading = ref(false)
+ const pipelineLoading = ref(false)
+
+ const factoryOptions = ref([] as { label: string; value: number }[])
+ const resourceGroupOptions = ref([] as { label: string; value: number }[])
+ const pipelineOptions = ref([] as { label: string; value: number }[])
+
+ const getFactoryOptions = async () => {
+ if (factoryLoading.value) return
+ factoryLoading.value = true
+ const factories = await queryDataFactoryFactories()
+ factoryOptions.value = factories.map((factory: string) => ({
+ label: factory,
+ value: factory
+ }))
+ factoryLoading.value = false
+ }
+
+ const getResourceGroupName = async () => {
+ if (resourceGroupLoading.value) return
+ resourceGroupLoading.value = true
+ const groupNames = await queryDataFactoryResourceGroups()
+ resourceGroupOptions.value = groupNames.map((groupName: string) => ({
+ label: groupName,
+ value: groupName
+ }))
+ resourceGroupLoading.value = false
+ }
+
+ const getPipelineName = async (
+ factoryName: string,
+ resourceGroupName: string
+ ) => {
+ if (pipelineLoading.value) return
+ pipelineLoading.value = true
+ const pipelineNames = await queryDataFactoryPipelines({
+ factoryName,
+ resourceGroupName
+ })
+ pipelineOptions.value = pipelineNames.map((pipelineName: string) => ({
+ label: pipelineName,
+ value: pipelineName
+ }))
+ pipelineLoading.value = false
+ }
+
+ const onChange = () => {
+ model['pipelineName'] = ''
+ if (model['factoryName'] && model['resourceGroupName']) {
+ getPipelineName(model['factoryName'], model['resourceGroupName'])
+ }
+ }
+
+ watch(
+ () => model['pipelineName'],
+ () => {
+ if (model['pipelineName'] && pipelineOptions.value.length === 0) {
+ getPipelineName(model['factoryName'], model['resourceGroupName'])
+ }
+ }
+ )
+
+ onMounted(() => {
+ getFactoryOptions()
+ getResourceGroupName()
+ })
+
+ return [
+ {
+ type: 'select',
+ field: 'factoryName',
+ span: 24,
+ name: t('project.node.factory_name'),
+ options: factoryOptions,
+ props: {
+ 'on-update:value': onChange,
+ loading: factoryLoading
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.factory_tips')
+ }
+ },
+ {
+ type: 'select',
+ field: 'resourceGroupName',
+ span: 24,
+ name: t('project.node.resource_group_name'),
+ options: resourceGroupOptions,
+ props: {
+ 'on-update:value': onChange,
+ loading: resourceGroupLoading
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.resource_group_tips')
+ }
+ },
+ {
+ type: 'select',
+ field: 'pipelineName',
+ span: 24,
+ name: t('project.node.pipeline_name'),
+ options: pipelineOptions,
+ props: {
+ loading: pipelineLoading
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.pipeline_tips')
+ }
+ },
+ ...useCustomParams({
+ model,
+ field: 'localParams',
+ isSimple: true
+ })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datasource.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datasource.ts
new file mode 100644
index 0000000000..8b4ef0b897
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datasource.ts
@@ -0,0 +1,238 @@
+/*
+ * 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 { ref, onMounted, nextTick, Ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryDataSourceList } from '@/service/modules/data-source'
+import { indexOf, find } from 'lodash'
+import type { IJsonItem } from '../types'
+import type { TypeReq } from '@/service/modules/data-source/types'
+
+export function useDatasource(
+ model: { [field: string]: any },
+ params: {
+ supportedDatasourceType?: string[]
+ typeField?: string
+ sourceField?: string
+ span?: Ref | number
+ testFlag?: Ref | number
+ } = {}
+): IJsonItem[] {
+ const { t } = useI18n()
+
+ const options = ref([] as { label: string; value: string }[])
+ const datasourceOptions = ref([] as { label: string; value: number }[])
+
+ const datasourceTypes = [
+ {
+ id: 0,
+ code: 'MYSQL',
+ disabled: false
+ },
+ {
+ id: 1,
+ code: 'POSTGRESQL',
+ disabled: false
+ },
+ {
+ id: 2,
+ code: 'HIVE',
+ disabled: false
+ },
+ {
+ id: 3,
+ code: 'SPARK',
+ disabled: false
+ },
+ {
+ id: 4,
+ code: 'CLICKHOUSE',
+ disabled: false
+ },
+ {
+ id: 5,
+ code: 'ORACLE',
+ disabled: false
+ },
+ {
+ id: 6,
+ code: 'SQLSERVER',
+ disabled: false
+ },
+ {
+ id: 7,
+ code: 'DB2',
+ disabled: false
+ },
+ {
+ id: 8,
+ code: 'PRESTO',
+ disabled: false
+ },
+ {
+ id: 10,
+ code: 'REDSHIFT',
+ disabled: false
+ },
+ {
+ id: 11,
+ code: 'ATHENA',
+ disabled: false
+ },
+ {
+ id: 12,
+ code: 'TRINO',
+ disabled: false
+ },
+ {
+ id: 13,
+ code: 'STARROCKS',
+ disabled: false
+ },
+ {
+ id: 14,
+ code: 'AZURESQL',
+ disabled: false
+ },
+ {
+ id: 15,
+ code: 'DAMENG',
+ disabled: false
+ },
+ {
+ id: 16,
+ code: 'OCEANBASE',
+ disabled: false
+ },
+ {
+ id: 17,
+ code: 'SSH',
+ disabled: true
+ },
+ {
+ id: 18,
+ code: 'KYUUBI',
+ disabled: false
+ },
+ {
+ id: 19,
+ code: 'DATABEND',
+ disabled: false
+ },
+ {
+ id: 21,
+ code: 'VERTICA',
+ disabled: false
+ },
+ {
+ id: 22,
+ code: 'HANA',
+ disabled: false
+ },
+ {
+ id: 23,
+ code: 'DORIS',
+ disabled: false
+ },
+ {
+ id: 24,
+ code: 'ZEPPELIN',
+ disabled: false
+ },
+ {
+ id: 25,
+ code: 'SAGEMAKER',
+ disabled: false
+ }
+ ]
+
+ const getDatasourceTypes = async () => {
+ options.value = datasourceTypes
+ .filter((item) => {
+ if (item.disabled) {
+ return false
+ }
+ if (params.supportedDatasourceType) {
+ return indexOf(params.supportedDatasourceType, item.code) !== -1
+ }
+ return true
+ })
+ .map((item) => ({ label: item.code, value: item.code }))
+ }
+
+ const refreshOptions = async () => {
+ const parameters = {
+ type: model[params.typeField || 'type'],
+ testFlag: 0
+ } as TypeReq
+ const res = await queryDataSourceList(parameters)
+ datasourceOptions.value = res.map((item: any) => ({
+ label: item.name,
+ value: item.id
+ }))
+ const sourceField = params.sourceField || 'datasource'
+ if (!res.length && model[sourceField]) model[sourceField] = null
+ if (res.length && model[sourceField]) {
+ const item = find(res, { id: model[sourceField] })
+ if (!item) {
+ model[sourceField] = null
+ }
+ }
+ }
+
+ const onChange = () => {
+ refreshOptions()
+ }
+
+ onMounted(async () => {
+ getDatasourceTypes()
+ await nextTick()
+ refreshOptions()
+ })
+ return [
+ {
+ type: 'select',
+ field: params.typeField || 'type',
+ span: params.span || 12,
+ name: t('project.node.datasource_type'),
+ props: {
+ 'on-update:value': onChange
+ },
+ options: options,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true
+ }
+ },
+ {
+ type: 'select',
+ field: params.sourceField || 'datasource',
+ span: params.span || 12,
+ name: t('project.node.datasource_instances'),
+ options: datasourceOptions,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(unuse: any, value) {
+ if (!value && value !== 0) {
+ return Error(t('project.node.datasource_instances'))
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datasync.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datasync.ts
new file mode 100644
index 0000000000..23ccd24d95
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datasync.ts
@@ -0,0 +1,85 @@
+/*
+ * 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 type { IJsonItem } from '../types'
+import { watch, ref } from 'vue'
+import { useCustomParams } from '.'
+
+export function useDatasync(model: { [field: string]: any }): IJsonItem[] {
+ const jsonSpan = ref(0)
+ const destinationLocationArnSpan = ref(0)
+ const sourceLocationArnSpan = ref(0)
+ const nameSpan = ref(0)
+ const cloudWatchLogGroupArnSpan = ref(0)
+
+ const resetSpan = () => {
+ jsonSpan.value = model.jsonFormat ? 24 : 0
+ destinationLocationArnSpan.value = model.jsonFormat ? 0 : 24
+ sourceLocationArnSpan.value = model.jsonFormat ? 0 : 24
+ nameSpan.value = model.jsonFormat ? 0 : 24
+ cloudWatchLogGroupArnSpan.value = model.jsonFormat ? 0 : 24
+ }
+
+ watch(
+ () => [model.jsonFormat],
+ () => {
+ resetSpan()
+ }
+ )
+
+ resetSpan()
+
+ return [
+ {
+ type: 'switch',
+ field: 'jsonFormat',
+ name: 'jsonFormat',
+ span: 12
+ },
+ {
+ type: 'editor',
+ field: 'json',
+ name: 'json',
+ span: jsonSpan
+ },
+ {
+ type: 'input',
+ field: 'destinationLocationArn',
+ name: 'destinationLocationArn',
+ span: destinationLocationArnSpan
+ },
+ {
+ type: 'input',
+ field: 'sourceLocationArn',
+ name: 'sourceLocationArn',
+ span: sourceLocationArnSpan
+ },
+ {
+ type: 'input',
+ field: 'name',
+ name: 'name',
+ span: nameSpan
+ },
+ {
+ type: 'input',
+ field: 'cloudWatchLogGroupArn',
+ name: 'cloudWatchLogGroupArn',
+ span: cloudWatchLogGroupArnSpan
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datax.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datax.ts
new file mode 100644
index 0000000000..24552bfb0b
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-datax.ts
@@ -0,0 +1,256 @@
+/*
+ * 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 { ref, onMounted, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams, useDatasource, useResources } from '.'
+import type { IJsonItem } from '../types'
+
+export function useDataX(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const jobSpeedByteOptions: any[] = [
+ {
+ label: `0(${t('project.node.unlimited')})`,
+ value: 0
+ },
+ {
+ label: '1KB',
+ value: 1024
+ },
+ {
+ label: '10KB',
+ value: 10240
+ },
+ {
+ label: '50KB',
+ value: 51200
+ },
+ {
+ label: '100KB',
+ value: 102400
+ },
+ {
+ label: '512KB',
+ value: 524288
+ }
+ ]
+ const jobSpeedRecordOptions: any[] = [
+ {
+ label: `0(${t('project.node.unlimited')})`,
+ value: 0
+ },
+ {
+ label: '500',
+ value: 500
+ },
+ {
+ label: '1000',
+ value: 1000
+ },
+ {
+ label: '1500',
+ value: 1500
+ },
+ {
+ label: '2000',
+ value: 2000
+ },
+ {
+ label: '2500',
+ value: 2500
+ },
+ {
+ label: '3000',
+ value: 3000
+ }
+ ]
+ const memoryLimitOptions = [
+ {
+ label: '1G',
+ value: 1
+ },
+ {
+ label: '2G',
+ value: 2
+ },
+ {
+ label: '3G',
+ value: 3
+ },
+ {
+ label: '4G',
+ value: 4
+ }
+ ]
+
+ const sqlEditorSpan = ref(24)
+ const jsonEditorSpan = ref(0)
+ const datasourceSpan = ref(12)
+ const destinationDatasourceSpan = ref(8)
+ const otherStatementSpan = ref(22)
+ const jobSpeedSpan = ref(12)
+ const useResourcesSpan = ref(0)
+
+ const initConstants = () => {
+ if (model.customConfig) {
+ sqlEditorSpan.value = 0
+ jsonEditorSpan.value = 24
+ datasourceSpan.value = 0
+ destinationDatasourceSpan.value = 0
+ otherStatementSpan.value = 0
+ jobSpeedSpan.value = 0
+ useResourcesSpan.value = 24
+ } else {
+ sqlEditorSpan.value = 24
+ jsonEditorSpan.value = 0
+ datasourceSpan.value = 12
+ destinationDatasourceSpan.value = 8
+ otherStatementSpan.value = 22
+ jobSpeedSpan.value = 12
+ useResourcesSpan.value = 0
+ }
+ }
+ const supportedDatasourceType = [
+ 'MYSQL',
+ 'POSTGRESQL',
+ 'ORACLE',
+ 'SQLSERVER',
+ 'CLICKHOUSE',
+ 'DATABEND',
+ 'HIVE',
+ 'PRESTO'
+ ]
+ onMounted(() => {
+ initConstants()
+ })
+ watch(
+ () => model.customConfig,
+ () => {
+ initConstants()
+ }
+ )
+
+ return [
+ {
+ type: 'switch',
+ field: 'customConfig',
+ name: t('project.node.datax_custom_template')
+ },
+ ...useDatasource(model, {
+ typeField: 'dsType',
+ sourceField: 'dataSource',
+ span: datasourceSpan,
+ supportedDatasourceType
+ }),
+ {
+ type: 'editor',
+ field: 'sql',
+ name: t('project.node.sql_statement'),
+ span: sqlEditorSpan,
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.sql_empty_tips')
+ }
+ },
+ {
+ type: 'editor',
+ field: 'json',
+ name: t('project.node.datax_json_template'),
+ span: jsonEditorSpan,
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.sql_empty_tips')
+ }
+ },
+ useResources(useResourcesSpan),
+ ...useDatasource(model, {
+ typeField: 'dtType',
+ sourceField: 'dataTarget',
+ span: destinationDatasourceSpan,
+ supportedDatasourceType
+ }),
+ {
+ type: 'input',
+ field: 'targetTable',
+ name: t('project.node.datax_target_table'),
+ span: destinationDatasourceSpan,
+ props: {
+ placeholder: t('project.node.datax_target_table_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true
+ }
+ },
+ {
+ type: 'multi-input',
+ field: 'preStatements',
+ name: t('project.node.datax_target_database_pre_sql'),
+ span: otherStatementSpan,
+ props: {
+ placeholder: t('project.node.datax_non_query_sql_tips'),
+ type: 'textarea',
+ autosize: { minRows: 1 }
+ }
+ },
+ {
+ type: 'multi-input',
+ field: 'postStatements',
+ name: t('project.node.datax_target_database_post_sql'),
+ span: otherStatementSpan,
+ props: {
+ placeholder: t('project.node.datax_non_query_sql_tips'),
+ type: 'textarea',
+ autosize: { minRows: 1 }
+ }
+ },
+ {
+ type: 'select',
+ field: 'jobSpeedByte',
+ name: t('project.node.datax_job_speed_byte'),
+ span: jobSpeedSpan,
+ options: jobSpeedByteOptions,
+ value: 0
+ },
+ {
+ type: 'select',
+ field: 'jobSpeedRecord',
+ name: t('project.node.datax_job_speed_record'),
+ span: jobSpeedSpan,
+ options: jobSpeedRecordOptions,
+ value: 1000
+ },
+ {
+ type: 'select',
+ field: 'xms',
+ name: t('project.node.datax_job_runtime_memory_xms'),
+ span: 12,
+ options: memoryLimitOptions,
+ value: 1
+ },
+ {
+ type: 'select',
+ field: 'xmx',
+ name: t('project.node.datax_job_runtime_memory_xmx'),
+ span: 12,
+ options: memoryLimitOptions,
+ value: 1
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: true })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-delay-time.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-delay-time.ts
new file mode 100644
index 0000000000..12a6702362
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-delay-time.ts
@@ -0,0 +1,36 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useDelayTime(model: { [field: string]: any }): IJsonItem {
+ const { t } = useI18n()
+ return {
+ type: 'input-number',
+ field: 'delayTime',
+ name: t('project.node.delay_execution_time'),
+ span: 12,
+ props: {
+ min: 0
+ },
+ slots: {
+ suffix: () => t('project.node.minute')
+ },
+ value: model.delayTime || 0
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dependent-timeout.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dependent-timeout.ts
new file mode 100644
index 0000000000..a84e50b43d
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dependent-timeout.ts
@@ -0,0 +1,109 @@
+/*
+ * 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 { computed, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useDependentTimeout(model: {
+ [field: string]: any
+}): IJsonItem[] {
+ const { t } = useI18n()
+ const timeCompleteSpan = computed(() => (model.timeoutShowFlag ? 24 : 0))
+ const timeCompleteEnableSpan = computed(() =>
+ model.timeoutFlag && model.timeoutShowFlag ? 12 : 0
+ )
+
+ const strategyOptions = [
+ {
+ label: t('project.node.timeout_alarm'),
+ value: 'WARN'
+ },
+ {
+ label: t('project.node.timeout_failure'),
+ value: 'FAILED'
+ }
+ ]
+
+ watch(
+ () => model.timeoutFlag,
+ (timeoutFlag) => {
+ model.timeoutShowFlag = timeoutFlag
+ }
+ )
+
+ return [
+ {
+ type: 'switch',
+ field: 'timeoutShowFlag',
+ name: t('project.node.timeout_alarm')
+ },
+ {
+ type: 'switch',
+ field: 'timeoutFlag',
+ name: t('project.node.waiting_dependent_complete'),
+ props: {
+ 'on-update:value': (value: boolean) => {
+ if (value) {
+ if (!model.timeoutNotifyStrategy.length) {
+ model.timeoutNotifyStrategy = ['WARN']
+ }
+ if (!model.timeout) {
+ model.timeout = 30
+ }
+ }
+ }
+ },
+ span: timeCompleteSpan
+ },
+ {
+ type: 'input-number',
+ field: 'timeout',
+ name: t('project.node.timeout_period'),
+ span: timeCompleteEnableSpan,
+ props: {
+ max: Math.pow(9, 10) - 1
+ },
+ slots: {
+ suffix: () => t('project.node.minute')
+ },
+ validate: {
+ trigger: ['input'],
+ validator(validate: any, value: number) {
+ if (model.timeoutFlag && !/^[1-9]\d*$/.test(String(value))) {
+ return new Error(t('project.node.timeout_period_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'checkbox',
+ field: 'timeoutNotifyStrategy',
+ name: t('project.node.timeout_strategy'),
+ options: strategyOptions,
+ span: timeCompleteEnableSpan,
+ validate: {
+ trigger: ['input'],
+ validator(validate: any, value: []) {
+ if (model.waitCompleteTimeoutEnable && !value.length) {
+ return new Error(t('project.node.timeout_strategy_tips'))
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dependent.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dependent.ts
new file mode 100644
index 0000000000..4a8e8cf2c0
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dependent.ts
@@ -0,0 +1,550 @@
+/*
+ * 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 { ref, onMounted, watch, h, computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { NEllipsis, NIcon } from 'naive-ui'
+import { useRelationCustomParams, useDependentTimeout } from '.'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import { queryAllProjectListForDependent } from '@/service/modules/projects'
+import { tasksState } from '@/common/common'
+import {
+ queryProcessDefinitionList,
+ getTasksByDefinitionList
+} from '@/service/modules/process-definition'
+import { Router, useRouter } from 'vue-router'
+import type {
+ IJsonItem,
+ IDependentItem,
+ IDependentItemOptions,
+ IDependTaskOptions,
+ IDependTask,
+ ITaskState,
+ IDateType
+} from '../types'
+import { IRenderOption } from '../types'
+
+export function useDependent(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const router: Router = useRouter()
+ const nodeStore = useTaskNodeStore()
+
+ const dependentFailurePolicyOptions = computed(() => {
+ return [
+ {
+ label: t('project.node.dependent_failure_policy_failure'),
+ value: 'DEPENDENT_FAILURE_FAILURE'
+ },
+ {
+ label: t('project.node.dependent_failure_policy_waiting'),
+ value: 'DEPENDENT_FAILURE_WAITING'
+ }
+ ]
+ })
+ const failureWaitingTimeSpan = computed(() =>
+ model.failurePolicy === 'DEPENDENT_FAILURE_WAITING' ? 12 : 0
+ )
+ const dependentResult = nodeStore.getDependentResult
+ const TasksStateConfig = tasksState(t)
+ const projectList = ref([] as IRenderOption[])
+ const processCache = {} as {
+ [key: number]: IRenderOption[]
+ }
+ const taskCache = {} as {
+ [key: number]: IRenderOption[]
+ }
+ const selectOptions = ref([] as IDependTaskOptions[])
+
+ const DependentTypeOptions = [
+ {
+ value: 'DEPENDENT_ON_WORKFLOW',
+ label: t('project.node.dependent_on_workflow')
+ },
+ {
+ value: 'DEPENDENT_ON_TASK',
+ label: t('project.node.dependent_on_task')
+ }
+ ]
+
+ const CYCLE_LIST = [
+ {
+ value: 'month',
+ label: t('project.node.month')
+ },
+ {
+ value: 'week',
+ label: t('project.node.week')
+ },
+ {
+ value: 'day',
+ label: t('project.node.day')
+ },
+ {
+ value: 'hour',
+ label: t('project.node.hour')
+ }
+ ]
+ const DATE_LIST = {
+ hour: [
+ {
+ value: 'currentHour',
+ label: t('project.node.current_hour')
+ },
+ {
+ value: 'last1Hour',
+ label: t('project.node.last_1_hour')
+ },
+ {
+ value: 'last2Hours',
+ label: t('project.node.last_2_hour')
+ },
+ {
+ value: 'last3Hours',
+ label: t('project.node.last_3_hour')
+ },
+ {
+ value: 'last24Hours',
+ label: t('project.node.last_24_hour')
+ }
+ ],
+ day: [
+ {
+ value: 'today',
+ label: t('project.node.today')
+ },
+ {
+ value: 'last1Days',
+ label: t('project.node.last_1_days')
+ },
+ {
+ value: 'last2Days',
+ label: t('project.node.last_2_days')
+ },
+ {
+ value: 'last3Days',
+ label: t('project.node.last_3_days')
+ },
+ {
+ value: 'last7Days',
+ label: t('project.node.last_7_days')
+ }
+ ],
+ week: [
+ {
+ value: 'thisWeek',
+ label: t('project.node.this_week')
+ },
+ {
+ value: 'lastWeek',
+ label: t('project.node.last_week')
+ },
+ {
+ value: 'lastMonday',
+ label: t('project.node.last_monday')
+ },
+ {
+ value: 'lastTuesday',
+ label: t('project.node.last_tuesday')
+ },
+ {
+ value: 'lastWednesday',
+ label: t('project.node.last_wednesday')
+ },
+ {
+ value: 'lastThursday',
+ label: t('project.node.last_thursday')
+ },
+ {
+ value: 'lastFriday',
+ label: t('project.node.last_friday')
+ },
+ {
+ value: 'lastSaturday',
+ label: t('project.node.last_saturday')
+ },
+ {
+ value: 'lastSunday',
+ label: t('project.node.last_sunday')
+ }
+ ],
+ month: [
+ {
+ value: 'thisMonth',
+ label: t('project.node.this_month')
+ },
+ {
+ value: 'thisMonthBegin',
+ label: t('project.node.this_month_begin')
+ },
+ {
+ value: 'lastMonth',
+ label: t('project.node.last_month')
+ },
+ {
+ value: 'lastMonthBegin',
+ label: t('project.node.last_month_begin')
+ },
+ {
+ value: 'lastMonthEnd',
+ label: t('project.node.last_month_end')
+ }
+ ]
+ } as { [key in IDateType]: { value: string; label: string }[] }
+
+ const getProjectList = async () => {
+ const result = await queryAllProjectListForDependent()
+ projectList.value = result.map((item: { code: number; name: string }) => ({
+ value: item.code,
+ label: () => h(NEllipsis, null, item.name),
+ filterLabel: item.name
+ }))
+ return projectList
+ }
+ const getProcessList = async (code: number) => {
+ if (processCache[code]) {
+ return processCache[code]
+ }
+ const result = await queryProcessDefinitionList(code)
+ const processList = result.map((item: { code: number; name: string }) => ({
+ value: item.code,
+ label: () => h(NEllipsis, null, item.name),
+ filterLabel: item.name
+ }))
+ processCache[code] = processList
+
+ return processList
+ }
+
+ const getTaskList = async (code: number, processCode: number) => {
+ if (taskCache[processCode]) {
+ return taskCache[processCode]
+ }
+ const result = await getTasksByDefinitionList(code, processCode)
+ const taskList = result.map((item: { code: number; name: string }) => ({
+ value: item.code,
+ label: () => h(NEllipsis, null, item.name),
+ filterLabel: item.name
+ }))
+ taskList.unshift({
+ value: -1,
+ label: 'ALL',
+ filterLabel: 'ALL'
+ })
+ taskCache[processCode] = taskList
+ return taskList
+ }
+
+ const renderState = (item: {
+ definitionCode: number
+ depTaskCode: number
+ cycle: string
+ dateValue: string
+ }) => {
+ if (!item || router.currentRoute.value.name !== 'workflow-instance-detail')
+ return null
+ const key = `${item.definitionCode}-${item.depTaskCode}-${item.cycle}-${item.dateValue}`
+ const state: ITaskState = dependentResult[key]
+ return h(NIcon, { size: 24, color: TasksStateConfig[state]?.color }, () =>
+ h(TasksStateConfig[state]?.icon)
+ )
+ }
+
+ onMounted(() => {
+ getProjectList()
+ })
+
+ watch(
+ () => model.dependTaskList,
+ (value) => {
+ selectOptions.value = []
+ value.forEach((item: IDependTask, taskIndex: number) => {
+ if (!item.dependItemList?.length) return
+
+ const itemListOptions = ref([] as IDependentItemOptions[])
+ item.dependItemList?.forEach(
+ async (dependItem: IDependentItem, itemIndex: number) => {
+ itemListOptions.value[itemIndex] = {}
+
+ if (!dependItem.dependentType) {
+ if (dependItem.depTaskCode == 0)
+ dependItem.dependentType = 'DEPENDENT_ON_WORKFLOW'
+ else dependItem.dependentType = 'DEPENDENT_ON_TASK'
+ }
+ if (dependItem.projectCode) {
+ itemListOptions.value[itemIndex].definitionCodeOptions =
+ await getProcessList(dependItem.projectCode)
+ }
+ if (dependItem.projectCode && dependItem.definitionCode) {
+ itemListOptions.value[itemIndex].depTaskCodeOptions =
+ await getTaskList(
+ dependItem.projectCode,
+ dependItem.definitionCode
+ )
+ }
+ if (dependItem.cycle) {
+ itemListOptions.value[itemIndex].dateOptions =
+ DATE_LIST[dependItem.cycle]
+ }
+ }
+ )
+ selectOptions.value[taskIndex] = {} as IDependTaskOptions
+ selectOptions.value[taskIndex].dependItemList = itemListOptions.value
+ })
+ }
+ )
+
+ return [
+ ...useDependentTimeout(model),
+ ...useRelationCustomParams({
+ model,
+ children: (i = 0) => ({
+ type: 'custom-parameters',
+ field: 'dependItemList',
+ span: 18,
+ children: [
+ (j = 0) => ({
+ type: 'select',
+ field: 'dependentType',
+ name: t('project.node.dependent_type'),
+ span: 24,
+ props: {
+ onUpdateValue: (dependentType: string) => {
+ const item = model.dependTaskList[i].dependItemList[j]
+ if (item.definitionCode)
+ item.depTaskCode =
+ dependentType === 'DEPENDENT_ON_WORKFLOW' ? 0 : -1
+ }
+ },
+ options: DependentTypeOptions,
+ value: 'DEPENDENT_ON_WORKFLOW'
+ }),
+ (j = 0) => ({
+ type: 'select',
+ field: 'projectCode',
+ name: t('project.node.project_name'),
+ span: 24,
+ props: {
+ filterable: true,
+ filter: (query: string, option: IRenderOption) => {
+ return option.filterLabel
+ .toLowerCase()
+ .includes(query.toLowerCase())
+ },
+ onUpdateValue: async (projectCode: number) => {
+ const item = model.dependTaskList[i].dependItemList[j]
+ const options = selectOptions?.value[i] || {}
+ const itemListOptions = options?.dependItemList || []
+ const itemOptions = {} as IDependentItemOptions
+ itemOptions.definitionCodeOptions = await getProcessList(
+ projectCode
+ )
+ itemListOptions[j] = itemOptions
+ options.dependItemList = itemListOptions
+ selectOptions.value[i] = options
+ item.depTaskCode = null
+ item.definitionCode = null
+ item.parameterPassing = false
+ }
+ },
+ options: projectList,
+ path: `dependTaskList.${i}.dependItemList.${j}.projectCode`,
+ rule: {
+ required: true,
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!value) {
+ return Error(t('project.node.project_name_tips'))
+ }
+ }
+ }
+ }),
+ (j = 0) => ({
+ type: 'select',
+ field: 'definitionCode',
+ span: 24,
+ name: t('project.node.process_name'),
+ props: {
+ filterable: true,
+ filter: (query: string, option: IRenderOption) => {
+ return option.filterLabel
+ .toLowerCase()
+ .includes(query.toLowerCase())
+ },
+ onUpdateValue: async (processCode: number) => {
+ const item = model.dependTaskList[i].dependItemList[j]
+ selectOptions.value[i].dependItemList[j].depTaskCodeOptions =
+ await getTaskList(item.projectCode, processCode)
+ item.depTaskCode =
+ item.dependentType === 'DEPENDENT_ON_WORKFLOW' ? 0 : -1
+ }
+ },
+ options:
+ selectOptions.value[i]?.dependItemList[j]
+ ?.definitionCodeOptions || [],
+ path: `dependTaskList.${i}.dependItemList.${j}.definitionCode`,
+ rule: {
+ required: true,
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!value) {
+ return Error(t('project.node.process_name_tips'))
+ }
+ }
+ }
+ }),
+ (j = 0) => ({
+ type: 'select',
+ field: 'depTaskCode',
+ span: computed(() => {
+ const item = model.dependTaskList[i].dependItemList[j]
+ return item.dependentType === 'DEPENDENT_ON_WORKFLOW' ? 0 : 24
+ }),
+ name: t('project.node.task_name'),
+ props: {
+ filterable: true,
+ filter: (query: string, option: IRenderOption) => {
+ return option.filterLabel
+ .toLowerCase()
+ .includes(query.toLowerCase())
+ }
+ },
+ options:
+ selectOptions.value[i]?.dependItemList[j]?.depTaskCodeOptions ||
+ [],
+ path: `dependTaskList.${i}.dependItemList.${j}.depTaskCode`,
+ rule: {
+ required: true,
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: number) {
+ if (!value && value !== 0) {
+ return Error(t('project.node.task_name_tips'))
+ }
+ }
+ }
+ }),
+ (j = 0) => ({
+ type: 'select',
+ field: 'cycle',
+ span: 10,
+ name: t('project.node.cycle_time'),
+ props: {
+ onUpdateValue: (value: IDateType) => {
+ selectOptions.value[i].dependItemList[j].dateOptions =
+ DATE_LIST[value]
+ model.dependTaskList[i].dependItemList[j].dateValue = null
+ }
+ },
+ options: CYCLE_LIST,
+ path: `dependTaskList.${i}.dependItemList.${j}.cycle`,
+ rule: {
+ required: true,
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!value) {
+ return Error(t('project.node.cycle_time_tips'))
+ }
+ }
+ }
+ }),
+ (j = 0) => ({
+ type: 'select',
+ field: 'dateValue',
+ span: 10,
+ name: ' ',
+ options:
+ selectOptions.value[i]?.dependItemList[j]?.dateOptions || [],
+ path: `dependTaskList.${i}.dependItemList.${j}.dateValue`,
+ rule: {
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!value) {
+ return Error(t('project.node.date_tips'))
+ }
+ }
+ }
+ }),
+ (j = 0) => ({
+ type: 'switch',
+ field: 'parameterPassing',
+ span: 20,
+ name: t('project.node.dependent_task_parameter_passing'),
+ path: `dependTaskList.${i}.dependItemList.${j}.parameterPassing`
+ }),
+ (j = 0) => ({
+ type: 'custom',
+ field: 'state',
+ span: 2,
+ name: ' ',
+ widget: renderState(model.dependTaskList[i]?.dependItemList[j])
+ })
+ ]
+ }),
+ childrenField: 'dependItemList',
+ name: 'add_dependency'
+ }),
+ {
+ type: 'input-number',
+ field: 'checkInterval',
+ name: t('project.node.check_interval'),
+ span: 12,
+ props: {
+ max: Math.pow(9, 10) - 1
+ },
+ slots: {
+ suffix: () => t('project.node.second')
+ },
+ validate: {
+ trigger: ['input'],
+ validator(validate: any, value: number) {
+ if (!value && !/^[1-9]\d*$/.test(String(value))) {
+ return new Error(t('project.node.check_interval_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'radio',
+ field: 'failurePolicy',
+ name: t('project.node.dependent_failure_policy'),
+ options: dependentFailurePolicyOptions,
+ span: 24
+ },
+ {
+ type: 'input-number',
+ field: 'failureWaitingTime',
+ name: t('project.node.dependent_failure_waiting_time'),
+ span: failureWaitingTimeSpan,
+ props: {
+ max: Math.pow(9, 10) - 1
+ },
+ slots: {
+ suffix: () => t('project.node.minute')
+ },
+ validate: {
+ trigger: ['input'],
+ required: true,
+ validator(validate: any, value: number) {
+ if (model.timeoutFlag && !/^[1-9]\d*$/.test(String(value))) {
+ return new Error(
+ t('project.node.dependent_failure_waiting_time_tips')
+ )
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-deploy-mode.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-deploy-mode.ts
new file mode 100644
index 0000000000..81587b96f0
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-deploy-mode.ts
@@ -0,0 +1,67 @@
+/*
+ * 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 { Ref, ref, watchEffect } from 'vue'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem, IOption } from '../types'
+
+export function useDeployMode(
+ span: number | Ref = 24,
+ showClient = ref(true),
+ showCluster = ref(true),
+ showLocal = ref(true)
+): IJsonItem {
+ const { t } = useI18n()
+
+ const deployModeOptions = ref(DEPLOY_MODES as IOption[])
+
+ watchEffect(() => {
+ deployModeOptions.value = DEPLOY_MODES.filter((option) => {
+ switch (option.value) {
+ case 'cluster':
+ return showCluster.value
+ case 'client':
+ return showClient.value
+ case 'local':
+ return showLocal.value
+ default:
+ return true
+ }
+ })
+ })
+ return {
+ type: 'radio',
+ field: 'deployMode',
+ name: t('project.node.deploy_mode'),
+ options: deployModeOptions,
+ span: span
+ }
+}
+
+export const DEPLOY_MODES = [
+ {
+ label: 'cluster',
+ value: 'cluster'
+ },
+ {
+ label: 'client',
+ value: 'client'
+ },
+ {
+ label: 'local',
+ value: 'local'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-description.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-description.ts
new file mode 100644
index 0000000000..e317554c4e
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-description.ts
@@ -0,0 +1,33 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useDescription(): IJsonItem {
+ const { t } = useI18n()
+ return {
+ type: 'input',
+ field: 'description',
+ name: t('project.node.description'),
+ props: {
+ placeholder: t('project.node.description_tips'),
+ rows: 2,
+ type: 'textarea'
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dinky.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dinky.ts
new file mode 100644
index 0000000000..d043b2209d
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dinky.ts
@@ -0,0 +1,66 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useDinky(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'input',
+ field: 'address',
+ name: t('project.node.dinky_address'),
+ props: {
+ placeholder: t('project.node.dinky_address_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(_validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.dinky_address_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'taskId',
+ name: t('project.node.dinky_task_id'),
+ props: {
+ placeholder: t('project.node.dinky_task_id_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(_validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.dinky_task_id_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'switch',
+ field: 'online',
+ name: t('project.node.dinky_online')
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dms.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dms.ts
new file mode 100644
index 0000000000..7c566141b6
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dms.ts
@@ -0,0 +1,141 @@
+/*
+ * 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 type { IJsonItem } from '../types'
+import { watch, ref } from 'vue'
+import { useCustomParams, useResources } from '.'
+
+export function useDms(model: { [field: string]: any }): IJsonItem[] {
+ const jsonDataSpan = ref(0)
+ const replicationTaskArnSpan = ref(0)
+ const replicationTaskIdentifierSpan = ref(0)
+ const sourceEndpointArnSpan = ref(0)
+ const targetEndpointArnSpan = ref(0)
+ const replicationInstanceArnSpan = ref(0)
+ const migrationTypeSpan = ref(0)
+ const tableMappingsSpan = ref(0)
+
+ const setFlag = () => {
+ model.isCreateAndNotJson =
+ !model.isRestartTask && !model.isJsonFormat ? true : false
+ model.isRestartAndNotJson =
+ model.isRestartTask && !model.isJsonFormat ? true : false
+ }
+
+ const resetSpan = () => {
+ jsonDataSpan.value = model.isJsonFormat ? 24 : 0
+ replicationTaskArnSpan.value = model.isRestartAndNotJson ? 24 : 0
+ migrationTypeSpan.value = model.isCreateAndNotJson ? 24 : 0
+ sourceEndpointArnSpan.value = model.isCreateAndNotJson ? 24 : 0
+ replicationTaskIdentifierSpan.value = model.isCreateAndNotJson ? 24 : 0
+ targetEndpointArnSpan.value = model.isCreateAndNotJson ? 24 : 0
+ replicationInstanceArnSpan.value = model.isCreateAndNotJson ? 24 : 0
+ tableMappingsSpan.value = model.isCreateAndNotJson ? 24 : 0
+ }
+
+ watch(
+ () => [model.isRestartTask, model.isJsonFormat],
+ () => {
+ setFlag()
+ resetSpan()
+ }
+ )
+
+ setFlag()
+ resetSpan()
+
+ return [
+ {
+ type: 'switch',
+ field: 'isRestartTask',
+ name: 'isRestartTask',
+ span: 12
+ },
+ {
+ type: 'switch',
+ field: 'isJsonFormat',
+ name: 'isJsonFormat',
+ span: 12
+ },
+ {
+ type: 'editor',
+ field: 'jsonData',
+ name: 'jsonData',
+ span: jsonDataSpan
+ },
+ {
+ type: 'select',
+ field: 'migrationType',
+ name: 'migrationType',
+ span: migrationTypeSpan,
+ options: MIGRATION_TYPE
+ },
+ {
+ type: 'input',
+ field: 'replicationTaskIdentifier',
+ name: 'replicationTaskIdentifier',
+ span: replicationTaskIdentifierSpan
+ },
+ {
+ type: 'input',
+ field: 'replicationInstanceArn',
+ name: 'replicationInstanceArn',
+ span: replicationInstanceArnSpan
+ },
+ {
+ type: 'input',
+ field: 'sourceEndpointArn',
+ name: 'sourceEndpointArn',
+ span: sourceEndpointArnSpan
+ },
+ {
+ type: 'input',
+ field: 'targetEndpointArn',
+ name: 'targetEndpointArn',
+ span: targetEndpointArnSpan
+ },
+ {
+ type: 'editor',
+ field: 'tableMappings',
+ name: 'tableMappings',
+ span: tableMappingsSpan
+ },
+ {
+ type: 'input',
+ field: 'replicationTaskArn',
+ name: 'replicationTaskArn',
+ span: replicationTaskArnSpan
+ },
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
+
+export const MIGRATION_TYPE = [
+ {
+ label: 'full-load',
+ value: 'full-load'
+ },
+ {
+ label: 'cdc',
+ value: 'cdc'
+ },
+ {
+ label: 'full-load-and-cdc',
+ value: 'full-load-and-cdc'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-driver-cores.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-driver-cores.ts
new file mode 100644
index 0000000000..82b06f0277
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-driver-cores.ts
@@ -0,0 +1,42 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useDriverCores(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input-number',
+ field: 'driverCores',
+ name: t('project.node.driver_cores'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.driver_cores_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.driver_cores_tips'))
+ }
+ }
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-driver-memory.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-driver-memory.ts
new file mode 100644
index 0000000000..6ba53b137b
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-driver-memory.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useDriverMemory(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input',
+ field: 'driverMemory',
+ name: t('project.node.driver_memory'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.driver_memory_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.driver_memory_tips'))
+ }
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.driver_memory') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dvc.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dvc.ts
new file mode 100644
index 0000000000..0ceac153c3
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dvc.ts
@@ -0,0 +1,171 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+import { watch, ref } from 'vue'
+
+export const DVC_TASK_TYPE = [
+ {
+ label: 'Upload',
+ value: 'Upload'
+ },
+ {
+ label: 'Download',
+ value: 'Download'
+ },
+ {
+ label: 'Init DVC',
+ value: 'Init DVC'
+ }
+]
+
+export function useDvc(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const dvcLoadSaveDataPathSpan = ref(0)
+ const dvcDataLocationSpan = ref(0)
+ const dvcVersionSpan = ref(0)
+ const dvcMessageSpan = ref(0)
+ const dvcStoreUrlSpan = ref(0)
+
+ const setFlag = () => {
+ model.isUpload = model.dvcTaskType === 'Upload'
+ model.isDownload = model.dvcTaskType === 'Download'
+ model.isInit = model.dvcTaskType === 'Init DVC'
+ }
+
+ const resetData = () => {
+ dvcLoadSaveDataPathSpan.value = model.isUpload || model.isDownload ? 24 : 0
+ dvcDataLocationSpan.value = model.isUpload || model.isDownload ? 24 : 0
+ dvcVersionSpan.value = model.isUpload || model.isDownload ? 24 : 0
+ dvcMessageSpan.value = model.isUpload ? 24 : 0
+ dvcStoreUrlSpan.value = model.isInit ? 24 : 0
+ }
+
+ watch(
+ () => [model.dvcTaskType],
+ () => {
+ setFlag()
+ resetData()
+ }
+ )
+ setFlag()
+ resetData()
+
+ return [
+ {
+ type: 'select',
+ field: 'dvcTaskType',
+ name: t('project.node.dvc_task_type'),
+ span: 12,
+ options: DVC_TASK_TYPE
+ },
+ {
+ type: 'input',
+ field: 'dvcRepository',
+ name: t('project.node.dvc_repository'),
+ span: 24,
+ props: {
+ placeholder: t('project.node.dvc_repository_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.dvc_empty_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'dvcDataLocation',
+ name: t('project.node.dvc_data_location'),
+ props: { placeholder: 'dvcDataLocation' },
+ span: dvcDataLocationSpan,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if ((model.isUpload || model.isDownload) && !value) {
+ return new Error(t('project.node.dvc_empty_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'dvcLoadSaveDataPath',
+ name: t('project.node.dvc_load_save_data_path'),
+ span: dvcLoadSaveDataPathSpan,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if ((model.isUpload || model.isDownload) && !value) {
+ return new Error(t('project.node.dvc_empty_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'dvcVersion',
+ name: t('project.node.dvc_version'),
+ span: dvcVersionSpan,
+ props: {
+ placeholder: t('project.node.dvc_version_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if ((model.isUpload || model.isDownload) && !value) {
+ return new Error(t('project.node.dvc_empty_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'dvcMessage',
+ name: t('project.node.dvc_message'),
+ span: dvcMessageSpan,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (model.isUpload && !value) {
+ return new Error(t('project.node.dvc_empty_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'dvcStoreUrl',
+ name: t('project.node.dvc_store_url'),
+ span: dvcStoreUrlSpan,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!model.isInit && value) {
+ return new Error(t('project.node.dvc_empty_tips'))
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dynamic.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dynamic.ts
new file mode 100644
index 0000000000..08e47c2d98
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-dynamic.ts
@@ -0,0 +1,120 @@
+/*
+ * 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 type { IJsonItem } from '../types'
+import { useI18n } from 'vue-i18n'
+
+export function useDynamic(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'input-number',
+ field: 'maxNumOfSubWorkflowInstances',
+ span: 12,
+ name: t('project.node.max_num_of_sub_workflow_instances'),
+ validate: {
+ required: true
+ }
+ },
+ {
+ type: 'input-number',
+ field: 'degreeOfParallelism',
+ span: 12,
+ name: t('project.node.parallelism'),
+ validate: {
+ required: true
+ }
+ },
+ {
+ type: 'custom-parameters',
+ field: 'listParameters',
+ name: t('project.node.params_value'),
+ span: 24,
+ children: [
+ {
+ type: 'input',
+ field: 'name',
+ span: 8,
+ props: {
+ placeholder: t('project.node.dynamic_name_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.dynamic_name_tips'))
+ }
+
+ const sameItems = model['listParameters'].filter(
+ (item: { name: string }) => item.name === value
+ )
+
+ if (sameItems.length > 1) {
+ return new Error(t('project.node.prop_repeat'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'value',
+ span: 8,
+ props: {
+ placeholder: t('project.node.dynamic_value_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.dynamic_value_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'separator',
+ span: 4,
+ props: {
+ placeholder: t('project.node.dynamic_separator_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.dynamic_separator_tips'))
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ type: 'input',
+ field: 'filterCondition',
+ span: 24,
+ name: t('project.node.filter_condition')
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-emr.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-emr.ts
new file mode 100644
index 0000000000..2d89af61d0
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-emr.ts
@@ -0,0 +1,89 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+import { computed } from 'vue'
+
+export function useEmr(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const jobFlowDefineJsonSpan = computed(() =>
+ model.programType === 'RUN_JOB_FLOW' ? 24 : 0
+ )
+
+ const stepsDefineJsonSpan = computed(() =>
+ model.programType === 'ADD_JOB_FLOW_STEPS' ? 24 : 0
+ )
+
+ return [
+ {
+ type: 'select',
+ field: 'programType',
+ span: 24,
+ name: t('project.node.program_type'),
+ options: PROGRAM_TYPES,
+ validate: {
+ required: true
+ }
+ },
+ {
+ type: 'editor',
+ field: 'jobFlowDefineJson',
+ span: jobFlowDefineJsonSpan,
+ name: t('project.node.emr_flow_define_json'),
+ props: {
+ language: 'json'
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.emr_flow_define_json_tips')
+ }
+ },
+ {
+ type: 'editor',
+ field: 'stepsDefineJson',
+ span: stepsDefineJsonSpan,
+ name: t('project.node.emr_steps_define_json'),
+ props: {
+ language: 'json'
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.emr_steps_define_json_tips')
+ }
+ },
+ ...useCustomParams({
+ model,
+ field: 'localParams',
+ isSimple: true
+ })
+ ]
+}
+
+export const PROGRAM_TYPES = [
+ {
+ label: 'RUN_JOB_FLOW',
+ value: 'RUN_JOB_FLOW'
+ },
+ {
+ label: 'ADD_JOB_FLOW_STEPS',
+ value: 'ADD_JOB_FLOW_STEPS'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-environment-name.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-environment-name.ts
new file mode 100644
index 0000000000..111310a471
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-environment-name.ts
@@ -0,0 +1,105 @@
+/*
+ * 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 { ref, onMounted, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryAllEnvironmentList } from '@/service/modules/environment'
+import type { IEnvironmentNameOption, IJsonItem } from '../types'
+
+export function useEnvironmentName(
+ model: { [field: string]: any },
+ isCreate: boolean
+): IJsonItem {
+ const { t } = useI18n()
+
+ let environmentList = [] as IEnvironmentNameOption[]
+ const options = ref([] as IEnvironmentNameOption[])
+ const loading = ref(false)
+ let mounted = false
+
+ const getEnvironmentList = async () => {
+ if (loading.value) return
+ loading.value = true
+ const res = await queryAllEnvironmentList()
+ environmentList = res.map(
+ (item: { code: string; name: string; workerGroups: string[] }) => ({
+ label: item.name,
+ value: item.code,
+ workerGroups: item.workerGroups
+ })
+ )
+ options.value = environmentList.filter((option: IEnvironmentNameOption) =>
+ filterByWorkerGroup(option)
+ )
+ loading.value = false
+ if (options.value.length === 0) {
+ model.environmentCode = null
+ } else {
+ isCreate &&
+ !model.environmentCode &&
+ (model.environmentCode = options.value[0].value)
+ }
+ }
+
+ const filterByWorkerGroup = (option: IEnvironmentNameOption) => {
+ if (!model.workerGroup) return false
+ if (!option?.workerGroups?.length) return false
+ return option.workerGroups.indexOf(model.workerGroup) !== -1
+ }
+
+ watch(
+ () => model.workerGroup,
+ () => {
+ if (!model.workerGroup || !mounted) return
+ options.value = environmentList.filter((option: IEnvironmentNameOption) =>
+ filterByWorkerGroup(option)
+ )
+ if (model?.environmentCode) {
+ if (options.value) {
+ const elementExists =
+ options.value.find(
+ (item) => item.value === model.environmentCode
+ ) !== undefined
+ if (!elementExists) {
+ model.environmentCode = null
+ }
+ }
+ } else {
+ model.environmentCode =
+ options.value.length === 0 ? null : options.value[0].value
+ }
+ }
+ )
+
+ onMounted(async () => {
+ await getEnvironmentList()
+ mounted = true
+ })
+
+ return {
+ type: 'select',
+ field: 'environmentCode',
+ class: 'env-select',
+ span: 12,
+ name: t('project.node.environment_name'),
+ props: {
+ loading: loading,
+ clearable: true
+ },
+ options: options
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-cores.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-cores.ts
new file mode 100644
index 0000000000..87540197c5
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-cores.ts
@@ -0,0 +1,42 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useExecutorCores(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input-number',
+ field: 'executorCores',
+ name: t('project.node.executor_cores'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.executor_cores_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.executor_cores_tips'))
+ }
+ }
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-memory.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-memory.ts
new file mode 100644
index 0000000000..b135d22751
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-memory.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useExecutorMemory(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input',
+ field: 'executorMemory',
+ name: t('project.node.executor_memory'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.executor_memory_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.executor_memory_tips'))
+ }
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.executor_memory_tips') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-number.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-number.ts
new file mode 100644
index 0000000000..34ba711d63
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-executor-number.ts
@@ -0,0 +1,42 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useExecutorNumber(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input-number',
+ field: 'numExecutors',
+ name: t('project.node.executor_number'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.executor_number_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.executor_number_tips'))
+ }
+ }
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-failed.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-failed.ts
new file mode 100644
index 0000000000..f511c8e455
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-failed.ts
@@ -0,0 +1,49 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useFailed(): IJsonItem[] {
+ const { t } = useI18n()
+ return [
+ {
+ type: 'input-number',
+ field: 'failRetryTimes',
+ name: t('project.node.number_of_failed_retries'),
+ span: 12,
+ props: {
+ min: 0
+ },
+ slots: {
+ suffix: () => t('project.node.times')
+ }
+ },
+ {
+ type: 'input-number',
+ field: 'failRetryInterval',
+ name: t('project.node.failed_retry_interval'),
+ span: 12,
+ props: {
+ min: 0
+ },
+ slots: {
+ suffix: () => t('project.node.minute')
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-flink.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-flink.ts
new file mode 100644
index 0000000000..aaedf5d2aa
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-flink.ts
@@ -0,0 +1,346 @@
+/*
+ * 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 { computed, watch, watchEffect } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams, useMainJar, useResources, useYarnQueue } from '.'
+import type { IJsonItem } from '../types'
+
+export function useFlink(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const mainClassSpan = computed(() =>
+ model.programType === 'PYTHON' || model.programType === 'SQL' ? 0 : 24
+ )
+
+ const mainArgsSpan = computed(() => (model.programType === 'SQL' ? 0 : 24))
+
+ const scriptSpan = computed(() => (model.programType === 'SQL' ? 24 : 0))
+
+ const flinkVersionOptions = computed(() =>
+ model.programType === 'SQL'
+ ? [{ label: '>=1.13', value: '>=1.13' }]
+ : FLINK_VERSIONS
+ )
+
+ const taskManagerNumberSpan = computed(() =>
+ model.flinkVersion === '<1.10' && model.deployMode !== 'local' ? 12 : 0
+ )
+
+ const deployModeSpan = computed(() => (model.deployMode !== 'local' ? 12 : 0))
+
+ const appNameSpan = computed(() => (model.deployMode !== 'local' ? 24 : 0))
+
+ const deployModeOptions = computed(() => {
+ if (model.programType === 'SQL') {
+ return [
+ {
+ label: 'per-job/cluster',
+ value: 'cluster'
+ },
+ {
+ label: 'local',
+ value: 'local'
+ },
+ {
+ label: 'standalone',
+ value: 'standalone'
+ }
+ ]
+ }
+ if (model.flinkVersion === '<1.10') {
+ return [
+ {
+ label: 'cluster',
+ value: 'cluster'
+ },
+ {
+ label: 'local',
+ value: 'local'
+ }
+ ]
+ } else {
+ return [
+ {
+ label: 'per-job/cluster',
+ value: 'cluster'
+ },
+ {
+ label: 'application',
+ value: 'application'
+ },
+ {
+ label: 'local',
+ value: 'local'
+ }
+ ]
+ }
+ })
+
+ watch(
+ () => model.flinkVersion,
+ () => {
+ if (
+ model.flinkVersion === '<1.10' &&
+ model.deployMode === 'application'
+ ) {
+ model.deployMode = 'cluster'
+ }
+ }
+ )
+
+ watchEffect(() => {
+ model.flinkVersion =
+ model.programType === 'SQL' ? '>=1.13' : model.flinkVersion
+ })
+
+ return [
+ {
+ type: 'select',
+ field: 'programType',
+ span: 24,
+ name: t('project.node.program_type'),
+ options: PROGRAM_TYPES,
+ props: {
+ 'on-update:value': () => {
+ model.mainJar = null
+ model.mainClass = ''
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'mainClass',
+ span: mainClassSpan,
+ name: t('project.node.main_class'),
+ props: {
+ placeholder: t('project.node.main_class_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: model.programType !== 'PYTHON' && model.programType !== 'SQL',
+ validator(validate: any, value: string) {
+ if (
+ model.programType !== 'PYTHON' &&
+ !value &&
+ model.programType !== 'SQL'
+ ) {
+ return new Error(t('project.node.main_class_tips'))
+ }
+ }
+ }
+ },
+ useMainJar(model),
+ {
+ type: 'radio',
+ field: 'deployMode',
+ name: t('project.node.deploy_mode'),
+ options: deployModeOptions,
+ span: 24
+ },
+ {
+ type: 'editor',
+ field: 'initScript',
+ span: scriptSpan,
+ name: t('project.node.init_script'),
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: false,
+ message: t('project.node.init_script_tips')
+ }
+ },
+ {
+ type: 'editor',
+ field: 'rawScript',
+ span: scriptSpan,
+ name: t('project.node.script'),
+ props: {
+ language: 'sql'
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.script_tips')
+ }
+ },
+ {
+ type: 'select',
+ field: 'flinkVersion',
+ name: t('project.node.flink_version'),
+ options: flinkVersionOptions,
+ value: model.flinkVersion,
+ span: deployModeSpan
+ },
+ {
+ type: 'input',
+ field: 'appName',
+ name: t('project.node.app_name'),
+ props: {
+ placeholder: t('project.node.app_name_tips')
+ },
+ span: appNameSpan
+ },
+ {
+ type: 'input',
+ field: 'jobManagerMemory',
+ name: t('project.node.job_manager_memory'),
+ span: deployModeSpan,
+ props: {
+ placeholder: t('project.node.job_manager_memory_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!value) {
+ return
+ }
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.job_manager_memory_tips') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'taskManagerMemory',
+ name: t('project.node.task_manager_memory'),
+ span: deployModeSpan,
+ props: {
+ placeholder: t('project.node.task_manager_memory_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!value) {
+ return
+ }
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.task_manager_memory') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ },
+ value: model.taskManagerMemory
+ },
+ {
+ type: 'input-number',
+ field: 'slot',
+ name: t('project.node.slot_number'),
+ span: deployModeSpan,
+ props: {
+ placeholder: t('project.node.slot_number_tips'),
+ min: 1
+ },
+ value: model.slot
+ },
+ {
+ type: 'input-number',
+ field: 'taskManager',
+ name: t('project.node.task_manager_number'),
+ span: taskManagerNumberSpan,
+ props: {
+ placeholder: t('project.node.task_manager_number_tips'),
+ min: 1
+ },
+ value: model.taskManager
+ },
+ {
+ type: 'input-number',
+ field: 'parallelism',
+ name: t('project.node.parallelism'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.parallelism_tips'),
+ min: 1
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.parallelism_tips'))
+ }
+ }
+ },
+ value: model.parallelism
+ },
+ useYarnQueue(),
+ {
+ type: 'input',
+ field: 'mainArgs',
+ span: mainArgsSpan,
+ name: t('project.node.main_arguments'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.main_arguments_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.option_parameters'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.option_parameters_tips')
+ }
+ },
+ useResources(),
+ ...useCustomParams({
+ model,
+ field: 'localParams',
+ isSimple: true
+ })
+ ]
+}
+
+const PROGRAM_TYPES = [
+ {
+ label: 'JAVA',
+ value: 'JAVA'
+ },
+ {
+ label: 'SCALA',
+ value: 'SCALA'
+ },
+ {
+ label: 'PYTHON',
+ value: 'PYTHON'
+ },
+ {
+ label: 'SQL',
+ value: 'SQL'
+ }
+]
+
+const FLINK_VERSIONS = [
+ {
+ label: '<1.10',
+ value: '<1.10'
+ },
+ {
+ label: '1.11',
+ value: '1.11'
+ },
+ {
+ label: '>=1.12',
+ value: '>=1.12'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-hive-cli.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-hive-cli.ts
new file mode 100644
index 0000000000..b285cc2353
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-hive-cli.ts
@@ -0,0 +1,87 @@
+/*
+ * 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 { computed, watch, ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams, useResources } from '.'
+import type { IJsonItem } from '../types'
+
+export function useHiveCli(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const hiveSqlScriptSpan = computed(() =>
+ model.hiveCliTaskExecutionType === 'SCRIPT' ? 24 : 0
+ )
+ const resourcesRequired = ref(model.hiveCliTaskExecutionType !== 'SCRIPT')
+
+ const resourcesLimit = computed(() =>
+ model.hiveCliTaskExecutionType === 'SCRIPT' ? -1 : 1
+ )
+
+ const SQL_EXECUTION_TYPES = [
+ {
+ label: t('project.node.sql_execution_type_from_script'),
+ value: 'SCRIPT'
+ },
+ {
+ label: t('project.node.sql_execution_type_from_file'),
+ value: 'FILE'
+ }
+ ]
+
+ watch(
+ () => model.hiveCliTaskExecutionType,
+ () => {
+ resourcesRequired.value = model.hiveCliTaskExecutionType !== 'SCRIPT'
+ }
+ )
+
+ return [
+ {
+ type: 'select',
+ field: 'hiveCliTaskExecutionType',
+ span: 12,
+ name: t('project.node.sql_execution_type'),
+ options: SQL_EXECUTION_TYPES,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true
+ }
+ },
+ {
+ type: 'editor',
+ field: 'hiveSqlScript',
+ name: t('project.node.hive_sql_script'),
+ props: {
+ language: 'sql'
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true
+ },
+ span: hiveSqlScriptSpan
+ },
+ {
+ type: 'input',
+ field: 'hiveCliOptions',
+ name: t('project.node.hive_cli_options'),
+ props: {
+ placeholder: t('project.node.hive_cli_options_tips')
+ }
+ },
+ useResources(24, resourcesRequired, resourcesLimit),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-http.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-http.ts
new file mode 100644
index 0000000000..525b05cdb7
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-http.ts
@@ -0,0 +1,244 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useHttp(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const HTTP_CHECK_CONDITIONS = [
+ {
+ label: t('project.node.status_code_default'),
+ value: 'STATUS_CODE_DEFAULT'
+ },
+ {
+ label: t('project.node.status_code_custom'),
+ value: 'STATUS_CODE_CUSTOM'
+ },
+ {
+ label: t('project.node.body_contains'),
+ value: 'BODY_CONTAINS'
+ },
+ {
+ label: t('project.node.body_not_contains'),
+ value: 'BODY_NOT_CONTAINS'
+ }
+ ]
+
+ return [
+ {
+ type: 'input',
+ class: 'input-url-name',
+ field: 'url',
+ name: t('project.node.http_url'),
+ props: {
+ placeholder: t('project.node.http_url_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.http_url_tips'))
+ }
+ if (value.search(new RegExp(/http[s]{0,1}:\/\/\S*/, 'i'))) {
+ return new Error(t('project.node.http_url_validator'))
+ }
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'httpMethod',
+ span: 12,
+ name: t('project.node.http_method'),
+ options: HTTP_METHODS
+ },
+ {
+ type: 'custom-parameters',
+ field: 'httpParams',
+ name: t('project.node.http_parameters'),
+ children: [
+ {
+ type: 'input',
+ field: 'prop',
+ span: 6,
+ props: {
+ placeholder: t('project.node.prop_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.prop_tips'))
+ }
+
+ const sameItems = model.httpParams.filter(
+ (item: { prop: string }) => item.prop === value
+ )
+
+ if (sameItems.length > 1) {
+ return new Error(t('project.node.prop_repeat'))
+ }
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'httpParametersType',
+ span: 6,
+ options: POSITIONS,
+ value: 'PARAMETER'
+ },
+ {
+ type: 'input',
+ field: 'value',
+ span: 6,
+ props: {
+ placeholder: t('project.node.value_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.value_required_tips'))
+ }
+ }
+ }
+ }
+ ]
+ },
+ {
+ type: 'input',
+ field: 'httpBody',
+ name: t('project.node.http_body'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.http_body_tips')
+ }
+ },
+ {
+ type: 'select',
+ field: 'httpCheckCondition',
+ name: t('project.node.http_check_condition'),
+ options: HTTP_CHECK_CONDITIONS
+ },
+ {
+ type: 'input',
+ field: 'condition',
+ name: t('project.node.http_condition'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.http_condition_tips')
+ }
+ },
+ {
+ type: 'input-number',
+ field: 'connectTimeout',
+ name: t('project.node.connect_timeout'),
+ span: 12,
+ props: {
+ max: Math.pow(7, 10) - 1
+ },
+ slots: {
+ suffix: () => t('project.node.ms')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.connect_timeout') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ }
+ },
+ {
+ type: 'input-number',
+ field: 'socketTimeout',
+ name: t('project.node.socket_timeout'),
+ span: 12,
+ props: {
+ max: Math.pow(7, 10) - 1
+ },
+ slots: {
+ suffix: () => t('project.node.ms')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ validator(validate: any, value: string) {
+ if (!Number.isInteger(parseInt(value))) {
+ return new Error(
+ t('project.node.socket_timeout') +
+ t('project.node.positive_integer_tips')
+ )
+ }
+ }
+ }
+ },
+ ...useCustomParams({
+ model,
+ field: 'localParams',
+ isSimple: true
+ })
+ ]
+}
+
+const HTTP_METHODS = [
+ {
+ value: 'GET',
+ label: 'GET'
+ },
+ {
+ value: 'POST',
+ label: 'POST'
+ },
+ {
+ value: 'HEAD',
+ label: 'HEAD'
+ },
+ {
+ value: 'PUT',
+ label: 'PUT'
+ },
+ {
+ value: 'DELETE',
+ label: 'DELETE'
+ }
+]
+
+const POSITIONS = [
+ {
+ value: 'PARAMETER',
+ label: 'Parameter'
+ },
+ {
+ value: 'BODY',
+ label: 'Body'
+ },
+ {
+ value: 'HEADERS',
+ label: 'Headers'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-java-task-main-jar.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-java-task-main-jar.ts
new file mode 100644
index 0000000000..826d709fad
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-java-task-main-jar.ts
@@ -0,0 +1,81 @@
+/*
+ * 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 { computed, ref, onMounted, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryResourceByProgramType } from '@/service/modules/resources'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import utils from '@/utils'
+import type { IJsonItem, ProgramType, IMainJar } from '../types'
+
+export function useJavaTaskMainJar(model: { [field: string]: any }): IJsonItem {
+ const { t } = useI18n()
+ const mainJarOptions = ref([] as IMainJar[])
+ const taskStore = useTaskNodeStore()
+
+ const mainJarSpan = computed(() => (model.runType === 'JAVA' ? 0 : 24))
+ const getMainJars = async (programType: ProgramType) => {
+ const storeMainJar = taskStore.getMainJar(programType)
+ if (storeMainJar) {
+ mainJarOptions.value = storeMainJar
+ return
+ }
+ const res = await queryResourceByProgramType({
+ type: 'FILE',
+ programType
+ })
+ utils.removeUselessChildren(res)
+ mainJarOptions.value = res || []
+ taskStore.updateMainJar(programType, res)
+ }
+
+ onMounted(() => {
+ getMainJars(model.programType)
+ })
+
+ watch(
+ () => model.programType,
+ (value) => {
+ getMainJars(value)
+ }
+ )
+
+ return {
+ type: 'tree-select',
+ field: 'mainJar',
+ name: t('project.node.main_package'),
+ span: mainJarSpan,
+ props: {
+ checkable: true,
+ cascade: true,
+ showPath: true,
+ checkStrategy: 'child',
+ placeholder: t('project.node.main_package_tips'),
+ keyField: 'fullName',
+ labelField: 'name'
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.main_package_tips'))
+ }
+ }
+ },
+ options: mainJarOptions
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-java.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-java.ts
new file mode 100644
index 0000000000..b8a47c8935
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-java.ts
@@ -0,0 +1,85 @@
+/*
+ * 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 { computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams, useResources, useJavaTaskMainJar } from '.'
+import type { IJsonItem } from '../types'
+
+export function useJava(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ 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: 'editor',
+ field: 'rawScript',
+ span: rawScriptSpan,
+ name: t('project.node.script'),
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.script_tips')
+ }
+ },
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
+
+export const RUN_TYPES = [
+ {
+ label: 'JAVA',
+ value: 'JAVA'
+ },
+ {
+ label: 'JAR',
+ value: 'JAR'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-jupyter.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-jupyter.ts
new file mode 100644
index 0000000000..582b308d6c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-jupyter.ts
@@ -0,0 +1,127 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams, useResources } from '.'
+import type { IJsonItem } from '../types'
+
+export function useJupyter(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'input',
+ field: 'condaEnvName',
+ name: t('project.node.jupyter_conda_env_name'),
+ props: {
+ placeholder: t('project.node.jupyter_conda_env_name_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.jupyter_conda_env_name_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'inputNotePath',
+ name: t('project.node.jupyter_input_note_path'),
+ props: {
+ placeholder: t('project.node.jupyter_input_note_path_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.jupyter_input_note_path_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'outputNotePath',
+ name: t('project.node.jupyter_output_note_path'),
+ props: {
+ placeholder: t('project.node.jupyter_output_note_path_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.jupyter_output_note_path_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'parameters',
+ name: t('project.node.jupyter_parameters'),
+ props: {
+ placeholder: t('project.node.jupyter_parameters_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'kernel',
+ name: t('project.node.jupyter_kernel'),
+ props: {
+ placeholder: t('project.node.jupyter_kernel_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'engine',
+ name: t('project.node.jupyter_engine'),
+ props: {
+ placeholder: t('project.node.jupyter_engine_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'executionTimeout',
+ name: t('project.node.jupyter_execution_timeout'),
+ props: {
+ placeholder: t('project.node.jupyter_execution_timeout_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'startTimeout',
+ name: t('project.node.jupyter_start_timeout'),
+ props: {
+ placeholder: t('project.node.jupyter_start_timeout_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.jupyter_others'),
+ props: {
+ placeholder: t('project.node.jupyter_others_tips')
+ }
+ },
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-k8s.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-k8s.ts
new file mode 100644
index 0000000000..8d2a702464
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-k8s.ts
@@ -0,0 +1,127 @@
+/*
+ * 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 { useCustomParams, useCustomLabels, useNodeSelectors } from '.'
+import type { IJsonItem } from '../types'
+import { useI18n } from 'vue-i18n'
+
+export function useK8s(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'input-number',
+ field: 'minCpuCores',
+ span: 12,
+ props: {
+ min: 0
+ },
+ name: t('project.node.min_cpu'),
+ slots: {
+ suffix: () => t('project.node.cores')
+ }
+ },
+ {
+ type: 'input-number',
+ field: 'minMemorySpace',
+ span: 12,
+ props: {
+ min: 0
+ },
+ name: t('project.node.min_memory'),
+ slots: {
+ suffix: () => t('project.node.mb')
+ }
+ },
+ {
+ type: 'input',
+ field: 'image',
+ name: t('project.node.image'),
+ span: 18,
+ props: {
+ placeholder: t('project.node.image_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.image_tips')
+ }
+ },
+ {
+ type: 'select',
+ field: 'imagePullPolicy',
+ name: t('project.node.image_pull_policy'),
+ span: 6,
+ options: IMAGE_PULL_POLICY_LIST,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.image_pull_policy_tips')
+ },
+ value: 'IfNotPresent'
+ },
+ {
+ type: 'input',
+ field: 'pullSecret',
+ name: t('project.node.pull_secret'),
+ props: {
+ placeholder: t('project.node.pull_secret_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'command',
+ name: t('project.node.command'),
+ props: {
+ placeholder: t('project.node.command_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'args',
+ name: t('project.node.args'),
+ props: {
+ placeholder: t('project.node.args_tips')
+ }
+ },
+ ...useCustomLabels({
+ model,
+ field: 'customizedLabels',
+ name: 'custom_labels'
+ }),
+ ...useNodeSelectors({
+ model,
+ field: 'nodeSelectors',
+ name: 'node_selectors'
+ }),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
+
+export const IMAGE_PULL_POLICY_LIST = [
+ {
+ value: 'IfNotPresent',
+ label: 'IfNotPresent'
+ },
+ {
+ value: 'Always',
+ label: 'Always'
+ },
+ {
+ value: 'Never',
+ label: 'Never'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-kubeflow.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-kubeflow.ts
new file mode 100644
index 0000000000..e03e524cf3
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-kubeflow.ts
@@ -0,0 +1,38 @@
+/*
+ * 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 type { IJsonItem } from '../types'
+import { useCustomParams, useNamespace } from '.'
+
+export function useKubeflow(model: { [field: string]: any }): IJsonItem[] {
+ return [
+ useNamespace(),
+ {
+ type: 'editor',
+ field: 'yamlContent',
+ name: 'yamlContent',
+ props: {
+ language: 'yaml'
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: 'requestJson'
+ }
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-linkis.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-linkis.ts
new file mode 100644
index 0000000000..d4028d8d0f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-linkis.ts
@@ -0,0 +1,94 @@
+/*
+ * 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 { computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useLinkis(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const configEditorSpan = computed(() => (model.useCustom ? 24 : 0))
+ const paramEditorSpan = computed(() => (model.useCustom ? 0 : 24))
+ computed(() => (model.useCustom ? 0 : 24))
+ return [
+ {
+ type: 'switch',
+ field: 'useCustom',
+ name: t('project.node.custom_config')
+ },
+ {
+ type: 'custom-parameters',
+ field: 'paramScript',
+ name: t('project.node.option_parameters'),
+ span: paramEditorSpan,
+ children: [
+ {
+ type: 'input',
+ field: 'prop',
+ span: 10,
+ props: {
+ placeholder: t('project.node.prop_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.prop_tips'))
+ }
+
+ const sameItems = model.localParams.filter(
+ (item: { prop: string }) => item.prop === value
+ )
+
+ if (sameItems.length > 1) {
+ return new Error(t('project.node.prop_repeat'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'value',
+ span: 10,
+ props: {
+ placeholder: t('project.node.value_tips'),
+ maxLength: 256
+ }
+ }
+ ]
+ },
+ {
+ type: 'editor',
+ field: 'rawScript',
+ name: t('project.node.script'),
+ span: configEditorSpan,
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: model.useCustom,
+ validator(validate: any, value: string) {
+ if (model.useCustom && !value) {
+ return new Error(t('project.node.script_tips'))
+ }
+ }
+ }
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: true })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-main-jar.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-main-jar.ts
new file mode 100644
index 0000000000..79ef7a2825
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-main-jar.ts
@@ -0,0 +1,83 @@
+/*
+ * 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 { computed, ref, onMounted, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryResourceByProgramType } from '@/service/modules/resources'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import utils from '@/utils'
+import type { IJsonItem, ProgramType, IMainJar } from '../types'
+
+export function useMainJar(model: { [field: string]: any }): IJsonItem {
+ const { t } = useI18n()
+ const mainJarOptions = ref([] as IMainJar[])
+ const taskStore = useTaskNodeStore()
+
+ const mainJarSpan = computed(() => (model.programType === 'SQL' ? 0 : 24))
+ const getMainJars = async (programType: ProgramType) => {
+ const storeMainJar = taskStore.getMainJar(programType)
+ if (storeMainJar) {
+ mainJarOptions.value = storeMainJar
+ return
+ }
+ const res = await queryResourceByProgramType({
+ type: 'FILE',
+ programType
+ })
+ utils.removeUselessChildren(res)
+ mainJarOptions.value = res || []
+ taskStore.updateMainJar(programType, res)
+ }
+
+ onMounted(() => {
+ getMainJars(model.programType)
+ })
+
+ watch(
+ () => model.programType,
+ (value) => {
+ if (value !== 'SQL') {
+ getMainJars(value)
+ }
+ }
+ )
+
+ return {
+ type: 'tree-select',
+ field: 'mainJar',
+ name: t('project.node.main_package'),
+ span: mainJarSpan,
+ props: {
+ checkable: true,
+ cascade: true,
+ showPath: true,
+ checkStrategy: 'child',
+ placeholder: t('project.node.main_package_tips'),
+ keyField: 'fullName',
+ labelField: 'name'
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: model.programType !== 'SQL',
+ validator(validate: any, value: string) {
+ if (!value && model.programType !== 'SQL') {
+ return new Error(t('project.node.main_package_tips'))
+ }
+ }
+ },
+ options: mainJarOptions
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow-models.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow-models.ts
new file mode 100644
index 0000000000..eef3837fde
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow-models.ts
@@ -0,0 +1,80 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+import { watch, ref } from 'vue'
+
+export function useMlflowModels(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const deployTypeSpan = ref(0)
+ const deployModelKeySpan = ref(0)
+ const deployPortSpan = ref(0)
+
+ const setFlag = () => {
+ model.isModels = model.mlflowTaskType === 'MLflow Models' ? true : false
+ }
+
+ const resetSpan = () => {
+ deployTypeSpan.value = model.isModels ? 12 : 0
+ deployModelKeySpan.value = model.isModels ? 24 : 0
+ deployPortSpan.value = model.isModels ? 12 : 0
+ }
+
+ watch(
+ () => [model.mlflowTaskType],
+ () => {
+ setFlag()
+ resetSpan()
+ }
+ )
+
+ setFlag()
+ resetSpan()
+
+ return [
+ {
+ type: 'select',
+ field: 'deployType',
+ name: t('project.node.mlflow_deployType'),
+ span: deployTypeSpan,
+ options: DEPLOY_TYPE
+ },
+ {
+ type: 'input',
+ field: 'deployModelKey',
+ name: t('project.node.mlflow_deployModelKey'),
+ span: deployModelKeySpan
+ },
+ {
+ type: 'input',
+ field: 'deployPort',
+ name: t('project.node.mlflow_deployPort'),
+ span: deployPortSpan
+ }
+ ]
+}
+
+const DEPLOY_TYPE = [
+ {
+ label: 'MLFLOW',
+ value: 'MLFLOW'
+ },
+ {
+ label: 'DOCKER',
+ value: 'DOCKER'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow-projects.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow-projects.ts
new file mode 100644
index 0000000000..c312ee435e
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow-projects.ts
@@ -0,0 +1,322 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+import { watch, ref } from 'vue'
+
+export function useMlflowProjects(model: {
+ [field: string]: any
+}): IJsonItem[] {
+ const { t } = useI18n()
+
+ const experimentNameSpan = ref(0)
+ const registerModelSpan = ref(0)
+ const modelNameSpan = ref(0)
+ const mlflowJobTypeSpan = ref(0)
+ const dataPathSpan = ref(0)
+ const paramsSpan = ref(0)
+
+ const setFlag = () => {
+ model.isProjects = model.mlflowTaskType === 'MLflow Projects' ? true : false
+ }
+
+ const resetSpan = () => {
+ experimentNameSpan.value = model.isProjects ? 12 : 0
+ mlflowJobTypeSpan.value = model.isProjects ? 12 : 0
+ paramsSpan.value = model.isProjects ? 24 : 0
+ registerModelSpan.value =
+ model.isProjects && model.mlflowJobType != 'CustomProject' ? 6 : 0
+ dataPathSpan.value =
+ model.isProjects && model.mlflowJobType != 'CustomProject' ? 24 : 0
+ }
+
+ watch(
+ () => [model.mlflowTaskType, model.mlflowJobType],
+ () => {
+ setFlag()
+ resetSpan()
+ }
+ )
+
+ watch(
+ () => [model.registerModel],
+ () => {
+ modelNameSpan.value = model.isProjects && model.registerModel ? 6 : 0
+ }
+ )
+
+ setFlag()
+ resetSpan()
+
+ return [
+ {
+ type: 'select',
+ field: 'mlflowJobType',
+ name: t('project.node.mlflow_jobType'),
+ span: mlflowJobTypeSpan,
+ options: MLFLOW_JOB_TYPE
+ },
+ {
+ type: 'input',
+ field: 'experimentName',
+ name: t('project.node.mlflow_experimentName'),
+ span: experimentNameSpan,
+ props: {
+ placeholder: t('project.node.mlflow_experimentName_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: false
+ }
+ },
+ {
+ type: 'switch',
+ field: 'registerModel',
+ name: t('project.node.mlflow_registerModel'),
+ span: registerModelSpan
+ },
+ {
+ type: 'input',
+ field: 'modelName',
+ name: t('project.node.mlflow_modelName'),
+ span: modelNameSpan,
+ props: {
+ placeholder: t('project.node.mlflow_modelName_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: false
+ }
+ },
+ {
+ type: 'input',
+ field: 'dataPath',
+ name: t('project.node.mlflow_dataPath'),
+ span: dataPathSpan,
+ props: {
+ placeholder: t('project.node.mlflow_dataPath_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'params',
+ name: t('project.node.mlflow_params'),
+ span: paramsSpan,
+ props: {
+ placeholder: t('project.node.mlflow_params_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: false
+ }
+ },
+ ...useBasicAlgorithm(model),
+ ...useAutoML(model),
+ ...useCustomProject(model)
+ ]
+}
+
+export function useBasicAlgorithm(model: {
+ [field: string]: any
+}): IJsonItem[] {
+ const { t } = useI18n()
+
+ const algorithmSpan = ref(0)
+ const searchParamsSpan = ref(0)
+
+ const setFlag = () => {
+ model.isBasicAlgorithm =
+ model.mlflowJobType === 'BasicAlgorithm' &&
+ model.mlflowTaskType === 'MLflow Projects'
+ ? true
+ : false
+ }
+
+ const resetSpan = () => {
+ algorithmSpan.value = model.isBasicAlgorithm ? 24 : 0
+ searchParamsSpan.value = model.isBasicAlgorithm ? 24 : 0
+ }
+
+ watch(
+ () => [model.mlflowTaskType, model.mlflowJobType],
+ () => {
+ setFlag()
+ resetSpan()
+ }
+ )
+ setFlag()
+ resetSpan()
+
+ return [
+ {
+ type: 'select',
+ field: 'algorithm',
+ name: t('project.node.mlflow_algorithm'),
+ span: algorithmSpan,
+ options: ALGORITHM
+ },
+ {
+ type: 'input',
+ field: 'searchParams',
+ name: t('project.node.mlflow_searchParams'),
+ props: {
+ placeholder: t('project.node.mlflow_searchParams_tips')
+ },
+ span: searchParamsSpan,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: false
+ }
+ }
+ ]
+}
+
+export function useAutoML(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const automlToolSpan = ref(0)
+
+ const setFlag = () => {
+ model.isAutoML =
+ model.mlflowJobType === 'AutoML' &&
+ model.mlflowTaskType === 'MLflow Projects'
+ ? true
+ : false
+ }
+
+ const resetSpan = () => {
+ automlToolSpan.value = model.isAutoML ? 12 : 0
+ }
+
+ watch(
+ () => [model.mlflowTaskType, model.mlflowJobType],
+ () => {
+ setFlag()
+ resetSpan()
+ }
+ )
+
+ setFlag()
+ resetSpan()
+
+ return [
+ {
+ type: 'select',
+ field: 'automlTool',
+ name: t('project.node.mlflow_automlTool'),
+ span: automlToolSpan,
+ options: AutoMLTOOL
+ }
+ ]
+}
+
+export function useCustomProject(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const mlflowProjectRepositorySpan = ref(0)
+ const mlflowProjectVersionSpan = ref(0)
+ const customParamsSpan = ref(0)
+
+ const setFlag = () => {
+ model.isCustomProject =
+ model.mlflowJobType === 'CustomProject' &&
+ model.mlflowTaskType === 'MLflow Projects'
+ ? true
+ : false
+ }
+
+ const resetSpan = () => {
+ mlflowProjectRepositorySpan.value = model.isCustomProject ? 24 : 0
+ mlflowProjectVersionSpan.value = model.isCustomProject ? 12 : 0
+ customParamsSpan.value = model.isCustomProject ? 24 : 0
+ }
+
+ watch(
+ () => [model.mlflowTaskType, model.mlflowJobType],
+ () => {
+ setFlag()
+ resetSpan()
+ }
+ )
+
+ setFlag()
+ resetSpan()
+
+ return [
+ {
+ type: 'input',
+ field: 'mlflowProjectRepository',
+ name: t('project.node.mlflowProjectRepository'),
+ span: mlflowProjectRepositorySpan,
+ props: {
+ placeholder: t('project.node.mlflowProjectRepository_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'mlflowProjectVersion',
+ name: t('project.node.mlflowProjectVersion'),
+ span: mlflowProjectVersionSpan,
+ props: {
+ placeholder: t('project.node.mlflowProjectVersion_tips')
+ }
+ }
+ ]
+}
+
+export const MLFLOW_JOB_TYPE = [
+ {
+ label: 'Custom Project',
+ value: 'CustomProject'
+ },
+ {
+ label: 'AutoML',
+ value: 'AutoML'
+ },
+ {
+ label: 'BasicAlgorithm',
+ value: 'BasicAlgorithm'
+ }
+]
+export const ALGORITHM = [
+ {
+ label: 'svm',
+ value: 'svm'
+ },
+ {
+ label: 'lr',
+ value: 'lr'
+ },
+ {
+ label: 'lightgbm',
+ value: 'lightgbm'
+ },
+ {
+ label: 'xgboost',
+ value: 'xgboost'
+ }
+]
+export const AutoMLTOOL = [
+ {
+ label: 'flaml',
+ value: 'flaml'
+ },
+ {
+ label: 'autosklearn',
+ value: 'autosklearn'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow.ts
new file mode 100644
index 0000000000..efed24661f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mlflow.ts
@@ -0,0 +1,69 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+import { useMlflowProjects, useMlflowModels } from '.'
+import { useCustomParams, useResources } from '.'
+
+export const MLFLOW_TASK_TYPE = [
+ {
+ label: 'MLflow Models',
+ value: 'MLflow Models'
+ },
+ {
+ label: 'MLflow Projects',
+ value: 'MLflow Projects'
+ }
+]
+
+export function useMlflow(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'input',
+ field: 'mlflowTrackingUri',
+ name: t('project.node.mlflow_mlflowTrackingUri'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.mlflow_mlflowTrackingUri_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: false,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(
+ t('project.node.mlflow_mlflowTrackingUri_error_tips')
+ )
+ }
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'mlflowTaskType',
+ name: t('project.node.mlflow_taskType'),
+ span: 12,
+ options: MLFLOW_TASK_TYPE
+ },
+ ...useMlflowProjects(model),
+ ...useMlflowModels(model),
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: true })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mr.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mr.ts
new file mode 100644
index 0000000000..9850db57c2
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-mr.ts
@@ -0,0 +1,108 @@
+/*
+ * 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 { computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams, useMainJar, useResources, useYarnQueue } from '.'
+import type { IJsonItem } from '../types'
+
+export function useMr(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const mainClassSpan = computed(() =>
+ model.programType === 'PYTHON' || model.programType === 'SQL' ? 0 : 24
+ )
+
+ return [
+ {
+ type: 'select',
+ field: 'programType',
+ span: 12,
+ name: t('project.node.program_type'),
+ options: PROGRAM_TYPES,
+ props: {
+ 'on-update:value': () => {
+ model.mainJar = null
+ model.mainClass = ''
+ }
+ },
+ value: model.programType
+ },
+ {
+ type: 'input',
+ field: 'mainClass',
+ span: mainClassSpan,
+ name: t('project.node.main_class'),
+ props: {
+ placeholder: t('project.node.main_class_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: model.programType !== 'PYTHON',
+ validator(validate: any, value: string) {
+ if (model.programType !== 'PYTHON' && !value) {
+ return new Error(t('project.node.main_class_tips'))
+ }
+ }
+ }
+ },
+ useMainJar(model),
+ {
+ type: 'input',
+ field: 'appName',
+ name: t('project.node.app_name'),
+ props: {
+ placeholder: t('project.node.app_name_tips')
+ }
+ },
+ useYarnQueue(),
+ {
+ type: 'input',
+ field: 'mainArgs',
+ name: t('project.node.main_arguments'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.main_arguments_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.option_parameters'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.option_parameters_tips')
+ }
+ },
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: true })
+ ]
+}
+
+export const PROGRAM_TYPES = [
+ {
+ label: 'JAVA',
+ value: 'JAVA'
+ },
+ {
+ label: 'SCALA',
+ value: 'SCALA'
+ },
+ {
+ label: 'PYTHON',
+ value: 'PYTHON'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-name.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-name.ts
new file mode 100644
index 0000000000..8133e6a81e
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-name.ts
@@ -0,0 +1,38 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useName(from?: number): IJsonItem {
+ const { t } = useI18n()
+ return {
+ type: 'input',
+ field: 'name',
+ class: 'input-node-name',
+ name: from === 1 ? t('project.node.task_name') : t('project.node.name'),
+ props: {
+ placeholder: t('project.node.name_tips'),
+ maxLength: 100
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.name_tips')
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-namespace.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-namespace.ts
new file mode 100644
index 0000000000..a00389ae1b
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-namespace.ts
@@ -0,0 +1,72 @@
+/*
+ * 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 type { IJsonItem } from '../types'
+import { useI18n } from 'vue-i18n'
+import { onMounted, ref, VNodeChild } from 'vue'
+import { getAllNamespaces } from '@/service/modules/k8s-namespace'
+import { SelectOption } from 'naive-ui'
+
+export function useNamespace(): IJsonItem {
+ const { t } = useI18n()
+
+ const options = ref([])
+ const loading = ref(false)
+
+ const getNamespaceList = async () => {
+ if (loading.value) return
+ loading.value = true
+ const totalList = await getAllNamespaces()
+ options.value = (totalList || []).map(
+ (item: { id: string; namespace: string; clusterName: string }) => ({
+ label: `${item.namespace}(${item.clusterName})`,
+ value: JSON.stringify({
+ name: item.namespace,
+ cluster: item.clusterName
+ })
+ })
+ )
+ loading.value = false
+ }
+
+ onMounted(() => {
+ getNamespaceList()
+ })
+
+ const renderLabel = (option: SelectOption): VNodeChild => {
+ if (option.type === 'group') return option.label as string
+ return [option.label as string]
+ }
+
+ return {
+ type: 'select',
+ field: 'namespace',
+ name: t('project.node.namespace_cluster'),
+ props: {
+ loading,
+ 'render-label': renderLabel,
+ clearable: true
+ },
+ options: [
+ {
+ type: 'group',
+ label: t('project.node.namespace_cluster'),
+ key: t('project.node.namespace_cluster'),
+ children: options as any
+ }
+ ]
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-node-selectors.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-node-selectors.ts
new file mode 100644
index 0000000000..48ca120127
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-node-selectors.ts
@@ -0,0 +1,117 @@
+/*
+ * 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 { Ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useNodeSelectors({
+ model,
+ field,
+ name,
+ span = 24
+}: {
+ model: { [field: string]: any }
+ field: string
+ name?: string
+ span?: Ref | number
+}): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'custom-parameters',
+ field: field,
+ name: t(`project.node.${name}`),
+ class: 'btn-custom-parameters',
+ span,
+ children: [
+ {
+ type: 'input',
+ field: 'key',
+ span: 8,
+ class: 'node-selector-label-name',
+ props: {
+ placeholder: t('project.node.expression_name_tips'),
+ maxLength: 256
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.expression_name_tips'))
+ }
+
+ const sameItems = model[field].filter(
+ (item: { label: string }) => item.label === value
+ )
+
+ if (sameItems.length > 1) {
+ return new Error(t('project.node.label_repeat'))
+ }
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'operator',
+ span: 4,
+ options: OPERATOR_LIST,
+ value: 'In'
+ },
+ {
+ type: 'input',
+ field: 'values',
+ span: 10,
+ class: 'node-selector-label-value',
+ props: {
+ placeholder: t('project.node.expression_value_tips'),
+ maxLength: 256,
+ disabled: false
+ }
+ }
+ ]
+ }
+ ]
+}
+
+export const OPERATOR_LIST = [
+ {
+ value: 'In',
+ label: 'In'
+ },
+ {
+ value: 'NotIn',
+ label: 'NotIn'
+ },
+ {
+ value: 'Exists',
+ label: 'Exists'
+ },
+ {
+ value: 'DoesNotExist',
+ label: 'DoesNotExist'
+ },
+ {
+ value: 'Gt',
+ label: 'Gt'
+ },
+ {
+ value: 'Lt',
+ label: 'Lt'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-openmldb.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-openmldb.ts
new file mode 100644
index 0000000000..742d404900
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-openmldb.ts
@@ -0,0 +1,87 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams, useResources } from '.'
+import type { IJsonItem } from '../types'
+
+export function useOpenmldb(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const options = [
+ {
+ label: t('project.node.openmldb_execute_mode_offline'),
+ value: 'offline'
+ },
+ {
+ label: t('project.node.openmldb_execute_mode_online'),
+ value: 'online'
+ }
+ ]
+ return [
+ {
+ type: 'input',
+ field: 'zk',
+ name: t('project.node.openmldb_zk_address'),
+ props: {
+ placeholder: t('project.node.openmldb_zk_address_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.openmldb_zk_address_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'zkPath',
+ name: t('project.node.openmldb_zk_path'),
+ props: {
+ placeholder: t('project.node.openmldb_zk_path_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.openmldb_zk_path_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'radio',
+ field: 'executeMode',
+ name: t('project.node.openmldb_execute_mode'),
+ options: options
+ },
+ {
+ type: 'editor',
+ field: 'sql',
+ name: t('project.node.sql_statement'),
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.sql_empty_tips')
+ }
+ },
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-pre-tasks.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-pre-tasks.ts
new file mode 100644
index 0000000000..80bd285e21
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-pre-tasks.ts
@@ -0,0 +1,47 @@
+/*
+ * 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 { ref, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import type { IJsonItem } from '../types'
+
+export function usePreTasks(): IJsonItem {
+ const { t } = useI18n()
+ const taskStore = useTaskNodeStore()
+ const options = ref(taskStore.getPreTaskOptions)
+
+ watch(
+ () => taskStore.getPreTaskOptions,
+ (value) => {
+ options.value = value
+ }
+ )
+
+ return {
+ type: 'select',
+ field: 'preTasks',
+ span: 24,
+ class: 'pre-tasks-model',
+ name: t('project.node.pre_tasks'),
+ props: {
+ multiple: true,
+ filterable: true
+ },
+ options
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-procedure.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-procedure.ts
new file mode 100644
index 0000000000..1c0b4f99a3
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-procedure.ts
@@ -0,0 +1,41 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useProcedure(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'editor',
+ field: 'method',
+ name: t('project.node.procedure_method'),
+ props: {
+ language: 'sql',
+ placeholder: t('project.node.procedure_method_tips')
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.procedure_method_tips')
+ }
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-process-name.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-process-name.ts
new file mode 100644
index 0000000000..f9cdccc224
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-process-name.ts
@@ -0,0 +1,96 @@
+/*
+ * 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 { ref, onMounted } from 'vue'
+import { useI18n } from 'vue-i18n'
+import {
+ querySimpleList,
+ queryProcessDefinitionByCode
+} from '@/service/modules/process-definition'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import type { IJsonItem } from '../types'
+
+export function useProcessName({
+ model,
+ projectCode,
+ isCreate,
+ from,
+ processName,
+ taskCode
+}: {
+ model: { [field: string]: any }
+ projectCode: number
+ isCreate: boolean
+ from?: number
+ processName?: number
+ taskCode?: number
+}): IJsonItem {
+ const { t } = useI18n()
+ const taskStore = useTaskNodeStore()
+ const options = ref([] as { label: string; value: string }[])
+ const loading = ref(false)
+
+ const getProcessList = async () => {
+ if (loading.value) return
+ loading.value = true
+ const res = await querySimpleList(projectCode)
+ options.value = res.map((option: { name: string; code: number }) => ({
+ label: option.name,
+ value: option.code
+ }))
+ loading.value = false
+ }
+ const getProcessListByCode = async (processCode: number) => {
+ if (!processCode) return
+ const res = await queryProcessDefinitionByCode(processCode, projectCode)
+ model.definition = res
+ taskStore.updateDefinition(res, taskCode)
+ }
+
+ const onChange = (code: number) => {
+ getProcessListByCode(code)
+ }
+
+ onMounted(() => {
+ if (from === 1 && processName) {
+ getProcessListByCode(processName)
+ }
+ getProcessList()
+ })
+
+ return {
+ type: 'select',
+ field: 'processName',
+ span: 24,
+ name: t('project.node.workflow_name'),
+ props: {
+ loading: loading,
+ disabled: !isCreate,
+ 'on-update:value': onChange
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.workflow_name_tips'))
+ }
+ }
+ },
+ options: options
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-pytorch.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-pytorch.ts
new file mode 100644
index 0000000000..7eeebab581
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-pytorch.ts
@@ -0,0 +1,139 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+import { watch, ref } from 'vue'
+import { useCustomParams, useResources } from '.'
+
+export function usePytorch(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const isCreateEnvironmentSpan = ref(0)
+ const pythonPathSpan = ref(0)
+ const pythonEnvToolSpan = ref(0)
+ const pythonCommandSpan = ref(0)
+ const requirementsSpan = ref(0)
+ const condaPythonVersionSpan = ref(0)
+
+ const setFlag = () => {
+ model.showCreateEnvironment = model.isCreateEnvironment && model.otherParams
+ model.showCreateConda =
+ model.showCreateEnvironment && model.pythonEnvTool === 'conda'
+ ? true
+ : false
+ model.showCreateEnv =
+ model.showCreateEnvironment && model.pythonEnvTool === 'virtualenv'
+ ? true
+ : false
+ }
+
+ const resetSpan = () => {
+ isCreateEnvironmentSpan.value = model.otherParams ? 12 : 0
+ pythonPathSpan.value = model.otherParams ? 24 : 0
+ pythonEnvToolSpan.value = model.showCreateEnvironment ? 12 : 0
+ pythonCommandSpan.value =
+ ~model.showCreateEnvironment & model.otherParams ? 12 : 0
+ requirementsSpan.value = model.showCreateEnvironment ? 24 : 0
+ condaPythonVersionSpan.value = model.showCreateConda ? 24 : 0
+ }
+
+ watch(
+ () => [model.isCreateEnvironment, model.pythonEnvTool, model.otherParams],
+ () => {
+ setFlag()
+ resetSpan()
+ }
+ )
+
+ return [
+ {
+ type: 'input',
+ field: 'script',
+ name: t('project.node.pytorch_script'),
+ span: 24
+ },
+ {
+ type: 'input',
+ field: 'scriptParams',
+ name: t('project.node.pytorch_script_params'),
+ span: 24
+ },
+ {
+ type: 'switch',
+ field: 'otherParams',
+ name: t('project.node.pytorch_other_params'),
+ span: 24
+ },
+ {
+ type: 'input',
+ field: 'pythonPath',
+ name: t('project.node.pytorch_python_path'),
+ span: pythonPathSpan
+ },
+ {
+ type: 'switch',
+ field: 'isCreateEnvironment',
+ name: t('project.node.pytorch_is_create_environment'),
+ span: isCreateEnvironmentSpan
+ },
+ {
+ type: 'input',
+ field: 'pythonCommand',
+ name: t('project.node.pytorch_python_command'),
+ span: pythonCommandSpan,
+ props: {
+ placeholder: t('project.node.pytorch_python_command_tips')
+ }
+ },
+ {
+ type: 'select',
+ field: 'pythonEnvTool',
+ name: t('project.node.pytorch_python_env_tool'),
+ span: pythonEnvToolSpan,
+ options: PYTHON_ENV_TOOL
+ },
+ {
+ type: 'input',
+ field: 'requirements',
+ name: t('project.node.pytorch_requirements'),
+ span: requirementsSpan
+ },
+ {
+ type: 'input',
+ field: 'condaPythonVersion',
+ name: t('project.node.pytorch_conda_python_version'),
+ span: condaPythonVersionSpan,
+ props: {
+ placeholder: t('project.node.pytorch_conda_python_version_tips')
+ }
+ },
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
+
+export const PYTHON_ENV_TOOL = [
+ {
+ label: 'conda',
+ value: 'conda'
+ },
+ {
+ label: 'virtualenv',
+ value: 'virtualenv'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-queue.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-queue.ts
new file mode 100644
index 0000000000..034aba1abd
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-queue.ts
@@ -0,0 +1,32 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useYarnQueue(): IJsonItem {
+ const { t } = useI18n()
+
+ return {
+ type: 'input',
+ field: 'yarnQueue',
+ name: t('project.node.yarn_queue'),
+ span: 12,
+ props: {
+ placeholder: t('project.node.yarn_queue_tips')
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-relation-custom-params.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-relation-custom-params.ts
new file mode 100644
index 0000000000..c194f83a6d
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-relation-custom-params.ts
@@ -0,0 +1,99 @@
+/*
+ * 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 { computed, watchEffect } from 'vue'
+import { useI18n } from 'vue-i18n'
+import styles from '../index.module.scss'
+import type { IJsonItem } from '../types'
+
+export function useRelationCustomParams({
+ model,
+ children,
+ childrenField,
+ name
+}: {
+ model: {
+ [field: string]: any
+ }
+ children: IJsonItem
+ childrenField: string
+ name: string
+}): IJsonItem[] {
+ const { t } = useI18n()
+ const firstLevelRelationSpan = computed(() =>
+ model.dependTaskList.length ? 3 : 0
+ )
+
+ watchEffect(() => {
+ model.dependTaskList.forEach(
+ (item: { [childrenField: string]: [] }, i: number) => {
+ if (item[childrenField].length === 0) {
+ model.dependTaskList.splice(i, 1)
+ }
+ }
+ )
+ })
+ return [
+ {
+ type: 'custom',
+ name: t(`project.node.${name}`),
+ field: 'relationLabel',
+ span: 24,
+ class: styles['relaction-label']
+ },
+ {
+ type: 'switch',
+ field: 'relation',
+ props: {
+ round: false,
+ 'checked-value': 'AND',
+ 'unchecked-value': 'OR',
+ size: 'small'
+ },
+ slots: {
+ checked: () => t('project.node.and'),
+ unchecked: () => t('project.node.or')
+ },
+ span: firstLevelRelationSpan,
+ class: styles['relaction-switch']
+ },
+ {
+ type: 'custom-parameters',
+ field: 'dependTaskList',
+ span: 20,
+ children: [
+ {
+ type: 'switch',
+ field: 'relation',
+ props: {
+ round: false,
+ 'checked-value': 'AND',
+ 'unchecked-value': 'OR',
+ size: 'small'
+ },
+ slots: {
+ checked: () => t('project.node.and'),
+ unchecked: () => t('project.node.or')
+ },
+ span: 4,
+ value: 'AND',
+ class: styles['relaction-switch']
+ },
+ children
+ ]
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-remote-shell.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-remote-shell.ts
new file mode 100644
index 0000000000..a3a6f55e46
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-remote-shell.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useRemoteShell(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'editor',
+ field: 'rawScript',
+ name: t('project.node.script'),
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.script_tips')
+ }
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-resource-limit.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-resource-limit.ts
new file mode 100644
index 0000000000..15c804113e
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-resource-limit.ts
@@ -0,0 +1,45 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useResourceLimit(): IJsonItem[] {
+ const { t } = useI18n()
+ return [
+ {
+ type: 'input-number',
+ field: 'cpuQuota',
+ name: t('project.node.cpu_quota'),
+ span: 12,
+ slots: {
+ suffix: () => '%'
+ },
+ props: { min: -1 }
+ },
+ {
+ type: 'input-number',
+ field: 'memoryMax',
+ name: t('project.node.memory_max'),
+ span: 12,
+ slots: {
+ suffix: () => t('project.node.mb')
+ },
+ props: { min: -1 }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-resources.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-resources.ts
new file mode 100644
index 0000000000..90ba0a40a7
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-resources.ts
@@ -0,0 +1,184 @@
+/*
+ * 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 { ref, onMounted, Ref, isRef } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryResourceList } from '@/service/modules/resources'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import utils from '@/utils'
+import type { IJsonItem, IResource } from '../types'
+
+export function useResources(
+ span: number | Ref = 24,
+ required: boolean | Ref = false,
+ limit: number | Ref = -1
+): IJsonItem {
+ const { t } = useI18n()
+
+ interface ResourceOption {
+ name: string
+ fullName: string
+ dirctory: boolean
+ disable: boolean
+ children?: ResourceOption[]
+ }
+
+ const resourcesOptions = ref([])
+ const resourcesLoading = ref(false)
+
+ const taskStore = useTaskNodeStore()
+
+ const getResources = async () => {
+ if (taskStore.resources.length) {
+ resourcesOptions.value = taskStore.resources
+ return
+ }
+ if (resourcesLoading.value) return
+ resourcesLoading.value = true
+ const res = await queryResourceList({ type: 'FILE', fullName: '' })
+ utils.removeUselessChildren(res)
+ resourcesOptions.value = res || []
+ resourcesLoading.value = false
+ taskStore.updateResource(res)
+ }
+
+ const validateResourceExist = (
+ fullName: string,
+ parentDir: string[],
+ resources: ResourceOption[]
+ ): boolean => {
+ const isDirectory = (res: ResourceOption): boolean => {
+ return res.dirctory && new RegExp(`^${res.fullName}`).test(fullName)
+ }
+
+ const processDirectory = (res: ResourceOption): boolean => {
+ if (!res.children) {
+ res.children = []
+ }
+ parentDir.push(res.name)
+ return validateResourceExist(
+ fullName,
+ parentDir,
+ res.children as ResourceOption[]
+ )
+ }
+
+ if (resources.length > 0) {
+ for (const res of resources) {
+ if (isDirectory(res)) {
+ return processDirectory(res)
+ }
+
+ if (res.fullName === fullName) {
+ return true
+ }
+ }
+ }
+ addResourceNode(fullName, parentDir, resources)
+ return false
+ }
+
+ const addResourceNode = (
+ fullName: string,
+ parentDir: string[],
+ resources: ResourceOption[]
+ ) => {
+ const resourceNode = {
+ fullName: fullName,
+ name: getResourceDirAfter(fullName, parentDir),
+ dirctory: false,
+ disable: true
+ }
+ resources.push(resourceNode)
+ }
+
+ const getResourceDirAfter = (fullName: string, parentDir: string[]) => {
+ const dirctory = '/resources/' + parentDir.join('')
+ const delimiterIndex = fullName.indexOf(dirctory)
+ if (delimiterIndex !== -1) {
+ return fullName.substring(delimiterIndex + dirctory.length)
+ } else {
+ return fullName
+ }
+ }
+
+ onMounted(() => {
+ getResources()
+ })
+
+ return {
+ type: 'tree-select',
+ field: 'resourceList',
+ name: t('project.node.resources'),
+ span: span,
+ options: resourcesOptions,
+ props: {
+ multiple: true,
+ checkable: true,
+ cascade: true,
+ showPath: true,
+ filterable: true,
+ clearFilterAfterSelect: false,
+ checkStrategy: 'child',
+ placeholder: t('project.node.resources_tips'),
+ keyField: 'fullName',
+ labelField: 'name',
+ disabledField: 'disable',
+ loading: resourcesLoading
+ },
+ validate: {
+ trigger: ['blur'],
+ required: required,
+ validator(validate: any, value: string[]) {
+ if (value) {
+ const errorNames: string[] = []
+ value.forEach((item) => {
+ if (
+ !validateResourceExist(
+ item,
+ [],
+ resourcesOptions.value as ResourceOption[]
+ )
+ ) {
+ errorNames.push(item)
+ }
+ })
+ if (errorNames.length > 0) {
+ let errorName = ': '
+ errorNames.forEach((name) => {
+ value.splice(value.indexOf(name), 1)
+ errorName += getResourceDirAfter(name, []) + ';'
+ })
+ return new Error(
+ t('project.node.useless_resources_tips') + errorName
+ )
+ }
+ }
+
+ if (isRef(required) ? required.value : required) {
+ if (!value || value.length == 0) {
+ return new Error(t('project.node.resources_tips'))
+ }
+ const limit_ = isRef(limit) ? limit.value : limit
+ if (limit_ > 0 && value.length > limit_) {
+ return new Error(t('project.node.resources_limit_tips') + limit)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-rules.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-rules.ts
new file mode 100644
index 0000000000..71fc56cc8e
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-rules.ts
@@ -0,0 +1,304 @@
+/*
+ * 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 { ref, onMounted, computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import {
+ queryRuleList,
+ getRuleFormCreateJson,
+ getDatasourceOptionsById
+} from '@/service/modules/data-quality'
+import {
+ getDatasourceDatabasesById,
+ getDatasourceTablesById,
+ getDatasourceTableColumnsById
+} from '@/service/modules/data-source'
+import type { IJsonItem, IResponseJsonItem, IJsonItemParams } from '../types'
+
+export function useRules(
+ model: { [field: string]: any },
+ updateRules: (items: IJsonItem[], len: number) => void
+): IJsonItem[] {
+ const { t } = useI18n()
+ const rules = ref([])
+ const ruleLoading = ref(false)
+ const srcDatasourceOptions = ref([] as { label: string; value: number }[])
+ const srcDatabaseOptions = ref([] as { label: string; value: number }[])
+ const srcTableOptions = ref([] as { label: string; value: number }[])
+ const srcTableColumnOptions = ref([] as { label: string; value: number }[])
+ const targetDatasourceOptions = ref([] as { label: string; value: number }[])
+ const targetDatabaseOptions = ref([] as { label: string; value: number }[])
+ const targetTableOptions = ref([] as { label: string; value: string }[])
+ const targetTableColumnOptions = ref([] as { label: string; value: number }[])
+ const writerDatasourceOptions = ref([] as { label: string; value: number }[])
+
+ const fixValueSpan = computed(() => (model.comparison_type === 1 ? 24 : 0))
+
+ let preItemLen = 0
+
+ const getRuleList = async () => {
+ if (ruleLoading.value) return
+ ruleLoading.value = true
+ const result = await queryRuleList()
+ rules.value = result.map((item: { id: number; name: string }) => {
+ let name = ''
+ if (item.name) {
+ name = item.name.replace('$t(', '').replace(')', '')
+ }
+ return {
+ value: item.id,
+ label: name ? t(`project.node.${name}`) : ''
+ }
+ })
+ ruleLoading.value = false
+ }
+
+ const getRuleById = async (ruleId: number) => {
+ if (ruleLoading.value) return
+ ruleLoading.value = true
+ const result = await getRuleFormCreateJson(ruleId)
+ const items = JSON.parse(result).map((item: IResponseJsonItem) =>
+ formatResponseJson(item)
+ )
+ updateRules(items, preItemLen)
+ preItemLen = items.length
+ ruleLoading.value = false
+ }
+
+ const formatResponseJson = (
+ responseItem: IResponseJsonItem
+ ): IJsonItemParams => {
+ const item: IJsonItemParams = {
+ field: responseItem.field,
+ options: responseItem.options,
+ validate: responseItem.validate,
+ props: responseItem.props,
+ value: responseItem.value
+ }
+ item.props.filterable = true
+ const name = responseItem.name?.replace('$t(', '').replace(')', '')
+ item.name = name ? t(`project.node.${name}`) : ''
+
+ if (responseItem.type !== 'group') {
+ item.type = responseItem.type
+ } else {
+ item.type = 'custom-parameters'
+ item.children = item.props.rules.map((child: IJsonItemParams) => {
+ child.span = Math.floor(22 / item.props.rules.length)
+ return child
+ })
+ model[item.field] = model[item.field] || []
+ delete item.props.rules
+ }
+ if (responseItem.emit) {
+ responseItem.emit.forEach((emit) => {
+ if (emit === 'change') {
+ item.props.onUpdateValue = (value: string | number) => {
+ onFieldChange(value, item.field, true)
+ }
+ }
+ })
+ }
+ if (responseItem.props.placeholder) {
+ item.props.placeholder = t(
+ 'project.node.' +
+ responseItem.props.placeholder
+ .split(' ')
+ .join('_')
+ .split(',')
+ .join('')
+ .toLowerCase()
+ )
+ }
+ if (item.field === 'src_datasource_id') {
+ item.options = srcDatasourceOptions
+ }
+ if (item.field === 'src_database') {
+ item.options = srcDatabaseOptions
+ }
+ if (item.field === 'target_datasource_id') {
+ item.options = targetDatasourceOptions
+ }
+ if (item.field === 'target_database') {
+ item.options = targetDatabaseOptions
+ }
+ if (item.field === 'writer_datasource_id') {
+ item.options = writerDatasourceOptions
+ }
+ if (item.field === 'src_table') {
+ item.options = srcTableOptions
+ item.props.filterable = true
+ }
+ if (item.field === 'target_table') {
+ item.options = targetTableOptions
+ item.props.filterable = true
+ }
+ if (item.field === 'src_field') {
+ item.options = srcTableColumnOptions
+ }
+ if (item.field === 'target_field') {
+ item.options = targetTableColumnOptions
+ }
+
+ if (model[item.field] !== void 0) {
+ onFieldChange(model[item.field], item.field, false)
+ item.value = model[item.field]
+ }
+
+ return item
+ }
+ const onFieldChange = async (
+ value: string | number,
+ field: string,
+ reset: boolean
+ ) => {
+ if (field === 'src_connector_type' && typeof value === 'number') {
+ const result = await getDatasourceOptionsById(value)
+ srcDatasourceOptions.value = result || []
+ if (reset) {
+ srcDatabaseOptions.value = []
+ srcTableOptions.value = []
+ srcTableColumnOptions.value = []
+ model.src_datasource_id = null
+ model.src_database = null
+ model.src_table = null
+ model.src_field = null
+ }
+ return
+ }
+ if (field === 'target_connector_type' && typeof value === 'number') {
+ const result = await getDatasourceOptionsById(value)
+ targetDatasourceOptions.value = result || []
+ if (reset) {
+ targetDatabaseOptions.value = []
+ targetTableOptions.value = []
+ targetTableColumnOptions.value = []
+ model.target_datasource_id = null
+ model.target_database = null
+ model.target_table = null
+ model.target_field = null
+ }
+ return
+ }
+ if (field === 'writer_connector_type' && typeof value === 'number') {
+ const result = await getDatasourceOptionsById(value)
+ writerDatasourceOptions.value = result || []
+ if (reset) {
+ model.writer_datasource_id = null
+ }
+ return
+ }
+ if (field === 'src_datasource_id' && typeof value === 'number') {
+ const result = await getDatasourceDatabasesById(value)
+ srcDatabaseOptions.value = result || []
+ if (reset) {
+ srcTableOptions.value = []
+ srcTableColumnOptions.value = []
+ model.src_database = null
+ model.src_table = null
+ model.src_field = null
+ }
+ }
+ if (field === 'target_datasource_id' && typeof value === 'number') {
+ const result = await getDatasourceDatabasesById(value)
+ targetDatabaseOptions.value = result || []
+ if (reset) {
+ targetTableOptions.value = []
+ targetTableColumnOptions.value = []
+ model.target_database = null
+ model.target_table = null
+ model.target_field = null
+ }
+ }
+
+ if (field === 'src_database' && typeof value === 'string') {
+ const result = await getDatasourceTablesById(
+ model.src_datasource_id,
+ value
+ )
+ srcTableOptions.value = result || []
+ if (reset) {
+ srcTableColumnOptions.value = []
+ model.src_table = null
+ model.src_field = null
+ }
+ }
+
+ if (field === 'target_database' && typeof value === 'string') {
+ const result = await getDatasourceTablesById(
+ model.target_datasource_id,
+ value
+ )
+ targetTableOptions.value = result || []
+ if (reset) {
+ targetTableColumnOptions.value = []
+ model.target_table = null
+ model.target_field = null
+ }
+ }
+
+ if (field === 'src_table' && typeof value === 'string') {
+ const result = await getDatasourceTableColumnsById(
+ model.src_datasource_id,
+ model.src_database,
+ value
+ )
+ srcTableColumnOptions.value = result || []
+ if (reset) {
+ model.src_field = null
+ }
+ }
+ if (field === 'target_table' && typeof value === 'string') {
+ const result = await getDatasourceTableColumnsById(
+ model.target_datasource_id,
+ model.target_database,
+ value
+ )
+ targetTableColumnOptions.value = result || []
+ if (reset) {
+ model.target_field = null
+ }
+ }
+ }
+
+ onMounted(async () => {
+ await getRuleList()
+ await getRuleById(model.ruleId)
+ })
+
+ return [
+ {
+ type: 'select',
+ field: 'ruleId',
+ name: t('project.node.rule_name'),
+ props: {
+ loading: ruleLoading,
+ filterable: true,
+ onUpdateValue: getRuleById
+ },
+ options: rules
+ },
+ {
+ type: 'input',
+ field: 'comparison_name',
+ name: t('project.node.fix_value'),
+ props: {
+ placeholder: t('project.node.fix_value')
+ },
+ span: fixValueSpan
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-run-flag.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-run-flag.ts
new file mode 100644
index 0000000000..ab61b88ce9
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-run-flag.ts
@@ -0,0 +1,40 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useRunFlag(): IJsonItem {
+ const { t } = useI18n()
+ const options = [
+ {
+ label: t('project.node.normal'),
+ value: 'YES'
+ },
+ {
+ label: t('project.node.prohibition_execution'),
+ value: 'NO'
+ }
+ ]
+ return {
+ type: 'radio',
+ field: 'flag',
+ name: t('project.node.run_flag'),
+ options: options,
+ span: 12
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sagemaker.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sagemaker.ts
new file mode 100644
index 0000000000..ad78353727
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sagemaker.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 type { IJsonItem } from '../types'
+import { useCustomParams } from '.'
+
+export function useSagemaker(model: { [field: string]: any }): IJsonItem[] {
+ return [
+ {
+ type: 'editor',
+ field: 'sagemakerRequestJson',
+ name: 'SagemakerRequestJson',
+ props: {
+ language: 'json'
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: 'requestJson'
+ }
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sea-tunnel.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sea-tunnel.ts
new file mode 100644
index 0000000000..7931e83049
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sea-tunnel.ts
@@ -0,0 +1,230 @@
+/*
+ * 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 { computed, ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useDeployMode, useResources, useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useSeaTunnel(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ const configEditorSpan = computed(() => (model.useCustom ? 24 : 0))
+ const resourceEditorSpan = computed(() => (model.useCustom ? 0 : 24))
+ const flinkSpan = computed(() =>
+ model.startupScript.includes('flink') ? 24 : 0
+ )
+ const deployModeSpan = computed(() =>
+ model.startupScript.includes('spark') ||
+ model.startupScript === 'seatunnel.sh'
+ ? 24
+ : 0
+ )
+ const masterSpan = computed(() =>
+ model.startupScript.includes('spark') && model.deployMode !== 'local'
+ ? 12
+ : 0
+ )
+ const masterUrlSpan = computed(() =>
+ model.startupScript.includes('spark') &&
+ model.deployMode !== 'local' &&
+ (model.master === 'SPARK' || model.master === 'MESOS')
+ ? 12
+ : 0
+ )
+ const showClient = computed(() => model.startupScript.includes('spark'))
+ const showLocal = computed(() => model.startupScript === 'seatunnel.sh')
+ const othersSpan = computed(() =>
+ model.startupScript.includes('flink') ||
+ model.startupScript === 'seatunnel.sh'
+ ? 24
+ : 0
+ )
+
+ return [
+ {
+ type: 'select',
+ field: 'startupScript',
+ span: 15,
+ name: t('project.node.startup_script'),
+ options: STARTUP_SCRIPT,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.startup_script_tips')
+ },
+ props: {
+ 'on-update:value': (value: boolean) => {
+ if (value) {
+ if (model.startupScript === 'seatunnel.sh') {
+ model.deployMode = 'local'
+ }
+ if (model.startupScript.includes('spark')) {
+ model.deployMode = 'client'
+ }
+ }
+ }
+ }
+ },
+
+ // SeaTunnel flink parameter
+ {
+ type: 'select',
+ field: 'runMode',
+ name: t('project.node.run_mode'),
+ options: FLINK_RUN_MODE,
+ value: model.runMode,
+ span: flinkSpan
+ },
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.option_parameters'),
+ span: othersSpan,
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.option_parameters_tips')
+ }
+ },
+
+ // SeaTunnel spark parameter
+ useDeployMode(deployModeSpan, showClient, ref(true), showLocal),
+ {
+ type: 'select',
+ field: 'master',
+ name: t('project.node.sea_tunnel_master'),
+ options: masterTypeOptions,
+ value: model.master,
+ span: masterSpan
+ },
+ {
+ type: 'input',
+ field: 'masterUrl',
+ name: t('project.node.sea_tunnel_master_url'),
+ value: model.masterUrl,
+ span: masterUrlSpan,
+ props: {
+ placeholder: t('project.node.sea_tunnel_master_url_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: masterUrlSpan.value !== 0,
+ validator(validate: any, value: string) {
+ if (masterUrlSpan.value !== 0 && !value) {
+ return new Error(t('project.node.sea_tunnel_master_url_tips'))
+ }
+ }
+ }
+ },
+
+ // SeaTunnel config parameter
+ {
+ type: 'switch',
+ field: 'useCustom',
+ name: t('project.node.custom_config')
+ },
+ {
+ type: 'editor',
+ field: 'rawScript',
+ name: t('project.node.script'),
+ span: configEditorSpan,
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: model.useCustom,
+ validator(validate: any, value: string) {
+ if (model.useCustom && !value) {
+ return new Error(t('project.node.script_tips'))
+ }
+ }
+ }
+ },
+ useResources(resourceEditorSpan, true, 1),
+ ...useCustomParams({ model, field: 'localParams', isSimple: true })
+ ]
+}
+
+export const STARTUP_SCRIPT = [
+ {
+ label: 'seatunnel.sh',
+ value: 'seatunnel.sh'
+ },
+ {
+ label: 'start-seatunnel-flink-13-connector-v2.sh',
+ value: 'start-seatunnel-flink-13-connector-v2.sh'
+ },
+ {
+ label: 'start-seatunnel-flink-15-connector-v2.sh',
+ value: 'start-seatunnel-flink-15-connector-v2.sh'
+ },
+ {
+ label: 'start-seatunnel-flink-connector-v2.sh',
+ value: 'start-seatunnel-flink-connector-v2.sh'
+ },
+ {
+ label: 'start-seatunnel-flink.sh',
+ value: 'start-seatunnel-flink.sh'
+ },
+ {
+ label: 'start-seatunnel-spark-2-connector-v2.sh',
+ value: 'start-seatunnel-spark-2-connector-v2.sh'
+ },
+ {
+ label: 'start-seatunnel-spark-3-connector-v2.sh',
+ value: 'start-seatunnel-spark-3-connector-v2.sh'
+ },
+ {
+ label: 'start-seatunnel-spark-connector-v2.sh',
+ value: 'start-seatunnel-spark-connector-v2.sh'
+ },
+ {
+ label: 'start-seatunnel-spark.sh',
+ value: 'start-seatunnel-spark.sh'
+ }
+]
+
+export const FLINK_RUN_MODE = [
+ {
+ label: 'none',
+ value: 'NONE'
+ },
+ {
+ label: 'run',
+ value: 'RUN'
+ },
+ {
+ label: 'run-application',
+ value: 'RUN_APPLICATION'
+ }
+]
+
+export const masterTypeOptions = [
+ {
+ label: 'yarn',
+ value: 'YARN'
+ },
+ {
+ label: 'local',
+ value: 'LOCAL'
+ },
+ {
+ label: 'spark://',
+ value: 'SPARK'
+ },
+ {
+ label: 'mesos://',
+ value: 'MESOS'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-shell.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-shell.ts
new file mode 100644
index 0000000000..9c9f171a1f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-shell.ts
@@ -0,0 +1,38 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams, useResources } from '.'
+import type { IJsonItem } from '../types'
+
+export function useShell(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'editor',
+ field: 'rawScript',
+ name: t('project.node.script'),
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.script_tips')
+ }
+ },
+ useResources(),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-spark.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-spark.ts
new file mode 100644
index 0000000000..ab89e69e6d
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-spark.ts
@@ -0,0 +1,224 @@
+/*
+ * 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 { computed, ref, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import {
+ useCustomParams,
+ useDeployMode,
+ useDriverCores,
+ useDriverMemory,
+ useExecutorNumber,
+ useExecutorMemory,
+ useExecutorCores,
+ useMainJar,
+ useNamespace,
+ useResources,
+ useYarnQueue
+} from '.'
+import type { IJsonItem } from '../types'
+
+export function useSpark(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const mainClassSpan = computed(() =>
+ model.programType === 'PYTHON' || model.programType === 'SQL' ? 0 : 24
+ )
+
+ const masterSpan = computed(() =>
+ model.programType === 'PYTHON' || model.programType === 'SQL' ? 0 : 24
+ )
+
+ const mainArgsSpan = computed(() => (model.programType === 'SQL' ? 0 : 24))
+
+ const rawScriptSpan = computed(() =>
+ model.programType === 'SQL' && model.sqlExecutionType === 'SCRIPT' ? 24 : 0
+ )
+
+ const showCluster = computed(() => model.programType !== 'SQL')
+
+ const resourcesRequired = ref(
+ model.programType === 'SQL' && model.sqlExecutionType === 'FILE'
+ )
+
+ const resourcesLimit = computed(() =>
+ model.programType === 'SQL' && model.sqlExecutionType === 'FILE' ? 1 : -1
+ )
+
+ const sqlExecutionTypeSpan = computed(() =>
+ model.programType === 'SQL' ? 12 : 0
+ )
+
+ const SQL_EXECUTION_TYPES = [
+ {
+ label: t('project.node.sql_execution_type_from_script'),
+ value: 'SCRIPT'
+ },
+ {
+ label: t('project.node.sql_execution_type_from_file'),
+ value: 'FILE'
+ }
+ ]
+
+ watch(
+ () => [model.sqlExecutionType, model.programType],
+ () => {
+ resourcesRequired.value =
+ model.programType === 'SQL' && model.sqlExecutionType === 'FILE'
+ }
+ )
+
+ return [
+ {
+ type: 'select',
+ field: 'programType',
+ span: 12,
+ name: t('project.node.program_type'),
+ options: PROGRAM_TYPES,
+ props: {
+ 'on-update:value': () => {
+ model.mainJar = null
+ model.mainClass = ''
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'sqlExecutionType',
+ span: sqlExecutionTypeSpan,
+ name: t('project.node.sql_execution_type'),
+ options: SQL_EXECUTION_TYPES,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true
+ }
+ },
+ {
+ type: 'input',
+ field: 'mainClass',
+ span: mainClassSpan,
+ name: t('project.node.main_class'),
+ props: {
+ placeholder: t('project.node.main_class_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: model.programType !== 'PYTHON' && model.programType !== 'SQL',
+ validator(validate: any, value: string) {
+ if (
+ model.programType !== 'PYTHON' &&
+ !value &&
+ model.programType !== 'SQL'
+ ) {
+ return new Error(t('project.node.main_class_tips'))
+ }
+ }
+ }
+ },
+ useMainJar(model),
+ {
+ type: 'editor',
+ field: 'rawScript',
+ span: rawScriptSpan,
+ name: t('project.node.script'),
+ props: {
+ language: 'sql'
+ },
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.script_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'master',
+ span: masterSpan,
+ name: t('project.node.master'),
+ props: {
+ placeholder: t('project.node.master_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: false,
+ validator(validate: any, value: string) {
+ if (
+ model.programType !== 'PYTHON' &&
+ !value &&
+ model.programType !== 'SQL'
+ ) {
+ return new Error(t('project.node.master_tips'))
+ }
+ }
+ }
+ },
+ useDeployMode(24, ref(true), showCluster),
+ useNamespace(),
+ {
+ type: 'input',
+ field: 'appName',
+ name: t('project.node.app_name'),
+ props: {
+ placeholder: t('project.node.app_name_tips')
+ }
+ },
+ useDriverCores(),
+ useDriverMemory(),
+ useExecutorNumber(),
+ useExecutorMemory(),
+ useExecutorCores(),
+ useYarnQueue(),
+ {
+ type: 'input',
+ field: 'mainArgs',
+ span: mainArgsSpan,
+ name: t('project.node.main_arguments'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.main_arguments_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.option_parameters'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.option_parameters_tips')
+ }
+ },
+ useResources(24, resourcesRequired, resourcesLimit),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
+
+export const PROGRAM_TYPES = [
+ {
+ label: 'JAVA',
+ value: 'JAVA'
+ },
+ {
+ label: 'SCALA',
+ value: 'SCALA'
+ },
+ {
+ label: 'PYTHON',
+ value: 'PYTHON'
+ },
+ {
+ label: 'SQL',
+ value: 'SQL'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sql-type.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sql-type.ts
new file mode 100644
index 0000000000..f54b922b00
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sql-type.ts
@@ -0,0 +1,165 @@
+/*
+ * 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 { ref, onMounted, computed, h } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { listNormalAlertGroupById } from '@/service/modules/alert-group'
+import styles from '../index.module.scss'
+import type { IJsonItem } from '../types'
+
+export function useSqlType(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const querySpan = computed(() => (model.sqlType === '0' ? 6 : 0))
+ const emailSpan = computed(() =>
+ model.sqlType === '0' && model.sendEmail ? 24 : 0
+ )
+ const groups = ref([])
+ const groupsLoading = ref(false)
+ const SQL_TYPES = [
+ {
+ value: '0',
+ label: t('project.node.sql_type_query')
+ },
+ {
+ value: '1',
+ label: t('project.node.sql_type_non_query')
+ }
+ ]
+
+ const getGroups = async () => {
+ if (groupsLoading.value) return
+ groupsLoading.value = true
+ const res = await listNormalAlertGroupById()
+ groups.value = res.map((item: { id: number; groupName: string }) => ({
+ label: item.groupName,
+ value: item.id
+ }))
+ groupsLoading.value = false
+ }
+
+ onMounted(() => {
+ getGroups()
+ })
+
+ return [
+ {
+ type: 'select',
+ field: 'sqlType',
+ span: 6,
+ name: t('project.node.sql_type'),
+ options: SQL_TYPES,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true
+ }
+ },
+ {
+ type: 'switch',
+ field: 'sendEmail',
+ span: querySpan,
+ name: t('project.node.send_email')
+ },
+ {
+ type: 'select',
+ field: 'displayRows',
+ span: querySpan,
+ name: t('project.node.log_display'),
+ options: DISPLAY_ROWS,
+ props: {
+ filterable: true,
+ tag: true
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ validator(unuse, value) {
+ if (!/^\+?[1-9][0-9]*$/.test(value)) {
+ return new Error(t('project.node.integer_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'custom',
+ field: 'displayRowsTips',
+ span: querySpan,
+ widget: h(
+ 'div',
+ { class: styles['display-rows-tips'] },
+ t('project.node.rows_of_result')
+ )
+ },
+ {
+ type: 'input',
+ field: 'title',
+ name: t('project.node.title'),
+ props: {
+ placeholder: t('project.node.title_tips')
+ },
+ span: emailSpan,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(unuse, value) {
+ if (model.sendEmail && !value)
+ return new Error(t('project.node.title_tips'))
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'groupId',
+ name: t('project.node.alarm_group'),
+ options: groups,
+ span: emailSpan,
+ props: {
+ loading: groupsLoading,
+ placeholder: t('project.node.alarm_group_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(unuse, value) {
+ if (model.sendEmail && !value)
+ return new Error(t('project.node.alarm_group_tips'))
+ }
+ }
+ }
+ ]
+}
+
+const DISPLAY_ROWS = [
+ {
+ label: '1',
+ value: 1
+ },
+ {
+ label: '10',
+ value: 10
+ },
+ {
+ label: '25',
+ value: 25
+ },
+ {
+ label: '50',
+ value: 50
+ },
+ {
+ label: '100',
+ value: 100
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sql.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sql.ts
new file mode 100644
index 0000000000..46e489d40e
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sql.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 { computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import { useUdfs } from './use-udfs'
+import type { IJsonItem } from '../types'
+
+export function useSql(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const hiveSpan = computed(() => (model.type === 'HIVE' ? 24 : 0))
+
+ return [
+ {
+ type: 'input',
+ field: 'connParams',
+ name: t('project.node.sql_parameter'),
+ props: {
+ placeholder:
+ t('project.node.format_tips') + ' key1=value1;key2=value2...'
+ },
+ span: hiveSpan
+ },
+ {
+ type: 'editor',
+ field: 'sql',
+ name: t('project.node.sql_statement'),
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ message: t('project.node.sql_empty_tips')
+ },
+ props: {
+ language: 'sql'
+ }
+ },
+ useUdfs(model),
+ ...useCustomParams({ model, field: 'localParams', isSimple: false }),
+ {
+ type: 'multi-input',
+ field: 'preStatements',
+ name: t('project.node.pre_sql_statement'),
+ span: 22,
+ props: {
+ placeholder: t('project.node.sql_input_placeholder'),
+ type: 'textarea',
+ autosize: { minRows: 1 }
+ }
+ },
+ {
+ type: 'multi-input',
+ field: 'postStatements',
+ name: t('project.node.post_sql_statement'),
+ span: 22,
+ props: {
+ placeholder: t('project.node.sql_input_placeholder'),
+ type: 'textarea',
+ autosize: { minRows: 1 }
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-datasource.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-datasource.ts
new file mode 100644
index 0000000000..399c88b387
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-datasource.ts
@@ -0,0 +1,107 @@
+/*
+ * 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 { onMounted, ref, Ref, watch } from 'vue'
+import { queryDataSourceList } from '@/service/modules/data-source'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem, IDataBase } from '../types'
+import type { TypeReq } from '@/service/modules/data-source/types'
+
+export function useDatasource(
+ model: { [field: string]: any },
+ span: Ref,
+ fieldType: string,
+ fieldDatasource: string
+): IJsonItem[] {
+ const { t } = useI18n()
+ const dataSourceList = ref([])
+ const loading = ref(false)
+ const hadoopSourceTypes = ref(['HIVE', 'HDFS'])
+ const getDataSource = async (type: IDataBase) => {
+ if (hadoopSourceTypes.value.some((source) => source === type)) {
+ loading.value = false
+ return
+ }
+ loading.value = true
+ if (model.modelType === 'import') {
+ model.sourceMysqlDatasource = model.sourceMysqlDatasource
+ ? model.sourceMysqlDatasource
+ : ''
+ model.sourceMysqlType = type
+ } else {
+ model.sourceMysqlDatasource = model.targetMysqlDatasource
+ ? model.targetMysqlDatasource
+ : ''
+ model.targetMysqlType = type
+ }
+ const params = { type, testFlag: 0 } as TypeReq
+ const result = await queryDataSourceList(params)
+ dataSourceList.value = result.map((item: { name: string; id: number }) => ({
+ label: item.name,
+ value: item.id
+ }))
+ loading.value = false
+ }
+ onMounted(() => {
+ getDataSource(model.sourceType)
+ })
+
+ watch(
+ () => [model.sourceType],
+ () => {
+ getDataSource(model.sourceType)
+ }
+ )
+
+ watch(
+ () => [model.targetType],
+ () => {
+ getDataSource(model.targetType)
+ }
+ )
+ return [
+ {
+ type: 'input',
+ field: fieldType,
+ name: t('project.node.datasource'),
+ span: 0,
+ validate: {
+ required: true
+ }
+ },
+ {
+ type: 'select',
+ field: fieldDatasource,
+ name: t('project.node.datasource'),
+ span: span,
+ props: {
+ placeholder: t('project.node.datasource_tips'),
+ filterable: true,
+ loading
+ },
+ options: dataSourceList,
+ validate: {
+ trigger: ['blur', 'input'],
+ validator(validate, value) {
+ if (!value) {
+ return new Error(t('project.node.datasource_tips'))
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-source-type.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-source-type.ts
new file mode 100644
index 0000000000..d5554e7a14
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-source-type.ts
@@ -0,0 +1,332 @@
+/*
+ * 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 { h, onMounted, Ref, ref, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useDatasource } from './use-sqoop-datasource'
+import { useCustomParams } from '.'
+import styles from '../index.module.scss'
+import type { IJsonItem, IOption, ModelType } from '../types'
+
+export function useSourceType(
+ model: { [field: string]: any },
+ unCustomSpan: Ref
+): IJsonItem[] {
+ const { t } = useI18n()
+ const rdbmsSpan = ref(24)
+ const tableSpan = ref(0)
+ const editorSpan = ref(24)
+ const columnSpan = ref(0)
+ const hiveSpan = ref(0)
+ const hdfsSpan = ref(0)
+ const datasourceSpan = ref(24)
+ const isChange: any = ref(false)
+ const rdbmsSourceTypes = ref([
+ {
+ label: 'MYSQL',
+ value: 'MYSQL'
+ },
+ {
+ label: 'ORACLE',
+ value: 'ORACLE'
+ },
+ {
+ label: 'SQLSERVER',
+ value: 'SQLSERVER'
+ },
+ {
+ label: 'HANA',
+ value: 'HANA'
+ }
+ ] as IOption[])
+ const hadoopSourceTypes = ref([
+ {
+ label: 'HIVE',
+ value: 'HIVE'
+ },
+ {
+ label: 'HDFS',
+ value: 'HDFS'
+ }
+ ] as IOption[])
+ const sourceTypes = ref()
+ const resetSpan = () => {
+ rdbmsSpan.value =
+ unCustomSpan.value &&
+ rdbmsSourceTypes.value.some((source) => source.value === model.sourceType)
+ ? 24
+ : 0
+ tableSpan.value = rdbmsSpan.value && model.srcQueryType === '0' ? 24 : 0
+ editorSpan.value = rdbmsSpan.value && model.srcQueryType === '1' ? 24 : 0
+ columnSpan.value = tableSpan.value && model.srcColumnType === '1' ? 24 : 0
+ hiveSpan.value = unCustomSpan.value && model.sourceType === 'HIVE' ? 24 : 0
+ hdfsSpan.value = unCustomSpan.value && model.sourceType === 'HDFS' ? 24 : 0
+ datasourceSpan.value =
+ unCustomSpan.value &&
+ rdbmsSourceTypes.value.some((source) => source.value === model.sourceType)
+ ? 24
+ : 0
+ }
+ const resetValue = () => {
+ if (!isChange.value) {
+ isChange.value = true
+ return
+ }
+ switch (model.modelType) {
+ case 'import':
+ model.sourceMysqlDatasource = ''
+ break
+ case 'export':
+ model.sourceHiveDatabase = ''
+ model.sourceHiveTable = ''
+ model.sourceHivePartitionKey = ''
+ model.sourceHivePartitionValue = ''
+ model.sourceHdfsExportDir = ''
+ break
+ default:
+ model.sourceMysqlDatasource = ''
+ }
+ }
+ const getSourceTypesByModelType = (modelType: ModelType): IOption[] => {
+ switch (modelType) {
+ case 'import':
+ return rdbmsSourceTypes.value
+ case 'export':
+ return hadoopSourceTypes.value
+ default:
+ return rdbmsSourceTypes.value
+ }
+ }
+
+ onMounted(() => {
+ sourceTypes.value = [...rdbmsSourceTypes.value]
+ })
+
+ watch(
+ () => model.modelType,
+ (modelType: ModelType) => {
+ sourceTypes.value = getSourceTypesByModelType(modelType)
+ model.sourceType = sourceTypes.value[0].value
+ }
+ )
+ watch(
+ () => [
+ unCustomSpan.value,
+ model.sourceType,
+ model.srcQueryType,
+ model.srcColumnType
+ ],
+ () => {
+ resetValue()
+ resetSpan()
+ }
+ )
+
+ return [
+ {
+ type: 'custom',
+ field: 'custom-title-source',
+ span: unCustomSpan,
+ widget: h(
+ 'div',
+ { class: styles['field-title'] },
+ t('project.node.data_source')
+ )
+ },
+ {
+ type: 'select',
+ field: 'sourceType',
+ name: t('project.node.type'),
+ span: unCustomSpan,
+ options: sourceTypes
+ },
+ ...useDatasource(
+ model,
+ datasourceSpan,
+ 'sourceMysqlType',
+ 'sourceMysqlDatasource'
+ ),
+ {
+ type: 'radio',
+ field: 'srcQueryType',
+ name: t('project.node.model_type'),
+ span: rdbmsSpan,
+ options: [
+ {
+ label: t('project.node.form'),
+ value: '0'
+ },
+ {
+ label: 'SQL',
+ value: '1'
+ }
+ ],
+ props: {
+ 'on-update:value': (value: '0' | '1') => {
+ model.targetType = value === '0' ? 'HIVE' : 'HDFS'
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'srcTable',
+ name: t('project.node.table'),
+ span: tableSpan,
+ props: {
+ placeholder: t('project.node.table_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate, value) {
+ if (tableSpan.value && !value) {
+ return new Error(t('project.node.table_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'radio',
+ field: 'srcColumnType',
+ name: t('project.node.column_type'),
+ span: tableSpan,
+ options: [
+ { label: t('project.node.all_columns'), value: '0' },
+ { label: t('project.node.some_columns'), value: '1' }
+ ]
+ },
+ {
+ type: 'input',
+ field: 'srcColumns',
+ name: t('project.node.column'),
+ span: columnSpan,
+ props: {
+ placeholder: t('project.node.column_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate, value) {
+ if (!!columnSpan.value && !value) {
+ return new Error(t('project.node.column_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'sourceHiveDatabase',
+ name: t('project.node.database'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.database_tips')
+ },
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(validate, value) {
+ if (hiveSpan.value && !value) {
+ return new Error(t('project.node.database_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'sourceHiveTable',
+ name: t('project.node.table'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.hive_table_tips')
+ },
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(validate, value) {
+ if (hiveSpan.value && !value) {
+ return new Error(t('project.node.hive_table_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'sourceHivePartitionKey',
+ name: t('project.node.hive_partition_keys'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.hive_partition_keys_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'sourceHivePartitionValue',
+ name: t('project.node.hive_partition_values'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.hive_partition_values_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'sourceHdfsExportDir',
+ name: t('project.node.export_dir'),
+ span: hdfsSpan,
+ props: {
+ placeholder: t('project.node.export_dir_tips')
+ },
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(validate, value) {
+ if (hdfsSpan.value && !value) {
+ return new Error(t('project.node.export_dir_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'editor',
+ field: 'sourceMysqlSrcQuerySql',
+ name: t('project.node.sql_statement'),
+ span: editorSpan,
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(validate, value) {
+ if (editorSpan.value && !value) {
+ return new Error(t('project.node.sql_statement_tips'))
+ }
+ }
+ }
+ },
+ ...useCustomParams({
+ model,
+ field: 'mapColumnHive',
+ name: 'map_column_hive',
+ isSimple: true,
+ span: rdbmsSpan
+ }),
+ ...useCustomParams({
+ model,
+ field: 'mapColumnJava',
+ name: 'map_column_java',
+ isSimple: true,
+ span: rdbmsSpan
+ })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-target-type.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-target-type.ts
new file mode 100644
index 0000000000..252ef7631a
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop-target-type.ts
@@ -0,0 +1,427 @@
+/*
+ * 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 { h, onMounted, Ref, ref, watch } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useDatasource } from './use-sqoop-datasource'
+import styles from '../index.module.scss'
+import type { IJsonItem, IOption, SourceType } from '../types'
+
+export function useTargetType(
+ model: { [field: string]: any },
+ unCustomSpan: Ref
+): IJsonItem[] {
+ const { t } = useI18n()
+ const hiveSpan = ref(24)
+ const hdfsSpan = ref(0)
+ const rdbmsSpan = ref(0)
+ const dataSourceSpan = ref(0)
+ const updateSpan = ref(0)
+ const isChange: any = ref(false)
+ const rdbmsSourceTypes = ref([
+ {
+ label: 'MYSQL',
+ value: 'MYSQL'
+ },
+ {
+ label: 'ORACLE',
+ value: 'ORACLE'
+ },
+ {
+ label: 'SQLSERVER',
+ value: 'SQLSERVER'
+ },
+ {
+ label: 'HANA',
+ value: 'HANA'
+ }
+ ] as IOption[])
+ const hadoopSourceTypes = ref([
+ {
+ label: 'HIVE',
+ value: 'HIVE'
+ },
+ {
+ label: 'HDFS',
+ value: 'HDFS'
+ }
+ ] as IOption[])
+ const targetTypes = ref()
+
+ const resetSpan = () => {
+ hiveSpan.value = unCustomSpan.value && model.targetType === 'HIVE' ? 24 : 0
+ hdfsSpan.value = unCustomSpan.value && model.targetType === 'HDFS' ? 24 : 0
+ rdbmsSpan.value =
+ unCustomSpan.value &&
+ rdbmsSourceTypes.value.some((target) => target.value === model.targetType)
+ ? 24
+ : 0
+ dataSourceSpan.value =
+ unCustomSpan.value &&
+ rdbmsSourceTypes.value.some((target) => target.value === model.targetType)
+ ? 24
+ : 0
+ updateSpan.value = rdbmsSpan.value && model.targetMysqlIsUpdate ? 24 : 0
+ }
+
+ const getTargetTypesBySourceType = (
+ sourceType: SourceType,
+ srcQueryType: string
+ ): IOption[] => {
+ switch (sourceType) {
+ case 'MYSQL':
+ if (srcQueryType === '1') {
+ return hadoopSourceTypes.value
+ }
+ return hadoopSourceTypes.value
+ case 'HDFS':
+ case 'HIVE':
+ return rdbmsSourceTypes.value
+ default:
+ return hadoopSourceTypes.value
+ }
+ }
+
+ const resetValue = () => {
+ if (!isChange.value) {
+ isChange.value = true
+ return
+ }
+ switch (model.modelType) {
+ case 'import':
+ model.targetHiveDatabase = ''
+ model.targetHiveTable = ''
+ model.targetHdfsTargetPath = ''
+ break
+ case 'export':
+ model.targetMysqlDatasource = ''
+ model.targetMysqlTable = ''
+ model.targetMysqlColumns = ''
+ model.targetMysqlFieldsTerminated = ''
+ model.targetMysqlLinesTerminated = ''
+ model.targetMysqlTable = ''
+ break
+ default:
+ model.sourceMysqlDatasource = ''
+ }
+ }
+
+ onMounted(() => {
+ targetTypes.value = [...hadoopSourceTypes.value]
+ })
+
+ watch(
+ () => [model.sourceType, model.srcQueryType],
+ ([sourceType, srcQueryType]) => {
+ targetTypes.value = getTargetTypesBySourceType(sourceType, srcQueryType)
+ model.targetType = targetTypes.value[0].value
+ }
+ )
+
+ watch(
+ () => [unCustomSpan.value, model.targetType, model.targetMysqlIsUpdate],
+ () => {
+ resetValue()
+ resetSpan()
+ }
+ )
+
+ return [
+ {
+ type: 'custom',
+ field: 'custom-title-target',
+ span: unCustomSpan,
+ widget: h(
+ 'div',
+ { class: styles['field-title'] },
+ t('project.node.data_target')
+ )
+ },
+ {
+ type: 'select',
+ field: 'targetType',
+ name: t('project.node.type'),
+ span: unCustomSpan,
+ options: targetTypes
+ },
+ {
+ type: 'input',
+ field: 'targetHiveDatabase',
+ name: t('project.node.database'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.database_tips')
+ },
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(validate, value) {
+ if (hiveSpan.value && !value) {
+ return new Error(t('project.node.database_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetHiveTable',
+ name: t('project.node.table'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.table')
+ },
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(rule, value) {
+ if (hiveSpan.value && !value) {
+ return new Error(t('project.node.table_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'switch',
+ field: 'targetHiveCreateTable',
+ span: hiveSpan,
+ name: t('project.node.create_hive_table')
+ },
+ {
+ type: 'switch',
+ field: 'targetHiveDropDelimiter',
+ span: hiveSpan,
+ name: t('project.node.drop_delimiter')
+ },
+ {
+ type: 'switch',
+ field: 'targetHiveOverWrite',
+ span: hiveSpan,
+ name: t('project.node.over_write_src')
+ },
+ {
+ type: 'input',
+ field: 'targetHiveTargetDir',
+ name: t('project.node.hive_target_dir'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.hive_target_dir_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetHiveReplaceDelimiter',
+ name: t('project.node.replace_delimiter'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.replace_delimiter_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetHivePartitionKey',
+ name: t('project.node.hive_partition_keys'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.hive_partition_keys_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetHivePartitionValue',
+ name: t('project.node.hive_partition_values'),
+ span: hiveSpan,
+ props: {
+ placeholder: t('project.node.hive_partition_values_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetHdfsTargetPath',
+ name: t('project.node.target_dir'),
+ span: hdfsSpan,
+ props: {
+ placeholder: t('project.node.target_dir_tips')
+ },
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(rule, value) {
+ if (hdfsSpan.value && !value) {
+ return new Error(t('project.node.target_dir_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'switch',
+ field: 'targetHdfsDeleteTargetDir',
+ name: t('project.node.delete_target_dir'),
+ span: hdfsSpan
+ },
+ {
+ type: 'radio',
+ field: 'targetHdfsCompressionCodec',
+ name: t('project.node.compression_codec'),
+ span: hdfsSpan,
+ options: COMPRESSIONCODECS
+ },
+ {
+ type: 'radio',
+ field: 'targetHdfsFileType',
+ name: t('project.node.file_type'),
+ span: hdfsSpan,
+ options: FILETYPES
+ },
+ {
+ type: 'input',
+ field: 'targetHdfsFieldsTerminated',
+ name: t('project.node.fields_terminated'),
+ span: hdfsSpan,
+ props: {
+ placeholder: t('project.node.fields_terminated_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetHdfsLinesTerminated',
+ name: t('project.node.lines_terminated'),
+ span: hdfsSpan,
+ props: {
+ placeholder: t('project.node.lines_terminated_tips')
+ }
+ },
+ ...useDatasource(
+ model,
+ dataSourceSpan,
+ 'targetMysqlType',
+ 'targetMysqlDatasource'
+ ),
+ {
+ type: 'input',
+ field: 'targetMysqlTable',
+ name: t('project.node.table'),
+ span: rdbmsSpan,
+ props: {
+ placeholder: t('project.node.table_tips')
+ },
+ validate: {
+ trigger: ['blur', 'input'],
+ required: true,
+ validator(validate, value) {
+ if (rdbmsSpan.value && !value) {
+ return new Error(t('project.node.table_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetMysqlColumns',
+ name: t('project.node.column'),
+ span: rdbmsSpan,
+ props: {
+ placeholder: t('project.node.column_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetMysqlFieldsTerminated',
+ name: t('project.node.fields_terminated'),
+ span: rdbmsSpan,
+ props: {
+ placeholder: t('project.node.fields_terminated_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'targetMysqlLinesTerminated',
+ name: t('project.node.lines_terminated'),
+ span: rdbmsSpan,
+ props: {
+ placeholder: t('project.node.lines_terminated_tips')
+ }
+ },
+ {
+ type: 'switch',
+ field: 'targetMysqlIsUpdate',
+ span: rdbmsSpan,
+ name: t('project.node.is_update')
+ },
+ {
+ type: 'input',
+ field: 'targetMysqlTargetUpdateKey',
+ name: t('project.node.update_key'),
+ span: updateSpan,
+ props: {
+ placeholder: t('project.node.update_key_tips')
+ }
+ },
+ {
+ type: 'radio',
+ field: 'targetMysqlUpdateMode',
+ name: t('project.node.update_mode'),
+ span: updateSpan,
+ options: [
+ {
+ label: t('project.node.only_update'),
+ value: 'updateonly'
+ },
+ {
+ label: t('project.node.allow_insert'),
+ value: 'allowinsert'
+ }
+ ]
+ }
+ ]
+}
+
+const COMPRESSIONCODECS = [
+ {
+ label: 'snappy',
+ value: 'snappy'
+ },
+ {
+ label: 'lzo',
+ value: 'lzo'
+ },
+ {
+ label: 'gzip',
+ value: 'gzip'
+ },
+ {
+ label: 'no',
+ value: ''
+ }
+]
+const FILETYPES = [
+ {
+ label: 'avro',
+ value: '--as-avrodatafile'
+ },
+ {
+ label: 'sequence',
+ value: '--as-sequencefile'
+ },
+ {
+ label: 'text',
+ value: '--as-textfile'
+ },
+ {
+ label: 'parquet',
+ value: '--as-parquetfile'
+ }
+]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop.ts
new file mode 100644
index 0000000000..20db90747c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-sqoop.ts
@@ -0,0 +1,128 @@
+/*
+ * 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 { computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useCustomParams, useSourceType, useTargetType } from '.'
+import type { IJsonItem, ModelType } from '../types'
+
+export function useSqoop(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const customSpan = computed(() => (model.isCustomTask ? 24 : 0))
+ const unCustomSpan = computed(() => (model.isCustomTask ? 0 : 24))
+
+ const unCustomHalfSpan = computed(() => (model.isCustomTask ? 0 : 12))
+
+ return [
+ {
+ type: 'switch',
+ field: 'isCustomTask',
+ name: t('project.node.custom_job')
+ },
+ {
+ type: 'input',
+ field: 'jobName',
+ name: t('project.node.sqoop_job_name'),
+ span: unCustomSpan,
+ props: {
+ placeholder: t('project.node.sqoop_job_name_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate, value) {
+ if (!model.isCustomTask && !value) {
+ return new Error(t('project.node.sqoop_job_name_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'select',
+ field: 'modelType',
+ name: t('project.node.direct'),
+ span: unCustomSpan,
+ options: MODEL_TYPES
+ },
+ ...useCustomParams({
+ model,
+ field: 'hadoopCustomParams',
+ name: 'hadoop_custom_params',
+ isSimple: true,
+ span: unCustomSpan
+ }),
+ ...useCustomParams({
+ model,
+ field: 'sqoopAdvancedParams',
+ name: 'sqoop_advanced_parameters',
+ isSimple: true,
+ span: unCustomSpan
+ }),
+ ...useSourceType(model, unCustomSpan),
+ ...useTargetType(model, unCustomSpan),
+ {
+ type: 'input-number',
+ field: 'concurrency',
+ name: t('project.node.concurrency'),
+ span: unCustomHalfSpan,
+ props: {
+ placeholder: t('project.node.concurrency_tips'),
+ min: 1
+ }
+ },
+ {
+ type: 'input',
+ field: 'splitBy',
+ name: t('project.node.concurrency_column'),
+ span: unCustomHalfSpan,
+ props: {
+ placeholder: t('project.node.concurrency_column_tips')
+ }
+ },
+ {
+ type: 'editor',
+ field: 'customShell',
+ name: t('project.node.custom_script'),
+ span: customSpan,
+ validate: {
+ trigger: ['input', 'trigger'],
+ required: true,
+ validator(rule, value) {
+ if (customSpan.value && !value) {
+ return new Error(t('project.node.custom_script'))
+ }
+ }
+ }
+ },
+ ...useCustomParams({
+ model,
+ field: 'localParams',
+ name: 'custom_parameters',
+ isSimple: true
+ })
+ ]
+}
+
+const MODEL_TYPES = [
+ {
+ label: 'import',
+ value: 'import'
+ },
+ {
+ label: 'export',
+ value: 'export'
+ }
+] as { label: ModelType; value: ModelType }[]
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-switch.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-switch.ts
new file mode 100644
index 0000000000..0b3a070220
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-switch.ts
@@ -0,0 +1,127 @@
+/*
+ * 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 { ref, watch, onMounted, nextTick } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useTaskNodeStore } from '@/store/project/task-node'
+import { queryProcessDefinitionByCode } from '@/service/modules/process-definition'
+import { findIndex } from 'lodash'
+import type { IJsonItem } from '../types'
+
+export function useSwitch(
+ model: { [field: string]: any },
+ projectCode: number
+): IJsonItem[] {
+ const { t } = useI18n()
+ const taskStore = useTaskNodeStore()
+ const branchFlowOptions = ref(taskStore.postTaskOptions as any)
+ const loading = ref(false)
+ const getOtherTaskDefinitionList = async () => {
+ if (loading.value) return
+ loading.value = true
+ branchFlowOptions.value = []
+ const res = await queryProcessDefinitionByCode(
+ model.processName,
+ projectCode
+ )
+ res?.taskDefinitionList.forEach((item: any) => {
+ if (item.code != model.code) {
+ branchFlowOptions.value.push({ label: item.name, value: item.code })
+ }
+ })
+ loading.value = false
+ clearUselessNode(branchFlowOptions.value)
+ }
+
+ const clearUselessNode = (options: { value: number }[]) => {
+ if (!options || !options.length) {
+ model.nextNode = null
+ model.dependTaskList?.forEach((task: { nextNode: number | null }) => {
+ task.nextNode = null
+ })
+ return
+ }
+ if (
+ findIndex(
+ branchFlowOptions.value,
+ (option: { value: number }) => option.value == model.nextNode
+ ) === -1
+ ) {
+ model.nextNode = null
+ }
+ model.dependTaskList?.forEach((task: { nextNode: number | null }) => {
+ if (
+ findIndex(
+ branchFlowOptions.value,
+ (option: { value: number }) => option.value == task.nextNode
+ ) === -1
+ ) {
+ task.nextNode = null
+ }
+ })
+ }
+
+ watch(
+ () => [model.processName, model.nextCode],
+ () => {
+ if (model.processName) {
+ getOtherTaskDefinitionList()
+ }
+ }
+ )
+
+ onMounted(async () => {
+ await nextTick()
+ clearUselessNode(branchFlowOptions.value)
+ })
+
+ return [
+ {
+ type: 'custom-parameters',
+ field: 'dependTaskList',
+ name: t('project.node.switch_condition'),
+ children: [
+ {
+ type: 'input',
+ field: 'condition',
+ span: 24,
+ props: {
+ loading: loading,
+ type: 'textarea',
+ autosize: { minRows: 2 }
+ }
+ },
+ {
+ type: 'select',
+ field: 'nextNode',
+ span: 22,
+ name: t('project.node.switch_branch_flow'),
+ options: branchFlowOptions
+ }
+ ]
+ },
+ {
+ type: 'select',
+ field: 'nextNode',
+ span: 24,
+ name: t('project.node.switch_branch_flow_default'),
+ props: {
+ loading: loading
+ },
+ options: branchFlowOptions
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-target-task-name.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-target-task-name.ts
new file mode 100644
index 0000000000..36e1adb5cd
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-target-task-name.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useTargetTaskName(): IJsonItem {
+ const { t } = useI18n()
+ return {
+ type: 'input',
+ field: 'targetJobName',
+ name: t('project.node.target_task_name'),
+ props: {
+ placeholder: t('project.node.target_task_name_tips'),
+ maxLength: 100
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.target_task_name_tips')
+ }
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-definition.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-definition.ts
new file mode 100644
index 0000000000..d740e366c1
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-definition.ts
@@ -0,0 +1,46 @@
+/*
+ * 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 { useTaskType, useProcessName } from '.'
+import type { IJsonItem, ITaskData } from '../types'
+
+export const useTaskDefinition = ({
+ projectCode,
+ from = 0,
+ readonly,
+ data,
+ model
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+ model: { [field: string]: any }
+}): IJsonItem[] => {
+ if (from === 0) return []
+ return [
+ useTaskType(model, readonly),
+ useProcessName({
+ model,
+ projectCode,
+ isCreate: !data?.id,
+ from,
+ processName: data?.processName,
+ taskCode: data?.code
+ })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-group.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-group.ts
new file mode 100644
index 0000000000..6966e4237b
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-group.ts
@@ -0,0 +1,85 @@
+/*
+ * 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 { ref, watch, computed, onMounted } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryTaskGroupListPagingByProjectCode } from '@/service/modules/task-group'
+import type { IJsonItem } from '../types'
+
+export function useTaskGroup(
+ model: { [field: string]: any },
+ projectCode: number
+): IJsonItem[] {
+ const { t } = useI18n()
+
+ const options = ref([])
+ const loading = ref(false)
+ const priorityDisabled = computed(() => !model.taskGroupId)
+
+ const getTaskGroupList = async () => {
+ if (loading.value) return
+ loading.value = true
+ const { totalList = [] } = await queryTaskGroupListPagingByProjectCode({
+ pageNo: 1,
+ pageSize: 2147483647,
+ projectCode
+ })
+ options.value = totalList.map((item: { id: string; name: string }) => ({
+ label: item.name,
+ value: item.id
+ }))
+ loading.value = false
+ }
+
+ onMounted(() => {
+ getTaskGroupList()
+ })
+
+ watch(
+ () => model.taskGroupId,
+ (taskGroupId) => {
+ if (!taskGroupId) {
+ model.taskGroupId = null
+ model.taskGroupPriority = null
+ }
+ }
+ )
+
+ return [
+ {
+ type: 'select',
+ field: 'taskGroupId',
+ span: 12,
+ name: t('project.node.task_group_name'),
+ props: {
+ loading,
+ clearable: true
+ },
+ options
+ },
+ {
+ type: 'input-number',
+ field: 'taskGroupPriority',
+ name: t('project.node.task_group_queue_priority'),
+ props: {
+ max: Math.pow(10, 60) - 1,
+ disabled: priorityDisabled
+ },
+ span: 12
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-priority.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-priority.ts
new file mode 100644
index 0000000000..3f8e860b6a
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-priority.ts
@@ -0,0 +1,92 @@
+/*
+ * 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 { h, markRaw, VNode, VNodeChild } from 'vue'
+import { NIcon } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { ArrowUpOutlined, ArrowDownOutlined } from '@vicons/antd'
+import type { ITaskPriorityOption, IJsonItem } from '../types'
+
+export function useTaskPriority(): IJsonItem {
+ const { t } = useI18n()
+ const options = markRaw([
+ {
+ label: 'HIGHEST',
+ value: 'HIGHEST',
+ icon: ArrowUpOutlined,
+ color: '#ff0000'
+ },
+ {
+ label: 'HIGH',
+ value: 'HIGH',
+ icon: ArrowUpOutlined,
+ color: '#ff0000'
+ },
+ {
+ label: 'MEDIUM',
+ value: 'MEDIUM',
+ icon: ArrowUpOutlined,
+ color: '#EA7D24'
+ },
+ {
+ label: 'LOW',
+ value: 'LOW',
+ icon: ArrowDownOutlined,
+ color: '#2A8734'
+ },
+ {
+ label: 'LOWEST',
+ value: 'LOWEST',
+ icon: ArrowDownOutlined,
+ color: '#2A8734'
+ }
+ ])
+ const renderOption = ({
+ node,
+ option
+ }: {
+ node: VNode
+ option: ITaskPriorityOption
+ }): VNodeChild =>
+ h(node, null, {
+ default: () => [
+ h(
+ NIcon,
+ {
+ color: option.color
+ },
+ {
+ default: () => h(option.icon)
+ }
+ ),
+ h('span', { style: { 'z-index': 1 } }, option.label as string)
+ ]
+ })
+ return {
+ type: 'select',
+ field: 'taskPriority',
+ name: t('project.node.task_priority'),
+ options,
+ validate: {
+ required: true
+ },
+ props: {
+ renderOption
+ },
+ value: 'MEDIUM'
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-type.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-type.ts
new file mode 100644
index 0000000000..fc8e50c4c5
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-task-type.ts
@@ -0,0 +1,51 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { TASK_TYPES_MAP } from '@/store/project/task-type'
+import type { IJsonItem } from '../types'
+
+export function useTaskType(
+ model: { [field: string]: any },
+ readonly?: boolean
+): IJsonItem {
+ const { t } = useI18n()
+ const disabledTaskType = ['CONDITIONS', 'SWITCH']
+
+ const options = Object.keys(TASK_TYPES_MAP).map((option: string) => ({
+ label: option,
+ value: option,
+ disabled: disabledTaskType.includes(option)
+ }))
+ return {
+ type: 'select',
+ field: 'taskType',
+ span: 24,
+ name: t('project.node.task_type'),
+ props: {
+ disabled: readonly || ['CONDITIONS', 'SWITCH'].includes(model.taskType),
+ filterable: true
+ },
+ options: options,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.task_type_tips')
+ },
+ value: model.taskType ? model.taskType : 'SHELL'
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-timeout-alarm.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-timeout-alarm.ts
new file mode 100644
index 0000000000..53b51bc4d7
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-timeout-alarm.ts
@@ -0,0 +1,88 @@
+/*
+ * 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 { computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import type { IJsonItem } from '../types'
+
+export function useTimeoutAlarm(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+ const span = computed(() => (model.timeoutFlag ? 12 : 0))
+
+ const strategyOptions = [
+ {
+ label: t('project.node.timeout_alarm'),
+ value: 'WARN'
+ },
+ {
+ label: t('project.node.timeout_failure'),
+ value: 'FAILED'
+ }
+ ]
+
+ return [
+ {
+ type: 'switch',
+ field: 'timeoutFlag',
+ name: t('project.node.timeout_alarm'),
+ props: {
+ 'on-update:value': (value: boolean) => {
+ if (value) {
+ if (!model.timeoutNotifyStrategy.length)
+ model.timeoutNotifyStrategy = ['WARN']
+ if (!model.timeout) model.timeout = 30
+ }
+ }
+ }
+ },
+ {
+ type: 'checkbox',
+ field: 'timeoutNotifyStrategy',
+ name: t('project.node.timeout_strategy'),
+ options: strategyOptions,
+ span: span,
+ validate: {
+ trigger: ['input'],
+ validator(validate: any, value: []) {
+ if (model.timeoutFlag && !value.length) {
+ return new Error(t('project.node.timeout_strategy_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input-number',
+ field: 'timeout',
+ name: t('project.node.timeout_period'),
+ span,
+ props: {
+ max: Math.pow(10, 10) - 1
+ },
+ slots: {
+ suffix: () => t('project.node.minute')
+ },
+ validate: {
+ trigger: ['input'],
+ validator(validate: any, value: number) {
+ if (model.timeoutFlag && !/^[1-9]\d*$/.test(String(value))) {
+ return new Error(t('project.node.timeout_period_tips'))
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-udfs.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-udfs.ts
new file mode 100644
index 0000000000..3c2f444354
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-udfs.ts
@@ -0,0 +1,62 @@
+/*
+ * 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 { ref, watch, computed } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryUdfFuncList } from '@/service/modules/resources'
+import type { IJsonItem } from '../types'
+
+export function useUdfs(model: { [field: string]: any }): IJsonItem {
+ const { t } = useI18n()
+ const options = ref([])
+ const loading = ref(false)
+ const span = computed(() =>
+ ['HIVE', 'SPARK', 'KYUUBI'].includes(model.type) ? 24 : 0
+ )
+
+ const getUdfs = async () => {
+ if (loading.value) return
+ loading.value = true
+ const type = model.type === 'KYUUBI' ? 'HIVE' : model.type
+ const res = await queryUdfFuncList({ type })
+ options.value = res.map((udf: { id: number; funcName: string }) => ({
+ value: String(udf.id),
+ label: udf.funcName
+ }))
+ loading.value = false
+ }
+
+ watch(
+ () => model.type,
+ (value) => {
+ if (['HIVE', 'SPARK', 'KYUUBI'].includes(value)) {
+ getUdfs()
+ }
+ }
+ )
+
+ return {
+ type: 'select',
+ field: 'udfs',
+ options: options,
+ name: t('project.node.udf_function'),
+ props: {
+ multiple: true,
+ loading
+ },
+ span
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-worker-group.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-worker-group.ts
new file mode 100644
index 0000000000..9b452b541a
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-worker-group.ts
@@ -0,0 +1,60 @@
+/*
+ * 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 { ref, onMounted } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { queryWorkerGroupsByProjectCode } from '@/service/modules/projects-worker-group'
+import type { IJsonItem } from '../types'
+
+export function useWorkerGroup(projectCode: number): IJsonItem {
+ const { t } = useI18n()
+
+ const options = ref([] as { label: string; value: string }[])
+ const loading = ref(false)
+
+ const getWorkerGroups = async () => {
+ if (loading.value) return
+ loading.value = true
+ await queryWorkerGroupsByProjectCode(projectCode).then((res: any) => {
+ options.value = res.data.map((item: any) => ({
+ label: item.workerGroup,
+ value: item.workerGroup
+ }))
+ })
+ loading.value = false
+ }
+
+ onMounted(() => {
+ getWorkerGroups()
+ })
+ return {
+ type: 'select',
+ field: 'workerGroup',
+ span: 12,
+ name: t('project.node.worker_group'),
+ props: {
+ loading: loading
+ },
+ options: options,
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: t('project.node.worker_group_tips')
+ },
+ value: 'default'
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-zeppelin.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-zeppelin.ts
new file mode 100644
index 0000000000..eff4777215
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/fields/use-zeppelin.ts
@@ -0,0 +1,68 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { useCustomParams } from '.'
+import type { IJsonItem } from '../types'
+
+export function useZeppelin(model: { [field: string]: any }): IJsonItem[] {
+ const { t } = useI18n()
+
+ return [
+ {
+ type: 'input',
+ field: 'noteId',
+ name: t('project.node.zeppelin_note_id'),
+ props: {
+ placeholder: t('project.node.zeppelin_note_id_tips')
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ validator(validate: any, value: string) {
+ if (!value) {
+ return new Error(t('project.node.zeppelin_note_id_tips'))
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'paragraphId',
+ name: t('project.node.zeppelin_paragraph_id'),
+ props: {
+ placeholder: t('project.node.zeppelin_paragraph_id_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'productionNoteDirectory',
+ name: t('project.node.zeppelin_production_note_directory'),
+ props: {
+ placeholder: t('project.node.zeppelin_production_note_directory_tips')
+ }
+ },
+ {
+ type: 'input',
+ field: 'parameters',
+ name: t('project.node.zeppelin_parameters'),
+ props: {
+ placeholder: t('project.node.zeppelin_parameters_tips')
+ }
+ },
+ ...useCustomParams({ model, field: 'localParams', isSimple: false })
+ ]
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/format-data.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/format-data.ts
new file mode 100644
index 0000000000..2ab1712b6f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/format-data.ts
@@ -0,0 +1,757 @@
+/*
+ * 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 { omit } from 'lodash'
+import type {
+ INodeData,
+ ITaskData,
+ ITaskParams,
+ ISqoopTargetParams,
+ ISqoopSourceParams,
+ ILocalParam,
+ IDependentParameters
+} from './types'
+import { ref } from 'vue'
+
+export function formatParams(data: INodeData): {
+ processDefinitionCode: string
+ upstreamCodes: string
+ taskDefinitionJsonObj: object
+} {
+ const rdbmsSourceTypes = ref(['MYSQL', 'ORACLE', 'SQLSERVER', 'HANA'])
+ const taskParams: ITaskParams = {}
+ if (data.taskType === 'SUB_PROCESS' || data.taskType === 'DYNAMIC') {
+ taskParams.processDefinitionCode = data.processDefinitionCode
+ }
+
+ 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 = { resourceName: data.mainJar }
+ }
+ }
+
+ if (
+ data.taskType &&
+ ['SPARK', 'MR', 'FLINK', 'FLINK_STREAM'].includes(data.taskType)
+ ) {
+ taskParams.programType = data.programType
+ taskParams.mainClass = data.mainClass
+ if (data.mainJar) {
+ taskParams.mainJar = { resourceName: data.mainJar }
+ }
+ taskParams.deployMode = data.deployMode
+ taskParams.appName = data.appName
+ taskParams.mainArgs = data.mainArgs
+ taskParams.others = data.others
+ if (data.namespace) {
+ taskParams.namespace = data.namespace
+ }
+ taskParams.yarnQueue = data.yarnQueue
+ }
+
+ if (data.taskType === 'SPARK') {
+ taskParams.master = data.master
+ taskParams.driverCores = data.driverCores
+ taskParams.driverMemory = data.driverMemory
+ taskParams.numExecutors = data.numExecutors
+ taskParams.executorMemory = data.executorMemory
+ taskParams.executorCores = data.executorCores
+ taskParams.sqlExecutionType = data.sqlExecutionType
+ }
+
+ if (data.taskType === 'FLINK' || data.taskType === 'FLINK_STREAM') {
+ taskParams.flinkVersion = data.flinkVersion
+ taskParams.jobManagerMemory = data.jobManagerMemory
+ taskParams.taskManagerMemory = data.taskManagerMemory
+ taskParams.slot = data.slot
+ taskParams.taskManager = data.taskManager
+ taskParams.parallelism = data.parallelism
+ }
+ if (data.taskType === 'HTTP') {
+ taskParams.httpMethod = data.httpMethod
+ taskParams.httpBody = data.httpBody
+ taskParams.httpCheckCondition = data.httpCheckCondition
+ taskParams.httpParams = data.httpParams
+ taskParams.url = data.url
+ taskParams.condition = data.condition
+ taskParams.connectTimeout = data.connectTimeout
+ taskParams.socketTimeout = data.socketTimeout
+ }
+
+ if (data.taskType === 'SQOOP') {
+ taskParams.jobType = data.isCustomTask ? 'CUSTOM' : 'TEMPLATE'
+ taskParams.localParams = data.localParams
+ if (data.isCustomTask) {
+ taskParams.customShell = data.customShell
+ } else {
+ taskParams.jobName = data.jobName
+ taskParams.hadoopCustomParams = data.hadoopCustomParams
+ taskParams.sqoopAdvancedParams = data.sqoopAdvancedParams
+ taskParams.concurrency = data.concurrency
+ taskParams.splitBy = data.splitBy
+ taskParams.modelType = data.modelType
+ taskParams.sourceType = data.sourceType
+ taskParams.targetType = data.targetType
+ let targetParams: ISqoopTargetParams = {}
+ let sourceParams: ISqoopSourceParams = {}
+ if (data.targetType === 'HIVE') {
+ targetParams = {
+ hiveDatabase: data.targetHiveDatabase,
+ hiveTable: data.targetHiveTable,
+ createHiveTable: data.targetHiveCreateTable,
+ dropDelimiter: data.targetHiveDropDelimiter,
+ hiveOverWrite: data.targetHiveOverWrite,
+ hiveTargetDir: data.targetHiveTargetDir,
+ replaceDelimiter: data.targetHiveReplaceDelimiter,
+ hivePartitionKey: data.targetHivePartitionKey,
+ hivePartitionValue: data.targetHivePartitionValue
+ }
+ } else if (data.targetType === 'HDFS') {
+ targetParams = {
+ targetPath: data.targetHdfsTargetPath,
+ deleteTargetDir: data.targetHdfsDeleteTargetDir,
+ compressionCodec: data.targetHdfsCompressionCodec,
+ fileType: data.targetHdfsFileType,
+ fieldsTerminated: data.targetHdfsFieldsTerminated,
+ linesTerminated: data.targetHdfsLinesTerminated
+ }
+ } else if (
+ rdbmsSourceTypes.value.some((target) => target === data.targetType)
+ ) {
+ targetParams = {
+ targetType: data.targetMysqlType,
+ targetDatasource: data.targetMysqlDatasource,
+ targetTable: data.targetMysqlTable,
+ targetColumns: data.targetMysqlColumns,
+ fieldsTerminated: data.targetMysqlFieldsTerminated,
+ linesTerminated: data.targetMysqlLinesTerminated,
+ isUpdate: data.targetMysqlIsUpdate,
+ targetUpdateKey: data.targetMysqlTargetUpdateKey,
+ targetUpdateMode: data.targetMysqlUpdateMode
+ }
+ }
+ if (rdbmsSourceTypes.value.some((target) => target === data.sourceType)) {
+ sourceParams = {
+ srcTable: data.srcQueryType === '1' ? '' : data.srcTable,
+ srcColumnType: data.srcQueryType === '1' ? '0' : data.srcColumnType,
+ srcColumns:
+ data.srcQueryType === '1' || data.srcColumnType === '0'
+ ? ''
+ : data.srcColumns,
+ srcQuerySql:
+ data.srcQueryType === '0' ? '' : data.sourceMysqlSrcQuerySql,
+ srcQueryType: data.srcQueryType,
+ srcType: data.sourceMysqlType,
+ srcDatasource: data.sourceMysqlDatasource,
+ mapColumnHive: data.mapColumnHive,
+ mapColumnJava: data.mapColumnJava
+ }
+ } else if (data.sourceType === 'HDFS') {
+ sourceParams = {
+ exportDir: data.sourceHdfsExportDir
+ }
+ } else if (data.sourceType === 'HIVE') {
+ sourceParams = {
+ hiveDatabase: data.sourceHiveDatabase,
+ hiveTable: data.sourceHiveTable,
+ hivePartitionKey: data.sourceHivePartitionKey,
+ hivePartitionValue: data.sourceHivePartitionValue
+ }
+ }
+ taskParams.targetParams = JSON.stringify(targetParams)
+ taskParams.sourceParams = JSON.stringify(sourceParams)
+ }
+ }
+
+ if (data.taskType === 'SQL') {
+ taskParams.type = data.type
+ taskParams.datasource = data.datasource
+ taskParams.sql = data.sql
+ taskParams.sqlType = data.sqlType
+ taskParams.preStatements = data.preStatements
+ taskParams.postStatements = data.postStatements
+ taskParams.sendEmail = data.sendEmail
+ taskParams.displayRows = data.displayRows
+ if (data.sqlType === '0' && data.sendEmail) {
+ taskParams.title = data.title
+ taskParams.groupId = data.groupId
+ }
+ if (data.type === 'HIVE') {
+ if (data.udfs) taskParams.udfs = data.udfs.join(',')
+ taskParams.connParams = data.connParams
+ }
+
+ if (data.type === 'KYUUBI') {
+ if (data.udfs) taskParams.udfs = data.udfs.join(',')
+ }
+ }
+
+ if (data.taskType === 'PROCEDURE') {
+ taskParams.type = data.type
+ taskParams.datasource = data.datasource
+ taskParams.method = data.method
+ }
+
+ if (data.taskType === 'SEATUNNEL') {
+ taskParams.startupScript = data.startupScript
+ taskParams.useCustom = data.useCustom
+ taskParams.rawScript = data.rawScript
+ if (data.startupScript?.includes('flink')) {
+ taskParams.runMode = data.runMode
+ taskParams.others = data.others
+ }
+ if (data.startupScript?.includes('spark')) {
+ taskParams.deployMode = data.deployMode
+ taskParams.master = data.master
+ taskParams.masterUrl = data.masterUrl
+ }
+ if (data.startupScript === 'seatunnel.sh') {
+ taskParams.deployMode = data.deployMode
+ taskParams.others = data.others
+ }
+ }
+
+ if (data.taskType === 'SWITCH') {
+ taskParams.switchResult = {}
+ taskParams.switchResult.dependTaskList = data.dependTaskList
+ taskParams.switchResult.nextNode = data.nextNode
+ }
+
+ if (data.taskType === 'CONDITIONS') {
+ taskParams.dependence = {
+ relation: data.relation,
+ dependTaskList: data.dependTaskList
+ }
+ taskParams.conditionResult = {}
+ if (data.successBranch) {
+ taskParams.conditionResult.successNode = [data.successBranch]
+ }
+ if (data.failedBranch) {
+ taskParams.conditionResult.failedNode = [data.failedBranch]
+ }
+ }
+
+ if (data.taskType === 'DATAX') {
+ taskParams.customConfig = data.customConfig ? 1 : 0
+ if (taskParams.customConfig === 0) {
+ taskParams.dsType = data.dsType
+ taskParams.dataSource = data.dataSource
+ taskParams.dtType = data.dtType
+ taskParams.dataTarget = data.dataTarget
+ taskParams.sql = data.sql
+ taskParams.targetTable = data.targetTable
+ taskParams.jobSpeedByte = data.jobSpeedByte
+ taskParams.jobSpeedRecord = data.jobSpeedRecord
+ taskParams.preStatements = data.preStatements
+ taskParams.postStatements = data.postStatements
+ } else {
+ taskParams.json = data.json
+ data?.localParams?.map((param: ILocalParam) => {
+ param.direct = 'IN'
+ param.type = 'VARCHAR'
+ })
+ }
+ taskParams.xms = data.xms
+ taskParams.xmx = data.xmx
+ }
+ if (data.taskType === 'DEPENDENT') {
+ taskParams.dependence = {
+ checkInterval: data.checkInterval,
+ failurePolicy: data.failurePolicy,
+ failureWaitingTime: data.failureWaitingTime,
+ relation: data.relation,
+ dependTaskList: data.dependTaskList
+ }
+ }
+ if (data.taskType === 'DATA_QUALITY') {
+ taskParams.ruleId = data.ruleId
+ taskParams.ruleInputParameter = {
+ check_type: data.check_type,
+ comparison_execute_sql: data.comparison_execute_sql,
+ comparison_type: data.comparison_type,
+ comparison_name: data.comparison_name,
+ failure_strategy: data.failure_strategy,
+ operator: data.operator,
+ src_connector_type: data.src_connector_type,
+ src_datasource_id: data.src_datasource_id,
+ src_database: data.src_database,
+ field_length: data.field_length,
+ begin_time: data.begin_time,
+ deadline: data.deadline,
+ datetime_format: data.datetime_format,
+ enum_list: data.enum_list,
+ regexp_pattern: data.regexp_pattern,
+ target_filter: data.target_filter,
+ src_filter: data.src_filter,
+ src_field: data.src_field,
+ src_table: data.src_table,
+ statistics_execute_sql: data.statistics_execute_sql,
+ statistics_name: data.statistics_name,
+ target_connector_type: data.target_connector_type,
+ target_datasource_id: data.target_datasource_id,
+ target_database: data.target_database,
+ target_table: data.target_table,
+ threshold: data.threshold,
+ mapping_columns: JSON.stringify(data.mapping_columns)
+ }
+ taskParams.sparkParameters = {
+ deployMode: data.deployMode,
+ driverCores: data.driverCores,
+ driverMemory: data.driverMemory,
+ executorCores: data.executorCores,
+ executorMemory: data.executorMemory,
+ numExecutors: data.numExecutors,
+ others: data.others,
+ yarnQueue: data.yarnQueue,
+ sqlExecutionType: data.sqlExecutionType
+ }
+ }
+
+ if (data.taskType === 'EMR') {
+ taskParams.type = data.type
+ taskParams.programType = data.programType
+ taskParams.jobFlowDefineJson = data.jobFlowDefineJson
+ taskParams.stepsDefineJson = data.stepsDefineJson
+ }
+
+ if (data.taskType === 'ZEPPELIN') {
+ taskParams.noteId = data.noteId
+ taskParams.paragraphId = data.paragraphId
+ taskParams.restEndpoint = data.restEndpoint
+ taskParams.username = data.username
+ taskParams.password = data.password
+ taskParams.productionNoteDirectory = data.productionNoteDirectory
+ taskParams.parameters = data.parameters
+ taskParams.datasource = data.datasource
+ taskParams.type = data.type
+ }
+
+ if (data.taskType === 'K8S') {
+ taskParams.namespace = data.namespace
+ taskParams.minCpuCores = data.minCpuCores
+ taskParams.minMemorySpace = data.minMemorySpace
+ taskParams.image = data.image
+ taskParams.imagePullPolicy = data.imagePullPolicy
+ taskParams.command = data.command
+ taskParams.args = data.args
+ taskParams.customizedLabels = data.customizedLabels
+ taskParams.nodeSelectors = data.nodeSelectors
+ taskParams.datasource = data.datasource
+ taskParams.type = data.type
+ taskParams.kubeConfig = data.kubeConfig
+ taskParams.pullSecret = data.pullSecret
+ }
+
+ if (data.taskType === 'JUPYTER') {
+ taskParams.condaEnvName = data.condaEnvName
+ taskParams.inputNotePath = data.inputNotePath
+ taskParams.outputNotePath = data.outputNotePath
+ taskParams.parameters = data.parameters
+ taskParams.kernel = data.kernel
+ taskParams.engine = data.engine
+ taskParams.executionTimeout = data.executionTimeout
+ taskParams.startTimeout = data.startTimeout
+ taskParams.others = data.others
+ }
+
+ if (data.taskType === 'MLFLOW') {
+ taskParams.algorithm = data.algorithm
+ taskParams.params = data.params
+ taskParams.searchParams = data.searchParams
+ taskParams.dataPath = data.dataPath
+ taskParams.experimentName = data.experimentName
+ taskParams.modelName = data.modelName
+ taskParams.mlflowTrackingUri = data.mlflowTrackingUri
+ taskParams.mlflowJobType = data.mlflowJobType
+ taskParams.automlTool = data.automlTool
+ taskParams.registerModel = data.registerModel
+ taskParams.mlflowTaskType = data.mlflowTaskType
+ taskParams.deployType = data.deployType
+ taskParams.deployPort = data.deployPort
+ taskParams.deployModelKey = data.deployModelKey
+ taskParams.mlflowProjectRepository = data.mlflowProjectRepository
+ taskParams.mlflowProjectVersion = data.mlflowProjectVersion
+ }
+
+ if (data.taskType === 'DVC') {
+ taskParams.dvcTaskType = data.dvcTaskType
+ taskParams.dvcRepository = data.dvcRepository
+ taskParams.dvcVersion = data.dvcVersion
+ taskParams.dvcDataLocation = data.dvcDataLocation
+ taskParams.dvcMessage = data.dvcMessage
+ taskParams.dvcLoadSaveDataPath = data.dvcLoadSaveDataPath
+ taskParams.dvcStoreUrl = data.dvcStoreUrl
+ }
+
+ if (data.taskType === 'SAGEMAKER') {
+ taskParams.sagemakerRequestJson = data.sagemakerRequestJson
+ taskParams.username = data.username
+ taskParams.password = data.password
+ taskParams.datasource = data.datasource
+ taskParams.type = data.type
+ taskParams.awsRegion = data.awsRegion
+ }
+ if (data.taskType === 'PYTORCH') {
+ taskParams.script = data.script
+ taskParams.scriptParams = data.scriptParams
+ taskParams.pythonPath = data.pythonPath
+ taskParams.isCreateEnvironment = data.isCreateEnvironment
+ taskParams.pythonCommand = data.pythonCommand
+ taskParams.pythonEnvTool = data.pythonEnvTool
+ taskParams.requirements = data.requirements
+ taskParams.condaPythonVersion = data.condaPythonVersion
+ }
+
+ if (data.taskType === 'DINKY') {
+ taskParams.address = data.address
+ taskParams.taskId = data.taskId
+ taskParams.online = data.online
+ }
+
+ if (data.taskType === 'OPENMLDB') {
+ taskParams.zk = data.zk
+ taskParams.zkPath = data.zkPath
+ taskParams.executeMode = data.executeMode
+ taskParams.sql = data.sql
+ }
+
+ if (data.taskType === 'CHUNJUN') {
+ taskParams.customConfig = data.customConfig ? 1 : 0
+ taskParams.json = data.json
+ taskParams.deployMode = data.deployMode
+ taskParams.others = data.others
+ }
+
+ if (data.taskType === 'PIGEON') {
+ taskParams.targetJobName = data.targetJobName
+ }
+
+ if (data.taskType === 'HIVECLI') {
+ taskParams.hiveCliTaskExecutionType = data.hiveCliTaskExecutionType
+ taskParams.hiveSqlScript = data.hiveSqlScript
+ taskParams.hiveCliOptions = data.hiveCliOptions
+ }
+ if (data.taskType === 'DMS') {
+ taskParams.isRestartTask = data.isRestartTask
+ taskParams.isJsonFormat = data.isJsonFormat
+ taskParams.jsonData = data.jsonData
+ taskParams.migrationType = data.migrationType
+ taskParams.replicationTaskIdentifier = data.replicationTaskIdentifier
+ taskParams.sourceEndpointArn = data.sourceEndpointArn
+ taskParams.targetEndpointArn = data.targetEndpointArn
+ taskParams.replicationInstanceArn = data.replicationInstanceArn
+ taskParams.tableMappings = data.tableMappings
+ taskParams.replicationTaskArn = data.replicationTaskArn
+ }
+
+ if (data.taskType === 'DATASYNC') {
+ taskParams.jsonFormat = data.jsonFormat
+ taskParams.json = data.json
+ taskParams.destinationLocationArn = data.destinationLocationArn
+ taskParams.sourceLocationArn = data.sourceLocationArn
+ taskParams.name = data.name
+ taskParams.cloudWatchLogGroupArn = data.cloudWatchLogGroupArn
+ }
+
+ if (data.taskType === 'KUBEFLOW') {
+ taskParams.yamlContent = data.yamlContent
+ taskParams.namespace = data.namespace
+ }
+
+ if (data.taskType === 'LINKIS') {
+ taskParams.useCustom = data.useCustom
+ taskParams.paramScript = data.paramScript
+ taskParams.rawScript = data.rawScript
+ }
+
+ if (data.taskType === 'DATA_FACTORY') {
+ taskParams.factoryName = data.factoryName
+ taskParams.resourceGroupName = data.resourceGroupName
+ taskParams.pipelineName = data.pipelineName
+ }
+
+ if (data.taskType === 'REMOTESHELL') {
+ taskParams.type = data.type
+ taskParams.datasource = data.datasource
+ }
+
+ if (data.taskType === 'DYNAMIC') {
+ taskParams.processDefinitionCode = data.processDefinitionCode
+ taskParams.maxNumOfSubWorkflowInstances = data.maxNumOfSubWorkflowInstances
+ taskParams.degreeOfParallelism = data.degreeOfParallelism
+ taskParams.filterCondition = data.filterCondition
+ taskParams.listParameters = data.listParameters
+ }
+
+ let timeoutNotifyStrategy = ''
+ if (data.timeoutNotifyStrategy) {
+ if (data.timeoutNotifyStrategy.length === 1) {
+ timeoutNotifyStrategy = data.timeoutNotifyStrategy[0]
+ }
+ if (data.timeoutNotifyStrategy.length === 2) {
+ timeoutNotifyStrategy = 'WARNFAILED'
+ }
+ }
+ const params = {
+ processDefinitionCode: data.processName ? String(data.processName) : '',
+ upstreamCodes: data?.preTasks?.join(','),
+ taskDefinitionJsonObj: {
+ code: data.code,
+ delayTime: data.delayTime ? String(data.delayTime) : '0',
+ description: data.description,
+ environmentCode: data.environmentCode || -1,
+ failRetryInterval: data.failRetryInterval
+ ? String(data.failRetryInterval)
+ : '0',
+ failRetryTimes: data.failRetryTimes ? String(data.failRetryTimes) : '0',
+ flag: data.flag,
+ isCache: data.isCache ? 'YES' : 'NO',
+ name: data.name,
+ taskGroupId: data.taskGroupId,
+ taskGroupPriority: data.taskGroupPriority,
+ taskParams: {
+ localParams: data.localParams?.map((item: any) => {
+ item.value = item.value || ''
+ return item
+ }),
+ initScript: data.initScript,
+ rawScript: data.rawScript,
+ resourceList: data.resourceList?.length
+ ? data.resourceList.map((fullName: string) => ({
+ resourceName: `${fullName}`
+ }))
+ : [],
+ ...taskParams
+ },
+ taskPriority: data.taskPriority,
+ taskType: data.taskType,
+ timeout: data.timeoutFlag ? data.timeout : 0,
+ timeoutFlag: data.timeoutFlag ? 'OPEN' : 'CLOSE',
+ timeoutNotifyStrategy: data.timeoutFlag ? timeoutNotifyStrategy : '',
+ workerGroup: data.workerGroup,
+ cpuQuota: data.cpuQuota || -1,
+ memoryMax: data.memoryMax || -1,
+ taskExecuteType: data.taskExecuteType
+ }
+ } as {
+ processDefinitionCode: string
+ upstreamCodes: string
+ taskDefinitionJsonObj: { timeout: number; timeoutNotifyStrategy: string }
+ }
+ if (!data.timeoutFlag) {
+ params.taskDefinitionJsonObj.timeout = 0
+ params.taskDefinitionJsonObj.timeoutNotifyStrategy = ''
+ }
+ return params
+}
+
+export function formatModel(data: ITaskData) {
+ const params = {
+ ...omit(data, [
+ 'environmentCode',
+ 'timeoutFlag',
+ 'timeoutNotifyStrategy',
+ 'taskParams'
+ ]),
+ ...omit(data.taskParams, ['resourceList', 'mainJar', 'localParams']),
+ environmentCode: data.environmentCode === -1 ? null : data.environmentCode,
+ timeoutFlag: data.timeoutFlag === 'OPEN',
+ isCache: data.isCache === 'YES',
+ timeoutNotifyStrategy: data.timeoutNotifyStrategy
+ ? [data.timeoutNotifyStrategy]
+ : [],
+ localParams: data.taskParams?.localParams || []
+ } as INodeData
+
+ if (data.timeoutNotifyStrategy === 'WARNFAILED') {
+ params.timeoutNotifyStrategy = ['WARN', 'FAILED']
+ }
+ if (data.taskParams?.resourceList) {
+ params.resourceList = data.taskParams.resourceList.map(
+ (item: { resourceName: string }) => `${item.resourceName}`
+ )
+ }
+ if (data.taskParams?.mainJar) {
+ params.mainJar = data.taskParams?.mainJar.resourceName
+ }
+
+ if (data.taskParams?.method) {
+ params.method = data.taskParams?.method
+ }
+
+ if (data.taskParams?.targetParams) {
+ const targetParams: ISqoopTargetParams = JSON.parse(
+ data.taskParams.targetParams
+ )
+ params.targetType = data.taskParams.targetType
+ params.targetHiveDatabase = targetParams.hiveDatabase
+ params.targetHiveTable = targetParams.hiveTable
+ params.targetHiveCreateTable = targetParams.createHiveTable
+ params.targetHiveDropDelimiter = targetParams.dropDelimiter
+ params.targetHiveOverWrite =
+ targetParams.hiveOverWrite === void 0 ? true : targetParams.hiveOverWrite
+ params.targetHiveTargetDir = targetParams.hiveTargetDir
+ params.targetHiveReplaceDelimiter = targetParams.replaceDelimiter
+ params.targetHivePartitionKey = targetParams.hivePartitionKey
+ params.targetHivePartitionValue = targetParams.hivePartitionValue
+ params.targetHdfsTargetPath = targetParams.targetPath
+ params.targetHdfsDeleteTargetDir =
+ targetParams.deleteTargetDir === void 0
+ ? true
+ : targetParams.deleteTargetDir
+ params.targetHdfsCompressionCodec =
+ targetParams.compressionCodec === void 0
+ ? 'snappy'
+ : targetParams.compressionCodec
+ params.targetHdfsFileType =
+ targetParams.fileType === void 0
+ ? '--as-avrodatafile'
+ : targetParams.fileType
+ params.targetHdfsFieldsTerminated = targetParams.fieldsTerminated
+ params.targetHdfsLinesTerminated = targetParams.linesTerminated
+ params.targetMysqlType = targetParams.targetType
+ params.targetMysqlDatasource = targetParams.targetDatasource
+ params.targetMysqlTable = targetParams.targetTable
+ params.targetMysqlColumns = targetParams.targetColumns
+ params.targetMysqlFieldsTerminated = targetParams.fieldsTerminated
+ params.targetMysqlLinesTerminated = targetParams.linesTerminated
+ params.targetMysqlIsUpdate = targetParams.isUpdate
+ params.targetMysqlTargetUpdateKey = targetParams.targetUpdateKey
+ params.targetMysqlUpdateMode =
+ targetParams.targetUpdateMode === void 0
+ ? 'allowinsert'
+ : targetParams.targetUpdateMode
+ }
+ if (data.taskParams?.sourceParams) {
+ const sourceParams: ISqoopSourceParams = JSON.parse(
+ data.taskParams.sourceParams
+ )
+ params.srcTable = sourceParams.srcTable
+ params.srcColumnType = sourceParams.srcColumnType
+ params.srcColumns = sourceParams.srcColumns
+ params.sourceMysqlSrcQuerySql = sourceParams.srcQuerySql
+ params.srcQueryType = sourceParams.srcQueryType
+ params.sourceMysqlType = sourceParams.srcType
+ params.sourceMysqlDatasource = sourceParams.srcDatasource
+ params.mapColumnHive = sourceParams.mapColumnHive || []
+ params.mapColumnJava = sourceParams.mapColumnJava || []
+ params.sourceHdfsExportDir = sourceParams.exportDir
+ params.sourceHiveDatabase = sourceParams.hiveDatabase
+ params.sourceHiveTable = sourceParams.hiveTable
+ params.sourceHivePartitionKey = sourceParams.hivePartitionKey
+ params.sourceHivePartitionValue = sourceParams.hivePartitionValue
+ }
+
+ if (data.taskParams?.rawScript) {
+ params.rawScript = data.taskParams?.rawScript
+ }
+
+ if (data.taskParams?.initScript) {
+ params.initScript = data.taskParams?.initScript
+ }
+
+ if (data.taskParams?.switchResult) {
+ params.switchResult = data.taskParams.switchResult
+ params.dependTaskList = data.taskParams.switchResult?.dependTaskList
+ ? data.taskParams.switchResult?.dependTaskList
+ : []
+ params.nextNode = data.taskParams.switchResult?.nextNode
+ }
+
+ if (data.taskParams?.dependence) {
+ const dependence: IDependentParameters = JSON.parse(
+ JSON.stringify(data.taskParams.dependence)
+ )
+ params.checkInterval = dependence.checkInterval
+ params.failurePolicy = dependence.failurePolicy
+ params.failureWaitingTime = dependence.failureWaitingTime
+ params.dependTaskList = dependence.dependTaskList || []
+ params.relation = dependence.relation
+ }
+
+ if (data.taskParams?.ruleInputParameter) {
+ params.check_type = data.taskParams.ruleInputParameter.check_type
+ params.comparison_execute_sql =
+ data.taskParams.ruleInputParameter.comparison_execute_sql
+ params.comparison_type = data.taskParams.ruleInputParameter.comparison_type
+ params.comparison_name = data.taskParams.ruleInputParameter.comparison_name
+ params.failure_strategy =
+ data.taskParams.ruleInputParameter.failure_strategy
+ params.operator = data.taskParams.ruleInputParameter.operator
+ params.src_connector_type =
+ data.taskParams.ruleInputParameter.src_connector_type
+ params.src_datasource_id =
+ data.taskParams.ruleInputParameter.src_datasource_id
+ params.src_database = data.taskParams.ruleInputParameter.src_database
+ params.src_table = data.taskParams.ruleInputParameter.src_table
+ params.field_length = data.taskParams.ruleInputParameter.field_length
+ params.begin_time = data.taskParams.ruleInputParameter.begin_time
+ params.deadline = data.taskParams.ruleInputParameter.deadline
+ params.datetime_format = data.taskParams.ruleInputParameter.datetime_format
+ params.target_filter = data.taskParams.ruleInputParameter.target_filter
+ params.regexp_pattern = data.taskParams.ruleInputParameter.regexp_pattern
+ params.enum_list = data.taskParams.ruleInputParameter.enum_list
+ params.src_filter = data.taskParams.ruleInputParameter.src_filter
+ params.src_field = data.taskParams.ruleInputParameter.src_field
+ params.statistics_execute_sql =
+ data.taskParams.ruleInputParameter.statistics_execute_sql
+ params.statistics_name = data.taskParams.ruleInputParameter.statistics_name
+ params.target_connector_type =
+ data.taskParams.ruleInputParameter.target_connector_type
+ params.target_datasource_id =
+ data.taskParams.ruleInputParameter.target_datasource_id
+ params.target_database = data.taskParams.ruleInputParameter.target_database
+ params.target_table = data.taskParams.ruleInputParameter.target_table
+ params.threshold = data.taskParams.ruleInputParameter.threshold
+ if (data.taskParams.ruleInputParameter.mapping_columns)
+ params.mapping_columns = JSON.parse(
+ data.taskParams.ruleInputParameter.mapping_columns
+ )
+ }
+ if (data.taskParams?.sparkParameters) {
+ params.deployMode = data.taskParams.sparkParameters.deployMode
+ params.driverCores = data.taskParams.sparkParameters.driverCores
+ params.driverMemory = data.taskParams.sparkParameters.driverMemory
+ params.executorCores = data.taskParams.sparkParameters.executorCores
+ params.executorMemory = data.taskParams.sparkParameters.executorMemory
+ params.numExecutors = data.taskParams.sparkParameters.numExecutors
+ params.others = data.taskParams.sparkParameters.others
+ params.sqlExecutionType = data.taskParams.sparkParameters.sqlExecutionType
+ }
+
+ if (data.taskParams?.conditionResult?.successNode?.length) {
+ params.successBranch = data.taskParams.conditionResult.successNode[0]
+ }
+ if (data.taskParams?.conditionResult?.failedNode?.length) {
+ params.failedBranch = data.taskParams.conditionResult.failedNode[0]
+ }
+ if (data.taskParams?.udfs) {
+ params.udfs = data.taskParams.udfs?.split(',')
+ }
+ if (data.taskParams?.customConfig !== void 0) {
+ params.customConfig = data.taskParams.customConfig === 1 ? true : false
+ }
+ if (data.taskParams?.jobType) {
+ params.isCustomTask = data.taskParams.jobType === 'CUSTOM'
+ }
+
+ return params
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/index.module.scss b/dolphinscheduler-ui/src/views/projects/trigger/components/node/index.module.scss
new file mode 100644
index 0000000000..6d9f1c9432
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/index.module.scss
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+.field-title {
+ font-weight: bold;
+ width: 100%;
+
+ &::before {
+ content: '';
+ display: inline-block;
+ vertical-align: -2px;
+ width: 4px;
+ height: 1em;
+ background-color: var(--n-color);
+ border-radius: 4px;
+ margin-right: 8px;
+ }
+}
+.relaction-label {
+ height: 30px;
+ overflow: hidden;
+}
+.relaction-switch {
+ position: relative;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ &::before {
+ content: '';
+ display: block;
+ width: 4px;
+ height: 100%;
+ background-color: var(--n-color);
+ border-radius: 4px;
+ position: absolute;
+ top: 0px;
+ left: 20px;
+ }
+}
+.display-rows-tips {
+ margin-top: 32px;
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/index.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/index.ts
new file mode 100644
index 0000000000..41f877d80c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/index.ts
@@ -0,0 +1,96 @@
+/*
+ * 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 { useFlink } from './use-flink'
+import { useFlinkStream } from './use-flink-stream'
+import { useShell } from './use-shell'
+import { useSubProcess } from './use-sub-process'
+import { usePigeon } from './use-pigeon'
+import { usePython } from './use-python'
+import { useSpark } from './use-spark'
+import { useMr } from './use-mr'
+import { useHttp } from './use-http'
+import { useSql } from './use-sql'
+import { useProcedure } from './use-procedure'
+import { useSqoop } from './use-sqoop'
+import { useSeaTunnel } from './use-sea-tunnel'
+import { useSwitch } from './use-switch'
+import { useConditions } from './use-conditions'
+import { useDataX } from './use-datax'
+import { useDependent } from './use-dependent'
+import { useDataQuality } from './use-data-quality'
+import { useEmr } from './use-emr'
+import { useZeppelin } from './use-zeppelin'
+import { useK8s } from './use-k8s'
+import { useJupyter } from './use-jupyter'
+import { useMlflow } from './use-mlflow'
+import { useOpenmldb } from './use-openmldb'
+import { useDvc } from './use-dvc'
+import { useJava } from './use-java'
+import { useDinky } from './use-dinky'
+import { userSagemaker } from './use-sagemaker'
+import { useChunjun } from './use-chunjun'
+import { usePytorch } from './use-pytorch'
+import { useHiveCli } from './use-hive-cli'
+import { useDms } from './use-dms'
+import { useDatasync } from './use-datasync'
+import { useKubeflow } from './use-kubeflow'
+import { useLinkis } from './use-linkis'
+import { useDataFactory } from './use-data-factory'
+import { useRemoteShell } from './use-remote-shell'
+import { useDynamic } from './use-dynamic'
+
+export default {
+ SHELL: useShell,
+ SUB_PROCESS: useSubProcess,
+ DYNAMIC: useDynamic,
+ PYTHON: usePython,
+ SPARK: useSpark,
+ MR: useMr,
+ FLINK: useFlink,
+ HTTP: useHttp,
+ PIGEON: usePigeon,
+ SQL: useSql,
+ PROCEDURE: useProcedure,
+ SQOOP: useSqoop,
+ SEATUNNEL: useSeaTunnel,
+ SWITCH: useSwitch,
+ CONDITIONS: useConditions,
+ DATAX: useDataX,
+ DEPENDENT: useDependent,
+ DATA_QUALITY: useDataQuality,
+ EMR: useEmr,
+ ZEPPELIN: useZeppelin,
+ K8S: useK8s,
+ JUPYTER: useJupyter,
+ MLFLOW: useMlflow,
+ OPENMLDB: useOpenmldb,
+ DVC: useDvc,
+ DINKY: useDinky,
+ SAGEMAKER: userSagemaker,
+ CHUNJUN: useChunjun,
+ FLINK_STREAM: useFlinkStream,
+ JAVA: useJava,
+ PYTORCH: usePytorch,
+ HIVECLI: useHiveCli,
+ DMS: useDms,
+ DATASYNC: useDatasync,
+ KUBEFLOW: useKubeflow,
+ LINKIS: useLinkis,
+ DATA_FACTORY: useDataFactory,
+ REMOTESHELL: useRemoteShell
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-chunjun.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-chunjun.ts
new file mode 100644
index 0000000000..fc24e1a7a8
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-chunjun.ts
@@ -0,0 +1,73 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useChunjun({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'CHUNJUN',
+ flag: 'YES',
+ description: '',
+ deployMode: 'local',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ customConfig: true,
+ preStatements: [],
+ postStatements: [],
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useChunjun(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-conditions.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-conditions.ts
new file mode 100644
index 0000000000..08e325099f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-conditions.ts
@@ -0,0 +1,69 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useConditions({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'CONDITIONS',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ timeout: 30,
+ relation: 'AND',
+ dependTaskList: [],
+ preTasks: [],
+ successNode: 'success',
+ failedNode: 'failed',
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useConditions(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-data-factory.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-data-factory.ts
new file mode 100644
index 0000000000..91fe1ff2f7
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-data-factory.ts
@@ -0,0 +1,72 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useDataFactory({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'DATA_FACTORY',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN'],
+ factoryName: '',
+ resourceGroupName: '',
+ pipelineName: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDataFactory(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-data-quality.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-data-quality.ts
new file mode 100644
index 0000000000..c45dfa7044
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-data-quality.ts
@@ -0,0 +1,107 @@
+/*
+ * 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 { Ref, reactive } from 'vue'
+import { useI18n } from 'vue-i18n'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useDataQuality({
+ projectCode,
+ from = 0,
+ readonly,
+ data,
+ jsonRef,
+ updateElements
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+ jsonRef: Ref
+ updateElements: () => void
+}) {
+ const { t } = useI18n()
+ const model = reactive({
+ taskType: 'DATA_QUALITY',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ timeoutNotifyStrategy: ['WARN'],
+ timeout: 30,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ ruleId: 1,
+ deployMode: 'cluster',
+ driverCores: 1,
+ driverMemory: '512M',
+ numExecutors: 2,
+ executorMemory: '2G',
+ executorCores: 2,
+ others: '--conf spark.yarn.maxAppAttempts=1',
+ yarnQueue: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useRules(model, (items: IJsonItem[], len: number) => {
+ jsonRef.value.splice(15, len, ...items)
+ updateElements()
+ }),
+ Fields.useDeployMode(),
+ Fields.useDriverCores(),
+ Fields.useDriverMemory(),
+ Fields.useExecutorNumber(),
+ Fields.useExecutorMemory(),
+ Fields.useExecutorCores(),
+ Fields.useYarnQueue(),
+ {
+ type: 'input',
+ field: 'others',
+ name: t('project.node.option_parameters'),
+ props: {
+ type: 'textarea',
+ placeholder: t('project.node.option_parameters_tips')
+ }
+ },
+ ...Fields.useCustomParams({
+ model,
+ field: 'localParams',
+ isSimple: true
+ }),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-datasync.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-datasync.ts
new file mode 100644
index 0000000000..843f90f349
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-datasync.ts
@@ -0,0 +1,83 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useDatasync({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'DATASYNC',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ let extra: IJsonItem[] = []
+ if (from === 1) {
+ extra = [
+ Fields.useTaskType(model, readonly),
+ Fields.useProcessName({
+ model,
+ projectCode,
+ isCreate: !data?.id,
+ from,
+ processName: data?.processName
+ })
+ ]
+ }
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...extra,
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDatasync(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-datax.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-datax.ts
new file mode 100644
index 0000000000..b1344fbf35
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-datax.ts
@@ -0,0 +1,77 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useDataX({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'DATAX',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ cpuQuota: -1,
+ memoryMax: -1,
+ delayTime: 0,
+ timeout: 30,
+ customConfig: false,
+ dsType: 'MYSQL',
+ dtType: 'MYSQL',
+ preStatements: [],
+ postStatements: [],
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDataX(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dependent.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dependent.ts
new file mode 100644
index 0000000000..b140eea7f3
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dependent.ts
@@ -0,0 +1,72 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useDependent({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'DEPENDENT',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutShowFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ relation: 'AND',
+ dependTaskList: [],
+ preTasks: [],
+ timeoutNotifyStrategy: [],
+ timeout: 30,
+ timeoutFlag: false,
+ failurePolicy: 'DEPENDENT_FAILURE_FAILURE',
+ checkInterval: 10,
+ ...data
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useDependent(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dinky.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dinky.ts
new file mode 100644
index 0000000000..846a6d7872
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dinky.ts
@@ -0,0 +1,68 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useDinky({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'DINKY',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDinky(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dms.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dms.ts
new file mode 100644
index 0000000000..7fe0922a73
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dms.ts
@@ -0,0 +1,84 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useDms({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'DMS',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN'],
+ isRestartTask: false
+ } as INodeData)
+
+ let extra: IJsonItem[] = []
+ if (from === 1) {
+ extra = [
+ Fields.useTaskType(model, readonly),
+ Fields.useProcessName({
+ model,
+ projectCode,
+ isCreate: !data?.id,
+ from,
+ processName: data?.processName
+ })
+ ]
+ }
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...extra,
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDms(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dvc.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dvc.ts
new file mode 100644
index 0000000000..d8376a5c9c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dvc.ts
@@ -0,0 +1,69 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useDvc({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'MLFLOW',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN'],
+ dvcTaskType: 'Upload'
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDvc(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dynamic.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dynamic.ts
new file mode 100644
index 0000000000..8f498fbfe9
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-dynamic.ts
@@ -0,0 +1,83 @@
+/*
+ * 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 { reactive } from 'vue'
+import { useRouter } from 'vue-router'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useDynamic({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const router = useRouter()
+ const workflowCode = router.currentRoute.value.params.code
+ const model = reactive({
+ taskType: 'DYNAMIC',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ maxNumOfSubWorkflowInstances: 1024,
+ degreeOfParallelism: 1,
+ filterCondition: '',
+ listParameters: [{ name: null, value: null, separator: ',' }]
+ } as INodeData)
+
+ if (model.listParameters?.length) {
+ model.listParameters[0].disabled = true
+ }
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useTimeoutAlarm(model),
+ Fields.useChildNode({
+ model,
+ projectCode,
+ from,
+ processName: data?.processName,
+ code: from === 1 ? 0 : Number(workflowCode)
+ }),
+ ...Fields.useDynamic(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-emr.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-emr.ts
new file mode 100644
index 0000000000..7af5aa3e3a
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-emr.ts
@@ -0,0 +1,70 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useEmr({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'EMR',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ programType: 'ADD_JOB_FLOW_STEPS',
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useEmr(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-flink-stream.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-flink-stream.ts
new file mode 100644
index 0000000000..0b35f9f275
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-flink-stream.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useFlinkStream({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'FLINK_STREAM',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ programType: 'SCALA',
+ deployMode: 'cluster',
+ initScript: '',
+ rawScript: '',
+ flinkVersion: '<1.10',
+ jobManagerMemory: '1G',
+ taskManagerMemory: '2G',
+ slot: 1,
+ taskManager: 2,
+ parallelism: 1,
+ timeoutNotifyStrategy: ['WARN'],
+ yarnQueue: ''
+ })
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ Fields.useDelayTime(model),
+ ...Fields.useFlink(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-flink.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-flink.ts
new file mode 100644
index 0000000000..204bfc7141
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-flink.ts
@@ -0,0 +1,79 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useFlink({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'FLINK',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ programType: 'SCALA',
+ deployMode: 'cluster',
+ initScript: '',
+ rawScript: '',
+ flinkVersion: '<1.10',
+ jobManagerMemory: '1G',
+ taskManagerMemory: '2G',
+ slot: 1,
+ taskManager: 2,
+ parallelism: 1,
+ timeoutNotifyStrategy: ['WARN'],
+ yarnQueue: ''
+ })
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useFlink(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-hive-cli.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-hive-cli.ts
new file mode 100644
index 0000000000..e9e485a9b7
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-hive-cli.ts
@@ -0,0 +1,82 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useHiveCli({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'HIVECLI',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ hiveCliTaskExecutionType: 'SCRIPT'
+ } as INodeData)
+
+ let extra: IJsonItem[] = []
+ if (from === 1) {
+ extra = [
+ Fields.useTaskType(model, readonly),
+ Fields.useProcessName({
+ model,
+ projectCode,
+ isCreate: !data?.id,
+ from,
+ processName: data?.processName
+ })
+ ]
+ }
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...extra,
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useHiveCli(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-http.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-http.ts
new file mode 100644
index 0000000000..0e5d5fe5ca
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-http.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useHttp({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'HTTP',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ httpMethod: 'GET',
+ httpBody: '',
+ httpCheckCondition: 'STATUS_CODE_DEFAULT',
+ httpParams: [],
+ url: '',
+ condition: '',
+ connectTimeout: 60000,
+ socketTimeout: 60000,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useHttp(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-java.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-java.ts
new file mode 100644
index 0000000000..1eb99de965
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-java.ts
@@ -0,0 +1,90 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useJava({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'JAVA',
+ flag: 'YES',
+ description: '',
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ isModulePath: false,
+ rawScript: '',
+ timeoutFlag: false,
+ timeoutNotifyStrategy: ['WARN'],
+ timeout: 30,
+ mainJar: undefined,
+ runType: 'JAVA',
+ mainArgs: '',
+ jvmArgs: '',
+ programType: 'JAVA'
+ } as unknown as INodeData)
+
+ let extra: IJsonItem[] = []
+ if (from === 1) {
+ extra = [
+ Fields.useTaskType(model, readonly),
+ Fields.useProcessName({
+ model,
+ projectCode,
+ isCreate: !data?.id,
+ from,
+ processName: data?.processName
+ })
+ ]
+ }
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...extra,
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useJava(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-jupyter.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-jupyter.ts
new file mode 100644
index 0000000000..1901209e73
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-jupyter.ts
@@ -0,0 +1,71 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useJupyter({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'JUPYTER',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ cpuQuota: -1,
+ memoryMax: -1,
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useJupyter(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-k8s.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-k8s.ts
new file mode 100644
index 0000000000..e20a506df6
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-k8s.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useK8s({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'K8S',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ customizedLabels: [],
+ nodeSelectors: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ type: 'K8S',
+ displayRows: 10,
+ timeoutNotifyStrategy: ['WARN'],
+ kubeConfig: '',
+ namespace: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDatasource(model),
+ ...Fields.useK8s(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-kubeflow.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-kubeflow.ts
new file mode 100644
index 0000000000..1c721a6dcd
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-kubeflow.ts
@@ -0,0 +1,68 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useKubeflow({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'KUBEFLOW',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useKubeflow(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-linkis.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-linkis.ts
new file mode 100644
index 0000000000..5507f79bf6
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-linkis.ts
@@ -0,0 +1,80 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useLinkis({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'LINKIS',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ cpuQuota: -1,
+ memoryMax: -1,
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN'],
+ useCustom: false,
+ paramScript: [
+ {
+ prop: '',
+ value: ''
+ }
+ ],
+ rawScript: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useLinkis(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-mlflow.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-mlflow.ts
new file mode 100644
index 0000000000..b25fdae436
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-mlflow.ts
@@ -0,0 +1,76 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useMlflow({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'MLFLOW',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ algorithm: 'svm',
+ mlflowTrackingUri: 'http://127.0.0.1:5000',
+ mlflowTaskType: 'MLflow Projects',
+ deployType: 'MLFLOW',
+ deployPort: '7000',
+ mlflowJobType: 'CustomProject',
+ automlTool: 'flaml',
+ mlflowCustomProjectParameters: [],
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useMlflow(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-mr.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-mr.ts
new file mode 100644
index 0000000000..4552133a20
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-mr.ts
@@ -0,0 +1,70 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useMr({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'MR',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ programType: 'SCALA',
+ timeoutNotifyStrategy: ['WARN'],
+ yarnQueue: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useMr(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-openmldb.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-openmldb.ts
new file mode 100644
index 0000000000..18bd0deadc
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-openmldb.ts
@@ -0,0 +1,72 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useOpenmldb({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'OPENMLDB',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ timeoutNotifyStrategy: ['WARN'],
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ zk: '',
+ zkPath: '',
+ executeMode: 'offline'
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useOpenmldb(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-pigeon.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-pigeon.ts
new file mode 100644
index 0000000000..22b879919b
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-pigeon.ts
@@ -0,0 +1,68 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function usePigeon({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'PIGEON',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ targetJobName: '',
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ Fields.useTargetTaskName(),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-procedure.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-procedure.ts
new file mode 100644
index 0000000000..90f2491613
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-procedure.ts
@@ -0,0 +1,73 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useProcedure({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'PROCEDURE',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ type: data?.taskParams?.type ? data?.taskParams?.type : 'MYSQL',
+ datasource: data?.taskParams?.datasource,
+ method: data?.taskParams?.method,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDatasource(model),
+ ...Fields.useProcedure(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-python.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-python.ts
new file mode 100644
index 0000000000..09f598e1d4
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-python.ts
@@ -0,0 +1,73 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function usePython({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'PYTHON',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ cpuQuota: -1,
+ memoryMax: -1,
+ delayTime: 0,
+ timeout: 30,
+ rawScript: '',
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useShell(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-pytorch.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-pytorch.ts
new file mode 100644
index 0000000000..ca0776aa38
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-pytorch.ts
@@ -0,0 +1,88 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function usePytorch({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'PYTORCH',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN'],
+ pythonEnvTool: 'conda',
+ pythonCommand: '${PYTHON_LAUNCHER}',
+ condaPythonVersion: '3.7',
+ requirements: 'requirements.txt',
+ pythonPath: '.'
+ } as INodeData)
+
+ let extra: IJsonItem[] = []
+ if (from === 1) {
+ extra = [
+ Fields.useTaskType(model, readonly),
+ Fields.useProcessName({
+ model,
+ projectCode,
+ isCreate: !data?.id,
+ from,
+ processName: data?.processName
+ })
+ ]
+ }
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...extra,
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.usePytorch(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-remote-shell.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-remote-shell.ts
new file mode 100644
index 0000000000..977776510d
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-remote-shell.ts
@@ -0,0 +1,74 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useRemoteShell({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'REMOTESHELL',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ timeoutNotifyStrategy: ['WARN'],
+ timeout: 30,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ type: 'SSH',
+ rawScript: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDatasource(model, {
+ supportedDatasourceType: ['SSH']
+ }),
+ ...Fields.useRemoteShell(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sagemaker.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sagemaker.ts
new file mode 100644
index 0000000000..88a38d8ea7
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sagemaker.ts
@@ -0,0 +1,74 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function userSagemaker({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'MLFLOW',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ type: 'SAGEMAKER',
+ displayRows: 10,
+ timeoutNotifyStrategy: ['WARN'],
+ username: '',
+ password: '',
+ awsRegion: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDatasource(model),
+ ...Fields.useSagemaker(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sea-tunnel.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sea-tunnel.ts
new file mode 100644
index 0000000000..1cf03008b9
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sea-tunnel.ts
@@ -0,0 +1,104 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useSeaTunnel({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'SEATUNNEL',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ cpuQuota: -1,
+ memoryMax: -1,
+ delayTime: 0,
+ timeout: 30,
+ startupScript: 'seatunnel.sh',
+ runMode: 'RUN',
+ useCustom: true,
+ deployMode: 'client',
+ master: 'YARN',
+ masterUrl: '',
+ resourceFiles: [],
+ timeoutNotifyStrategy: ['WARN'],
+ rawScript:
+ 'env {\n' +
+ ' execution.parallelism = 2\n' +
+ ' job.mode = "BATCH"\n' +
+ ' checkpoint.interval = 10000\n' +
+ '}\n' +
+ '\n' +
+ 'source {\n' +
+ ' FakeSource {\n' +
+ ' parallelism = 2\n' +
+ ' result_table_name = "fake"\n' +
+ ' row.num = 16\n' +
+ ' schema = {\n' +
+ ' fields {\n' +
+ ' name = "string"\n' +
+ ' age = "int"\n' +
+ ' }\n' +
+ ' }\n' +
+ ' }\n' +
+ '}\n' +
+ '\n' +
+ 'sink {\n' +
+ ' Console {\n' +
+ ' }\n' +
+ '}'
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useSeaTunnel(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-shell.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-shell.ts
new file mode 100644
index 0000000000..96b1c9ce6c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-shell.ts
@@ -0,0 +1,72 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useShell({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'SHELL',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ timeoutNotifyStrategy: ['WARN'],
+ timeout: 30,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ cpuQuota: -1,
+ memoryMax: -1,
+ delayTime: 0,
+ rawScript: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useShell(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-spark.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-spark.ts
new file mode 100644
index 0000000000..1e5c929b0f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-spark.ts
@@ -0,0 +1,79 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useSpark({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'SPARK',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ programType: 'SCALA',
+ rawScript: '',
+ master: '',
+ deployMode: '',
+ driverCores: 1,
+ driverMemory: '512M',
+ numExecutors: 2,
+ executorMemory: '2G',
+ executorCores: 2,
+ yarnQueue: '',
+ timeoutNotifyStrategy: ['WARN'],
+ sqlExecutionType: 'SCRIPT'
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useSpark(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sql.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sql.ts
new file mode 100644
index 0000000000..e733387c1d
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sql.ts
@@ -0,0 +1,78 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData } from '../types'
+import { ITaskData } from '../types'
+
+export function useSql({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'SQL',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ type: 'MYSQL',
+ displayRows: 10,
+ sql: '',
+ sqlType: '0',
+ preStatements: [],
+ postStatements: [],
+ udfs: [],
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDatasource(model),
+ ...Fields.useSqlType(model),
+ ...Fields.useSql(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sqoop.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sqoop.ts
new file mode 100644
index 0000000000..f401fb6d2c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sqoop.ts
@@ -0,0 +1,92 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useSqoop({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'SQOOP',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ cpuQuota: -1,
+ memoryMax: -1,
+ delayTime: 0,
+ timeout: 30,
+ isCustomTask: false,
+ hadoopCustomParams: [],
+ sqoopAdvancedParams: [],
+ mapColumnHive: [],
+ mapColumnJava: [],
+ modelType: 'import',
+ sourceType: 'MYSQL',
+ srcQueryType: '1',
+ srcColumnType: '0',
+ targetType: 'HIVE',
+ sourceMysqlType: 'MYSQL',
+ targetHdfsDeleteTargetDir: true,
+ targetHdfsCompressionCodec: 'snappy',
+ targetHdfsFileType: '--as-avrodatafile',
+ targetMysqlType: 'MYSQL',
+ targetMysqlUpdateMode: 'allowinsert',
+ targetHiveCreateTable: false,
+ targetHiveDropDelimiter: false,
+ targetHiveOverWrite: true,
+ concurrency: 1,
+ splitBy: '',
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ ...Fields.useResourceLimit(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useSqoop(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sub-process.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sub-process.ts
new file mode 100644
index 0000000000..8c855666bc
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-sub-process.ts
@@ -0,0 +1,74 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import { useRouter } from 'vue-router'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useSubProcess({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const router = useRouter()
+ const workflowCode = router.currentRoute.value.params.code
+ const model = reactive({
+ taskType: 'SUB_PROCESS',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useTimeoutAlarm(model),
+ Fields.useChildNode({
+ model,
+ projectCode,
+ from,
+ processName: data?.processName,
+ code: from === 1 ? 0 : Number(workflowCode)
+ }),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-switch.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-switch.ts
new file mode 100644
index 0000000000..1e6d3f80cc
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-switch.ts
@@ -0,0 +1,71 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useSwitch({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ taskType: 'SWITCH',
+ name: '',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ rawScript: '',
+ switchResult: {},
+ dependTaskList: [],
+ nextNode: undefined,
+ timeoutNotifyStrategy: ['WARN']
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useSwitch(model, projectCode),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-zeppelin.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-zeppelin.ts
new file mode 100644
index 0000000000..c8ac1260e4
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/tasks/use-zeppelin.ts
@@ -0,0 +1,74 @@
+/*
+ * 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 { reactive } from 'vue'
+import * as Fields from '../fields/index'
+import type { IJsonItem, INodeData, ITaskData } from '../types'
+
+export function useZeppelin({
+ projectCode,
+ from = 0,
+ readonly,
+ data
+}: {
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ data?: ITaskData
+}) {
+ const model = reactive({
+ name: '',
+ taskType: 'ZEPPELIN',
+ flag: 'YES',
+ description: '',
+ timeoutFlag: false,
+ localParams: [],
+ environmentCode: null,
+ failRetryInterval: 1,
+ failRetryTimes: 0,
+ workerGroup: 'default',
+ delayTime: 0,
+ timeout: 30,
+ type: 'ZEPPELIN',
+ displayRows: 10,
+ timeoutNotifyStrategy: ['WARN'],
+ restEndpoint: '',
+ username: '',
+ password: ''
+ } as INodeData)
+
+ return {
+ json: [
+ Fields.useName(from),
+ ...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }),
+ Fields.useRunFlag(),
+ Fields.useCache(),
+ Fields.useDescription(),
+ Fields.useTaskPriority(),
+ Fields.useWorkerGroup(projectCode),
+ Fields.useEnvironmentName(model, !data?.id),
+ ...Fields.useTaskGroup(model, projectCode),
+ ...Fields.useFailed(),
+ Fields.useDelayTime(model),
+ ...Fields.useTimeoutAlarm(model),
+ ...Fields.useDatasource(model),
+ ...Fields.useZeppelin(model),
+ Fields.usePreTasks()
+ ] as IJsonItem[],
+ model
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/types.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/types.ts
new file mode 100644
index 0000000000..0f6e1cd0c7
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/types.ts
@@ -0,0 +1,555 @@
+/*
+ * 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 { VNode } from 'vue'
+import type { SelectOption } from 'naive-ui'
+import type { TaskExecuteType, TriggerType } from '@/store/project/types'
+import type { IDataBase } from '@/service/modules/data-source/types'
+import type {
+ IFormItem,
+ IJsonItem,
+ FormRules,
+ IJsonItemParams
+} from '@/components/form/types'
+export type { EditWorkflowDefinition } from '@/views/projects/workflow/components/dag/types'
+export type {
+ IWorkflowTaskInstance,
+ WorkflowInstance
+} from '@/views/projects/workflow/components/dag/types'
+export type { IResource, ProgramType, IMainJar } from '@/store/project/types'
+export type { ITaskState } from '@/common/types'
+
+export type RelationType = 'AND' | 'OR'
+
+type SourceType = 'MYSQL' | 'HDFS' | 'HIVE'
+type ModelType = 'import' | 'export'
+type ITriggerType = TriggerType
+type IDateType = 'hour' | 'day' | 'week' | 'month'
+
+interface IOption {
+ label: string
+ value: string | number
+}
+
+interface IRenderOption extends IOption {
+ filterLabel: string
+}
+
+interface ITaskPriorityOption extends SelectOption {
+ icon: VNode
+ color: string
+}
+interface IEnvironmentNameOption {
+ label: string
+ value: string
+ workerGroups?: string[]
+}
+
+interface ILocalParam {
+ prop: string
+ direct?: string
+ type?: string
+ value?: string
+}
+
+interface ILabel {
+ label: string
+ value: string
+}
+
+interface IMatchExpression {
+ key: string
+ operator: string
+ values: string
+}
+
+interface IResponseJsonItem extends Omit {
+ type: 'input' | 'select' | 'radio' | 'group'
+ emit: 'change'[]
+}
+
+interface IDependentItemOptions {
+ dependentTypeOptions?: IOption[]
+ definitionCodeOptions?: IOption[]
+ depTaskCodeOptions?: IOption[]
+ dateOptions?: IOption[]
+}
+
+interface IDependTaskOptions {
+ dependItemList: IDependentItemOptions[]
+}
+
+interface IDependentItem {
+ depTaskCode?: number
+ status?: 'SUCCESS' | 'FAILURE'
+ projectCode?: number
+ definitionCode?: number
+ cycle?: 'month' | 'week' | 'day' | 'hour'
+ dateValue?: string
+ dependentType?: 'DEPENDENT_ON_WORKFLOW' | 'DEPENDENT_ON_TASK'
+ parameterPassing?: boolean
+}
+
+interface IDependTask {
+ condition?: string
+ nextNode?: number
+ relation?: RelationType
+ dependItemList?: IDependentItem[]
+}
+
+interface ISwitchResult {
+ dependTaskList?: IDependTask[]
+ nextNode?: number
+}
+
+interface IDependentParameters {
+ checkInterval?: number
+ failurePolicy?: 'DEPENDENT_FAILURE_FAILURE' | 'DEPENDENT_FAILURE_WAITING'
+ failureWaitingTime?: number
+ relation?: RelationType
+ dependTaskList?: IDependTask[]
+}
+
+/*
+ * resourceName: resource full name
+ * res: resource file name
+ */
+interface ISourceItem {
+ id?: number
+ resourceName: string
+ res?: string
+}
+
+interface ISqoopTargetData {
+ targetHiveDatabase?: string
+ targetHiveTable?: string
+ targetHiveCreateTable?: boolean
+ targetHiveDropDelimiter?: boolean
+ targetHiveOverWrite?: boolean
+ targetHiveTargetDir?: string
+ targetHiveReplaceDelimiter?: string
+ targetHivePartitionKey?: string
+ targetHivePartitionValue?: string
+ targetHdfsTargetPath?: string
+ targetHdfsDeleteTargetDir?: boolean
+ targetHdfsCompressionCodec?: string
+ targetHdfsFileType?: string
+ targetHdfsFieldsTerminated?: string
+ targetHdfsLinesTerminated?: string
+ targetMysqlType?: string
+ targetMysqlDatasource?: string
+ targetMysqlTable?: string
+ targetMysqlColumns?: string
+ targetMysqlFieldsTerminated?: string
+ targetMysqlLinesTerminated?: string
+ targetMysqlIsUpdate?: string
+ targetMysqlTargetUpdateKey?: string
+ targetMysqlUpdateMode?: string
+}
+
+interface ISqoopSourceData {
+ srcQueryType?: '1' | '0'
+ srcTable?: string
+ srcColumnType?: '1' | '0'
+ srcColumns?: string
+ sourceMysqlSrcQuerySql?: string
+ sourceMysqlType?: string
+ sourceMysqlDatasource?: string
+ mapColumnHive?: ILocalParam[]
+ mapColumnJava?: ILocalParam[]
+ sourceHdfsExportDir?: string
+ sourceHiveDatabase?: string
+ sourceHiveTable?: string
+ sourceHivePartitionKey?: string
+ sourceHivePartitionValue?: string
+}
+
+interface ISqoopTargetParams {
+ hiveDatabase?: string
+ hiveTable?: string
+ createHiveTable?: boolean
+ dropDelimiter?: boolean
+ hiveOverWrite?: boolean
+ hiveTargetDir?: string
+ replaceDelimiter?: string
+ hivePartitionKey?: string
+ hivePartitionValue?: string
+ targetPath?: string
+ deleteTargetDir?: boolean
+ compressionCodec?: string
+ fileType?: string
+ fieldsTerminated?: string
+ linesTerminated?: string
+ targetType?: string
+ targetDatasource?: string
+ targetTable?: string
+ targetColumns?: string
+ isUpdate?: string
+ targetUpdateKey?: string
+ targetUpdateMode?: string
+}
+interface ISqoopSourceParams {
+ srcTable?: string
+ srcColumnType?: '1' | '0'
+ srcColumns?: string
+ srcQuerySql?: string
+ srcQueryType?: '1' | '0'
+ srcType?: string
+ srcDatasource?: string
+ mapColumnHive?: ILocalParam[]
+ mapColumnJava?: ILocalParam[]
+ exportDir?: string
+ hiveDatabase?: string
+ hiveTable?: string
+ hivePartitionKey?: string
+ hivePartitionValue?: string
+}
+interface ISparkParameters {
+ deployMode?: string
+ driverCores?: number
+ driverMemory?: string
+ executorCores?: number
+ executorMemory?: string
+ numExecutors?: number
+ others?: string
+ yarnQueue?: string
+ sqlExecutionType?: string
+}
+
+interface IRuleParameters {
+ check_type?: string
+ comparison_execute_sql?: string
+ comparison_name?: string
+ comparison_type?: number
+ failure_strategy?: string
+ operator?: string
+ src_connector_type?: number
+ src_datasource_id?: number
+ src_database?: string
+ src_table?: string
+ field_length?: number
+ begin_time?: string
+ deadline?: string
+ datetime_format?: string
+ target_filter?: string
+ regexp_pattern?: string
+ enum_list?: string
+ src_filter?: string
+ src_field?: string
+ statistics_execute_sql?: string
+ statistics_name?: string
+ target_connector_type?: number
+ target_datasource_id?: number
+ target_database?: string
+ target_table?: string
+ threshold?: string
+ mapping_columns?: string
+}
+
+interface ITriggerParams {
+ resourceList?: ISourceItem[]
+ mainJar?: ISourceItem
+ localParams?: ILocalParam[]
+ runType?: string
+ jvmArgs?: string
+ isModulePath?: boolean
+ rawScript?: string
+ initScript?: string
+ programType?: string
+ flinkVersion?: string
+ jobManagerMemory?: string
+ taskManagerMemory?: string
+ slot?: number
+ taskManager?: number
+ parallelism?: number
+ mainClass?: string
+ deployMode?: string
+ appName?: string
+ driverCores?: number
+ driverMemory?: string
+ numExecutors?: number
+ executorMemory?: string
+ executorCores?: number
+ mainArgs?: string
+ others?: string
+ httpMethod?: string
+ httpBody?: string
+ httpCheckCondition?: string
+ httpParams?: []
+ url?: string
+ condition?: string
+ connectTimeout?: number
+ socketTimeout?: number
+ type?: string
+ datasource?: string
+ sql?: string
+ sqlType?: string
+ sendEmail?: boolean
+ displayRows?: number
+ title?: string
+ groupId?: string
+ preStatements?: string[]
+ postStatements?: string[]
+ method?: string
+ jobType?: 'CUSTOM' | 'TEMPLATE'
+ customShell?: string
+ jobName?: string
+ hadoopCustomParams?: ILocalParam[]
+ sqoopAdvancedParams?: ILocalParam[]
+ concurrency?: number
+ splitBy?: string
+ modelType?: ModelType
+ sourceType?: SourceType
+ targetType?: SourceType
+ targetParams?: string
+ sourceParams?: string
+ queue?: string
+ master?: string
+ masterUrl?: string
+ switchResult?: ISwitchResult
+ dependTaskList?: IDependTask[]
+ nextNode?: number
+ dependence?: IDependentParameters
+ customConfig?: number
+ json?: string
+ dsType?: string
+ dataSource?: number
+ dtType?: string
+ dataTarget?: number
+ targetTable?: string
+ jobSpeedByte?: number
+ jobSpeedRecord?: number
+ xms?: number
+ xmx?: number
+ sparkParameters?: ISparkParameters
+ ruleId?: number
+ ruleInputParameter?: IRuleParameters
+ jobFlowDefineJson?: string
+ stepsDefineJson?: string
+ zeppelinNoteId?: string
+ zeppelinParagraphId?: string
+ zeppelinRestEndpoint?: string
+ restEndpoint?: string
+ zeppelinUsername?: string
+ username?: string
+ zeppelinPassword?: string
+ password?: string
+ zeppelinProductionNoteDirectory?: string
+ productionNoteDirectory?: string
+ hiveCliOptions?: string
+ hiveSqlScript?: string
+ hiveCliTaskExecutionType?: string
+ sqlExecutionType?: string
+ noteId?: string
+ paragraphId?: string
+ condaEnvName?: string
+ inputNotePath?: string
+ outputNotePath?: string
+ parameters?: string
+ kernel?: string
+ engine?: string
+ startupScript?: string
+ executionTimeout?: string
+ startTimeout?: string
+ processDefinitionCode?: number
+ conditionResult?: {
+ successNode?: number[]
+ failedNode?: number[]
+ }
+ udfs?: string
+ connParams?: string
+ targetJobName?: string
+ cluster?: string
+ namespace?: string
+ clusterNamespace?: string
+ minCpuCores?: string
+ minMemorySpace?: string
+ image?: string
+ imagePullPolicy?: string
+ pullSecret?: string
+ command?: string
+ args?: string
+ customizedLabels?: ILabel[]
+ nodeSelectors?: IMatchExpression[]
+ algorithm?: string
+ params?: string
+ searchParams?: string
+ dataPath?: string
+ experimentName?: string
+ modelName?: string
+ mlflowTrackingUri?: string
+ mlflowJobType?: string
+ automlTool?: string
+ registerModel?: boolean
+ mlflowTaskType?: string
+ mlflowProjectRepository?: string
+ mlflowProjectVersion?: string
+ deployType?: string
+ deployPort?: string
+ deployModelKey?: string
+ cpuLimit?: string
+ memoryLimit?: string
+ zk?: string
+ zkPath?: string
+ executeMode?: string
+ useCustom?: boolean
+ runMode?: string
+ dvcTaskType?: string
+ dvcRepository?: string
+ dvcVersion?: string
+ dvcDataLocation?: string
+ dvcMessage?: string
+ dvcLoadSaveDataPath?: string
+ dvcStoreUrl?: string
+ address?: string
+ taskId?: string
+ online?: boolean
+ sagemakerRequestJson?: string
+ script?: string
+ scriptParams?: string
+ pythonPath?: string
+ isCreateEnvironment?: string
+ pythonCommand?: string
+ pythonEnvTool?: string
+ requirements?: string
+ condaPythonVersion?: string
+ isRestartTask?: boolean
+ isJsonFormat?: boolean
+ jsonData?: string
+ migrationType?: string
+ replicationTaskIdentifier?: string
+ sourceEndpointArn?: string
+ targetEndpointArn?: string
+ replicationInstanceArn?: string
+ tableMappings?: string
+ replicationTaskArn?: string
+ jsonFormat?: boolean
+ destinationLocationArn?: string
+ sourceLocationArn?: string
+ name?: string
+ cloudWatchLogGroupArn?: string
+ yamlContent?: string
+ paramScript?: ILocalParam[]
+ factoryName?: string
+ resourceGroupName?: string
+ pipelineName?: string
+ maxNumOfSubWorkflowInstances?: number
+ degreeOfParallelism?: number
+ filterCondition?: string
+ listParameters?: Array
+ yarnQueue?: string
+ awsRegion?: string
+ kubeConfig?: string
+}
+
+interface INodeData
+ extends Omit<
+ ITriggerParams,
+ | 'resourceList'
+ | 'mainJar'
+ | 'targetParams'
+ | 'sourceParams'
+ | 'dependence'
+ | 'sparkParameters'
+ | 'conditionResult'
+ | 'udfs'
+ | 'customConfig'
+ >,
+ ISqoopTargetData,
+ ISqoopSourceData,
+ IDependentParameters,
+ Omit {
+ id?: string
+ triggerType?: ITriggerType
+ processName?: number
+ delayTime?: number
+ description?: string
+ environmentCode?: number | null
+ failRetryInterval?: number
+ failRetryTimes?: number
+ cpuQuota?: number
+ memoryMax?: number
+ flag?: 'YES' | 'NO'
+ isCache?: boolean
+ taskGroupId?: number
+ taskGroupPriority?: number
+ taskPriority?: string
+ timeout?: number
+ timeoutFlag?: boolean
+ timeoutNotifyStrategy?: string[]
+ workerGroup?: string
+ code?: number
+ name?: string
+ preTasks?: number[]
+ preTaskOptions?: []
+ postTaskOptions?: []
+ resourceList?: string[]
+ mainJar?: string
+ timeoutSetting?: boolean
+ isCustomTask?: boolean
+ method?: string
+ resourceFiles?: { id: number; fullName: string }[] | null
+ relation?: RelationType
+ definition?: object
+ successBranch?: number
+ failedBranch?: number
+ udfs?: string[]
+ customConfig?: boolean
+ mapping_columns?: object[]
+ taskExecuteType?: TaskExecuteType
+}
+
+interface ITriggerData
+ extends Omit<
+ INodeData,
+ 'isCache' | 'timeoutFlag' | 'taskPriority' | 'timeoutNotifyStrategy'
+ > {
+ name?: string
+ taskPriority?: string
+ isCache?: 'YES' | 'NO'
+ timeoutFlag?: 'OPEN' | 'CLOSE'
+ timeoutNotifyStrategy?: string | []
+ triggerParams?: ITriggerParams
+}
+
+export {
+ ITaskPriorityOption,
+ IEnvironmentNameOption,
+ ILocalParam,
+ ITriggerType,
+ ITriggerData,
+ INodeData,
+ ITriggerParams,
+ IOption,
+ IRenderOption,
+ IDataBase,
+ ModelType,
+ SourceType,
+ ISqoopSourceParams,
+ ISqoopTargetParams,
+ IDependTask,
+ IDependentItem,
+ IDependentItemOptions,
+ IDependTaskOptions,
+ IFormItem,
+ IJsonItem,
+ FormRules,
+ IJsonItemParams,
+ IResponseJsonItem,
+ IDateType,
+ IDependentParameters
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/components/node/use-task.ts b/dolphinscheduler-ui/src/views/projects/trigger/components/node/use-task.ts
new file mode 100644
index 0000000000..c9c804188c
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/components/node/use-task.ts
@@ -0,0 +1,82 @@
+/*
+ * 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 { 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 '@/store/project/task-type'
+import type {
+ EditWorkflowDefinition,
+ FormRules,
+ IFormItem,
+ IJsonItem,
+ INodeData,
+ ITaskData
+} from './types'
+
+export function useTask({
+ data,
+ projectCode,
+ from,
+ readonly,
+ definition
+}: {
+ data: ITaskData
+ projectCode: number
+ from?: number
+ readonly?: boolean
+ definition?: EditWorkflowDefinition
+}): {
+ elementsRef: Ref
+ rulesRef: Ref
+ model: INodeData
+} {
+ const taskStore = useTaskNodeStore()
+ taskStore.updateDefinition(unref(definition), data?.code)
+
+ const jsonRef = ref([]) as Ref
+ const elementsRef = ref([]) as Ref
+ const rulesRef = ref({})
+
+ const params = {
+ projectCode,
+ from,
+ readonly,
+ data,
+ jsonRef,
+ updateElements: () => {
+ getElements()
+ }
+ }
+
+ const { model, json } = nodes[data.taskType || 'SHELL'](params)
+ jsonRef.value = json
+ model.preTasks = taskStore.getPreTasks
+ model.name = taskStore.getName
+ model.taskExecuteType =
+ TASK_TYPES_MAP[data.taskType || 'SHELL'].taskExecuteType || 'BATCH'
+
+ const getElements = () => {
+ const { rules, elements } = getElementByJson(jsonRef.value, model)
+ elementsRef.value = elements
+ rulesRef.value = rules
+ }
+
+ getElements()
+
+ return { elementsRef, rulesRef, model }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/components/start-modal.tsx b/dolphinscheduler-ui/src/views/projects/trigger/definition/components/start-modal.tsx
new file mode 100644
index 0000000000..10b2098058
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/components/start-modal.tsx
@@ -0,0 +1,272 @@
+/*
+ * 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 {
+ defineComponent,
+ PropType,
+ toRefs,
+ onMounted,
+ watch,
+ getCurrentInstance
+} from 'vue'
+import { useI18n } from 'vue-i18n'
+import Modal from '@/components/modal'
+import { useStart } from './use-start'
+import {
+ NForm,
+ NFormItem,
+ NButton,
+ NIcon,
+ NInput,
+ NSpace,
+ NSelect,
+ NSwitch
+} from 'naive-ui'
+import { DeleteOutlined, PlusCircleOutlined } from '@vicons/antd'
+
+const props = {
+ row: {
+ type: Object,
+ default: {}
+ },
+ show: {
+ type: Boolean as PropType,
+ default: false
+ },
+ taskCode: {
+ type: String
+ }
+}
+
+export default defineComponent({
+ name: 'task-definition-start',
+ props,
+ emits: ['update:show', 'update:row', 'updateList'],
+ setup(props, ctx) {
+ const { t } = useI18n()
+ const {
+ variables,
+ handleStartDefinition,
+ getWorkerGroups,
+ getTenantList,
+ getAlertGroups,
+ getEnvironmentList,
+ getStartParamsList
+ } = useStart(ctx)
+
+ const generalWarningTypeListOptions = () => [
+ {
+ value: 'NONE',
+ label: t('project.task.none_send')
+ },
+ {
+ value: 'SUCCESS',
+ label: t('project.task.success_send')
+ },
+ {
+ value: 'FAILURE',
+ label: t('project.task.failure_send')
+ },
+ {
+ value: 'ALL',
+ label: t('project.task.all_send')
+ }
+ ]
+
+ const hideModal = () => {
+ ctx.emit('update:show')
+ }
+
+ const handleStart = () => {
+ handleStartDefinition(props.row.taskCode)
+ }
+
+ const updateWorkerGroup = () => {
+ variables.startForm.environmentCode = null
+ }
+
+ const addStartParams = () => {
+ variables.startState.startParamsList.push({
+ prop: '',
+ value: ''
+ })
+ }
+
+ const updateParamsList = (index: number, param: Array) => {
+ variables.startState.startParamsList[index].prop = param[0]
+ variables.startState.startParamsList[index].value = param[1]
+ }
+
+ const removeStartParams = (index: number) => {
+ variables.startState.startParamsList.splice(index, 1)
+ }
+
+ const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
+
+ onMounted(() => {
+ getWorkerGroups()
+ getTenantList()
+ getAlertGroups()
+ getEnvironmentList()
+ })
+
+ watch(
+ () => props.show,
+ () => {
+ if (props.show) {
+ getStartParamsList(props.row.processDefinitionCode)
+ }
+ }
+ )
+
+ return {
+ t,
+ hideModal,
+ handleStart,
+ updateWorkerGroup,
+ removeStartParams,
+ addStartParams,
+ updateParamsList,
+ generalWarningTypeListOptions,
+ ...toRefs(variables),
+ ...toRefs(variables.startState),
+ ...toRefs(props),
+ trim
+ }
+ },
+
+ render() {
+ const { t } = this
+
+ return (
+
+
+
+ ]{this.row.taskName}
+
+
+
+
+
+
+
+
+
+
+
+
+ item.workerGroups?.includes(this.startForm.workerGroup)
+ )}
+ v-model:value={this.startForm.environmentCode}
+ clearable
+ />
+
+
+
+
+
+ {this.startParamsList.length === 0 ? (
+
+
+
+
+
+ ) : (
+
+ {this.startParamsList.map((item, index) => (
+
+
+ this.updateParamsList(index, param)
+ }
+ />
+ this.removeStartParams(index)}
+ class='btn-delete-custom-parameter'
+ >
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+ )}
+
+
+
+
+
+
+ )
+ }
+})
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/components/use-start.tsx b/dolphinscheduler-ui/src/views/projects/trigger/definition/components/use-start.tsx
new file mode 100644
index 0000000000..f824a4dba8
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/components/use-start.tsx
@@ -0,0 +1,156 @@
+/*
+ * 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 { startTaskDefinition } from '@/service/modules/task-definition'
+import _ from 'lodash'
+import { reactive, ref, SetupContext } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useRoute } from 'vue-router'
+import { queryProcessDefinitionByCode } from '@/service/modules/process-definition'
+import { queryAllWorkerGroups } from '@/service/modules/worker-groups'
+import { queryTenantList } from '@/service/modules/tenants'
+import { queryAllEnvironmentList } from '@/service/modules/environment'
+import { listNormalAlertGroupById } from '@/service/modules/alert-group'
+import type { EnvironmentItem } from '@/service/modules/environment/types'
+import type { IStartState } from '../types'
+
+export const useStart = (
+ ctx: SetupContext<('update:show' | 'update:row' | 'updateList')[]>
+) => {
+ const { t } = useI18n()
+ const route = useRoute()
+
+ const variables = reactive({
+ startFormRef: ref(),
+ startForm: {
+ version: 1,
+ warningType: 'NONE',
+ warningGroupId: null,
+ workerGroup: 'default',
+ tenantCode: 'default',
+ environmentCode: null,
+ startParams: null as null | string,
+ dryRun: 0
+ },
+ startState: {
+ projectCode: Number(route.params.projectCode),
+ workerGroups: [],
+ tenantList: [],
+ alertGroups: [],
+ environmentList: [],
+ startParamsList: []
+ } as IStartState,
+ saving: false
+ })
+
+ const cachedStartParams = {} as {
+ [key: string]: { prop: string; value: string }[]
+ }
+
+ const getWorkerGroups = () => {
+ queryAllWorkerGroups().then((res: any) => {
+ variables.startState.workerGroups = res.map((item: string) => ({
+ label: item,
+ value: item
+ }))
+ })
+ }
+
+ const getTenantList = () => {
+ queryTenantList().then((res: any) => {
+ variables.startState.tenantList = res.map((item: any) => ({
+ label: item.tenantCode,
+ value: item.tenantCode
+ }))
+ })
+ }
+
+ const getEnvironmentList = () => {
+ queryAllEnvironmentList().then((res: Array) => {
+ variables.startState.environmentList = res.map((item) => ({
+ label: item.name,
+ value: item.code,
+ workerGroups: item.workerGroups
+ }))
+ })
+ }
+
+ const getAlertGroups = () => {
+ listNormalAlertGroupById().then((res: any) => {
+ variables.startState.alertGroups = res.map((item: any) => ({
+ label: item.groupName,
+ value: item.id
+ }))
+ })
+ }
+
+ const getStartParamsList = (code: number) => {
+ if (cachedStartParams[code]) {
+ variables.startState.startParamsList = _.cloneDeep(
+ cachedStartParams[code]
+ )
+ return
+ }
+ queryProcessDefinitionByCode(code, variables.startState.projectCode).then(
+ (res: any) => {
+ variables.startState.startParamsList =
+ res.processDefinition.globalParamList
+ cachedStartParams[code] = _.cloneDeep(
+ variables.startState.startParamsList
+ )
+ }
+ )
+ }
+
+ const handleStartDefinition = async (code: number) => {
+ await variables.startFormRef.validate()
+
+ if (variables.saving) return
+ variables.saving = true
+ try {
+ const startParams = {} as any
+ for (const item of variables.startState.startParamsList) {
+ if (item.value !== '') {
+ startParams[item.prop] = item.value
+ }
+ }
+ variables.startForm.startParams = !_.isEmpty(startParams)
+ ? JSON.stringify(startParams)
+ : ''
+
+ await startTaskDefinition(variables.startState.projectCode, code, {
+ ...variables.startForm
+ } as any)
+ window.$message.success(t('project.task.success'))
+ variables.saving = false
+ ctx.emit('updateList')
+ ctx.emit('update:show')
+ } catch (err) {
+ variables.saving = false
+ }
+ }
+
+ return {
+ variables,
+ getWorkerGroups,
+ getTenantList,
+ getEnvironmentList,
+ getAlertGroups,
+ getStartParamsList,
+ handleStartDefinition
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/components/use-version.ts b/dolphinscheduler-ui/src/views/projects/trigger/definition/components/use-version.ts
new file mode 100644
index 0000000000..924dca6864
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/components/use-version.ts
@@ -0,0 +1,213 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { h, reactive, ref } from 'vue'
+import { NButton, NPopconfirm, NSpace, NTag, NTooltip } from 'naive-ui'
+import { DeleteOutlined, CheckOutlined } from '@vicons/antd'
+import { useAsyncState } from '@vueuse/core'
+import {
+ queryTaskVersions,
+ switchVersion,
+ deleteVersion
+} from '@/service/modules/task-definition'
+import { useRoute } from 'vue-router'
+import type {
+ TaskDefinitionVersionRes,
+ TaskDefinitionVersionItem
+} from '@/service/modules/task-definition/types'
+
+export function useVersion() {
+ const { t } = useI18n()
+ const route = useRoute()
+ const projectCode = Number(route.params.projectCode)
+
+ const createColumns = (variables: any) => {
+ variables.columns = [
+ {
+ title: '#',
+ key: 'index',
+ render: (row: any, index: number) => index + 1
+ },
+ {
+ title: t('project.task.version'),
+ key: 'version',
+ render: (row: TaskDefinitionVersionItem) =>
+ h(
+ 'span',
+ null,
+ row.version !== variables.taskVersion
+ ? 'v' + row.version
+ : h(
+ NTag,
+ { type: 'success', size: 'small' },
+ {
+ default: () =>
+ `v${row.version} ${t('project.task.current_version')}`
+ }
+ )
+ )
+ },
+ {
+ title: t('project.task.description'),
+ key: 'description',
+ render: (row: TaskDefinitionVersionItem) =>
+ h('span', null, row.description ? row.description : '-')
+ },
+ {
+ title: t('project.task.create_time'),
+ key: 'createTime'
+ },
+ {
+ title: t('project.task.operation'),
+ key: 'operation',
+ render(row: TaskDefinitionVersionItem) {
+ return h(NSpace, null, {
+ default: () => [
+ h(
+ NPopconfirm,
+ {
+ onPositiveClick: () => {
+ handleSwitchVersion(row)
+ }
+ },
+ {
+ trigger: () =>
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'info',
+ size: 'small',
+ disabled: row.version === variables.taskVersion
+ },
+ {
+ icon: () => h(CheckOutlined)
+ }
+ ),
+ default: () => t('project.task.switch_version')
+ }
+ ),
+ default: () => t('project.task.confirm_switch_version')
+ }
+ ),
+ h(
+ NPopconfirm,
+ {
+ onPositiveClick: () => {
+ handleDelete(row)
+ }
+ },
+ {
+ trigger: () =>
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'error',
+ size: 'small',
+ disabled: row.version === variables.taskVersion
+ },
+ {
+ icon: () => h(DeleteOutlined)
+ }
+ ),
+ default: () => t('project.task.delete')
+ }
+ ),
+ default: () => t('project.task.delete_confirm')
+ }
+ )
+ ]
+ })
+ }
+ }
+ ]
+ }
+
+ const variables = reactive({
+ columns: [],
+ tableData: [],
+ page: ref(1),
+ pageSize: ref(10),
+ totalPage: ref(1),
+ taskVersion: ref(null),
+ taskCode: ref(null),
+ refreshTaskDefinition: ref(false),
+ row: {},
+ loadingRef: ref(false)
+ })
+
+ const handleSwitchVersion = (row: TaskDefinitionVersionItem) => {
+ switchVersion(
+ { version: row.version },
+ { code: variables.taskCode },
+ { projectCode }
+ ).then(() => {
+ variables.refreshTaskDefinition = true
+ })
+ }
+
+ const handleDelete = (row: TaskDefinitionVersionItem) => {
+ deleteVersion(
+ { version: row.version },
+ { code: variables.taskCode },
+ { projectCode }
+ ).then(() => {
+ variables.refreshTaskDefinition = true
+ })
+ }
+
+ const getTableData = (params: any) => {
+ if (variables.loadingRef) return
+ variables.loadingRef = true
+ const { state } = useAsyncState(
+ queryTaskVersions(
+ { ...params },
+ { code: variables.taskCode },
+ { projectCode }
+ ).then((res: TaskDefinitionVersionRes) => {
+ variables.tableData = res.totalList.map((item, unused) => {
+ return {
+ ...item
+ }
+ }) as any
+ variables.totalPage = res.totalPage
+ variables.loadingRef = false
+ }),
+ {}
+ )
+
+ return state
+ }
+
+ return {
+ variables,
+ getTableData,
+ createColumns
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/index.tsx b/dolphinscheduler-ui/src/views/projects/trigger/definition/index.tsx
new file mode 100644
index 0000000000..05f5e9a72f
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/index.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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 { defineComponent } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { NTabPane, NTabs } from 'naive-ui'
+import BatchTriggerDefinition from './trigger'
+
+const TriggerDefinition = defineComponent({
+ name: 'trigger-definition',
+ setup() {
+ const { t } = useI18n()
+ return () => (
+
+
+
+
+
+ )
+ }
+})
+
+export default TriggerDefinition
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/trigger.tsx b/dolphinscheduler-ui/src/views/projects/trigger/definition/trigger.tsx
new file mode 100644
index 0000000000..b059f4ece2
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/trigger.tsx
@@ -0,0 +1,226 @@
+/*
+ * 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 {
+ defineComponent,
+ getCurrentInstance,
+ onMounted,
+ toRefs,
+ watch
+} from 'vue'
+import { useRoute } from 'vue-router'
+import {
+ NButton,
+ NDataTable,
+ NIcon,
+ NInput,
+ NPagination,
+ NSelect,
+ NSpace
+} from 'naive-ui'
+import { SearchOutlined } from '@vicons/antd'
+import { useI18n } from 'vue-i18n'
+import { useTable } from './use-table'
+import { useTrigger } from './use-trigger'
+import { TASK_TYPES_MAP } from '@/store/project/task-type'
+import Card from '@/components/card'
+import TaskModal from '@/views/projects/trigger/components/node/detail-modal'
+import type { INodeData } from './types'
+import DependenciesModal from '@/views/projects/components/dependencies/dependencies-modal'
+
+const BatchTriggerDefinition = defineComponent({
+ name: 'trigger-definition',
+ setup() {
+ const route = useRoute()
+ const projectCode = Number(route.params.projectCode)
+ const { t } = useI18n()
+
+ const {
+ trigger,
+ onToggleShow,
+ onTriggerSave,
+ onEditTrigger,
+ onInitTrigger
+ } = useTrigger(projectCode)
+
+ const { variables, getTableData, createColumns } = useTable(onEditTrigger)
+
+ const requestData = () => {
+ getTableData({
+ pageSize: variables.pageSize,
+ pageNo: variables.page,
+ searchTaskName: variables.searchTaskName,
+ taskType: variables.taskType
+ })
+ }
+
+ const onUpdatePageSize = () => {
+ variables.page = 1
+ requestData()
+ }
+
+ const onSearch = () => {
+ variables.page = 1
+ requestData()
+ }
+
+ const onClearSearchTaskName = () => {
+ variables.searchTaskName = null
+ onSearch()
+ }
+
+ const onClearSearchTaskType = () => {
+ variables.taskType = null
+ onSearch()
+ }
+
+ const onRefresh = () => {
+ variables.showVersionModalRef = false
+ requestData()
+ }
+ const onCreate = () => {
+ onToggleShow(true)
+ }
+ const onTaskCancel = () => {
+ onToggleShow(false)
+ onInitTrigger()
+ }
+ const onTaskSubmit = async (params: { data: INodeData }) => {
+ const result = await onTriggerSave(params.data)
+ if (result) {
+ onTaskCancel()
+ onRefresh()
+ }
+ }
+
+ const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
+ onMounted(() => {
+ createColumns(variables)
+ requestData()
+ })
+
+ watch(useI18n().locale, () => {
+ createColumns(variables)
+ })
+
+ return {
+ t,
+ ...toRefs(variables),
+ ...toRefs(trigger),
+ onSearch,
+ onClearSearchTaskName,
+ onClearSearchTaskType,
+ requestData,
+ onUpdatePageSize,
+ onRefresh,
+ onCreate,
+ onTaskSubmit,
+ onTaskCancel,
+ projectCode,
+ trim
+ }
+ },
+ render() {
+ const {
+ t,
+ onSearch,
+ requestData,
+ onUpdatePageSize,
+ onCreate,
+ loadingRef
+ } = this
+
+ return (
+
+
+
+
+ {t('project.trigger.create_trigger')}
+
+
+
+ {
+ return { value: item, label: item }
+ })}
+ placeholder={t('project.task.task_type')}
+ style={{ width: '180px' }}
+ clearable
+ onClear={this.onClearSearchTaskType}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+})
+
+export default BatchTriggerDefinition
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/types.ts b/dolphinscheduler-ui/src/views/projects/trigger/definition/types.ts
new file mode 100644
index 0000000000..a21876b0a4
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/types.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 { IOption } from '@/components/form/types'
+import { IParam } from '../../workflow/definition/components/types'
+import { IEnvironmentNameOption } from '../components/node/types'
+export type { ITriggerData, INodeData } from '../components/node/types'
+export type { ISingleSaveReq } from '@/service/modules/task-definition/types'
+
+interface IRecord {
+ processDefinitionCode: number
+ triggerCode: number
+ triggerName: string
+}
+
+interface IStartState {
+ projectCode: number
+ workerGroups: Array
+ tenantList: Array
+ alertGroups: Array
+ environmentList: Array
+ startParamsList: Array
+}
+
+export { IRecord, IStartState }
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/use-table.ts b/dolphinscheduler-ui/src/views/projects/trigger/definition/use-table.ts
new file mode 100644
index 0000000000..9ebf3347ae
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/use-table.ts
@@ -0,0 +1,348 @@
+/*
+ * 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 { useAsyncState } from '@vueuse/core'
+import { reactive, h, ref } from 'vue'
+import {
+ NButton,
+ NIcon,
+ NPopconfirm,
+ NSpace,
+ NTag,
+ NTooltip,
+ NEllipsis
+} from 'naive-ui'
+import ButtonLink from '@/components/button-link'
+import { useI18n } from 'vue-i18n'
+import {
+ DeleteOutlined,
+ EditOutlined,
+ ExclamationCircleOutlined
+} from '@vicons/antd'
+import {
+ queryTriggerDefinitionListPaging,
+ deleteTriggerDefinition
+} from '@/service/modules/trigger-definition'
+import { useRoute } from 'vue-router'
+import {
+ COLUMN_WIDTH_CONFIG,
+ calculateTableWidth,
+ DefaultTableWidth
+} from '@/common/column-width-config'
+import type {
+ TaskDefinitionItem,
+ TaskDefinitionRes
+} from '@/service/modules/task-definition/types'
+import type { IRecord } from './types'
+
+import { useDependencies } from '../../components/dependencies/use-dependencies'
+
+export function useTable(onEdit: Function) {
+ const { t } = useI18n()
+ const route = useRoute()
+ const projectCode = Number(route.params.projectCode)
+
+ const { getDependentTaskLinksByTask } = useDependencies()
+
+ const createColumns = (variables: any) => {
+ variables.columns = [
+ {
+ title: '#',
+ key: 'index',
+ render: (row: any, index: number) => index + 1,
+ ...COLUMN_WIDTH_CONFIG['index']
+ },
+ {
+ title: t('project.trigger.trigger_name'),
+ key: 'triggerName',
+ ...COLUMN_WIDTH_CONFIG['linkName'],
+ resizable: true,
+ minWidth: 200,
+ maxWidth: 600,
+ render: (row: IRecord) =>
+ h(
+ ButtonLink,
+ {
+ onClick: () => void onEdit(row, true)
+ },
+ {
+ default: () =>
+ h(
+ NEllipsis,
+ {
+ style: 'max-width: 580px;line-height: 1.5'
+ },
+ () => row.triggerName
+ )
+ }
+ )
+ },
+ {
+ title: t('project.task.workflow_name'),
+ key: 'processDefinitionName',
+ ...COLUMN_WIDTH_CONFIG['name'],
+ resizable: true,
+ minWidth: 200,
+ maxWidth: 600
+ },
+ {
+ title: t('project.task.workflow_state'),
+ key: 'processReleaseState',
+ render: (row: any) => {
+ if (row.processReleaseState === 'OFFLINE') {
+ return h(NTag, { type: 'error', size: 'small' }, () =>
+ t('project.task.offline')
+ )
+ } else if (row.processReleaseState === 'ONLINE') {
+ return h(NTag, { type: 'info', size: 'small' }, () =>
+ t('project.task.online')
+ )
+ }
+ },
+ width: 130
+ },
+ {
+ title: t('project.task.task_type'),
+ key: 'taskType',
+ ...COLUMN_WIDTH_CONFIG['type']
+ },
+ {
+ title: t('project.task.version'),
+ key: 'taskVersion',
+ render: (row: TaskDefinitionItem) =>
+ h('span', null, 'v' + row.taskVersion),
+ ...COLUMN_WIDTH_CONFIG['version']
+ },
+ {
+ title: t('project.task.upstream_tasks'),
+ key: 'upstreamTaskMap',
+ render: (row: TaskDefinitionItem) =>
+ row.upstreamTaskMap.map((item: string, index: number) => {
+ return h('p', null, { default: () => `[${index + 1}] ${item}` })
+ }),
+ ...COLUMN_WIDTH_CONFIG['name']
+ },
+ {
+ title: t('project.task.create_time'),
+ key: 'taskCreateTime',
+ ...COLUMN_WIDTH_CONFIG['time']
+ },
+ {
+ title: t('project.task.update_time'),
+ key: 'taskUpdateTime',
+ ...COLUMN_WIDTH_CONFIG['time']
+ },
+ {
+ title: t('project.task.operation'),
+ key: 'operation',
+ ...COLUMN_WIDTH_CONFIG['operation'](3),
+ render(row: any) {
+ return h(NSpace, null, {
+ default: () => [
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'info',
+ size: 'small',
+ disabled:
+ ['CONDITIONS', 'SWITCH'].includes(row.taskType) ||
+ (!!row.processDefinitionCode &&
+ row.processReleaseState === 'ONLINE'),
+ onClick: () => {
+ onEdit(row, false)
+ }
+ },
+ {
+ icon: () =>
+ h(NIcon, null, { default: () => h(EditOutlined) })
+ }
+ ),
+ default: () => t('project.task.edit')
+ }
+ ),
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'info',
+ size: 'small',
+ onClick: () => {
+ variables.showVersionModalRef = true
+ variables.row = row
+ }
+ },
+ {
+ icon: () =>
+ h(NIcon, null, {
+ default: () => h(ExclamationCircleOutlined)
+ })
+ }
+ ),
+ default: () => t('project.task.version')
+ }
+ ),
+ h(
+ NPopconfirm,
+ {
+ onPositiveClick: () => {
+ handleDelete(row)
+ }
+ },
+ {
+ trigger: () =>
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'error',
+ size: 'small',
+ disabled:
+ !!row.processDefinitionCode &&
+ row.processReleaseState === 'ONLINE'
+ },
+ {
+ icon: () =>
+ h(NIcon, null, {
+ default: () => h(DeleteOutlined)
+ })
+ }
+ ),
+ default: () => t('project.task.delete')
+ }
+ ),
+ default: () => t('project.task.delete_confirm')
+ }
+ )
+ ]
+ })
+ }
+ }
+ ]
+ if (variables.tableWidth) {
+ variables.tableWidth = calculateTableWidth(variables.columns)
+ }
+ }
+
+ const variables = reactive({
+ columns: [],
+ tableWidth: DefaultTableWidth,
+ tableData: [],
+ page: ref(1),
+ pageSize: ref(10),
+ searchTaskName: ref(null),
+ searchWorkflowName: ref(null),
+ totalPage: ref(1),
+ taskType: ref(null),
+ showVersionModalRef: ref(false),
+ dependentTasksShowRef: ref(false),
+ dependentTaskLinksRef: ref([]),
+ row: {},
+ loadingRef: ref(false),
+ dependenciesData: ref({
+ showRef: ref(false),
+ taskLinks: ref([]),
+ required: ref(false),
+ tip: ref(''),
+ action: () => {}
+ })
+ })
+
+ const handleDelete = (row: any) => {
+ variables.row = row
+ getDependentTaskLinksByTask(
+ projectCode,
+ row.processDefinitionCode,
+ row.taskCode
+ ).then((res: any) => {
+ if (res && res.length > 0) {
+ variables.dependenciesData = {
+ showRef: true,
+ taskLinks: res,
+ tip: t('project.workflow.delete_validate_dependent_tasks_desc'),
+ required: true,
+ action: () => {}
+ }
+ } else {
+ deleteTriggerDefinition({ code: row.taskCode }, { projectCode }).then(
+ () => {
+ getTableData({
+ pageSize: variables.pageSize,
+ pageNo:
+ variables.tableData.length === 1 && variables.page > 1
+ ? variables.page - 1
+ : variables.page,
+ searchTaskName: variables.searchTaskName,
+ searchWorkflowName: variables.searchWorkflowName,
+ taskType: variables.taskType
+ })
+ }
+ )
+ }
+ })
+ }
+
+ const getTableData = (params: any) => {
+ if (variables.loadingRef) return
+ variables.loadingRef = true
+ const { state } = useAsyncState(
+ queryTriggerDefinitionListPaging({ ...params }, { projectCode }).then(
+ (res: TaskDefinitionRes) => {
+ variables.tableData = res.totalList.map((item, unused) => {
+ if (Object.keys(item.upstreamTaskMap).length > 0) {
+ item.upstreamTaskMap = Object.keys(item.upstreamTaskMap).map(
+ (code) => item.upstreamTaskMap[code]
+ )
+ } else {
+ item.upstreamTaskMap = []
+ }
+
+ return {
+ ...item
+ }
+ }) as any
+ variables.totalPage = res.totalPage
+ variables.loadingRef = false
+ }
+ ),
+ {}
+ )
+
+ return state
+ }
+
+ return {
+ variables,
+ getTableData,
+ createColumns
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/definition/use-trigger.ts b/dolphinscheduler-ui/src/views/projects/trigger/definition/use-trigger.ts
new file mode 100644
index 0000000000..34d344c227
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/definition/use-trigger.ts
@@ -0,0 +1,142 @@
+/*
+ * 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 { reactive } from 'vue'
+import {
+ updateTrigger,
+ genTaskCodeList,
+ saveSingle,
+ queryTriggerDefinitionByCode,
+ updateWithUpstream
+} from '@/service/modules/trigger-definition'
+import { formatParams as formatData } from '../components/node/format-data'
+import type { ITriggerData, INodeData, ISingleSaveReq, IRecord } from './types'
+import { Connect } from '../../workflow/components/dag/types'
+
+export function useTrigger(projectCode: number) {
+ const initialTrigger = {
+ taskType: 'SIMPLE'
+ } as ITriggerData
+ const trigger = reactive({
+ triggerShow: false,
+ triggerData: { ...initialTrigger },
+ triggerSaving: false,
+ triggerReadonly: false
+ } as { triggerShow: boolean; triggerData: ITriggerData; triggerSaving: boolean; triggerReadonly: boolean })
+
+ const formatParams = (data: INodeData, isCreate: boolean): ISingleSaveReq => {
+ const params = formatData(data)
+ if (isCreate) {
+ return {
+ processDefinitionCode: params.processDefinitionCode,
+ upstreamCodes: params.upstreamCodes,
+ taskDefinitionJsonObj: JSON.stringify(params.taskDefinitionJsonObj)
+ }
+ }
+ return {
+ upstreamCodes: params.upstreamCodes,
+ taskDefinitionJsonObj: JSON.stringify(params.taskDefinitionJsonObj)
+ }
+ }
+
+ const getTaskCode = async () => {
+ const result = await genTaskCodeList(1, projectCode)
+ return result[0]
+ }
+
+ const onToggleShow = (show: boolean) => {
+ trigger.triggerShow = show
+ }
+ const onTriggerSave = async (data: INodeData) => {
+ if (trigger.triggerSaving) return
+ trigger.triggerSaving = true
+ try {
+ if (data.id) {
+ data.code &&
+ (await updateWithUpstream(
+ projectCode,
+ data.code,
+ formatParams({ ...data, code: data.code }, false)
+ ))
+ } else {
+ const taskCode = await getTaskCode()
+ await saveSingle(
+ projectCode,
+ formatParams({ ...data, code: taskCode }, true)
+ )
+ }
+
+ trigger.triggerSaving = false
+ return true
+ } catch (err) {
+ trigger.triggerSaving = false
+ return false
+ }
+ }
+
+ const onEditTrigger = async (row: IRecord, readonly: boolean) => {
+ const result = await queryTriggerDefinitionByCode(
+ row.triggerCode,
+ projectCode
+ )
+ trigger.triggerData = {
+ ...result,
+ processName: row.processDefinitionCode,
+ preTasks:
+ result?.processTaskRelationList?.map(
+ (item: Connect) => item.preTaskCode
+ ) || []
+ }
+ trigger.triggerShow = true
+ trigger.triggerReadonly = readonly
+ }
+
+ const onInitTrigger = () => {
+ trigger.triggerData = { ...initialTrigger }
+ trigger.triggerReadonly = false
+ }
+
+ const onUpdateTrigger = async (data: INodeData) => {
+ if (trigger.triggerSaving || !data.code) return
+ trigger.triggerSaving = true
+
+ const params = {
+ taskExecuteType: 'STREAM',
+ taskDefinitionJsonObj: JSON.stringify(
+ formatData(data).taskDefinitionJsonObj
+ )
+ }
+
+ try {
+ await updateTrigger(projectCode, data.code, params)
+ trigger.triggerSaving = false
+ return true
+ } catch (err) {
+ trigger.triggerSaving = false
+ return false
+ }
+ }
+
+ return {
+ trigger: trigger,
+ onToggleShow,
+ onTriggerSave,
+ onEditTrigger,
+ onInitTrigger,
+ onUpdateTrigger
+ }
+}
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/instance/index.tsx b/dolphinscheduler-ui/src/views/projects/trigger/instance/index.tsx
new file mode 100644
index 0000000000..12774262b2
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/instance/index.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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 { defineComponent } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { NTabPane, NTabs } from 'naive-ui'
+import BatchTriggerInstance from './trigger'
+
+const TriggerDefinition = defineComponent({
+ name: 'trigger-instance',
+ setup() {
+ const { t } = useI18n()
+ return () => (
+
+
+
+
+
+ )
+ }
+})
+
+export default TriggerDefinition
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/instance/trigger.tsx b/dolphinscheduler-ui/src/views/projects/trigger/instance/trigger.tsx
new file mode 100644
index 0000000000..57d137fcd1
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/instance/trigger.tsx
@@ -0,0 +1,318 @@
+/*
+ * 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 {
+ defineComponent,
+ getCurrentInstance,
+ onMounted,
+ toRefs,
+ watch
+} from 'vue'
+import {
+ NSpace,
+ NInput,
+ NSelect,
+ NDatePicker,
+ NButton,
+ NIcon,
+ NDataTable,
+ NPagination
+} from 'naive-ui'
+import { SearchOutlined } from '@vicons/antd'
+import { useTable } from './use-table'
+import { useI18n } from 'vue-i18n'
+import { useAsyncState } from '@vueuse/core'
+import { queryLog } from '@/service/modules/log'
+import { stateType } from '@/common/common'
+import { useUISettingStore } from '@/store/ui-setting/ui-setting'
+import Card from '@/components/card'
+import LogModal from '@/components/log-modal'
+
+const BatchTriggerInstance = defineComponent({
+ name: 'trigger-instance',
+ setup() {
+ const uiSettingStore = useUISettingStore()
+ const logTimer = uiSettingStore.getLogTimer
+ const { t, variables, getTableData, createColumns } = useTable()
+
+ const requestTableData = () => {
+ getTableData({
+ pageSize: variables.pageSize,
+ pageNo: variables.page,
+ searchVal: variables.searchVal,
+ taskCode: variables.taskCode,
+ processInstanceId: variables.processInstanceId,
+ host: variables.host,
+ stateType: variables.stateType,
+ datePickerRange: variables.datePickerRange,
+ executorName: variables.executorName,
+ processInstanceName: variables.processInstanceName
+ })
+ }
+
+ const onUpdatePageSize = () => {
+ variables.page = 1
+ requestTableData()
+ }
+
+ const onSearch = () => {
+ variables.page = 1
+ requestTableData()
+ }
+
+ const onClearSearchTaskCode = () => {
+ variables.taskCode = null
+ onSearch()
+ }
+
+ const onClearSearchTaskName = () => {
+ variables.searchVal = ''
+ onSearch()
+ }
+
+ const onClearSearchProcessInstanceName = () => {
+ variables.processInstanceName = null
+ onSearch()
+ }
+
+ const onClearSearchExecutorName = () => {
+ variables.executorName = null
+ onSearch()
+ }
+
+ const onClearSearchHost = () => {
+ variables.host = null
+ onSearch()
+ }
+
+ const onClearSearchStateType = () => {
+ variables.stateType = null
+ onSearch()
+ }
+
+ const onClearSearchTime = () => {
+ variables.datePickerRange = null
+ onSearch()
+ }
+
+ const onConfirmModal = () => {
+ variables.showModalRef = false
+ }
+
+ let getLogsID: number
+
+ const getLogs = (row: any, logTimer: number) => {
+ const { state } = useAsyncState(
+ queryLog({
+ taskInstanceId: Number(row.id),
+ limit: variables.limit,
+ skipLineNum: variables.skipLineNum
+ }).then((res: any) => {
+ variables.logRef += res.message || ''
+ if (res && res.message !== '') {
+ variables.limit += 1000
+ variables.skipLineNum += res.lineNum
+ getLogs(row, logTimer)
+ } else {
+ variables.logLoadingRef = false
+ if (logTimer !== 0) {
+ if (typeof getLogsID === 'number') {
+ clearTimeout(getLogsID)
+ }
+ getLogsID = setTimeout(() => {
+ variables.logRef = ''
+ variables.limit = 1000
+ variables.skipLineNum = 0
+ variables.logLoadingRef = true
+ getLogs(row, logTimer)
+ }, logTimer * 1000)
+ }
+ }
+ }),
+ {}
+ )
+
+ return state
+ }
+
+ const refreshLogs = (row: any) => {
+ variables.logRef = ''
+ variables.limit = 1000
+ variables.skipLineNum = 0
+ getLogs(row, logTimer)
+ }
+
+ const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
+
+ onMounted(() => {
+ createColumns(variables)
+ requestTableData()
+ })
+
+ watch(useI18n().locale, () => {
+ createColumns(variables)
+ })
+
+ watch(
+ () => variables.showModalRef,
+ () => {
+ if (variables.showModalRef) {
+ getLogs(variables.row, logTimer)
+ } else {
+ variables.row = {}
+ variables.logRef = ''
+ variables.logLoadingRef = true
+ variables.skipLineNum = 0
+ variables.limit = 1000
+ }
+ }
+ )
+
+ return {
+ t,
+ ...toRefs(variables),
+ requestTableData,
+ onUpdatePageSize,
+ onSearch,
+ onClearSearchTaskCode,
+ onClearSearchTaskName,
+ onClearSearchProcessInstanceName,
+ onClearSearchExecutorName,
+ onClearSearchHost,
+ onClearSearchStateType,
+ onClearSearchTime,
+ onConfirmModal,
+ refreshLogs,
+ trim
+ }
+ },
+ render() {
+ const {
+ t,
+ requestTableData,
+ onUpdatePageSize,
+ onSearch,
+ onConfirmModal,
+ loadingRef,
+ refreshLogs
+ } = this
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+})
+
+export default BatchTriggerInstance
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/instance/types.ts b/dolphinscheduler-ui/src/views/projects/trigger/instance/types.ts
new file mode 100644
index 0000000000..af4dfa8061
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/instance/types.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 { ITaskState } from '@/common/types'
+
+export type { Router } from 'vue-router'
+export type { TaskInstancesRes } from '@/service/modules/task-instances/types'
+
+interface IRecord {
+ name: string
+ processInstanceName: string
+ executorName: string
+ taskType: string
+ state: ITaskState
+ submitTime: string
+ startTime: string
+ endTime: string
+ duration?: string
+ retryTimes: number
+ dryRun: number
+ host: string
+ appLink: string
+ testFlag?: number
+}
+
+export { ITaskState, IRecord }
diff --git a/dolphinscheduler-ui/src/views/projects/trigger/instance/use-table.ts b/dolphinscheduler-ui/src/views/projects/trigger/instance/use-table.ts
new file mode 100644
index 0000000000..dd8c944af0
--- /dev/null
+++ b/dolphinscheduler-ui/src/views/projects/trigger/instance/use-table.ts
@@ -0,0 +1,377 @@
+/*
+ * 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 { useI18n } from 'vue-i18n'
+import { h, reactive, ref } from 'vue'
+import { useAsyncState } from '@vueuse/core'
+import {
+ queryTaskListPaging,
+ forceSuccess,
+ downloadLog
+} from '@/service/modules/task-instances'
+import { NButton, NIcon, NSpace, NTooltip, NSpin, NEllipsis } from 'naive-ui'
+import ButtonLink from '@/components/button-link'
+import {
+ AlignLeftOutlined,
+ CheckCircleOutlined,
+ DownloadOutlined
+} from '@vicons/antd'
+import { format } from 'date-fns'
+import { useRoute, useRouter } from 'vue-router'
+import { parseTime, renderTableTime, tasksState } from '@/common/common'
+import {
+ COLUMN_WIDTH_CONFIG,
+ calculateTableWidth,
+ DefaultTableWidth
+} from '@/common/column-width-config'
+import type { Router, TaskInstancesRes, IRecord, ITaskState } from './types'
+
+export function useTable() {
+ const { t } = useI18n()
+ const route = useRoute()
+ const router: Router = useRouter()
+
+ const projectCode = Number(route.params.projectCode)
+ const processInstanceId = Number(route.query.processInstanceId)
+ const taskName = route.query.taskName
+ const taskCode = route.query.taskCode
+
+ const variables = reactive({
+ columns: [],
+ tableWidth: DefaultTableWidth,
+ tableData: [] as IRecord[],
+ page: ref(1),
+ pageSize: ref(10),
+ searchVal: ref(taskName || null),
+ taskCode: ref(taskCode || null),
+ processInstanceId: ref(processInstanceId ? processInstanceId : null),
+ host: ref(null),
+ stateType: ref(null),
+ datePickerRange: ref(null),
+ executorName: ref(null),
+ processInstanceName: ref(null),
+ totalPage: ref(1),
+ showModalRef: ref(false),
+ row: {},
+ loadingRef: ref(false),
+ logRef: '',
+ logLoadingRef: ref(true),
+ skipLineNum: ref(0),
+ limit: ref(1000)
+ })
+
+ const createColumns = (variables: any) => {
+ variables.columns = [
+ {
+ title: '#',
+ key: 'index',
+ render: (row: any, index: number) => index + 1,
+ ...COLUMN_WIDTH_CONFIG['index']
+ },
+ {
+ title: t('project.task.task_name'),
+ key: 'name',
+ ...COLUMN_WIDTH_CONFIG['name'],
+ resizable: true,
+ minWidth: 200,
+ maxWidth: 600
+ },
+ {
+ title: t('project.task.workflow_instance'),
+ key: 'processInstanceName',
+ ...COLUMN_WIDTH_CONFIG['linkName'],
+ resizable: true,
+ minWidth: 300,
+ maxWidth: 600,
+ render: (row: {
+ processInstanceId: number
+ processInstanceName: string
+ }) =>
+ h(
+ ButtonLink,
+ {
+ onClick: () => {
+ const routeUrl = router.resolve({
+ name: 'workflow-instance-detail',
+ params: { id: row.processInstanceId },
+ query: { code: projectCode }
+ })
+ window.open(routeUrl.href, '_blank')
+ }
+ },
+ {
+ default: () =>
+ h(
+ NEllipsis,
+ {
+ style: 'max-width: 580px;line-height: 1.5'
+ },
+ () => row.processInstanceName
+ )
+ }
+ )
+ },
+ {
+ title: t('project.task.executor'),
+ key: 'executorName',
+ ...COLUMN_WIDTH_CONFIG['name']
+ },
+ {
+ title: t('project.task.node_type'),
+ key: 'taskType',
+ ...COLUMN_WIDTH_CONFIG['type']
+ },
+ {
+ title: t('project.task.state'),
+ key: 'state',
+ ...COLUMN_WIDTH_CONFIG['state'],
+ render: (row: IRecord) => renderStateCell(row.state, t)
+ },
+ {
+ title: t('project.task.submit_time'),
+ ...COLUMN_WIDTH_CONFIG['time'],
+ key: 'submitTime',
+ render: (row: IRecord) => renderTableTime(row.submitTime)
+ },
+ {
+ title: t('project.task.start_time'),
+ ...COLUMN_WIDTH_CONFIG['time'],
+ key: 'startTime',
+ render: (row: IRecord) => renderTableTime(row.startTime)
+ },
+ {
+ title: t('project.task.end_time'),
+ ...COLUMN_WIDTH_CONFIG['time'],
+ key: 'endTime',
+ render: (row: IRecord) => renderTableTime(row.endTime)
+ },
+ {
+ title: t('project.task.duration'),
+ key: 'duration',
+ ...COLUMN_WIDTH_CONFIG['duration'],
+ render: (row: any) => h('span', null, row.duration ? row.duration : '-')
+ },
+ {
+ title: t('project.task.retry_count'),
+ key: 'retryTimes',
+ ...COLUMN_WIDTH_CONFIG['times']
+ },
+ {
+ title: t('project.task.dry_run_flag'),
+ key: 'dryRun',
+ ...COLUMN_WIDTH_CONFIG['dryRun'],
+ render: (row: IRecord) => (row.dryRun === 1 ? 'YES' : 'NO')
+ },
+ {
+ title: t('project.task.host'),
+ key: 'host',
+ ...COLUMN_WIDTH_CONFIG['name'],
+ render: (row: IRecord) => row.host || '-'
+ },
+ {
+ title: t('project.task.app_link'),
+ key: 'appLink',
+ ...COLUMN_WIDTH_CONFIG['name'],
+ render: (row: IRecord) => row.appLink || '-'
+ },
+ {
+ title: t('project.task.operation'),
+ key: 'operation',
+ ...COLUMN_WIDTH_CONFIG['operation'](3),
+ render(row: any) {
+ return h(NSpace, null, {
+ default: () => [
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ tag: 'div',
+ circle: true,
+ type: 'info',
+ size: 'small',
+ disabled: !(
+ row.state === 'FAILURE' ||
+ row.state === 'NEED_FAULT_TOLERANCE' ||
+ row.state === 'KILL'
+ ),
+ onClick: () => {
+ handleForcedSuccess(row)
+ }
+ },
+ {
+ icon: () =>
+ h(NIcon, null, {
+ default: () => h(CheckCircleOutlined)
+ })
+ }
+ ),
+ default: () => t('project.task.forced_success')
+ }
+ ),
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'info',
+ size: 'small',
+ disabled: !row.host,
+ onClick: () => handleLog(row)
+ },
+ {
+ icon: () =>
+ h(NIcon, null, {
+ default: () => h(AlignLeftOutlined)
+ })
+ }
+ ),
+ default: () => t('project.task.view_log')
+ }
+ ),
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'info',
+ size: 'small',
+ disabled: !row.host,
+ onClick: () => downloadLog(row.id)
+ },
+ {
+ icon: () =>
+ h(NIcon, null, { default: () => h(DownloadOutlined) })
+ }
+ ),
+ default: () => t('project.task.download_log')
+ }
+ )
+ ]
+ })
+ }
+ }
+ ]
+ if (variables.tableWidth) {
+ variables.tableWidth = calculateTableWidth(variables.columns)
+ }
+ }
+
+ const handleLog = (row: any) => {
+ variables.showModalRef = true
+ variables.row = row
+ }
+
+ const handleForcedSuccess = (row: any) => {
+ forceSuccess({ id: row.id }, { projectCode }).then(() => {
+ getTableData({
+ pageSize: variables.pageSize,
+ pageNo:
+ variables.tableData.length === 1 && variables.page > 1
+ ? variables.page - 1
+ : variables.page,
+ searchVal: variables.searchVal,
+ taskCode: variables.taskCode,
+ processInstanceId: variables.processInstanceId,
+ host: variables.host,
+ stateType: variables.stateType,
+ datePickerRange: variables.datePickerRange,
+ executorName: variables.executorName,
+ processInstanceName: variables.processInstanceName
+ })
+ })
+ }
+
+ const getTableData = (params: any) => {
+ if (variables.loadingRef) return
+ variables.loadingRef = true
+ const data = {
+ pageSize: params.pageSize,
+ pageNo: params.pageNo,
+ searchVal: params.searchVal,
+ taskCode: params.taskCode,
+ processInstanceId: params.processInstanceId,
+ host: params.host,
+ stateType: params.stateType,
+ startDate: params.datePickerRange
+ ? format(parseTime(params.datePickerRange[0]), 'yyyy-MM-dd HH:mm:ss')
+ : '',
+ endDate: params.datePickerRange
+ ? format(parseTime(params.datePickerRange[1]), 'yyyy-MM-dd HH:mm:ss')
+ : '',
+ executorName: params.executorName,
+ processInstanceName: params.processInstanceName
+ }
+
+ const { state } = useAsyncState(
+ queryTaskListPaging(data, { projectCode }).then(
+ (res: TaskInstancesRes) => {
+ variables.tableData = res.totalList as IRecord[]
+ variables.totalPage = res.totalPage
+ variables.loadingRef = false
+ }
+ ),
+ {}
+ )
+
+ return state
+ }
+
+ return {
+ t,
+ variables,
+ getTableData,
+ createColumns
+ }
+}
+
+export function renderStateCell(state: ITaskState, t: Function) {
+ if (!state) return ''
+
+ const stateOption = tasksState(t)[state]
+
+ const Icon = h(
+ NIcon,
+ {
+ color: stateOption.color,
+ class: stateOption.classNames,
+ style: {
+ display: 'flex'
+ },
+ size: 20
+ },
+ () => h(stateOption.icon)
+ )
+ return h(NTooltip, null, {
+ trigger: () => {
+ if (!stateOption.isSpin) return Icon
+ return h(NSpin, { size: 20 }, { icon: () => Icon })
+ },
+ default: () => stateOption.desc
+ })
+}
diff --git a/dolphinscheduler-ui/src/views/projects/workflow/definition/components/table-action.tsx b/dolphinscheduler-ui/src/views/projects/workflow/definition/components/table-action.tsx
index 61499a898c..4092d3df05 100644
--- a/dolphinscheduler-ui/src/views/projects/workflow/definition/components/table-action.tsx
+++ b/dolphinscheduler-ui/src/views/projects/workflow/definition/components/table-action.tsx
@@ -160,6 +160,27 @@ export default defineComponent({
)
}}
+
+ {{
+ default: () => t('project.workflow.trigger'),
+ trigger: () => (
+
+
+
+
+
+ )
+ }}
+
{{
default: () =>
diff --git a/dolphinscheduler-worker/pom.xml b/dolphinscheduler-worker/pom.xml
index a6f39ca15e..87d7ca2432 100644
--- a/dolphinscheduler-worker/pom.xml
+++ b/dolphinscheduler-worker/pom.xml
@@ -61,6 +61,11 @@
dolphinscheduler-task-all
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-all
+
+
org.apache.dolphinscheduler
dolphinscheduler-storage-all
diff --git a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java
index 797d8f78a3..c8e8d9ab04 100644
--- a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java
+++ b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java
@@ -31,6 +31,7 @@ import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager;
import org.apache.dolphinscheduler.plugin.task.api.utils.LogUtils;
import org.apache.dolphinscheduler.plugin.task.api.utils.ProcessUtils;
+import org.apache.dolphinscheduler.plugin.trigger.api.TriggerPluginManager;
import org.apache.dolphinscheduler.registry.api.RegistryConfiguration;
import org.apache.dolphinscheduler.server.worker.message.MessageRetryRunner;
import org.apache.dolphinscheduler.server.worker.metrics.WorkerServerMetrics;
@@ -87,6 +88,7 @@ public class WorkerServer implements IStoppable {
public void run() {
this.workerRpcServer.start();
TaskPluginManager.loadPlugin();
+ TriggerPluginManager.loadPlugin();
DataSourceProcessorProvider.initialize();
this.workerRegistryClient.setRegistryStoppable(this);
diff --git a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TenantUtils.java b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TenantUtils.java
index 0b0bba7484..ccc5219bcc 100644
--- a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TenantUtils.java
+++ b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/utils/TenantUtils.java
@@ -56,7 +56,8 @@ public class TenantUtils {
String tenantCode = taskExecutionContext.getTenantCode();
if (isDefaultTenant(tenantCode)) {
- if (tenantConfig.isDefaultTenantEnabled()) {
+// if (tenantConfig.isDefaultTenantEnabled()) {
+ if (true) {
log.info("Current tenant is default tenant, will use bootstrap user: {} to execute the task",
getBootstrapTenant());
return getBootstrapTenant();
diff --git a/dolphinscheduler-worker/src/main/resources/application.yaml b/dolphinscheduler-worker/src/main/resources/application.yaml
index a4a7476984..03e73448a6 100644
--- a/dolphinscheduler-worker/src/main/resources/application.yaml
+++ b/dolphinscheduler-worker/src/main/resources/application.yaml
@@ -25,18 +25,16 @@ spring:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
registry:
- type: zookeeper
- zookeeper:
- namespace: dolphinscheduler
- connect-string: localhost:2181
- retry-policy:
- base-sleep-time: 60ms
- max-sleep: 300ms
- max-retries: 5
- session-timeout: 30s
- connection-timeout: 9s
- block-until-connected: 600ms
- digest: ~
+ type: jdbc
+ term-refresh-interval: 2s
+ term-expire-times: 3
+ hikari-config:
+ jdbc-url: jdbc:postgresql://localhost:5432/dolphinscheduler
+ username: root
+ password: root
+ maximum-pool-size: 5
+ connection-timeout: 9000
+ idle-timeout: 600000
worker:
# worker listener port
diff --git a/dolphinscheduler-worker/src/main/resources/logback-spring.xml b/dolphinscheduler-worker/src/main/resources/logback-spring.xml
index b272315f2f..7f502f29bd 100644
--- a/dolphinscheduler-worker/src/main/resources/logback-spring.xml
+++ b/dolphinscheduler-worker/src/main/resources/logback-spring.xml
@@ -67,13 +67,9 @@
-
-
-
-
-
-
+
+
-
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index aeadd3adc0..a452ecfc6e 100755
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,7 @@
dolphinscheduler-extract
dolphinscheduler-dao-plugin
dolphinscheduler-authentication
+ dolphinscheduler-trigger-plugin
@@ -234,6 +235,17 @@
${project.version}
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-api
+ ${project.version}
+
+
+ org.apache.dolphinscheduler
+ dolphinscheduler-trigger-all
+ ${project.version}
+
+
org.apache.dolphinscheduler
dolphinscheduler-storage-api