Browse Source

[Feature][UI] Support to view and manage all timing settings of a project. (#14178)

3.2.0-release
calvin 2 years ago committed by GitHub
parent
commit
4c2e57cfb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java
  2. 16
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
  3. 14
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.java
  4. 19
      dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.xml
  5. 38
      dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/ScheduleMapperTest.java
  6. 2
      dolphinscheduler-ui/src/common/column-width-config.ts
  7. 7
      dolphinscheduler-ui/src/common/common.ts
  8. 19
      dolphinscheduler-ui/src/components/input-search/index.tsx
  9. 8
      dolphinscheduler-ui/src/layouts/content/components/navbar/index.tsx
  10. 4
      dolphinscheduler-ui/src/layouts/content/components/sidebar/use-menuClick.ts
  11. 21
      dolphinscheduler-ui/src/layouts/content/use-dataList.ts
  12. 12
      dolphinscheduler-ui/src/locales/en_US/datasource.ts
  13. 2
      dolphinscheduler-ui/src/locales/en_US/input-search.ts
  14. 3
      dolphinscheduler-ui/src/locales/en_US/menu.ts
  15. 3
      dolphinscheduler-ui/src/locales/en_US/project.ts
  16. 2
      dolphinscheduler-ui/src/locales/en_US/resource.ts
  17. 2
      dolphinscheduler-ui/src/locales/en_US/security.ts
  18. 12
      dolphinscheduler-ui/src/locales/zh_CN/datasource.ts
  19. 2
      dolphinscheduler-ui/src/locales/zh_CN/input-search.ts
  20. 1
      dolphinscheduler-ui/src/locales/zh_CN/menu.ts
  21. 1
      dolphinscheduler-ui/src/locales/zh_CN/project.ts
  22. 2
      dolphinscheduler-ui/src/locales/zh_CN/security.ts
  23. 11
      dolphinscheduler-ui/src/router/modules/projects.ts
  24. 34
      dolphinscheduler-ui/src/service/modules/data-source/types.ts
  25. 6
      dolphinscheduler-ui/src/service/modules/process-definition/index.ts
  26. 1
      dolphinscheduler-ui/src/service/modules/process-instances/index.ts
  27. 12
      dolphinscheduler-ui/src/service/modules/projects/index.ts
  28. 49
      dolphinscheduler-ui/src/service/modules/resources/index.ts
  29. 2
      dolphinscheduler-ui/src/service/modules/resources/types.ts
  30. 2
      dolphinscheduler-ui/src/service/modules/schedules/types.ts
  31. 5
      dolphinscheduler-ui/src/service/modules/task-instances/index.ts
  32. 47
      dolphinscheduler-ui/src/utils/environmental-distinction.ts
  33. 7
      dolphinscheduler-ui/src/utils/tree-format.ts
  34. 8
      dolphinscheduler-ui/src/views/data-quality/rule/index.tsx
  35. 6
      dolphinscheduler-ui/src/views/data-quality/task-result/index.tsx
  36. 126
      dolphinscheduler-ui/src/views/datasource/list/detail.tsx
  37. 5
      dolphinscheduler-ui/src/views/datasource/list/use-columns.ts
  38. 48
      dolphinscheduler-ui/src/views/datasource/list/use-form.ts
  39. 2
      dolphinscheduler-ui/src/views/datasource/list/use-table.ts
  40. 36
      dolphinscheduler-ui/src/views/login/index.tsx
  41. 2
      dolphinscheduler-ui/src/views/login/use-login.ts
  42. 4
      dolphinscheduler-ui/src/views/profile/use-form.ts
  43. 18
      dolphinscheduler-ui/src/views/projects/list/index.tsx
  44. 2
      dolphinscheduler-ui/src/views/projects/list/use-table.ts
  45. 14
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-cache.ts
  46. 108
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-custom-labels.ts
  47. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasource.ts
  48. 115
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasync.ts
  49. 466
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datax.ts
  50. 4
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-dependent-timeout.ts
  51. 7
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-dms.ts
  52. 6
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-environment-name.ts
  53. 3
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-flink.ts
  54. 14
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-hive-cli.ts
  55. 4
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-linkis.ts
  56. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-namespace.ts
  57. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts
  58. 32
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-sea-tunnel.ts
  59. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-zeppelin.ts
  60. 14
      dolphinscheduler-ui/src/views/projects/task/components/node/format-data.ts
  61. 110
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-datasync.ts
  62. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-dms.ts
  63. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-linkis.ts
  64. 46
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-sea-tunnel.ts
  65. 6
      dolphinscheduler-ui/src/views/projects/task/components/node/types.ts
  66. 14
      dolphinscheduler-ui/src/views/projects/task/definition/use-table.ts
  67. 2
      dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx
  68. 1
      dolphinscheduler-ui/src/views/projects/task/instance/index.tsx
  69. 28
      dolphinscheduler-ui/src/views/projects/task/instance/use-table.ts
  70. 2
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-config.ts
  71. 79
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-context-menu.tsx
  72. 51
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-sidebar.tsx
  73. 58
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-toolbar.tsx
  74. 37
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/index.tsx
  75. 16
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-canvas-init.ts
  76. 21
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/dag-canvas.tsx
  77. 20
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/dag-sidebar.tsx
  78. 16
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/index.tsx
  79. 79
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/index.tsx
  80. 7
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-form-field.ts
  81. 2
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-form-request.ts
  82. 4
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-task-form.ts
  83. 5
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/use-sidebar.ts
  84. 2
      dolphinscheduler-ui/src/views/projects/workflow/definition/components/use-modal.ts
  85. 8
      dolphinscheduler-ui/src/views/projects/workflow/definition/create/index.tsx
  86. 10
      dolphinscheduler-ui/src/views/projects/workflow/definition/index.tsx
  87. 4
      dolphinscheduler-ui/src/views/projects/workflow/definition/timing/index.tsx
  88. 2
      dolphinscheduler-ui/src/views/projects/workflow/definition/timing/types.ts
  89. 59
      dolphinscheduler-ui/src/views/projects/workflow/definition/timing/use-table.ts
  90. 2
      dolphinscheduler-ui/src/views/projects/workflow/definition/use-table.ts
  91. 19
      dolphinscheduler-ui/src/views/projects/workflow/instance/components/variables-view.tsx
  92. 2
      dolphinscheduler-ui/src/views/projects/workflow/instance/use-table.ts
  93. 17
      dolphinscheduler-ui/src/views/projects/workflow/relation/index.tsx
  94. 87
      dolphinscheduler-ui/src/views/projects/workflow/timing/components/timing-condition.tsx
  95. 116
      dolphinscheduler-ui/src/views/projects/workflow/timing/index.tsx
  96. 22
      dolphinscheduler-ui/src/views/projects/workflow/timing/types.ts
  97. 2
      dolphinscheduler-ui/src/views/resource/components/resource/create/use-form.ts
  98. 4
      dolphinscheduler-ui/src/views/resource/components/resource/edit/index.tsx
  99. 17
      dolphinscheduler-ui/src/views/resource/components/resource/edit/use-edit.ts
  100. 2
      dolphinscheduler-ui/src/views/resource/components/resource/folder/index.tsx
  101. Some files were not shown because too many files have changed in this diff Show More

2
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/SchedulerController.java

@ -250,7 +250,7 @@ public class SchedulerController extends BaseController {
@AccessLogAnnotation(ignoreRequestArgs = "loginUser") @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result queryScheduleListPaging(@Parameter(hidden = true) @RequestAttribute(value = SESSION_USER) User loginUser, public Result queryScheduleListPaging(@Parameter(hidden = true) @RequestAttribute(value = SESSION_USER) User loginUser,
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode, @Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
@RequestParam long processDefinitionCode, @RequestParam(value = "processDefinitionCode", required = false, defaultValue = "0") long processDefinitionCode,
@RequestParam(value = "searchVal", required = false) String searchVal, @RequestParam(value = "searchVal", required = false) String searchVal,
@RequestParam("pageNo") Integer pageNo, @RequestParam("pageNo") Integer pageNo,
@RequestParam("pageSize") Integer pageSize) { @RequestParam("pageSize") Integer pageSize) {

16
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java

@ -568,16 +568,20 @@ public class SchedulerServiceImpl extends BaseServiceImpl implements SchedulerSe
return result; return result;
} }
ProcessDefinition processDefinition = processDefinitionMapper.queryByCode(processDefineCode); if (processDefineCode != 0) {
if (processDefinition == null || projectCode != processDefinition.getProjectCode()) { ProcessDefinition processDefinition = processDefinitionMapper.queryByCode(processDefineCode);
log.error("Process definition does not exist, processDefinitionCode:{}.", processDefineCode); if (processDefinition == null || projectCode != processDefinition.getProjectCode()) {
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, String.valueOf(processDefineCode)); log.error("Process definition does not exist, processDefinitionCode:{}.", processDefineCode);
return result; putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, String.valueOf(processDefineCode));
return result;
}
} }
Page<Schedule> page = new Page<>(pageNo, pageSize); Page<Schedule> page = new Page<>(pageNo, pageSize);
IPage<Schedule> schedulePage = IPage<Schedule> schedulePage =
scheduleMapper.queryByProcessDefineCodePaging(page, processDefineCode, searchVal); scheduleMapper.queryByProjectAndProcessDefineCodePaging(page, projectCode, processDefineCode,
searchVal);
List<ScheduleVo> scheduleList = new ArrayList<>(); List<ScheduleVo> scheduleList = new ArrayList<>();
for (Schedule schedule : schedulePage.getRecords()) { for (Schedule schedule : schedulePage.getRecords()) {

14
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.java

@ -63,6 +63,20 @@ public interface ScheduleMapper extends BaseMapper<Schedule> {
@Param("processDefinitionCode") long processDefinitionCode, @Param("processDefinitionCode") long processDefinitionCode,
@Param("searchVal") String searchVal); @Param("searchVal") String searchVal);
/**
* scheduler page
*
* @param page page
* @param projectCode projectCode
* @param processDefinitionCode processDefinitionCode
* @param searchVal searchVal
* @return scheduler IPage
*/
IPage<Schedule> queryByProjectAndProcessDefineCodePaging(IPage<Schedule> page,
@Param("projectCode") long projectCode,
@Param("processDefinitionCode") long processDefinitionCode,
@Param("searchVal") String searchVal);
/** /**
* Filter schedule * Filter schedule
* *

19
dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ScheduleMapper.xml

@ -44,6 +44,25 @@
</if> </if>
order by s.update_time desc order by s.update_time desc
</select> </select>
<select id="queryByProjectAndProcessDefineCodePaging" resultType="org.apache.dolphinscheduler.dao.entity.Schedule">
select p_f.name as process_definition_name, p.name as project_name,u.user_name,e.name as environment_name,
<include refid="baseSqlV2">
<property name="alias" value="s"/>
</include>
from t_ds_schedules s
join t_ds_process_definition p_f on s.process_definition_code = p_f.code
join t_ds_project as p on p_f.project_code = p.code
join t_ds_user as u on s.user_id = u.id
left join t_ds_environment as e on s.environment_code = e.code
where 1=1
<if test="projectCode != 0">
and p.code = #{projectCode}
</if>
<if test="processDefinitionCode != 0">
and s.process_definition_code = #{processDefinitionCode}
</if>
order by s.update_time desc
</select>
<select id="querySchedulerListByProjectName" resultType="org.apache.dolphinscheduler.dao.entity.Schedule"> <select id="querySchedulerListByProjectName" resultType="org.apache.dolphinscheduler.dao.entity.Schedule">
select p_f.name as process_definition_name, p_f.description as definition_description, p.name as project_name,u.user_name, s.* select p_f.name as process_definition_name, p_f.description as definition_description, p.name as project_name,u.user_name, s.*
from t_ds_schedules s from t_ds_schedules s

38
dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/ScheduleMapperTest.java

@ -141,6 +141,44 @@ public class ScheduleMapperTest extends BaseDaoTest {
Assertions.assertNotEquals(scheduleIPage.getSize(), 0); Assertions.assertNotEquals(scheduleIPage.getSize(), 0);
} }
/**
* test page
*/
@Test
public void testQueryByProjectAndProcessDefineIdPaging() {
User user = new User();
user.setUserName("ut name");
userMapper.insert(user);
Project project = new Project();
project.setName("ut project");
project.setUserId(user.getId());
project.setCode(1L);
project.setUpdateTime(new Date());
project.setCreateTime(new Date());
projectMapper.insert(project);
ProcessDefinition processDefinition = new ProcessDefinition();
processDefinition.setCode(1L);
processDefinition.setProjectCode(project.getCode());
processDefinition.setUserId(user.getId());
processDefinition.setLocations("");
processDefinition.setCreateTime(new Date());
processDefinition.setUpdateTime(new Date());
processDefinitionMapper.insert(processDefinition);
Schedule schedule = insertOne();
schedule.setUserId(user.getId());
schedule.setProcessDefinitionCode(processDefinition.getCode());
scheduleMapper.updateById(schedule);
Page<Schedule> page = new Page(1, 3);
IPage<Schedule> scheduleIPage = scheduleMapper.queryByProjectAndProcessDefineCodePaging(page, project.getCode(),
processDefinition.getCode(), "");
Assertions.assertNotEquals(scheduleIPage.getSize(), 0);
}
/** /**
* test query schedule list by project name * test query schedule list by project name
*/ */

2
dolphinscheduler-ui/src/common/column-width-config.ts

@ -98,7 +98,7 @@ export const COLUMN_WIDTH_CONFIG = {
tag: { tag: {
width: 160 width: 160
}, },
checkbox:{ checkbox: {
width: 20 width: 20
}, },
copy: { copy: {

7
dolphinscheduler-ui/src/common/common.ts

@ -154,7 +154,6 @@ export const workflowExecutionStateType = (t: any) => [
})) }))
] ]
/** /**
* Stream task state * Stream task state
*/ */
@ -271,7 +270,7 @@ export const tasksState = (t: any): ITaskStateConfig => ({
icon: SendOutlined, icon: SendOutlined,
isSpin: false, isSpin: false,
classNames: 'dispatch' classNames: 'dispatch'
}, }
}) })
/** /**
@ -282,7 +281,9 @@ export const tasksState = (t: any): ITaskStateConfig => ({
* @icon icon * @icon icon
* @isSpin is loading (Need to execute the code block to write if judgment) * @isSpin is loading (Need to execute the code block to write if judgment)
*/ */
export const workflowExecutionState = (t: any): IWorkflowExecutionStateConfig => ({ export const workflowExecutionState = (
t: any
): IWorkflowExecutionStateConfig => ({
SUBMITTED_SUCCESS: { SUBMITTED_SUCCESS: {
id: 0, id: 0,
desc: `${t('project.workflow.submit_success')}`, desc: `${t('project.workflow.submit_success')}`,

19
dolphinscheduler-ui/src/components/input-search/index.tsx

@ -28,8 +28,8 @@ const props = {
const Search = defineComponent({ const Search = defineComponent({
name: 'Search', name: 'Search',
emits: ['search','clear'],
props: props, props: props,
emits: ['search', 'clear'],
setup(props, ctx) { setup(props, ctx) {
const { t } = useI18n() const { t } = useI18n()
@ -40,14 +40,15 @@ const Search = defineComponent({
ctx.emit('clear', (ev.target as HTMLInputElement)?.value || '') ctx.emit('clear', (ev.target as HTMLInputElement)?.value || '')
} }
return () => ( return () => (
<NInput
<NInput size='small'
size='small' clearable
clearable placeholder={
placeholder = {props.placeholder?props.placeholder:t('input_search.placeholder')} props.placeholder ? props.placeholder : t('input_search.placeholder')
onKeydown={withKeys(onKeyDown, ['enter'])} }
onClear = {onClear} onKeydown={withKeys(onKeyDown, ['enter'])}
/> onClear={onClear}
/>
) )
} }
}) })

8
dolphinscheduler-ui/src/layouts/content/components/navbar/index.tsx

@ -85,9 +85,11 @@ const Navbar = defineComponent({
<div class={styles.settings}> <div class={styles.settings}>
<NButton quaternary onClick={this.handleUISettingClick}> <NButton quaternary onClick={this.handleUISettingClick}>
{{ {{
icon: () => <NIcon size='16'> icon: () => (
<SettingOutlined /> <NIcon size='16'>
</NIcon>, <SettingOutlined />
</NIcon>
),
default: this.t('menu.ui_setting') default: this.t('menu.ui_setting')
}} }}
</NButton> </NButton>

4
dolphinscheduler-ui/src/layouts/content/components/sidebar/use-menuClick.ts

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import {LocationQueryRaw, useRouter} from 'vue-router' import { LocationQueryRaw, useRouter } from 'vue-router'
import type { Router } from 'vue-router' import type { Router } from 'vue-router'
import { MenuOption } from 'naive-ui' import { MenuOption } from 'naive-ui'
@ -25,7 +25,7 @@ export function useMenuClick() {
const handleMenuClick = (key: string, menuOption: MenuOption) => { const handleMenuClick = (key: string, menuOption: MenuOption) => {
router.push({ router.push({
path: `${key}`, path: `${key}`,
query: menuOption.payload? menuOption.payload as LocationQueryRaw: {} query: menuOption.payload ? (menuOption.payload as LocationQueryRaw) : {}
}) })
} }

21
dolphinscheduler-ui/src/layouts/content/use-dataList.ts

@ -102,10 +102,12 @@ export function useDataList() {
icon: renderIcon(ProfileOutlined), icon: renderIcon(ProfileOutlined),
children: [ children: [
{ {
label: t('menu.project_overview') + (projectName? `[${projectName}]` : ''), label:
t('menu.project_overview') +
(projectName ? `[${projectName}]` : ''),
key: `/projects/${projectCode}`, key: `/projects/${projectCode}`,
icon: renderIcon(FundProjectionScreenOutlined), icon: renderIcon(FundProjectionScreenOutlined),
payload: {projectName:projectName} payload: { projectName: projectName }
}, },
{ {
label: t('menu.workflow'), label: t('menu.workflow'),
@ -115,17 +117,22 @@ export function useDataList() {
{ {
label: t('menu.workflow_relation'), label: t('menu.workflow_relation'),
key: `/projects/${projectCode}/workflow/relation`, key: `/projects/${projectCode}/workflow/relation`,
payload: {projectName:projectName} payload: { projectName: projectName }
}, },
{ {
label: t('menu.workflow_definition'), label: t('menu.workflow_definition'),
key: `/projects/${projectCode}/workflow-definition`, key: `/projects/${projectCode}/workflow-definition`,
payload: {projectName:projectName} payload: { projectName: projectName }
}, },
{ {
label: t('menu.workflow_instance'), label: t('menu.workflow_instance'),
key: `/projects/${projectCode}/workflow/instances`, key: `/projects/${projectCode}/workflow/instances`,
payload: {projectName:projectName} payload: { projectName: projectName }
},
{
label: t('menu.workflow_timing'),
key: `/projects/${projectCode}/workflow/timings`,
payload: { projectName: projectName }
} }
] ]
}, },
@ -137,12 +144,12 @@ export function useDataList() {
{ {
label: t('menu.task_definition'), label: t('menu.task_definition'),
key: `/projects/${projectCode}/task/definitions`, key: `/projects/${projectCode}/task/definitions`,
payload: {projectName:projectName} payload: { projectName: projectName }
}, },
{ {
label: t('menu.task_instance'), label: t('menu.task_instance'),
key: `/projects/${projectCode}/task/instances`, key: `/projects/${projectCode}/task/instances`,
payload: {projectName:projectName} payload: { projectName: projectName }
} }
] ]
} }

12
dolphinscheduler-ui/src/locales/en_US/datasource.ts

@ -90,10 +90,10 @@ export default {
clientSecret: 'ClientSecret', clientSecret: 'ClientSecret',
OAuth_token_endpoint: 'OAuth 2.0 token endpoint', OAuth_token_endpoint: 'OAuth 2.0 token endpoint',
endpoint_tips: 'Please enter OAuth Token', endpoint_tips: 'Please enter OAuth Token',
AccessKeyID:'AccessKeyID', AccessKeyID: 'AccessKeyID',
AccessKeyID_tips:'Please input AccessKeyID', AccessKeyID_tips: 'Please input AccessKeyID',
SecretAccessKey:'SecretAccessKey', SecretAccessKey: 'SecretAccessKey',
SecretAccessKey_tips:'Please input SecretAccessKey', SecretAccessKey_tips: 'Please input SecretAccessKey',
dbUser:'DbUser', dbUser: 'DbUser',
dbUser_tips:'Please input DbUser', dbUser_tips: 'Please input DbUser'
} }

2
dolphinscheduler-ui/src/locales/en_US/input-search.ts

@ -16,5 +16,5 @@
*/ */
export default { export default {
placeholder: 'Please enter keyword' placeholder: 'Please enter keyword'
} }

3
dolphinscheduler-ui/src/locales/en_US/menu.ts

@ -27,6 +27,7 @@ export default {
workflow: 'Workflow', workflow: 'Workflow',
workflow_definition: 'Workflow Definition', workflow_definition: 'Workflow Definition',
workflow_instance: 'Workflow Instance', workflow_instance: 'Workflow Instance',
workflow_timing: 'Workflow Timing',
task: 'Task', task: 'Task',
task_instance: 'Task Instance', task_instance: 'Task Instance',
task_definition: 'Task Definition', task_definition: 'Task Definition',
@ -57,5 +58,5 @@ export default {
data_quality: 'Data Quality', data_quality: 'Data Quality',
task_result: 'Task Result', task_result: 'Task Result',
rule: 'Rule management', rule: 'Rule management',
ui_setting: 'UI Setting', ui_setting: 'UI Setting'
} }

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

@ -65,6 +65,7 @@ export default {
workflow_publish_status: 'Workflow Publish Status', workflow_publish_status: 'Workflow Publish Status',
schedule_publish_status: 'Schedule Publish Status', schedule_publish_status: 'Schedule Publish Status',
workflow_definition: 'Workflow Definition', workflow_definition: 'Workflow Definition',
workflow_timing: 'Workflow Timing',
workflow_instance: 'Workflow Instance', workflow_instance: 'Workflow Instance',
status: 'Status', status: 'Status',
create_time: 'Create Time', create_time: 'Create Time',
@ -82,7 +83,7 @@ export default {
copy_workflow: 'Copy Workflow', copy_workflow: 'Copy Workflow',
copy_workflow_name: 'Copy workflow name', copy_workflow_name: 'Copy workflow name',
visit_workflow_instances: 'Visit workflow instances', visit_workflow_instances: 'Visit workflow instances',
cron_manage: 'Cron manage', cron_manage: 'Timing Management',
delete: 'Delete', delete: 'Delete',
tree_view: 'Tree View', tree_view: 'Tree View',
tree_limit: 'Limit Size', tree_limit: 'Limit Size',

2
dolphinscheduler-ui/src/locales/en_US/resource.ts

@ -59,7 +59,7 @@ export default {
udf_resources: 'UDF resources', udf_resources: 'UDF resources',
upload_udf_resources: 'Upload UDF Resources', upload_udf_resources: 'Upload UDF Resources',
udf_source_name: 'UDF Resource Name', udf_source_name: 'UDF Resource Name',
user_name: 'Resource userName', user_name: 'Resource userName'
}, },
function: { function: {
udf_function: 'UDF Function', udf_function: 'UDF Function',

2
dolphinscheduler-ui/src/locales/en_US/security.ts

@ -152,7 +152,7 @@ export default {
namespace: 'Namespace', namespace: 'Namespace',
revoke_auth: 'Revoke', revoke_auth: 'Revoke',
grant_read: 'Grant Read', grant_read: 'Grant Read',
grant_all:'Grant All', grant_all: 'Grant All',
authorize_project: 'Project Authorize', authorize_project: 'Project Authorize',
authorize_resource: 'Resource Authorize', authorize_resource: 'Resource Authorize',
authorize_namespace: 'Namespace Authorize', authorize_namespace: 'Namespace Authorize',

12
dolphinscheduler-ui/src/locales/zh_CN/datasource.ts

@ -87,10 +87,10 @@ export default {
clientSecret: 'ClientSecret', clientSecret: 'ClientSecret',
OAuth_token_endpoint: 'OAuth 2.0 token endpoint', OAuth_token_endpoint: 'OAuth 2.0 token endpoint',
endpoint_tips: '请输入OAuth', endpoint_tips: '请输入OAuth',
AccessKeyID:'AccessKeyID', AccessKeyID: 'AccessKeyID',
AccessKeyID_tips:'请输入AccessKeyID', AccessKeyID_tips: '请输入AccessKeyID',
SecretAccessKey:'SecretAccessKey', SecretAccessKey: 'SecretAccessKey',
SecretAccessKey_tips:'请输入SecretAccessKey', SecretAccessKey_tips: '请输入SecretAccessKey',
dbUser:'DbUser', dbUser: 'DbUser',
dbUser_tips:'请输入DbUser', dbUser_tips: '请输入DbUser'
} }

2
dolphinscheduler-ui/src/locales/zh_CN/input-search.ts

@ -16,5 +16,5 @@
*/ */
export default { export default {
placeholder: '请输入关键词' placeholder: '请输入关键词'
} }

1
dolphinscheduler-ui/src/locales/zh_CN/menu.ts

@ -28,6 +28,7 @@ export default {
workflow: '工作流', workflow: '工作流',
workflow_definition: '工作流定义', workflow_definition: '工作流定义',
workflow_instance: '工作流实例', workflow_instance: '工作流实例',
workflow_timing: '工作流定时',
task: '任务', task: '任务',
task_instance: '任务实例', task_instance: '任务实例',
task_definition: '任务定义', task_definition: '任务定义',

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

@ -66,6 +66,7 @@ export default {
schedule_publish_status: '定时状态', schedule_publish_status: '定时状态',
workflow_definition: '工作流定义', workflow_definition: '工作流定义',
workflow_instance: '工作流实例', workflow_instance: '工作流实例',
workflow_timing: '工作流定时',
status: '状态', status: '状态',
create_time: '创建时间', create_time: '创建时间',
update_time: '更新时间', update_time: '更新时间',

2
dolphinscheduler-ui/src/locales/zh_CN/security.ts

@ -150,7 +150,7 @@ export default {
namespace: '命名空间', namespace: '命名空间',
revoke_auth: '撤销权限', revoke_auth: '撤销权限',
grant_read: '授予读权限', grant_read: '授予读权限',
grant_all:'授予所有权限', grant_all: '授予所有权限',
authorize_project: '项目授权', authorize_project: '项目授权',
authorize_resource: '资源授权', authorize_resource: '资源授权',
authorize_namespace: '命名空间授权', authorize_namespace: '命名空间授权',

11
dolphinscheduler-ui/src/router/modules/projects.ts

@ -111,6 +111,17 @@ export default {
auth: [] auth: []
} }
}, },
{
path: '/projects/:projectCode/workflow/timings',
name: 'workflow-timing-list',
component: components['projects-workflow-timing'],
meta: {
title: '工作流定时管理',
activeMenu: 'projects',
showSide: true,
auth: []
}
},
{ {
path: '/projects/:projectCode/workflow/instances', path: '/projects/:projectCode/workflow/instances',
name: 'workflow-instance-list', name: 'workflow-instance-list',

34
dolphinscheduler-ui/src/service/modules/data-source/types.ts

@ -37,23 +37,23 @@ type IDataBase =
| 'SNOWFLAKE' | 'SNOWFLAKE'
type IDataBaseLabel = type IDataBaseLabel =
| 'MYSQL' | 'MYSQL'
| 'POSTGRESQL' | 'POSTGRESQL'
| 'HIVE' | 'HIVE'
| 'SPARK' | 'SPARK'
| 'CLICKHOUSE' | 'CLICKHOUSE'
| 'ORACLE' | 'ORACLE'
| 'SQLSERVER' | 'SQLSERVER'
| 'DB2' | 'DB2'
| 'PRESTO' | 'PRESTO'
| 'REDSHIFT' | 'REDSHIFT'
| 'ATHENA' | 'ATHENA'
| 'TRINO' | 'TRINO'
| 'AZURESQL' | 'AZURESQL'
| 'STARROCKS' | 'STARROCKS'
| 'DAMENG' | 'DAMENG'
| 'OCEANBASE' | 'OCEANBASE'
| 'SSH' | 'SSH'
interface IDataSource { interface IDataSource {
id?: number id?: number

6
dolphinscheduler-ui/src/service/modules/process-definition/index.ts

@ -248,10 +248,12 @@ export function viewTree(
}) })
} }
export function viewProcessDefinitionVariables(code: number, processCode: number): any { export function viewProcessDefinitionVariables(
code: number,
processCode: number
): any {
return axios({ return axios({
url: `/projects/${code}/process-definition/${processCode}/view-variables`, url: `/projects/${code}/process-definition/${processCode}/view-variables`,
method: 'get' method: 'get'
}) })
} }

1
dolphinscheduler-ui/src/service/modules/process-instances/index.ts

@ -130,4 +130,3 @@ export function viewVariables(id: number, code: number): any {
method: 'get' method: 'get'
}) })
} }

12
dolphinscheduler-ui/src/service/modules/projects/index.ts

@ -16,7 +16,13 @@
*/ */
import { axios } from '@/service/service' import { axios } from '@/service/service'
import { ListReq, ListIdReq, ProjectsReq, UserIdReq, UpdateProjectsReq } from './types' import {
ListReq,
ListIdReq,
ProjectsReq,
UserIdReq,
UpdateProjectsReq
} from './types'
export function queryProjectListPaging(params: ListReq): any { export function queryProjectListPaging(params: ListReq): any {
return axios({ return axios({
@ -26,7 +32,9 @@ export function queryProjectListPaging(params: ListReq): any {
}) })
} }
export function queryProjectWithAuthorizedLevelListPaging(params: ListIdReq): any { export function queryProjectWithAuthorizedLevelListPaging(
params: ListIdReq
): any {
return axios({ return axios({
url: '/projects/project-with-authorized-level-list-paging', url: '/projects/project-with-authorized-level-list-paging',
method: 'get', method: 'get',

49
dolphinscheduler-ui/src/service/modules/resources/index.ts

@ -45,9 +45,7 @@ export function queryResourceListPaging(
}) })
} }
export function queryBaseDir( export function queryBaseDir(params: ResourceTypeReq): any {
params: ResourceTypeReq
): any {
return axios({ return axios({
url: '/resources/base-dir', url: '/resources/base-dir',
method: 'get', method: 'get',
@ -56,20 +54,20 @@ export function queryBaseDir(
} }
export function queryCurrentResourceByFileName( export function queryCurrentResourceByFileName(
params: ResourceTypeReq & FileNameReq & TenantCodeReq, params: ResourceTypeReq & FileNameReq & TenantCodeReq
): any { ): any {
return axios({ return axios({
url: `/resources/query-file-name`, url: '/resources/query-file-name',
method: 'get', method: 'get',
params params
}) })
} }
export function queryCurrentResourceByFullName( export function queryCurrentResourceByFullName(
params: ResourceTypeReq & FullNameReq & TenantCodeReq, params: ResourceTypeReq & FullNameReq & TenantCodeReq
): any { ): any {
return axios({ return axios({
url: `/resources/query-full-name`, url: '/resources/query-full-name',
method: 'get', method: 'get',
params params
}) })
@ -195,21 +193,19 @@ export function verifyResourceName(params: FullNameReq & ResourceTypeReq): any {
}) })
} }
export function doesResourceExist( export function doesResourceExist(params: FullNameReq & ResourceTypeReq): any {
params: FullNameReq & ResourceTypeReq,
): any {
return axios({ return axios({
url: `/resources/verify-name`, url: '/resources/verify-name',
method: 'get', method: 'get',
params params
}) })
} }
export function updateResource( export function updateResource(
data: NameReq & ResourceTypeReq & DescriptionReq & FullNameReq & TenantCodeReq, data: NameReq & ResourceTypeReq & DescriptionReq & FullNameReq & TenantCodeReq
): any { ): any {
return axios({ return axios({
url: `/resources`, url: '/resources',
method: 'put', method: 'put',
data data
}) })
@ -217,14 +213,14 @@ export function updateResource(
export function deleteResource(params: FullNameReq & TenantCodeReq): any { export function deleteResource(params: FullNameReq & TenantCodeReq): any {
return axios({ return axios({
url: `/resources`, url: '/resources',
method: 'delete', method: 'delete',
params params
}) })
} }
export function downloadResource(params: FullNameReq): void { export function downloadResource(params: FullNameReq): void {
utils.downloadFile(`resources/download`, params) utils.downloadFile('resources/download', params)
} }
export function viewUIUdfFunction(id: IdReq): any { export function viewUIUdfFunction(id: IdReq): any {
@ -234,36 +230,35 @@ export function viewUIUdfFunction(id: IdReq): any {
}) })
} }
export function updateResourceContent(data: ContentReq & TenantCodeReq & FullNameReq): any { export function updateResourceContent(
data: ContentReq & TenantCodeReq & FullNameReq
): any {
return axios({ return axios({
url: `/resources/update-content`, url: '/resources/update-content',
method: 'put', method: 'put',
data data
}) })
} }
export function viewResource(params: ViewResourceReq & FullNameReq & TenantCodeReq): any { export function viewResource(
params: ViewResourceReq & FullNameReq & TenantCodeReq
): any {
return axios({ return axios({
url: `/resources/view`, url: '/resources/view',
method: 'get', method: 'get',
params params
}) })
} }
export function createUdfFunc( export function createUdfFunc(data: UdfFuncReq): any {
data: UdfFuncReq
): any {
return axios({ return axios({
url: `/resources/udf-func`, url: '/resources/udf-func',
method: 'post', method: 'post',
data data
}) })
} }
export function updateUdfFunc( export function updateUdfFunc(data: UdfFuncReq, id: number): any {
data: UdfFuncReq,
id: number
): any {
return axios({ return axios({
url: `/resources/udf-func/${id}`, url: `/resources/udf-func/${id}`,
method: 'put', method: 'put',

2
dolphinscheduler-ui/src/service/modules/resources/types.ts

@ -36,7 +36,7 @@ interface FileNameReq {
fileName: string fileName: string
} }
interface TenantCodeReq{ interface TenantCodeReq {
tenantCode: string tenantCode: string
} }

2
dolphinscheduler-ui/src/service/modules/schedules/types.ts

@ -34,7 +34,7 @@ interface ListReq {
} }
interface ProcessDefinitionCodeReq { interface ProcessDefinitionCodeReq {
processDefinitionCode: number processDefinitionCode?: number
} }
interface ScheduleReq { interface ScheduleReq {

5
dolphinscheduler-ui/src/service/modules/task-instances/index.ts

@ -55,7 +55,10 @@ export function savePoint(projectCode: number, taskId: number): any {
}) })
} }
export function removeTaskInstanceCache(projectCode: number, taskId: number): any { export function removeTaskInstanceCache(
projectCode: number,
taskId: number
): any {
return axios({ return axios({
url: `projects/${projectCode}/task-instances/${taskId}/remove-cache`, url: `projects/${projectCode}/task-instances/${taskId}/remove-cache`,
method: 'delete' method: 'delete'

47
dolphinscheduler-ui/src/utils/environmental-distinction.ts

@ -15,31 +15,30 @@
* limitations under the License. * limitations under the License.
*/ */
import {h} from "vue"; import { h } from 'vue'
import {NTag} from "naive-ui"; import { NTag } from 'naive-ui'
export function renderEnvironmentalDistinctionCell( export function renderEnvironmentalDistinctionCell(
testFlag: number | undefined, testFlag: number | undefined,
t: Function t: Function
) { ) {
if (testFlag === 0) { if (testFlag === 0) {
return h( return h(
NTag, NTag,
{ type: 'success', size: 'small' }, { type: 'success', size: 'small' },
{ {
default: () => t('datasource.on_line') default: () => t('datasource.on_line')
} }
) )
} else if (testFlag === 1) { } else if (testFlag === 1) {
return h( return h(
NTag, NTag,
{ type: 'warning', size: 'small' }, { type: 'warning', size: 'small' },
{ {
default: () => t('datasource.test') default: () => t('datasource.test')
} }
) )
} else { } else {
return '-' return '-'
} }
} }

7
dolphinscheduler-ui/src/utils/tree-format.ts

@ -16,7 +16,12 @@
*/ */
const removeUselessChildren = ( const removeUselessChildren = (
list: { children?: []; directory?: boolean; disabled?: boolean; dirctory?: boolean }[] list: {
children?: []
directory?: boolean
disabled?: boolean
dirctory?: boolean
}[]
) => { ) => {
if (!list.length) return if (!list.length) return
list.forEach((item) => { list.forEach((item) => {

8
dolphinscheduler-ui/src/views/data-quality/rule/index.tsx

@ -22,7 +22,7 @@ import {
ref, ref,
toRefs toRefs
} from 'vue' } from 'vue'
import {NSpace, NButton, NIcon, NDataTable, NPagination} from 'naive-ui' import { NSpace, NButton, NIcon, NDataTable, NPagination } from 'naive-ui'
import { SearchOutlined } from '@vicons/antd' import { SearchOutlined } from '@vicons/antd'
import { useTable } from './use-table' import { useTable } from './use-table'
import Card from '@/components/card' import Card from '@/components/card'
@ -113,11 +113,7 @@ const TaskResult = defineComponent({
placeholder={t('data_quality.rule.name')} placeholder={t('data_quality.rule.name')}
onSearch={onSearch} onSearch={onSearch}
/> />
<NButton <NButton size='small' type='primary' onClick={onSearch}>
size='small'
type='primary'
onClick={onSearch}
>
<NIcon> <NIcon>
<SearchOutlined /> <SearchOutlined />
</NIcon> </NIcon>

6
dolphinscheduler-ui/src/views/data-quality/task-result/index.tsx

@ -91,9 +91,9 @@ const TaskResult = defineComponent({
<Card> <Card>
<NSpace justify='end'> <NSpace justify='end'>
<Search <Search
v-model:value={this.searchVal} v-model:value={this.searchVal}
placeholder={t('data_quality.task_result.task_name')} placeholder={t('data_quality.task_result.task_name')}
onSearch={onSearch} onSearch={onSearch}
/> />
<NSelect <NSelect
v-model={[this.ruleType, 'value']} v-model={[this.ruleType, 'value']}

126
dolphinscheduler-ui/src/views/datasource/list/detail.tsx

@ -108,7 +108,8 @@ const DetailModal = defineComponent({
() => props.show, () => props.show,
async () => { async () => {
state.detailForm.type = props.selectType state.detailForm.type = props.selectType
state.detailForm.label = props.selectType === 'HIVE' ? 'HIVE/IMPALA' : props.selectType state.detailForm.label =
props.selectType === 'HIVE' ? 'HIVE/IMPALA' : props.selectType
props.show && props.show &&
state.detailForm.type && state.detailForm.type &&
(await changeType( (await changeType(
@ -116,7 +117,9 @@ const DetailModal = defineComponent({
datasourceType[state.detailForm.type] datasourceType[state.detailForm.type]
)) ))
props.show && props.id && setFieldsValue(await queryById(props.id)) props.show && props.id && setFieldsValue(await queryById(props.id))
props.show && state.detailForm.testFlag == 0 && await getSameTypeTestDataSource() props.show &&
state.detailForm.testFlag == 0 &&
(await getSameTypeTestDataSource())
} }
) )
@ -124,12 +127,13 @@ const DetailModal = defineComponent({
() => props.selectType, () => props.selectType,
async () => { async () => {
state.detailForm.type = props.selectType state.detailForm.type = props.selectType
state.detailForm.label = props.selectType === 'HIVE' ? 'HIVE/IMPALA' : props.selectType state.detailForm.label =
props.selectType === 'HIVE' ? 'HIVE/IMPALA' : props.selectType
state.detailForm.type && state.detailForm.type &&
(await changeType( (await changeType(
state.detailForm.type, state.detailForm.type,
datasourceType[state.detailForm.type] datasourceType[state.detailForm.type]
)) ))
} }
) )
@ -205,8 +209,18 @@ const DetailModal = defineComponent({
show-require-mark show-require-mark
> >
<div class={[styles.typeBox, !!id && styles.disabledBox]}> <div class={[styles.typeBox, !!id && styles.disabledBox]}>
<div v-model={[detailForm.type, 'value']}>{detailForm.label}</div> <div v-model={[detailForm.type, 'value']}>
<div class={[styles['text-color'], 'btn-data-source-type-drop-down']} onClick={handleSourceModalOpen}>{t('datasource.select')}</div> {detailForm.label}
</div>
<div
class={[
styles['text-color'],
'btn-data-source-type-drop-down'
]}
onClick={handleSourceModalOpen}
>
{t('datasource.select')}
</div>
</div> </div>
</NFormItem> </NFormItem>
<NFormItem <NFormItem
@ -290,14 +304,18 @@ const DetailModal = defineComponent({
</NFormItem> </NFormItem>
{/* 验证条件选择 */} {/* 验证条件选择 */}
<NFormItem <NFormItem
v-show={showMode} v-show={showMode}
label={t('datasource.validation')} label={t('datasource.validation')}
path='mode' path='mode'
show-require-mark show-require-mark
> >
<NSelect <NSelect
v-model={[detailForm.mode, 'value']} v-model={[detailForm.mode, 'value']}
options={detailForm.type === 'REDSHIFT' ? redShitModeOptions : modeOptions} options={
detailForm.type === 'REDSHIFT'
? redShitModeOptions
: modeOptions
}
></NSelect> ></NSelect>
</NFormItem> </NFormItem>
{/* SqlPassword */} {/* SqlPassword */}
@ -329,7 +347,9 @@ const DetailModal = defineComponent({
</NFormItem> </NFormItem>
{/* ActiveDirectoryPassword */} {/* ActiveDirectoryPassword */}
<NFormItem <NFormItem
v-show={showMode && detailForm.mode === 'ActiveDirectoryPassword'} v-show={
showMode && detailForm.mode === 'ActiveDirectoryPassword'
}
label={t('datasource.Azure_AD_username')} label={t('datasource.Azure_AD_username')}
path='userName' path='userName'
show-require-mark show-require-mark
@ -342,7 +362,9 @@ const DetailModal = defineComponent({
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
v-show={showMode && detailForm.mode === 'ActiveDirectoryPassword'} v-show={
showMode && detailForm.mode === 'ActiveDirectoryPassword'
}
label={t('datasource.Azure_AD_password')} label={t('datasource.Azure_AD_password')}
path='password' path='password'
show-require-mark show-require-mark
@ -369,7 +391,10 @@ const DetailModal = defineComponent({
</NFormItem> </NFormItem>
{/* ActiveDirectoryServicePrincipal */} {/* ActiveDirectoryServicePrincipal */}
<NFormItem <NFormItem
v-show={showMode && detailForm.mode === 'ActiveDirectoryServicePrincipal'} v-show={
showMode &&
detailForm.mode === 'ActiveDirectoryServicePrincipal'
}
label={t('datasource.clientId')} label={t('datasource.clientId')}
path='userName' path='userName'
show-require-mark show-require-mark
@ -382,7 +407,10 @@ const DetailModal = defineComponent({
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
v-show={showMode && detailForm.mode === 'ActiveDirectoryServicePrincipal'} v-show={
showMode &&
detailForm.mode === 'ActiveDirectoryServicePrincipal'
}
label={t('datasource.clientSecret')} label={t('datasource.clientSecret')}
path='password' path='password'
show-require-mark show-require-mark
@ -528,17 +556,17 @@ const DetailModal = defineComponent({
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
v-show={showAwsRegion} v-show={showAwsRegion}
label={t('datasource.aws_region')} label={t('datasource.aws_region')}
path='awsRegion' path='awsRegion'
show-require-mark show-require-mark
> >
<NInput <NInput
allowInput={this.trim} allowInput={this.trim}
v-model={[detailForm.awsRegion, 'value']} v-model={[detailForm.awsRegion, 'value']}
type='text' type='text'
maxlength={60} maxlength={60}
placeholder={t('datasource.aws_region_tips')} placeholder={t('datasource.aws_region_tips')}
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
@ -557,19 +585,19 @@ const DetailModal = defineComponent({
/> />
</NFormItem> </NFormItem>
{detailForm.type === 'SNOWFLAKE' && ( {detailForm.type === 'SNOWFLAKE' && (
<NFormItem <NFormItem
label={t('datasource.datawarehouse')} label={t('datasource.datawarehouse')}
path='datawarehouse' path='datawarehouse'
show-require-mark show-require-mark
> >
<NInput <NInput
allowInput={this.trim} allowInput={this.trim}
class='input-datawarehouse' class='input-datawarehouse'
v-model={[detailForm.datawarehouse, 'value']} v-model={[detailForm.datawarehouse, 'value']}
maxlength={60} maxlength={60}
placeholder={t('datasource.datawarehouse_tips')} placeholder={t('datasource.datawarehouse_tips')}
/> />
</NFormItem> </NFormItem>
)} )}
<NFormItem <NFormItem
v-show={showConnectType} v-show={showConnectType}
@ -655,16 +683,16 @@ const DetailModal = defineComponent({
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
v-show={showPublicKey} v-show={showPublicKey}
label='PublicKey' label='PublicKey'
path='publicKey' path='publicKey'
> >
<NInput <NInput
v-model={[detailForm.publicKey, 'value']} v-model={[detailForm.publicKey, 'value']}
type='textarea' type='textarea'
autosize={{ autosize={{
minRows: 4 minRows: 4
}} }}
/> />
</NFormItem> </NFormItem>
</NForm> </NForm>

5
dolphinscheduler-ui/src/views/datasource/list/use-columns.ts

@ -34,7 +34,7 @@ import {
calculateTableWidth, calculateTableWidth,
DefaultTableWidth DefaultTableWidth
} from '@/common/column-width-config' } from '@/common/column-width-config'
import {renderEnvironmentalDistinctionCell} from "@/utils/environmental-distinction"; import { renderEnvironmentalDistinctionCell } from '@/utils/environmental-distinction'
export function useColumns(onCallback: Function) { export function useColumns(onCallback: Function) {
const { t } = useI18n() const { t } = useI18n()
@ -118,7 +118,8 @@ export function useColumns(onCallback: Function) {
circle: true, circle: true,
type: 'info', type: 'info',
size: 'small', size: 'small',
onClick: () => void onCallback(rowData.id, 'edit', rowData) onClick: () =>
void onCallback(rowData.id, 'edit', rowData)
}, },
{ {
default: () => default: () =>

48
dolphinscheduler-ui/src/views/datasource/list/use-form.ts

@ -220,25 +220,25 @@ export function useForm(id?: number) {
} as FormRules, } as FormRules,
modeOptions: [ modeOptions: [
{ {
label: "SqlPassword", label: 'SqlPassword',
value: 'SqlPassword', value: 'SqlPassword'
}, },
{ {
label: "ActiveDirectoryPassword", label: 'ActiveDirectoryPassword',
value: 'ActiveDirectoryPassword', value: 'ActiveDirectoryPassword'
}, },
{ {
label: "ActiveDirectoryMSI", label: 'ActiveDirectoryMSI',
value: 'ActiveDirectoryMSI', value: 'ActiveDirectoryMSI'
}, },
{ {
label: "ActiveDirectoryServicePrincipal", label: 'ActiveDirectoryServicePrincipal',
value: 'ActiveDirectoryServicePrincipal', value: 'ActiveDirectoryServicePrincipal'
}, },
{ {
label: "accessToken", label: 'accessToken',
value: 'accessToken', value: 'accessToken'
}, }
], ],
redShitModeOptions: [ redShitModeOptions: [
{ {
@ -256,7 +256,7 @@ export function useForm(id?: number) {
state.detailForm.port = options.previousPort || options.defaultPort state.detailForm.port = options.previousPort || options.defaultPort
state.detailForm.type = type state.detailForm.type = type
state.requiredDataBase = (type !== 'POSTGRESQL' && type !== 'ATHENA') state.requiredDataBase = type !== 'POSTGRESQL' && type !== 'ATHENA'
state.showHost = type !== 'ATHENA' state.showHost = type !== 'ATHENA'
state.showPort = type !== 'ATHENA' state.showPort = type !== 'ATHENA'
@ -280,12 +280,11 @@ export function useForm(id?: number) {
state.requiredDataBase = false state.requiredDataBase = false
state.showJDBCConnectParameters = false state.showJDBCConnectParameters = false
state.showPublicKey = true state.showPublicKey = true
}else { } else {
state.showDataBaseName = true state.showDataBaseName = true
state.requiredDataBase = true state.requiredDataBase = true
state.showJDBCConnectParameters = true state.showJDBCConnectParameters = true
state.showPublicKey = false state.showPublicKey = false
} }
if (state.detailForm.id === undefined) { if (state.detailForm.id === undefined) {
@ -312,13 +311,13 @@ export function useForm(id?: number) {
const params = { type: state.detailForm.type, testFlag: 1 } as TypeReq const params = { type: state.detailForm.type, testFlag: 1 } as TypeReq
const result = await queryDataSourceList(params) const result = await queryDataSourceList(params)
state.bindTestDataSourceExample = result state.bindTestDataSourceExample = result
.filter((value: { label: string; value: string }) => { .filter((value: { label: string; value: string }) => {
// @ts-ignore // @ts-ignore
if (state.detailForm.id && state.detailForm.id === value.id) if (state.detailForm.id && state.detailForm.id === value.id)
return false return false
return true return true
}) })
.map((TestDataSourceExample: { name: string; id: number }) => ({ .map((TestDataSourceExample: { name: string; id: number }) => ({
label: TestDataSourceExample.name, label: TestDataSourceExample.name,
value: TestDataSourceExample.id value: TestDataSourceExample.id
})) }))
@ -338,7 +337,6 @@ export function useForm(id?: number) {
const getFieldsValue = () => state.detailForm const getFieldsValue = () => state.detailForm
return { return {
state, state,
changeType, changeType,
@ -418,9 +416,9 @@ export const datasourceType: IDataBaseOptionKeys = {
defaultPort: 1433 defaultPort: 1433
}, },
STARROCKS: { STARROCKS: {
value: 'STARROCKS', value: 'STARROCKS',
label: 'STARROCKS', label: 'STARROCKS',
defaultPort: 9030 defaultPort: 9030
}, },
DAMENG: { DAMENG: {
value: 'DAMENG', value: 'DAMENG',

2
dolphinscheduler-ui/src/views/datasource/list/use-table.ts

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import {reactive, ref} from 'vue' import { reactive, ref } from 'vue'
import { import {
queryDataSourceListPaging, queryDataSourceListPaging,
deleteDataSource deleteDataSource

36
dolphinscheduler-ui/src/views/login/index.tsx

@ -15,7 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import {defineComponent, getCurrentInstance, onMounted, toRefs, withKeys} from 'vue' import {
defineComponent,
getCurrentInstance,
onMounted,
toRefs,
withKeys
} from 'vue'
import styles from './index.module.scss' import styles from './index.module.scss'
import { import {
NInput, NInput,
@ -31,7 +37,7 @@ import { useLogin } from './use-login'
import { useLocalesStore } from '@/store/locales/locales' import { useLocalesStore } from '@/store/locales/locales'
import { useThemeStore } from '@/store/theme/theme' import { useThemeStore } from '@/store/theme/theme'
import cookies from 'js-cookie' import cookies from 'js-cookie'
import {ssoLoginUrl} from "@/service/modules/login"; import { ssoLoginUrl } from '@/service/modules/login'
const login = defineComponent({ const login = defineComponent({
name: 'login', name: 'login',
@ -57,8 +63,8 @@ const login = defineComponent({
state.loginForm.ssoLoginUrl = ssoLoginUrlRes state.loginForm.ssoLoginUrl = ssoLoginUrlRes
if (state.loginForm.ssoLoginUrl) { if (state.loginForm.ssoLoginUrl) {
const url = new URL(window.location.href) const url = new URL(window.location.href)
let ssoState = url.searchParams.get('state') const ssoState = url.searchParams.get('state')
let ssoCode = url.searchParams.get('code') const ssoCode = url.searchParams.get('code')
if (ssoState && ssoCode) { if (ssoState && ssoCode) {
state.loginForm.userName = ssoState state.loginForm.userName = ssoState
state.loginForm.userPassword = ssoCode state.loginForm.userPassword = ssoCode
@ -98,7 +104,10 @@ const login = defineComponent({
<div class={styles.logo}> <div class={styles.logo}>
<div class={styles['logo-img']} /> <div class={styles['logo-img']} />
</div> </div>
<div class={styles['form-model']} v-show={this.loginForm.ssoLoginUrl.length === 0}> <div
class={styles['form-model']}
v-show={this.loginForm.ssoLoginUrl.length === 0}
>
<NForm rules={this.rules} ref='loginFormRef'> <NForm rules={this.rules} ref='loginFormRef'>
<NFormItem <NFormItem
label={this.t('login.userName')} label={this.t('login.userName')}
@ -145,14 +154,17 @@ const login = defineComponent({
{this.t('login.login')} {this.t('login.login')}
</NButton> </NButton>
</div> </div>
<div class={styles['form-model']} v-show={this.loginForm.ssoLoginUrl.length !== 0}> <div
<a href={this.loginForm.ssoLoginUrl} style="text-decoration:none"> class={styles['form-model']}
v-show={this.loginForm.ssoLoginUrl.length !== 0}
>
<a href={this.loginForm.ssoLoginUrl} style='text-decoration:none'>
<NButton <NButton
class='btn-login-sso' class='btn-login-sso'
round round
type='info' type='info'
style={{width: '100%', marginTop: '30px'}} style={{ width: '100%', marginTop: '30px' }}
onClick={this.handleLogin} onClick={this.handleLogin}
> >
{this.t('login.ssoLogin')} {this.t('login.ssoLogin')}
</NButton> </NButton>

2
dolphinscheduler-ui/src/views/login/use-login.ts

@ -25,7 +25,7 @@ import type { UserInfoRes } from '@/service/modules/users/types'
import { useRouteStore } from '@/store/route/route' import { useRouteStore } from '@/store/route/route'
import { useTimezoneStore } from '@/store/timezone/timezone' import { useTimezoneStore } from '@/store/timezone/timezone'
import cookies from 'js-cookie' import cookies from 'js-cookie'
import {queryBaseDir} from "@/service/modules/resources"; import { queryBaseDir } from '@/service/modules/resources'
export function useLogin(state: any) { export function useLogin(state: any) {
const router: Router = useRouter() const router: Router = useRouter()

4
dolphinscheduler-ui/src/views/profile/use-form.ts

@ -32,7 +32,7 @@ export function useForm() {
profileForm: { profileForm: {
username: userInfo.userName, username: userInfo.userName,
email: userInfo.email, email: userInfo.email,
phone: userInfo.phone, phone: userInfo.phone
}, },
saving: false, saving: false,
rules: { rules: {
@ -63,7 +63,7 @@ export function useForm() {
state.profileForm = { state.profileForm = {
username: userInfo.userName, username: userInfo.userName,
email: userInfo.email, email: userInfo.email,
phone: userInfo.phone, phone: userInfo.phone
} }
}) })

18
dolphinscheduler-ui/src/views/projects/list/index.tsx

@ -16,13 +16,7 @@
*/ */
import { SearchOutlined } from '@vicons/antd' import { SearchOutlined } from '@vicons/antd'
import { import { NButton, NDataTable, NIcon, NPagination, NSpace } from 'naive-ui'
NButton,
NDataTable,
NIcon,
NPagination,
NSpace
} from 'naive-ui'
import { import {
defineComponent, defineComponent,
getCurrentInstance, getCurrentInstance,
@ -33,7 +27,7 @@ import {
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useTable } from './use-table' import { useTable } from './use-table'
import Card from '@/components/card' import Card from '@/components/card'
import Search from "@/components/input-search"; import Search from '@/components/input-search'
import ProjectModal from './components/project-modal' import ProjectModal from './components/project-modal'
const list = defineComponent({ const list = defineComponent({
@ -122,10 +116,10 @@ const list = defineComponent({
</NButton> </NButton>
<NSpace> <NSpace>
<Search <Search
v-model:value = {this.searchVal} v-model:value={this.searchVal}
placeholder={t('project.list.project_tips')} placeholder={t('project.list.project_tips')}
onSearch={this.handleSearch} onSearch={this.handleSearch}
onClear={this.onClearSearch} onClear={this.onClearSearch}
/> />
<NButton size='small' type='primary' onClick={this.handleSearch}> <NButton size='small' type='primary' onClick={this.handleSearch}>

2
dolphinscheduler-ui/src/views/projects/list/use-table.ts

@ -84,7 +84,7 @@ export function useTable() {
onClick: () => { onClick: () => {
router.push({ router.push({
path: `/projects/${row.code}`, path: `/projects/${row.code}`,
query: {projectName: row.name} query: { projectName: row.name }
}) })
} }
}, },

14
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-cache.ts

@ -19,11 +19,11 @@ import { useI18n } from 'vue-i18n'
import type { IJsonItem } from '../types' import type { IJsonItem } from '../types'
export function useCache(): IJsonItem { export function useCache(): IJsonItem {
const { t } = useI18n() const { t } = useI18n()
return { return {
type: 'switch', type: 'switch',
field: 'isCache', field: 'isCache',
name: t('project.node.is_cache'), name: t('project.node.is_cache'),
span: 12 span: 12
} }
} }

108
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-custom-labels.ts

@ -19,64 +19,64 @@ import { useI18n } from 'vue-i18n'
import type { IJsonItem } from '../types' import type { IJsonItem } from '../types'
export function useCustomLabels({ export function useCustomLabels({
model, model,
field, field,
name = 'custom_labels', name = 'custom_labels',
span = 24 span = 24
}: { }: {
model: { [field: string]: any } model: { [field: string]: any }
field: string field: string
name?: string name?: string
span?: Ref | number span?: Ref | number
}): IJsonItem[] { }): IJsonItem[] {
const { t } = useI18n() const { t } = useI18n()
return [ return [
{
type: 'custom-parameters',
field: field,
name: t(`project.node.${name}`),
class: 'btn-custom-parameters',
span,
children: [
{ {
type: 'custom-parameters', type: 'input',
field: field, field: 'label',
name: t(`project.node.${name}`), span: 8,
class: 'btn-custom-parameters', class: 'customized-label-name',
span, props: {
children: [ placeholder: t('project.node.label_name_tips'),
{ maxLength: 256
type: 'input', },
field: 'label', validate: {
span: 8, trigger: ['input', 'blur'],
class: 'customized-label-name', required: true,
props: { validator(validate: any, value: string) {
placeholder: t('project.node.label_name_tips'), if (!value) {
maxLength: 256 return new Error(t('project.node.label_name_tips'))
}, }
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( const sameItems = model[field].filter(
(item: { label: string }) => item.label === value (item: { label: string }) => item.label === value
) )
if (sameItems.length > 1) { if (sameItems.length > 1) {
return new Error(t('project.node.label_repeat')) return new Error(t('project.node.label_repeat'))
} }
} }
} }
}, },
{ {
type: 'input', type: 'input',
field: 'value', field: 'value',
span: 14, span: 14,
class: 'customized-label-value', class: 'customized-label-value',
props: { props: {
placeholder: t('project.node.label_value_tips'), placeholder: t('project.node.label_value_tips'),
maxLength: 256 maxLength: 256
} }
}
]
} }
] ]
}
]
} }

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

@ -122,7 +122,7 @@ export function useDatasource(
id: 16, id: 16,
code: 'DATABEND', code: 'DATABEND',
disabled: false disabled: false
}, }
] ]
const getDatasourceTypes = async () => { const getDatasourceTypes = async () => {

115
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasync.ts

@ -20,67 +20,66 @@ import { watch, ref } from 'vue'
import { useCustomParams } from '.' import { useCustomParams } from '.'
export function useDatasync(model: { [field: string]: any }): IJsonItem[] { 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 jsonSpan = ref(0) const resetSpan = () => {
const destinationLocationArnSpan = ref(0) jsonSpan.value = model.jsonFormat ? 24 : 0
const sourceLocationArnSpan = ref(0) destinationLocationArnSpan.value = model.jsonFormat ? 0 : 24
const nameSpan = ref(0) sourceLocationArnSpan.value = model.jsonFormat ? 0 : 24
const cloudWatchLogGroupArnSpan = ref(0) nameSpan.value = model.jsonFormat ? 0 : 24
cloudWatchLogGroupArnSpan.value = model.jsonFormat ? 0 : 24
}
const resetSpan = () => { watch(
jsonSpan.value = model.jsonFormat ? 24 : 0 () => [model.jsonFormat],
destinationLocationArnSpan.value = model.jsonFormat ? 0 : 24 () => {
sourceLocationArnSpan.value = model.jsonFormat ? 0 : 24 resetSpan()
nameSpan.value = model.jsonFormat ? 0 : 24
cloudWatchLogGroupArnSpan.value = model.jsonFormat ? 0 : 24
} }
)
watch( resetSpan()
() => [model.jsonFormat],
() => {
resetSpan()
}
)
resetSpan() return [
{
return [ type: 'switch',
{ field: 'jsonFormat',
type: 'switch', name: 'jsonFormat',
field: 'jsonFormat', span: 12
name: 'jsonFormat', },
span: 12 {
}, type: 'editor',
{ field: 'json',
type: 'editor', name: 'json',
field: 'json', span: jsonSpan
name: 'json', },
span: jsonSpan {
}, type: 'input',
{ field: 'destinationLocationArn',
type: 'input', name: 'destinationLocationArn',
field: 'destinationLocationArn', span: destinationLocationArnSpan
name: 'destinationLocationArn', },
span: destinationLocationArnSpan {
}, type: 'input',
{ field: 'sourceLocationArn',
type: 'input', name: 'sourceLocationArn',
field: 'sourceLocationArn', span: sourceLocationArnSpan
name: 'sourceLocationArn', },
span: sourceLocationArnSpan {
}, type: 'input',
{ field: 'name',
type: 'input', name: 'name',
field: 'name', span: nameSpan
name: 'name', },
span: nameSpan {
}, type: 'input',
{ field: 'cloudWatchLogGroupArn',
type: 'input', name: 'cloudWatchLogGroupArn',
field: 'cloudWatchLogGroupArn', span: cloudWatchLogGroupArnSpan
name: 'cloudWatchLogGroupArn', },
span: cloudWatchLogGroupArnSpan ...useCustomParams({ model, field: 'localParams', isSimple: false })
}, ]
...useCustomParams({ model, field: 'localParams', isSimple: false })
]
} }

466
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datax.ts

@ -14,243 +14,243 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import {ref, onMounted, watch} from 'vue' import { ref, onMounted, watch } from 'vue'
import {useI18n} from 'vue-i18n' import { useI18n } from 'vue-i18n'
import {useCustomParams, useDatasource, useResources} from '.' import { useCustomParams, useDatasource, useResources } from '.'
import type {IJsonItem} from '../types' import type { IJsonItem } from '../types'
export function useDataX(model: { [field: string]: any }): IJsonItem[] { export function useDataX(model: { [field: string]: any }): IJsonItem[] {
const {t} = useI18n() const { t } = useI18n()
const jobSpeedByteOptions: any[] = [ const jobSpeedByteOptions: any[] = [
{ {
label: `0(${t('project.node.unlimited')})`, label: `0(${t('project.node.unlimited')})`,
value: 0 value: 0
}, },
{ {
label: '1KB', label: '1KB',
value: 1024 value: 1024
}, },
{ {
label: '10KB', label: '10KB',
value: 10240 value: 10240
}, },
{ {
label: '50KB', label: '50KB',
value: 51200 value: 51200
}, },
{ {
label: '100KB', label: '100KB',
value: 102400 value: 102400
}, },
{ {
label: '512KB', label: '512KB',
value: 524288 value: 524288
} }
] ]
const jobSpeedRecordOptions: any[] = [ const jobSpeedRecordOptions: any[] = [
{ {
label: `0(${t('project.node.unlimited')})`, label: `0(${t('project.node.unlimited')})`,
value: 0 value: 0
}, },
{ {
label: '500', label: '500',
value: 500 value: 500
}, },
{ {
label: '1000', label: '1000',
value: 1000 value: 1000
}, },
{ {
label: '1500', label: '1500',
value: 1500 value: 1500
}, },
{ {
label: '2000', label: '2000',
value: 2000 value: 2000
}, },
{ {
label: '2500', label: '2500',
value: 2500 value: 2500
}, },
{ {
label: '3000', label: '3000',
value: 3000 value: 3000
} }
] ]
const memoryLimitOptions = [ const memoryLimitOptions = [
{ {
label: '1G', label: '1G',
value: 1 value: 1
}, },
{ {
label: '2G', label: '2G',
value: 2 value: 2
}, },
{ {
label: '3G', label: '3G',
value: 3 value: 3
}, },
{ {
label: '4G', label: '4G',
value: 4 value: 4
} }
] ]
const sqlEditorSpan = ref(24) const sqlEditorSpan = ref(24)
const jsonEditorSpan = ref(0) const jsonEditorSpan = ref(0)
const datasourceSpan = ref(12) const datasourceSpan = ref(12)
const destinationDatasourceSpan = ref(8) const destinationDatasourceSpan = ref(8)
const otherStatementSpan = ref(22) const otherStatementSpan = ref(22)
const jobSpeedSpan = ref(12) const jobSpeedSpan = ref(12)
const useResourcesSpan = ref(0) const useResourcesSpan = ref(0)
const initConstants = () => { const initConstants = () => {
if (model.customConfig) { if (model.customConfig) {
sqlEditorSpan.value = 0 sqlEditorSpan.value = 0
jsonEditorSpan.value = 24 jsonEditorSpan.value = 24
datasourceSpan.value = 0 datasourceSpan.value = 0
destinationDatasourceSpan.value = 0 destinationDatasourceSpan.value = 0
otherStatementSpan.value = 0 otherStatementSpan.value = 0
jobSpeedSpan.value = 0 jobSpeedSpan.value = 0
useResourcesSpan.value = 24 useResourcesSpan.value = 24
} else { } else {
sqlEditorSpan.value = 24 sqlEditorSpan.value = 24
jsonEditorSpan.value = 0 jsonEditorSpan.value = 0
datasourceSpan.value = 12 datasourceSpan.value = 12
destinationDatasourceSpan.value = 8 destinationDatasourceSpan.value = 8
otherStatementSpan.value = 22 otherStatementSpan.value = 22
jobSpeedSpan.value = 12 jobSpeedSpan.value = 12
useResourcesSpan.value = 0 useResourcesSpan.value = 0
} }
}
const supportedDatasourceType = [
'MYSQL',
'POSTGRESQL',
'ORACLE',
'SQLSERVER',
'CLICKHOUSE',
'DATABEND',
'HIVE',
'PRESTO'
]
onMounted(() => {
initConstants()
})
watch(
() => model.customConfig,
() => {
initConstants()
} }
const supportedDatasourceType = [ )
'MYSQL',
'POSTGRESQL',
'ORACLE',
'SQLSERVER',
'CLICKHOUSE',
'DATABEND',
'HIVE',
'PRESTO'
]
onMounted(() => {
initConstants()
})
watch(
() => model.customConfig,
() => {
initConstants()
}
)
return [ return [
{ {
type: 'switch', type: 'switch',
field: 'customConfig', field: 'customConfig',
name: t('project.node.datax_custom_template') name: t('project.node.datax_custom_template')
}, },
...useDatasource(model, { ...useDatasource(model, {
typeField: 'dsType', typeField: 'dsType',
sourceField: 'dataSource', sourceField: 'dataSource',
span: datasourceSpan, span: datasourceSpan,
supportedDatasourceType supportedDatasourceType
}), }),
{ {
type: 'editor', type: 'editor',
field: 'sql', field: 'sql',
name: t('project.node.sql_statement'), name: t('project.node.sql_statement'),
span: sqlEditorSpan, span: sqlEditorSpan,
validate: { validate: {
trigger: ['input', 'trigger'], trigger: ['input', 'trigger'],
required: true, required: true,
message: t('project.node.sql_empty_tips') message: t('project.node.sql_empty_tips')
} }
}, },
{ {
type: 'editor', type: 'editor',
field: 'json', field: 'json',
name: t('project.node.datax_json_template'), name: t('project.node.datax_json_template'),
span: jsonEditorSpan, span: jsonEditorSpan,
validate: { validate: {
trigger: ['input', 'trigger'], trigger: ['input', 'trigger'],
required: true, required: true,
message: t('project.node.sql_empty_tips') message: t('project.node.sql_empty_tips')
} }
}, },
useResources(useResourcesSpan), useResources(useResourcesSpan),
...useDatasource(model, { ...useDatasource(model, {
typeField: 'dtType', typeField: 'dtType',
sourceField: 'dataTarget', sourceField: 'dataTarget',
span: destinationDatasourceSpan, span: destinationDatasourceSpan,
supportedDatasourceType supportedDatasourceType
}), }),
{ {
type: 'input', type: 'input',
field: 'targetTable', field: 'targetTable',
name: t('project.node.datax_target_table'), name: t('project.node.datax_target_table'),
span: destinationDatasourceSpan, span: destinationDatasourceSpan,
props: { props: {
placeholder: t('project.node.datax_target_table_tips') placeholder: t('project.node.datax_target_table_tips')
}, },
validate: { validate: {
trigger: ['input', 'blur'], trigger: ['input', 'blur'],
required: true required: true
} }
}, },
{ {
type: 'multi-input', type: 'multi-input',
field: 'preStatements', field: 'preStatements',
name: t('project.node.datax_target_database_pre_sql'), name: t('project.node.datax_target_database_pre_sql'),
span: otherStatementSpan, span: otherStatementSpan,
props: { props: {
placeholder: t('project.node.datax_non_query_sql_tips'), placeholder: t('project.node.datax_non_query_sql_tips'),
type: 'textarea', type: 'textarea',
autosize: {minRows: 1} autosize: { minRows: 1 }
} }
}, },
{ {
type: 'multi-input', type: 'multi-input',
field: 'postStatements', field: 'postStatements',
name: t('project.node.datax_target_database_post_sql'), name: t('project.node.datax_target_database_post_sql'),
span: otherStatementSpan, span: otherStatementSpan,
props: { props: {
placeholder: t('project.node.datax_non_query_sql_tips'), placeholder: t('project.node.datax_non_query_sql_tips'),
type: 'textarea', type: 'textarea',
autosize: {minRows: 1} autosize: { minRows: 1 }
} }
}, },
{ {
type: 'select', type: 'select',
field: 'jobSpeedByte', field: 'jobSpeedByte',
name: t('project.node.datax_job_speed_byte'), name: t('project.node.datax_job_speed_byte'),
span: jobSpeedSpan, span: jobSpeedSpan,
options: jobSpeedByteOptions, options: jobSpeedByteOptions,
value: 0 value: 0
}, },
{ {
type: 'select', type: 'select',
field: 'jobSpeedRecord', field: 'jobSpeedRecord',
name: t('project.node.datax_job_speed_record'), name: t('project.node.datax_job_speed_record'),
span: jobSpeedSpan, span: jobSpeedSpan,
options: jobSpeedRecordOptions, options: jobSpeedRecordOptions,
value: 1000 value: 1000
}, },
{ {
type: 'select', type: 'select',
field: 'xms', field: 'xms',
name: t('project.node.datax_job_runtime_memory_xms'), name: t('project.node.datax_job_runtime_memory_xms'),
span: 12, span: 12,
options: memoryLimitOptions, options: memoryLimitOptions,
value: 1 value: 1
}, },
{ {
type: 'select', type: 'select',
field: 'xmx', field: 'xmx',
name: t('project.node.datax_job_runtime_memory_xmx'), name: t('project.node.datax_job_runtime_memory_xmx'),
span: 12, span: 12,
options: memoryLimitOptions, options: memoryLimitOptions,
value: 1 value: 1
}, },
...useCustomParams({model, field: 'localParams', isSimple: true}) ...useCustomParams({ model, field: 'localParams', isSimple: true })
] ]
} }

4
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-dependent-timeout.ts

@ -24,7 +24,9 @@ export function useDependentTimeout(model: {
}): IJsonItem[] { }): IJsonItem[] {
const { t } = useI18n() const { t } = useI18n()
const timeCompleteSpan = computed(() => (model.timeoutShowFlag ? 24 : 0)) const timeCompleteSpan = computed(() => (model.timeoutShowFlag ? 24 : 0))
const timeCompleteEnableSpan = computed(() => (model.timeoutFlag && model.timeoutShowFlag ? 12 : 0)) const timeCompleteEnableSpan = computed(() =>
model.timeoutFlag && model.timeoutShowFlag ? 12 : 0
)
const strategyOptions = [ const strategyOptions = [
{ {

7
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-dms.ts

@ -20,7 +20,6 @@ import { watch, ref } from 'vue'
import { useCustomParams, useResources } from '.' import { useCustomParams, useResources } from '.'
export function useDms(model: { [field: string]: any }): IJsonItem[] { export function useDms(model: { [field: string]: any }): IJsonItem[] {
const jsonDataSpan = ref(0) const jsonDataSpan = ref(0)
const replicationTaskArnSpan = ref(0) const replicationTaskArnSpan = ref(0)
const replicationTaskIdentifierSpan = ref(0) const replicationTaskIdentifierSpan = ref(0)
@ -31,8 +30,10 @@ export function useDms(model: { [field: string]: any }): IJsonItem[] {
const tableMappingsSpan = ref(0) const tableMappingsSpan = ref(0)
const setFlag = () => { const setFlag = () => {
model.isCreateAndNotJson = !model.isRestartTask && !model.isJsonFormat ? true : false model.isCreateAndNotJson =
model.isRestartAndNotJson = model.isRestartTask && !model.isJsonFormat ? true : false !model.isRestartTask && !model.isJsonFormat ? true : false
model.isRestartAndNotJson =
model.isRestartTask && !model.isJsonFormat ? true : false
} }
const resetSpan = () => { const resetSpan = () => {

6
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-environment-name.ts

@ -49,7 +49,9 @@ export function useEnvironmentName(
if (options.value.length === 0) { if (options.value.length === 0) {
model.environmentCode = null model.environmentCode = null
} else { } else {
(isCreate && !model.environmentCode) && (model.environmentCode = options.value[0].value) isCreate &&
!model.environmentCode &&
(model.environmentCode = options.value[0].value)
} }
} }
@ -83,7 +85,7 @@ export function useEnvironmentName(
name: t('project.node.environment_name'), name: t('project.node.environment_name'),
props: { props: {
loading: loading, loading: loading,
clearable: true, clearable: true
}, },
options: options options: options
} }

3
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-flink.ts

@ -102,7 +102,8 @@ export function useFlink(model: { [field: string]: any }): IJsonItem[] {
) )
watchEffect(() => { watchEffect(() => {
model.flinkVersion = model.programType === 'SQL' ? '>=1.13' : model.flinkVersion model.flinkVersion =
model.programType === 'SQL' ? '>=1.13' : model.flinkVersion
}) })
return [ return [

14
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-hive-cli.ts

@ -14,16 +14,22 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { computed } from 'vue' import { computed } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useCustomParams, useResources } from '.' import { useCustomParams, useResources } from '.'
import type { IJsonItem } from '../types' import type { IJsonItem } from '../types'
export function useHiveCli(model: { [field: string]: any }): IJsonItem[] { export function useHiveCli(model: { [field: string]: any }): IJsonItem[] {
const { t } = useI18n() const { t } = useI18n()
const hiveSqlScriptSpan = computed(() => (model.hiveCliTaskExecutionType === 'SCRIPT' ? 24 : 0)) const hiveSqlScriptSpan = computed(() =>
const resourcesRequired = computed(() => (model.hiveCliTaskExecutionType === 'SCRIPT' ? false : true)) model.hiveCliTaskExecutionType === 'SCRIPT' ? 24 : 0
const resourcesLimit = computed(() => (model.hiveCliTaskExecutionType === 'SCRIPT' ? -1 : 1)) )
const resourcesRequired = computed(() =>
model.hiveCliTaskExecutionType === 'SCRIPT' ? false : true
)
const resourcesLimit = computed(() =>
model.hiveCliTaskExecutionType === 'SCRIPT' ? -1 : 1
)
return [ return [
{ {

4
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-linkis.ts

@ -24,7 +24,7 @@ export function useLinkis(model: { [field: string]: any }): IJsonItem[] {
const configEditorSpan = computed(() => (model.useCustom ? 24 : 0)) const configEditorSpan = computed(() => (model.useCustom ? 24 : 0))
const parmaEditorSpan = computed(() => (model.useCustom ? 0 : 24)) const parmaEditorSpan = computed(() => (model.useCustom ? 0 : 24))
computed(() => (model.useCustom ? 0 : 24)); computed(() => (model.useCustom ? 0 : 24))
return [ return [
{ {
type: 'switch', type: 'switch',
@ -54,7 +54,7 @@ export function useLinkis(model: { [field: string]: any }): IJsonItem[] {
} }
const sameItems = model.localParams.filter( const sameItems = model.localParams.filter(
(item: { prop: string }) => item.prop === value (item: { prop: string }) => item.prop === value
) )
if (sameItems.length > 1) { if (sameItems.length > 1) {

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

@ -58,7 +58,7 @@ export function useNamespace(): IJsonItem {
props: { props: {
loading, loading,
'render-label': renderLabel, 'render-label': renderLabel,
'clearable': true clearable: true
}, },
options: [ options: [
{ {

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

@ -41,7 +41,7 @@ export function useResources(
} }
if (resourcesLoading.value) return if (resourcesLoading.value) return
resourcesLoading.value = true resourcesLoading.value = true
const res = await queryResourceList({ type: 'FILE', fullName:"" }) const res = await queryResourceList({ type: 'FILE', fullName: '' })
utils.removeUselessChildren(res) utils.removeUselessChildren(res)
resourcesOptions.value = res || [] resourcesOptions.value = res || []
resourcesLoading.value = false resourcesLoading.value = false

32
dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-sea-tunnel.ts

@ -24,19 +24,35 @@ export function useSeaTunnel(model: { [field: string]: any }): IJsonItem[] {
const configEditorSpan = computed(() => (model.useCustom ? 24 : 0)) const configEditorSpan = computed(() => (model.useCustom ? 24 : 0))
const resourceEditorSpan = computed(() => (model.useCustom ? 0 : 24)) const resourceEditorSpan = computed(() => (model.useCustom ? 0 : 24))
const flinkSpan = computed(() => (model.startupScript.includes("flink") ? 24 : 0)) const flinkSpan = computed(() =>
const deployModeSpan = computed(() => (model.startupScript.includes("spark") || model.startupScript === "seatunnel.sh" ? 24 : 0)) model.startupScript.includes('flink') ? 24 : 0
const masterSpan = computed(() => (model.startupScript.includes("spark")) && model.deployMode !== 'local' ? 12 : 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(() => const masterUrlSpan = computed(() =>
(model.startupScript.includes("spark")) && model.startupScript.includes('spark') &&
model.deployMode !== 'local' && model.deployMode !== 'local' &&
(model.master === 'SPARK' || model.master === 'MESOS') (model.master === 'SPARK' || model.master === 'MESOS')
? 12 ? 12
: 0 : 0
) )
const showClient = computed(() => model.startupScript.includes("spark")) const showClient = computed(() => model.startupScript.includes('spark'))
const showLocal = computed(() => model.startupScript === 'seatunnel.sh') const showLocal = computed(() => model.startupScript === 'seatunnel.sh')
const othersSpan = computed(() => (model.startupScript.includes("flink") || model.startupScript === 'seatunnel.sh' ? 24 : 0)) const othersSpan = computed(() =>
model.startupScript.includes('flink') ||
model.startupScript === 'seatunnel.sh'
? 24
: 0
)
return [ return [
{ {
@ -56,12 +72,12 @@ export function useSeaTunnel(model: { [field: string]: any }): IJsonItem[] {
if (model.startupScript === 'seatunnel.sh') { if (model.startupScript === 'seatunnel.sh') {
model.deployMode = 'local' model.deployMode = 'local'
} }
if (model.startupScript.includes("spark")) { if (model.startupScript.includes('spark')) {
model.deployMode = 'client' model.deployMode = 'client'
} }
} }
} }
}, }
}, },
// SeaTunnel flink parameter // SeaTunnel flink parameter

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

@ -85,7 +85,7 @@ export function useZeppelin(model: { [field: string]: any }): IJsonItem[] {
field: 'password', field: 'password',
name: t('project.node.zeppelin_password'), name: t('project.node.zeppelin_password'),
props: { props: {
placeholder: t('project.node.zeppelin_password_tips') placeholder: t('project.node.zeppelin_password_tips')
} }
}, },
{ {

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

@ -218,16 +218,16 @@ export function formatParams(data: INodeData): {
taskParams.startupScript = data.startupScript taskParams.startupScript = data.startupScript
taskParams.useCustom = data.useCustom taskParams.useCustom = data.useCustom
taskParams.rawScript = data.rawScript taskParams.rawScript = data.rawScript
if (data.startupScript?.includes("flink")) { if (data.startupScript?.includes('flink')) {
taskParams.runMode = data.runMode taskParams.runMode = data.runMode
taskParams.others = data.others taskParams.others = data.others
} }
if (data.startupScript?.includes("spark")) { if (data.startupScript?.includes('spark')) {
taskParams.deployMode = data.deployMode taskParams.deployMode = data.deployMode
taskParams.master = data.master taskParams.master = data.master
taskParams.masterUrl = data.masterUrl taskParams.masterUrl = data.masterUrl
} }
if (data.startupScript === "seatunnel.sh") { if (data.startupScript === 'seatunnel.sh') {
taskParams.deployMode = data.deployMode taskParams.deployMode = data.deployMode
taskParams.others = data.others taskParams.others = data.others
} }
@ -502,7 +502,7 @@ export function formatParams(data: INodeData): {
: '0', : '0',
failRetryTimes: data.failRetryTimes ? String(data.failRetryTimes) : '0', failRetryTimes: data.failRetryTimes ? String(data.failRetryTimes) : '0',
flag: data.flag, flag: data.flag,
isCache: data.isCache ? "YES" : "NO", isCache: data.isCache ? 'YES' : 'NO',
name: data.name, name: data.name,
taskGroupId: data.taskGroupId, taskGroupId: data.taskGroupId,
taskGroupPriority: data.taskGroupPriority, taskGroupPriority: data.taskGroupPriority,
@ -514,7 +514,9 @@ export function formatParams(data: INodeData): {
initScript: data.initScript, initScript: data.initScript,
rawScript: data.rawScript, rawScript: data.rawScript,
resourceList: data.resourceList?.length resourceList: data.resourceList?.length
? data.resourceList.map((fullName: string) => ({ resourceName: `${fullName}` })) ? data.resourceList.map((fullName: string) => ({
resourceName: `${fullName}`
}))
: [], : [],
...taskParams ...taskParams
}, },
@ -563,7 +565,7 @@ export function formatModel(data: ITaskData) {
} }
if (data.taskParams?.resourceList) { if (data.taskParams?.resourceList) {
params.resourceList = data.taskParams.resourceList.map( params.resourceList = data.taskParams.resourceList.map(
(item: { resourceName: string }) => (`${item.resourceName}`) (item: { resourceName: string }) => `${item.resourceName}`
) )
} }
if (data.taskParams?.mainJar) { if (data.taskParams?.mainJar) {

110
dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-datasync.ts

@ -20,64 +20,64 @@ import * as Fields from '../fields/index'
import type { IJsonItem, INodeData, ITaskData } from '../types' import type { IJsonItem, INodeData, ITaskData } from '../types'
export function useDatasync({ export function useDatasync({
projectCode, projectCode,
from = 0, from = 0,
readonly, readonly,
data data
}: { }: {
projectCode: number projectCode: number
from?: number from?: number
readonly?: boolean readonly?: boolean
data?: ITaskData data?: ITaskData
}) { }) {
const model = reactive({ const model = reactive({
name: '', name: '',
taskType: 'DATASYNC', taskType: 'DATASYNC',
flag: 'YES', flag: 'YES',
description: '', description: '',
timeoutFlag: false, timeoutFlag: false,
localParams: [], localParams: [],
environmentCode: null, environmentCode: null,
failRetryInterval: 1, failRetryInterval: 1,
failRetryTimes: 0, failRetryTimes: 0,
workerGroup: 'default', workerGroup: 'default',
delayTime: 0, delayTime: 0,
timeout: 30, timeout: 30,
timeoutNotifyStrategy: ['WARN'], timeoutNotifyStrategy: ['WARN']
} as INodeData) } as INodeData)
let extra: IJsonItem[] = [] let extra: IJsonItem[] = []
if (from === 1) { if (from === 1) {
extra = [ extra = [
Fields.useTaskType(model, readonly), Fields.useTaskType(model, readonly),
Fields.useProcessName({ Fields.useProcessName({
model, model,
projectCode, projectCode,
isCreate: !data?.id, isCreate: !data?.id,
from, from,
processName: data?.processName processName: data?.processName
}) })
] ]
} }
return { return {
json: [ json: [
Fields.useName(from), Fields.useName(from),
...extra, ...extra,
Fields.useRunFlag(), Fields.useRunFlag(),
Fields.useCache(), Fields.useCache(),
Fields.useDescription(), Fields.useDescription(),
Fields.useTaskPriority(), Fields.useTaskPriority(),
Fields.useWorkerGroup(), Fields.useWorkerGroup(),
Fields.useEnvironmentName(model, !model.id), Fields.useEnvironmentName(model, !model.id),
...Fields.useTaskGroup(model, projectCode), ...Fields.useTaskGroup(model, projectCode),
...Fields.useFailed(), ...Fields.useFailed(),
...Fields.useResourceLimit(), ...Fields.useResourceLimit(),
Fields.useDelayTime(model), Fields.useDelayTime(model),
...Fields.useTimeoutAlarm(model), ...Fields.useTimeoutAlarm(model),
...Fields.useDatasync(model), ...Fields.useDatasync(model),
Fields.usePreTasks() Fields.usePreTasks()
] as IJsonItem[], ] as IJsonItem[],
model model
} }
} }

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

@ -44,7 +44,7 @@ export function useDms({
delayTime: 0, delayTime: 0,
timeout: 30, timeout: 30,
timeoutNotifyStrategy: ['WARN'], timeoutNotifyStrategy: ['WARN'],
isRestartTask: false, isRestartTask: false
} as INodeData) } as INodeData)
let extra: IJsonItem[] = [] let extra: IJsonItem[] = []

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

@ -52,7 +52,7 @@ export function useLinkis({
{ {
prop: '', prop: '',
value: '' value: ''
}, }
], ],
rawScript: '' rawScript: ''
} as INodeData) } as INodeData)

46
dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-sea-tunnel.ts

@ -56,29 +56,29 @@ export function useSeaTunnel({
timeoutNotifyStrategy: ['WARN'], timeoutNotifyStrategy: ['WARN'],
rawScript: rawScript:
'env {\n' + 'env {\n' +
' execution.parallelism = 2\n' + ' execution.parallelism = 2\n' +
' job.mode = "BATCH"\n' + ' job.mode = "BATCH"\n' +
' checkpoint.interval = 10000\n' + ' checkpoint.interval = 10000\n' +
'}\n' + '}\n' +
'\n' + '\n' +
'source {\n' + 'source {\n' +
' FakeSource {\n' + ' FakeSource {\n' +
' parallelism = 2\n' + ' parallelism = 2\n' +
' result_table_name = "fake"\n' + ' result_table_name = "fake"\n' +
' row.num = 16\n' + ' row.num = 16\n' +
' schema = {\n' + ' schema = {\n' +
' fields {\n' + ' fields {\n' +
' name = "string"\n' + ' name = "string"\n' +
' age = "int"\n' + ' age = "int"\n' +
' }\n' + ' }\n' +
' }\n' + ' }\n' +
' }\n' + ' }\n' +
'}\n' + '}\n' +
'\n' + '\n' +
'sink {\n' + 'sink {\n' +
' Console {\n' + ' Console {\n' +
' }\n' + ' }\n' +
'}' '}'
} as INodeData) } as INodeData)
return { return {

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

@ -120,8 +120,8 @@ interface IDependentParameters {
* res: resource file name * res: resource file name
*/ */
interface ISourceItem { interface ISourceItem {
id?: number, id?: number
resourceName: string, resourceName: string
res?: string res?: string
} }
@ -495,7 +495,7 @@ interface ITaskData
> { > {
name?: string name?: string
taskPriority?: string taskPriority?: string
isCache?: "YES" | "NO" isCache?: 'YES' | 'NO'
timeoutFlag?: 'OPEN' | 'CLOSE' timeoutFlag?: 'OPEN' | 'CLOSE'
timeoutNotifyStrategy?: string | [] timeoutNotifyStrategy?: string | []
taskParams?: ITaskParams taskParams?: ITaskParams

14
dolphinscheduler-ui/src/views/projects/task/definition/use-table.ts

@ -77,13 +77,13 @@ export function useTable(onEdit: Function) {
}, },
{ {
default: () => default: () =>
h( h(
NEllipsis, NEllipsis,
{ {
style: 'max-width: 580px;line-height: 1.5' style: 'max-width: 580px;line-height: 1.5'
}, },
() => row.taskName () => row.taskName
) )
} }
) )
}, },

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

@ -107,7 +107,7 @@ const BatchTaskInstance = defineComponent({
variables.showModalRef = false variables.showModalRef = false
} }
var getLogsID: number let getLogsID: number
const getLogs = (row: any, logTimer: number) => { const getLogs = (row: any, logTimer: number) => {
const { state } = useAsyncState( const { state } = useAsyncState(

1
dolphinscheduler-ui/src/views/projects/task/instance/index.tsx

@ -21,7 +21,6 @@ import { NTabPane, NTabs } from 'naive-ui'
import BatchTaskInstance from './batch-task' import BatchTaskInstance from './batch-task'
import StreamTaskInstance from './stream-task' import StreamTaskInstance from './stream-task'
const TaskDefinition = defineComponent({ const TaskDefinition = defineComponent({
name: 'task-instance', name: 'task-instance',
setup() { setup() {

28
dolphinscheduler-ui/src/views/projects/task/instance/use-table.ts

@ -23,14 +23,7 @@ import {
forceSuccess, forceSuccess,
downloadLog downloadLog
} from '@/service/modules/task-instances' } from '@/service/modules/task-instances'
import { import { NButton, NIcon, NSpace, NTooltip, NSpin, NEllipsis } from 'naive-ui'
NButton,
NIcon,
NSpace,
NTooltip,
NSpin,
NEllipsis
} from 'naive-ui'
import ButtonLink from '@/components/button-link' import ButtonLink from '@/components/button-link'
import { import {
AlignLeftOutlined, AlignLeftOutlined,
@ -39,19 +32,14 @@ import {
} from '@vicons/antd' } from '@vicons/antd'
import { format } from 'date-fns' import { format } from 'date-fns'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { import { parseTime, renderTableTime, tasksState } from '@/common/common'
parseTime,
renderTableTime,
tasksState
} from '@/common/common'
import { import {
COLUMN_WIDTH_CONFIG, COLUMN_WIDTH_CONFIG,
calculateTableWidth, calculateTableWidth,
DefaultTableWidth DefaultTableWidth
} from '@/common/column-width-config' } from '@/common/column-width-config'
import type { Router, TaskInstancesRes, IRecord, ITaskState } from './types' import type { Router, TaskInstancesRes, IRecord, ITaskState } from './types'
import {renderEnvironmentalDistinctionCell} from "@/utils/environmental-distinction"; import { renderEnvironmentalDistinctionCell } from '@/utils/environmental-distinction'
export function useTable() { export function useTable() {
const { t } = useI18n() const { t } = useI18n()
@ -98,7 +86,7 @@ export function useTable() {
...COLUMN_WIDTH_CONFIG['name'], ...COLUMN_WIDTH_CONFIG['name'],
resizable: true, resizable: true,
minWidth: 200, minWidth: 200,
maxWidth: 600, maxWidth: 600
}, },
{ {
title: t('project.task.workflow_instance'), title: t('project.task.workflow_instance'),
@ -115,7 +103,7 @@ export function useTable() {
ButtonLink, ButtonLink,
{ {
onClick: () => { onClick: () => {
let routeUrl = router.resolve({ const routeUrl = router.resolve({
name: 'workflow-instance-detail', name: 'workflow-instance-detail',
params: { id: row.processInstanceId }, params: { id: row.processInstanceId },
query: { code: projectCode } query: { code: projectCode }
@ -127,9 +115,9 @@ export function useTable() {
default: () => default: () =>
h( h(
NEllipsis, NEllipsis,
{ {
style: 'max-width: 580px;line-height: 1.5' style: 'max-width: 580px;line-height: 1.5'
}, },
() => row.processInstanceName () => row.processInstanceName
) )
} }

2
dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-config.ts

@ -252,7 +252,7 @@ export const EDGE = {
router: { router: {
name: 'er', name: 'er',
args: { args: {
offset: 12, offset: 12
} }
}, },
defaultLabel: { defaultLabel: {

79
dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-context-menu.tsx

@ -63,7 +63,16 @@ const props = {
export default defineComponent({ export default defineComponent({
name: 'dag-context-menu', name: 'dag-context-menu',
props, props,
emits: ['hide', 'start', 'edit', 'viewLog', 'copyTask', 'removeTasks', 'executeTask', 'removeTaskInstanceCache'], emits: [
'hide',
'start',
'edit',
'viewLog',
'copyTask',
'removeTasks',
'executeTask',
'removeTaskInstanceCache'
],
setup(props, ctx) { setup(props, ctx) {
const graph = inject('graph', ref()) const graph = inject('graph', ref())
const route = useRoute() const route = useRoute()
@ -188,42 +197,42 @@ export default defineComponent({
</> </>
)} )}
{this.taskInstance && ( {this.taskInstance && (
<> <>
<NButton <NButton
class={`${styles['menu-item']}`} class={`${styles['menu-item']}`}
onClick={this.handleViewLog} onClick={this.handleViewLog}
> >
{t('project.node.view_log')} {t('project.node.view_log')}
</NButton> </NButton>
<NButton <NButton
class={`${styles['menu-item']}`} class={`${styles['menu-item']}`}
onClick={this.handleRemoveTaskInstanceCache} onClick={this.handleRemoveTaskInstanceCache}
> >
{t('project.task.remove_task_cache')} {t('project.task.remove_task_cache')}
</NButton> </NButton>
</> </>
)} )}
{this.executeTaskDisplay && ( {this.executeTaskDisplay && (
<> <>
<NButton <NButton
class={`${styles['menu-item']}`} class={`${styles['menu-item']}`}
onClick={this.handleExecuteTaskOnly} onClick={this.handleExecuteTaskOnly}
> >
{t('project.workflow.current_node_execution_task')} {t('project.workflow.current_node_execution_task')}
</NButton> </NButton>
<NButton <NButton
class={`${styles['menu-item']}`} class={`${styles['menu-item']}`}
onClick={this.handleExecuteTaskPOST} onClick={this.handleExecuteTaskPOST}
> >
{t('project.workflow.backward_execution_task')} {t('project.workflow.backward_execution_task')}
</NButton> </NButton>
<NButton <NButton
class={`${styles['menu-item']}`} class={`${styles['menu-item']}`}
onClick={this.handleExecuteTaskPRE} onClick={this.handleExecuteTaskPRE}
> >
{t('project.workflow.forward_execution_task')} {t('project.workflow.forward_execution_task')}
</NButton> </NButton>
</> </>
)} )}
</div> </div>
) )

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

@ -96,7 +96,7 @@ export default defineComponent({
handleDagMenu() handleDagMenu()
}) })
return () => return () => (
<div class={styles.sidebar}> <div class={styles.sidebar}>
<NCollapse default-expanded-names='1' accordion> <NCollapse default-expanded-names='1' accordion>
{variables.fav.length > 0 && ( {variables.fav.length > 0 && (
@ -139,11 +139,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -192,11 +188,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -245,11 +237,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -298,11 +286,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -351,11 +335,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -404,11 +384,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -457,11 +433,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -510,11 +482,7 @@ export default defineComponent({
: '#ccc' : '#ccc'
} }
> >
{task.collection ? ( {task.collection ? <StarFilled /> : <StarOutlined />}
<StarFilled />
) : (
<StarOutlined />
)}
</NIcon> </NIcon>
</div> </div>
</div> </div>
@ -525,5 +493,6 @@ export default defineComponent({
)} )}
</NCollapse> </NCollapse>
</div> </div>
)
} }
}) })

58
dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-toolbar.tsx

@ -217,37 +217,33 @@ export default defineComponent({
)} )}
{props.definition?.processDefinition?.name && ( {props.definition?.processDefinition?.name && (
<NTooltip <NTooltip
v-slots={{ v-slots={{
trigger: () => ( trigger: () => (
<NPopover <NPopover
placement='bottom' placement='bottom'
trigger='click' trigger='click'
scrollable scrollable
style={{ maxWidth: '50vw', maxHeight: '70vh' }} style={{ maxWidth: '50vw', maxHeight: '70vh' }}
> >
{{ {{
trigger: () => ( trigger: () => (
<NButton <NButton quaternary circle class={Styles['toolbar-btn']}>
quaternary <NIcon>
circle <FundViewOutlined />
class={Styles['toolbar-btn']} </NIcon>
> </NButton>
<NIcon> ),
<FundViewOutlined /> header: () => (
</NIcon> <NText strong depth={1}>
</NButton> {t('project.workflow.parameters_variables')}
), </NText>
header: () => ( ),
<NText strong depth={1}> default: () => <VariablesView onCopy={copy} />
{t('project.workflow.parameters_variables')} }}
</NText> </NPopover>
), ),
default: () => <VariablesView onCopy={copy} /> default: () => t('project.dag.view_variables')
}} }}
</NPopover>
),
default: () => t('project.dag.view_variables')
}}
></NTooltip> ></NTooltip>
)} )}
<div class={Styles['toolbar-left-part']}> <div class={Styles['toolbar-left-part']}>

37
dolphinscheduler-ui/src/views/projects/workflow/components/dag/index.tsx

@ -139,9 +139,7 @@ export default defineComponent({
// execute task buttons in the dag node menu // execute task buttons in the dag node menu
const executeTaskDisplay = computed(() => { const executeTaskDisplay = computed(() => {
return ( return route.name === 'workflow-instance-detail'
route.name === 'workflow-instance-detail'
)
}) })
// other button in the dag node menu // other button in the dag node menu
@ -250,7 +248,7 @@ export default defineComponent({
getLogs(logTimer) getLogs(logTimer)
} }
var getLogsID: number let getLogsID: number
const getLogs = (logTimer: number) => { const getLogs = (logTimer: number) => {
const { state } = useAsyncState( const { state } = useAsyncState(
@ -259,7 +257,6 @@ export default defineComponent({
limit: nodeVariables.limit, limit: nodeVariables.limit,
skipLineNum: nodeVariables.skipLineNum skipLineNum: nodeVariables.skipLineNum
}).then((res: any) => { }).then((res: any) => {
nodeVariables.logRef += res.message || '' nodeVariables.logRef += res.message || ''
if (res && res.message !== '') { if (res && res.message !== '') {
nodeVariables.limit += 1000 nodeVariables.limit += 1000
@ -292,18 +289,23 @@ export default defineComponent({
getLogs(logTimer) getLogs(logTimer)
} }
const handleExecuteTask = (startNodeList: number, taskDependType: string) => { const handleExecuteTask = (
executeTask({ startNodeList: number,
processInstanceId: Number(route.params.id), taskDependType: string
startNodeList: startNodeList, ) => {
taskDependType: taskDependType, executeTask(
}, {
props.projectCode).then(() => { processInstanceId: Number(route.params.id),
window.$message.success(t('project.workflow.success')) startNodeList: startNodeList,
setTimeout(() => { taskDependType: taskDependType
window.location.reload(); },
}, 1000); props.projectCode
}) ).then(() => {
window.$message.success(t('project.workflow.success'))
setTimeout(() => {
window.location.reload()
}, 1000)
})
} }
const handleRemoveTaskInstanceCache = (taskId: number) => { const handleRemoveTaskInstanceCache = (taskId: number) => {
@ -450,4 +452,3 @@ export default defineComponent({
) )
} }
}) })

16
dolphinscheduler-ui/src/views/projects/workflow/components/dag/use-canvas-init.ts

@ -108,10 +108,10 @@ export function useCanvasInit(options: Options) {
const { sourceCell, targetCell } = data const { sourceCell, targetCell } = data
if ( if (
sourceCell && sourceCell &&
targetCell && targetCell &&
sourceCell.isNode() && sourceCell.isNode() &&
targetCell.isNode() targetCell.isNode()
) { ) {
const sourceData = sourceCell.getData() const sourceData = sourceCell.getData()
if (!sourceData) return true if (!sourceData) return true
@ -135,10 +135,10 @@ export function useCanvasInit(options: Options) {
edge?.setAttrs({ edge?.setAttrs({
line: { line: {
strokeDasharray: strokeDasharray:
sourceData.taskExecuteType === 'STREAM' || sourceData.taskExecuteType === 'STREAM' ||
targetData.taskExecuteType === 'STREAM' targetData.taskExecuteType === 'STREAM'
? '5 5' ? '5 5'
: 'none' : 'none'
} }
}) })
return true return true

21
dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/dag-canvas.tsx

@ -62,7 +62,7 @@ const DagCanvas = defineComponent({
}) })
watch(dagTasks, () => { watch(dagTasks, () => {
useAddDagShape((graph.value as Graph)) useAddDagShape(graph.value as Graph)
}) })
return { return {
@ -74,16 +74,19 @@ const DagCanvas = defineComponent({
} }
}, },
render() { render() {
return( return (
<> <>
<div ref='container' class={styles.container} <div
onDrop={this.handleDrop} ref='container'
onDragenter={this.handlePreventDefault} class={styles.container}
onDragover={this.handlePreventDefault} onDrop={this.handleDrop}
onDragleave={this.handlePreventDefault}> onDragenter={this.handlePreventDefault}
<div ref='dag-container' class={styles['dag-container']}/> onDragover={this.handlePreventDefault}
onDragleave={this.handlePreventDefault}
>
<div ref='dag-container' class={styles['dag-container']} />
</div> </div>
<div ref='minimapContainer' class={styles.minimap}/> <div ref='minimapContainer' class={styles.minimap} />
</> </>
) )
} }

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

@ -41,15 +41,17 @@ const DagSidebar = defineComponent({
render() { render() {
return ( return (
<div> <div>
{ {this.taskList.map((task: any) => {
this.taskList.map((task: any) => { return (
return ( <div
<div class={styles['task-item']} draggable='true' onDragstart={() => this.handleDragstart(task)}> class={styles['task-item']}
{task.name} draggable='true'
</div> onDragstart={() => this.handleDragstart(task)}
) >
}) {task.name}
} </div>
)
})}
</div> </div>
) )
} }

16
dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/index.tsx

@ -40,7 +40,7 @@ const DynamicDag = defineComponent({
} }
const handelDrop = (e: DragEvent) => { const handelDrop = (e: DragEvent) => {
if (!draggedTask) return if (!draggedTask.value) return
const shapes = useDagStore().getDagTasks const shapes = useDagStore().getDagTasks
@ -73,18 +73,18 @@ const DynamicDag = defineComponent({
return ( return (
<> <>
<div class={styles['workflow-dag']}> <div class={styles['workflow-dag']}>
<DagSidebar onDragstart={this.handelDragstart}/> <DagSidebar onDragstart={this.handelDragstart} />
<DagCanvas onDrop={this.handelDrop}/> <DagCanvas onDrop={this.handelDrop} />
</div> </div>
{ {this.draggedTask && this.formData && (
this.draggedTask && this.formData && <TaskForm <TaskForm
task={this.draggedTask} task={this.draggedTask}
formData={this.formData} formData={this.formData}
showModal={this.showModal} showModal={this.showModal}
onCancelModal={() => this.showModal = false} onCancelModal={() => (this.showModal = false)}
onConfirmModal={() => this.showModal = false} onConfirmModal={() => (this.showModal = false)}
/> />
} )}
</> </>
) )
} }

79
dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/index.tsx

@ -15,7 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineComponent, getCurrentInstance, PropType, toRefs, watch } from 'vue' import {
defineComponent,
getCurrentInstance,
PropType,
toRefs,
watch
} from 'vue'
import { NForm, NFormItem, NInput, NSelect } from 'naive-ui' import { NForm, NFormItem, NInput, NSelect } from 'naive-ui'
import { useTaskForm } from './use-task-form' import { useTaskForm } from './use-task-form'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@ -55,15 +61,19 @@ const TaskForm = defineComponent({
} }
const onUpdateValue = (v: any, f: any) => { const onUpdateValue = (v: any, f: any) => {
f.modelField.indexOf('.') >= 0 ? f.modelField.indexOf('.') >= 0
(variables.model as any)[f.modelField.split('.')[0]][f.modelField.split('.')[1]] = v : ? ((variables.model as any)[f.modelField.split('.')[0]][
(variables.model as any)[f.modelField] = v f.modelField.split('.')[1]
] = v)
: ((variables.model as any)[f.modelField] = v)
} }
const setDefaultValue = (f: any) => { const setDefaultValue = (f: any) => {
return f.modelField.indexOf('.') >= 0 ? return f.modelField.indexOf('.') >= 0
(variables.model as any)[f.modelField.split('.')[0]][f.modelField.split('.')[1]] : ? (variables.model as any)[f.modelField.split('.')[0]][
(variables.model as any)[f.modelField] f.modelField.split('.')[1]
]
: (variables.model as any)[f.modelField]
} }
watch(variables.model, () => { watch(variables.model, () => {
@ -86,52 +96,47 @@ const TaskForm = defineComponent({
title={this.task} title={this.task}
show={this.showModal} show={this.showModal}
onCancel={this.cancelModal} onCancel={this.cancelModal}
onConfirm={this.confirmModal}> onConfirm={this.confirmModal}
<NForm >
model={this.model} <NForm model={this.model} rules={this.rules} ref={'taskForm'}>
rules={this.rules} {(this.formStructure as Array<any>).map((f) => {
ref={'taskForm'}> return (
{ <NFormItem label={this.t(f.label)} path={f.field}>
(this.formStructure as Array<any>).map(f => { {f.type === 'input' && (
return <NFormItem <NInput
label={this.t(f.label)}
path={f.field}
>
{
f.type === 'input' && <NInput
allowInput={this.trim} allowInput={this.trim}
placeholder={f.placeholder ? this.t(f.placeholder) : ''} placeholder={f.placeholder ? this.t(f.placeholder) : ''}
defaultValue={this.setDefaultValue(f)} defaultValue={this.setDefaultValue(f)}
onUpdateValue={(v) => this.onUpdateValue(v, f)} onUpdateValue={(v) => this.onUpdateValue(v, f)}
clearable={f.clearable} clearable={f.clearable}
/> />
} )}
{ {f.type === 'select' && (
f.type === 'select' && <NSelect <NSelect
placeholder={f.placeholder ? this.t(f.placeholder) : ''} placeholder={f.placeholder ? this.t(f.placeholder) : ''}
defaultValue={this.setDefaultValue(f)} defaultValue={this.setDefaultValue(f)}
onUpdateValue={(v) => this.onUpdateValue(v, f)} onUpdateValue={(v) => this.onUpdateValue(v, f)}
options={ options={
f.optionsLocale ? f.optionsLocale
f.options.map((o: SelectOption) => { ? f.options.map((o: SelectOption) => {
return { return {
label: this.t(o.label as string), label: this.t(o.label as string),
value: o.value value: o.value
} }
}) : })
f.options : f.options
} }
/> />
} )}
{ {f.type === 'studio' && (
f.type === 'studio' && <MonacoEditor <MonacoEditor
defaultValue={this.setDefaultValue(f)} defaultValue={this.setDefaultValue(f)}
onUpdateValue={(v) => this.onUpdateValue(v, f)} onUpdateValue={(v) => this.onUpdateValue(v, f)}
/> />
} )}
</NFormItem> </NFormItem>
}) )
} })}
</NForm> </NForm>
</Modal> </Modal>
) )

7
dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-form-field.ts

@ -22,12 +22,7 @@ export function useFormField(forms: Array<any>) {
const model: any = {} const model: any = {}
const setField = (value: string, type: string): Ref<null | string> => { const setField = (value: string, type: string): Ref<null | string> => {
return ref(value ? return ref(value ? value : type === 'select' ? null : '')
value :
type === 'select' ?
null :
''
)
} }
forms.forEach((f: any) => { forms.forEach((f: any) => {

2
dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-form-request.ts

@ -25,7 +25,7 @@ const reqFunction = (url: string, method: string) => {
} }
export function useFormRequest(apis: any, forms: Array<any>): Array<any> { export function useFormRequest(apis: any, forms: Array<any>): Array<any> {
forms.map(f => { forms.map((f) => {
if (f.api) { if (f.api) {
reqFunction(apis[f.api].url, apis[f.api].method).then((res: any) => { reqFunction(apis[f.api].url, apis[f.api].method).then((res: any) => {
f.options = res.map((r: any) => { f.options = res.map((r: any) => {

4
dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-task-form.ts

@ -33,7 +33,9 @@ export function useTaskForm(data: any) {
useDynamicLocales(data.locales) useDynamicLocales(data.locales)
variables.model = useFormField(data.forms) variables.model = useFormField(data.forms)
variables.rules = useFormValidate(data.forms, variables.model) variables.rules = useFormValidate(data.forms, variables.model)
variables.formStructure = useFormStructure(useFormRequest(data.apis, data.forms)) variables.formStructure = useFormStructure(
useFormRequest(data.apis, data.forms)
)
const handleValidate = () => { const handleValidate = () => {
variables.taskForm.validate((err: any) => { variables.taskForm.validate((err: any) => {

5
dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/use-sidebar.ts

@ -16,7 +16,10 @@
*/ */
import { reactive } from 'vue' import { reactive } from 'vue'
import { queryDynamicTaskCategories, queryDynamicTaskResourceList } from '@/service/modules/dynamic-dag' import {
queryDynamicTaskCategories,
queryDynamicTaskResourceList
} from '@/service/modules/dynamic-dag'
export function useSidebar() { export function useSidebar() {
const variables = reactive({ const variables = reactive({

2
dolphinscheduler-ui/src/views/projects/workflow/definition/components/use-modal.ts

@ -87,7 +87,7 @@ export function useModal(
} }
} }
const handleStartDefinition = async (code: number,version: number) => { const handleStartDefinition = async (code: number, version: number) => {
await state.startFormRef.validate() await state.startFormRef.validate()
if (state.saving) return if (state.saving) return

8
dolphinscheduler-ui/src/views/projects/workflow/definition/create/index.tsx

@ -88,9 +88,11 @@ export default defineComponent({
theme.darkTheme ? Styles['dark'] : Styles['light'] theme.darkTheme ? Styles['dark'] : Styles['light']
]} ]}
> >
{ {route.query.dynamic === 'true' ? (
route.query.dynamic === 'true' ? <DynamicDag /> : <Dag projectCode={projectCode} onSave={onSave} /> <DynamicDag />
} ) : (
<Dag projectCode={projectCode} onSave={onSave} />
)}
</div> </div>
) )
} }

10
dolphinscheduler-ui/src/views/projects/workflow/definition/index.tsx

@ -43,7 +43,7 @@ import TimingModal from './components/timing-modal'
import VersionModal from './components/version-modal' import VersionModal from './components/version-modal'
import CopyModal from './components/copy-modal' import CopyModal from './components/copy-modal'
import type { Router } from 'vue-router' import type { Router } from 'vue-router'
import Search from "@/components/input-search"; import Search from '@/components/input-search'
export default defineComponent({ export default defineComponent({
name: 'WorkflowDefinitionList', name: 'WorkflowDefinitionList',
@ -158,15 +158,15 @@ export default defineComponent({
> >
{t('project.workflow.create_workflow')} {t('project.workflow.create_workflow')}
</NButton> </NButton>
{ {this.uiSettingStore.getDynamicTask && (
this.uiSettingStore.getDynamicTask && <NButton <NButton
type='warning' type='warning'
size='small' size='small'
onClick={this.createDefinitionDynamic} onClick={this.createDefinitionDynamic}
> >
{t('project.workflow.create_workflow_dynamic')} {t('project.workflow.create_workflow_dynamic')}
</NButton> </NButton>
} )}
<NButton <NButton
strong strong
secondary secondary
@ -178,7 +178,7 @@ export default defineComponent({
</NSpace> </NSpace>
<NSpace> <NSpace>
<Search <Search
placeholder = {t('resource.function.enter_keyword_tips')} placeholder={t('resource.function.enter_keyword_tips')}
v-model:value={this.searchVal} v-model:value={this.searchVal}
onSearch={this.handleSearch} onSearch={this.handleSearch}
onClear={this.onClearSearch} onClear={this.onClearSearch}

4
dolphinscheduler-ui/src/views/projects/workflow/definition/timing/index.tsx

@ -34,7 +34,9 @@ export default defineComponent({
getTableData({ getTableData({
pageSize: variables.pageSize, pageSize: variables.pageSize,
pageNo: variables.page, pageNo: variables.page,
searchVal: variables.searchVal searchVal: variables.searchVal,
projectCode: variables.projectCode,
processDefinitionCode: variables.processDefinitionCode
}) })
} }

2
dolphinscheduler-ui/src/views/projects/workflow/definition/timing/types.ts

@ -18,5 +18,7 @@
export interface ISearchParam { export interface ISearchParam {
pageSize: number pageSize: number
pageNo: number pageNo: number
projectCode: number
processDefinitionCode: number
searchVal: string | undefined searchVal: string | undefined
} }

59
dolphinscheduler-ui/src/views/projects/workflow/definition/timing/use-table.ts

@ -18,7 +18,7 @@
import { h, ref, reactive } from 'vue' import { h, ref, reactive } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { NSpace, NTooltip, NButton, NPopconfirm } from 'naive-ui' import { NSpace, NTooltip, NButton, NPopconfirm, NTag } from 'naive-ui'
import { import {
deleteScheduleById, deleteScheduleById,
offline, offline,
@ -55,7 +55,10 @@ export function useTable() {
searchVal: ref(), searchVal: ref(),
totalPage: ref(1), totalPage: ref(1),
showRef: ref(false), showRef: ref(false),
loadingRef: ref(false) loadingRef: ref(false),
processDefinitionCode: router.currentRoute.value.params.definitionCode
? ref(Number(router.currentRoute.value.params.definitionCode))
: ref()
}) })
const renderTime = (time: string, timeZone: string) => { const renderTime = (time: string, timeZone: string) => {
@ -118,10 +121,25 @@ export function useTable() {
title: t('project.workflow.status'), title: t('project.workflow.status'),
key: 'releaseState', key: 'releaseState',
...COLUMN_WIDTH_CONFIG['state'], ...COLUMN_WIDTH_CONFIG['state'],
render: (row: any) => render: (row: any) => {
row.releaseState === 'ONLINE' if (row.releaseState === 'ONLINE') {
? t('project.workflow.up_line') return h(
: t('project.workflow.down_line') NTag,
{ type: 'success', size: 'small' },
{
default: () => t('project.workflow.up_line')
}
)
} else {
return h(
NTag,
{ type: 'warning', size: 'small' },
{
default: () => t('project.workflow.down_line')
}
)
}
}
}, },
{ {
title: t('project.workflow.worker_group'), title: t('project.workflow.worker_group'),
@ -258,19 +276,16 @@ export function useTable() {
const getTableData = (params: ISearchParam) => { const getTableData = (params: ISearchParam) => {
if (variables.loadingRef) return if (variables.loadingRef) return
variables.loadingRef = true variables.loadingRef = true
const definitionCode = Number(
router.currentRoute.value.params.definitionCode queryScheduleListPaging({ ...params }, variables.projectCode).then(
(res: any) => {
variables.totalPage = res.totalPage
variables.tableData = res.totalList.map((item: any) => {
return { ...item }
})
variables.loadingRef = false
}
) )
queryScheduleListPaging(
{ ...params, processDefinitionCode: definitionCode },
variables.projectCode
).then((res: any) => {
variables.totalPage = res.totalPage
variables.tableData = res.totalList.map((item: any) => {
return { ...item }
})
variables.loadingRef = false
})
} }
const handleReleaseState = (row: any) => { const handleReleaseState = (row: any) => {
@ -284,7 +299,9 @@ export function useTable() {
getTableData({ getTableData({
pageSize: variables.pageSize, pageSize: variables.pageSize,
pageNo: variables.page, pageNo: variables.page,
searchVal: variables.searchVal searchVal: variables.searchVal,
projectCode: variables.projectCode,
processDefinitionCode: variables.processDefinitionCode
}) })
}) })
} }
@ -299,7 +316,9 @@ export function useTable() {
getTableData({ getTableData({
pageSize: variables.pageSize, pageSize: variables.pageSize,
pageNo: variables.page, pageNo: variables.page,
searchVal: variables.searchVal searchVal: variables.searchVal,
projectCode: variables.projectCode,
processDefinitionCode: variables.processDefinitionCode
}) })
}) })
} }

2
dolphinscheduler-ui/src/views/projects/workflow/definition/use-table.ts

@ -103,7 +103,7 @@ export function useTable() {
ButtonLink, ButtonLink,
{ {
onClick: () => { onClick: () => {
let routeUrl = router.resolve({ const routeUrl = router.resolve({
name: 'workflow-definition-detail', name: 'workflow-definition-detail',
params: { code: row.code } params: { code: row.code }
}) })

19
dolphinscheduler-ui/src/views/projects/workflow/instance/components/variables-view.tsx

@ -19,11 +19,10 @@ import { useRoute } from 'vue-router'
import { defineComponent, onMounted, ref, computed } from 'vue' import { defineComponent, onMounted, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { viewVariables } from '@/service/modules/process-instances' import { viewVariables } from '@/service/modules/process-instances'
import { viewProcessDefinitionVariables } from "@/service/modules/process-definition"; import { viewProcessDefinitionVariables } from '@/service/modules/process-definition'
import styles from './variables.module.scss' import styles from './variables.module.scss'
import { NButton } from 'naive-ui' import { NButton } from 'naive-ui'
export default defineComponent({ export default defineComponent({
name: 'variables-view', name: 'variables-view',
emits: ['copy'], emits: ['copy'],
@ -38,18 +37,24 @@ export default defineComponent({
const processCode = Number(route.params.code) const processCode = Number(route.params.code)
const globalParams = computed(() => { const globalParams = computed(() => {
return paramsRef.value && paramsRef.value.globalParams ? paramsRef.value.globalParams : [] return paramsRef.value && paramsRef.value.globalParams
? paramsRef.value.globalParams
: []
}) })
const localParams = computed(() => { const localParams = computed(() => {
return paramsRef.value && paramsRef.value.localParams ? paramsRef.value.localParams : {} return paramsRef.value && paramsRef.value.localParams
? paramsRef.value.localParams
: {}
}) })
const getViewVariables = () => { const getViewVariables = () => {
if (Number.isNaN(instanceId)) { if (Number.isNaN(instanceId)) {
viewProcessDefinitionVariables(projectCode, processCode).then((res: any) => { viewProcessDefinitionVariables(projectCode, processCode).then(
paramsRef.value = res (res: any) => {
}) paramsRef.value = res
}
)
} else { } else {
viewVariables(instanceId, projectCode).then((res: any) => { viewVariables(instanceId, projectCode).then((res: any) => {
paramsRef.value = res paramsRef.value = res

2
dolphinscheduler-ui/src/views/projects/workflow/instance/use-table.ts

@ -98,7 +98,7 @@ export function useTable() {
ButtonLink, ButtonLink,
{ {
onClick: () => { onClick: () => {
let routeUrl = router.resolve({ const routeUrl = router.resolve({
name: 'workflow-instance-detail', name: 'workflow-instance-detail',
params: { id: row.id }, params: { id: row.id },
query: { code: row.processDefinitionCode } query: { code: row.processDefinitionCode }

17
dolphinscheduler-ui/src/views/projects/workflow/relation/index.tsx

@ -18,7 +18,14 @@
import { defineComponent, onMounted, toRefs, watch, VNode, h } from 'vue' import { defineComponent, onMounted, toRefs, watch, VNode, h } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { NSelect, NButton, NIcon, NSpace, NTooltip, SelectOption } from 'naive-ui' import {
NSelect,
NButton,
NIcon,
NSpace,
NTooltip,
SelectOption
} from 'naive-ui'
import { ReloadOutlined, EyeOutlined } from '@vicons/antd' import { ReloadOutlined, EyeOutlined } from '@vicons/antd'
import { useRelation } from './use-relation' import { useRelation } from './use-relation'
import Card from '@/components/card' import Card from '@/components/card'
@ -48,7 +55,13 @@ const workflowRelation = defineComponent({
: getWorkflowList(Number(route.params.projectCode)) : getWorkflowList(Number(route.params.projectCode))
} }
const renderOption = ({ node, option }: { node: VNode; option: SelectOption }) => const renderOption = ({
node,
option
}: {
node: VNode
option: SelectOption
}) =>
h(NTooltip, null, { h(NTooltip, null, {
trigger: () => node, trigger: () => node,
default: () => option.label default: () => option.label

87
dolphinscheduler-ui/src/views/projects/workflow/timing/components/timing-condition.tsx

@ -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 { SearchOutlined } from '@vicons/antd'
import { NButton, NSelect, NIcon, NSpace, NEllipsis } from 'naive-ui'
import { defineComponent, h, ref } from 'vue'
import { queryProcessDefinitionList } from '@/service/modules/process-definition'
import { SelectMixedOption } from 'naive-ui/lib/select/src/interface'
import { Router, useRouter } from 'vue-router'
export default defineComponent({
name: 'TimingCondition',
emits: ['handleSearch'],
setup(props, ctx) {
const router: Router = useRouter()
const projectCode = ref(
Number(router.currentRoute.value.params.projectCode)
)
const processDefineCodeRef = router.currentRoute.value.query
.processDefineCode
? ref(Number(router.currentRoute.value.query.processDefineCode))
: ref()
const processDefinitionOptions = ref<Array<SelectMixedOption>>([])
const initProcessList = (code: number) => {
queryProcessDefinitionList(code).then((result: any) => {
result.map((item: { code: number; name: string }) => {
const option: SelectMixedOption = {
value: item.code,
label: () => h(NEllipsis, null, item.name),
filterLabel: item.name
}
processDefinitionOptions.value.push(option)
})
})
}
initProcessList(projectCode.value)
const handleSearch = () => {
ctx.emit('handleSearch', {
processDefinitionCode: processDefineCodeRef.value
})
}
return {
handleSearch,
processDefinitionOptions,
processDefineCodeRef
}
},
render() {
return (
<NSpace justify='end'>
<NSelect
clearable
filterable
options={this.processDefinitionOptions}
size='small'
style={{ width: '310px' }}
v-model:value={this.processDefineCodeRef}
/>
<NButton type='primary' size='small' onClick={this.handleSearch}>
<NIcon>
<SearchOutlined />
</NIcon>
</NButton>
</NSpace>
)
}
})

116
dolphinscheduler-ui/src/views/projects/workflow/timing/index.tsx

@ -0,0 +1,116 @@
/*
* 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 { NDataTable, NPagination, NSpace } from 'naive-ui'
import { defineComponent, onMounted, toRefs, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useTable } from '../definition/timing/use-table'
import Card from '@/components/card'
import TimingModal from '../definition/components/timing-modal'
import TimingCondition from '@/views/projects/workflow/timing/components/timing-condition'
import { ITimingSearch } from '@/views/projects/workflow/timing/types'
export default defineComponent({
name: 'WorkflowTimingList',
setup() {
const { variables, createColumns, getTableData } = useTable()
const requestData = () => {
getTableData({
pageSize: variables.pageSize,
pageNo: variables.page,
searchVal: variables.searchVal,
projectCode: variables.projectCode,
processDefinitionCode: variables.processDefinitionCode
})
}
const handleUpdateList = () => {
requestData()
}
const handleSearch = (params: ITimingSearch) => {
variables.processDefinitionCode = params.processDefinitionCode
variables.page = 1
requestData()
}
const handleChangePageSize = () => {
variables.page = 1
requestData()
}
onMounted(() => {
createColumns(variables)
requestData()
})
watch(useI18n().locale, () => {
createColumns(variables)
})
return {
requestData,
handleSearch,
handleUpdateList,
handleChangePageSize,
...toRefs(variables)
}
},
render() {
const { t } = useI18n()
const { loadingRef } = this
return (
<NSpace vertical>
<Card>
<TimingCondition onHandleSearch={this.handleSearch} />
</Card>
<Card title={t('project.workflow.cron_manage')}>
<NSpace vertical>
<NDataTable
loading={loadingRef}
columns={this.columns}
data={this.tableData}
striped
size={'small'}
scrollX={this.tableWidth}
/>
<NSpace justify='center'>
<NPagination
v-model:page={this.page}
v-model:page-size={this.pageSize}
page-count={this.totalPage}
show-size-picker
page-sizes={[10, 30, 50]}
show-quick-jumper
onUpdatePage={this.requestData}
onUpdatePageSize={this.handleChangePageSize}
/>
</NSpace>
</NSpace>
</Card>
<TimingModal
type={'update'}
v-model:row={this.row}
v-model:show={this.showRef}
onUpdateList={this.handleUpdateList}
/>
</NSpace>
)
}
})

22
dolphinscheduler-ui/src/views/projects/workflow/timing/types.ts

@ -0,0 +1,22 @@
/*
* 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 ITimingSearch {
processDefinitionCode: number
}
export { ITimingSearch }

2
dolphinscheduler-ui/src/views/resource/components/resource/create/use-form.ts

@ -18,7 +18,7 @@
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { reactive, ref, unref } from 'vue' import { reactive, ref, unref } from 'vue'
import type { FormRules } from 'naive-ui' import type { FormRules } from 'naive-ui'
import { ICreateFileDefaultValue } from "@/views/resource/components/resource/types"; import { ICreateFileDefaultValue } from '@/views/resource/components/resource/types'
const defaultValue: ICreateFileDefaultValue = () => ({ const defaultValue: ICreateFileDefaultValue = () => ({
pid: -1, pid: -1,

4
dolphinscheduler-ui/src/views/resource/components/resource/edit/index.tsx

@ -33,8 +33,8 @@ export default defineComponent({
const componentName = route.name const componentName = route.name
// fullname is now the id of resources // fullname is now the id of resources
const fullName = String(router.currentRoute.value.query.prefix || "") const fullName = String(router.currentRoute.value.query.prefix || '')
const tenantCode = String(router.currentRoute.value.query.tenantCode || "") const tenantCode = String(router.currentRoute.value.query.tenantCode || '')
const { state } = useForm() const { state } = useForm()
const { getResourceView, handleUpdateContent } = useEdit(state) const { getResourceView, handleUpdateContent } = useEdit(state)

17
dolphinscheduler-ui/src/views/resource/components/resource/edit/use-edit.ts

@ -19,7 +19,10 @@ import { useI18n } from 'vue-i18n'
import type { Router } from 'vue-router' import type { Router } from 'vue-router'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useAsyncState } from '@vueuse/core' import { useAsyncState } from '@vueuse/core'
import { updateResourceContent, viewResource } from '@/service/modules/resources' import {
updateResourceContent,
viewResource
} from '@/service/modules/resources'
export function useEdit(state: any) { export function useEdit(state: any) {
const { t } = useI18n() const { t } = useI18n()
@ -41,13 +44,11 @@ export function useEdit(state: any) {
const handleUpdateContent = (fullName: string, tenantCode: string) => { const handleUpdateContent = (fullName: string, tenantCode: string) => {
state.fileFormRef.validate(async (valid: any) => { state.fileFormRef.validate(async (valid: any) => {
if (!valid) { if (!valid) {
await updateResourceContent( await updateResourceContent({
{ ...state.fileForm,
...state.fileForm, tenantCode: tenantCode,
tenantCode: tenantCode, fullName: fullName
fullName: fullName, })
},
)
window.$message.success(t('resource.file.success')) window.$message.success(t('resource.file.success'))
router.go(-1) router.go(-1)

2
dolphinscheduler-ui/src/views/resource/components/resource/folder/index.tsx

@ -22,7 +22,7 @@ import Modal from '@/components/modal'
import { noSpace } from '@/utils/trim' import { noSpace } from '@/utils/trim'
import { useForm } from './use-form' import { useForm } from './use-form'
import { useFolder } from './use-folder' import { useFolder } from './use-folder'
import { ResourceType } from "@/views/resource/components/resource/types"; import { ResourceType } from '@/views/resource/components/resource/types'
const props = { const props = {
show: { show: {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save