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. 6
      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. 9
      dolphinscheduler-ui/src/components/input-search/index.tsx
  9. 6
      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. 3
      dolphinscheduler-ui/src/locales/en_US/menu.ts
  14. 3
      dolphinscheduler-ui/src/locales/en_US/project.ts
  15. 2
      dolphinscheduler-ui/src/locales/en_US/resource.ts
  16. 2
      dolphinscheduler-ui/src/locales/en_US/security.ts
  17. 12
      dolphinscheduler-ui/src/locales/zh_CN/datasource.ts
  18. 1
      dolphinscheduler-ui/src/locales/zh_CN/menu.ts
  19. 1
      dolphinscheduler-ui/src/locales/zh_CN/project.ts
  20. 2
      dolphinscheduler-ui/src/locales/zh_CN/security.ts
  21. 11
      dolphinscheduler-ui/src/router/modules/projects.ts
  22. 34
      dolphinscheduler-ui/src/service/modules/data-source/types.ts
  23. 6
      dolphinscheduler-ui/src/service/modules/process-definition/index.ts
  24. 1
      dolphinscheduler-ui/src/service/modules/process-instances/index.ts
  25. 12
      dolphinscheduler-ui/src/service/modules/projects/index.ts
  26. 49
      dolphinscheduler-ui/src/service/modules/resources/index.ts
  27. 2
      dolphinscheduler-ui/src/service/modules/resources/types.ts
  28. 2
      dolphinscheduler-ui/src/service/modules/schedules/types.ts
  29. 5
      dolphinscheduler-ui/src/service/modules/task-instances/index.ts
  30. 5
      dolphinscheduler-ui/src/utils/environmental-distinction.ts
  31. 7
      dolphinscheduler-ui/src/utils/tree-format.ts
  32. 8
      dolphinscheduler-ui/src/views/data-quality/rule/index.tsx
  33. 48
      dolphinscheduler-ui/src/views/datasource/list/detail.tsx
  34. 5
      dolphinscheduler-ui/src/views/datasource/list/use-columns.ts
  35. 28
      dolphinscheduler-ui/src/views/datasource/list/use-form.ts
  36. 2
      dolphinscheduler-ui/src/views/datasource/list/use-table.ts
  37. 28
      dolphinscheduler-ui/src/views/login/index.tsx
  38. 2
      dolphinscheduler-ui/src/views/login/use-login.ts
  39. 4
      dolphinscheduler-ui/src/views/profile/use-form.ts
  40. 12
      dolphinscheduler-ui/src/views/projects/list/index.tsx
  41. 2
      dolphinscheduler-ui/src/views/projects/list/use-table.ts
  42. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-custom-labels.ts
  43. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasource.ts
  44. 1
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datasync.ts
  45. 16
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-datax.ts
  46. 4
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-dependent-timeout.ts
  47. 7
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-dms.ts
  48. 6
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-environment-name.ts
  49. 3
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-flink.ts
  50. 14
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-hive-cli.ts
  51. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-linkis.ts
  52. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-namespace.ts
  53. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts
  54. 32
      dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-sea-tunnel.ts
  55. 14
      dolphinscheduler-ui/src/views/projects/task/components/node/format-data.ts
  56. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-datasync.ts
  57. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-dms.ts
  58. 2
      dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-linkis.ts
  59. 6
      dolphinscheduler-ui/src/views/projects/task/components/node/types.ts
  60. 2
      dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx
  61. 1
      dolphinscheduler-ui/src/views/projects/task/instance/index.tsx
  62. 22
      dolphinscheduler-ui/src/views/projects/task/instance/use-table.ts
  63. 2
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-config.ts
  64. 11
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-context-menu.tsx
  65. 51
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-sidebar.tsx
  66. 6
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/dag-toolbar.tsx
  67. 25
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/index.tsx
  68. 15
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/dag-canvas.tsx
  69. 12
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/dag-sidebar.tsx
  70. 16
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/index.tsx
  71. 69
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/index.tsx
  72. 7
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-form-field.ts
  73. 2
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-form-request.ts
  74. 4
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/task/use-task-form.ts
  75. 5
      dolphinscheduler-ui/src/views/projects/workflow/components/dynamic-dag/use-sidebar.ts
  76. 2
      dolphinscheduler-ui/src/views/projects/workflow/definition/components/use-modal.ts
  77. 8
      dolphinscheduler-ui/src/views/projects/workflow/definition/create/index.tsx
  78. 10
      dolphinscheduler-ui/src/views/projects/workflow/definition/index.tsx
  79. 4
      dolphinscheduler-ui/src/views/projects/workflow/definition/timing/index.tsx
  80. 2
      dolphinscheduler-ui/src/views/projects/workflow/definition/timing/types.ts
  81. 51
      dolphinscheduler-ui/src/views/projects/workflow/definition/timing/use-table.ts
  82. 2
      dolphinscheduler-ui/src/views/projects/workflow/definition/use-table.ts
  83. 17
      dolphinscheduler-ui/src/views/projects/workflow/instance/components/variables-view.tsx
  84. 2
      dolphinscheduler-ui/src/views/projects/workflow/instance/use-table.ts
  85. 17
      dolphinscheduler-ui/src/views/projects/workflow/relation/index.tsx
  86. 87
      dolphinscheduler-ui/src/views/projects/workflow/timing/components/timing-condition.tsx
  87. 116
      dolphinscheduler-ui/src/views/projects/workflow/timing/index.tsx
  88. 22
      dolphinscheduler-ui/src/views/projects/workflow/timing/types.ts
  89. 2
      dolphinscheduler-ui/src/views/resource/components/resource/create/use-form.ts
  90. 4
      dolphinscheduler-ui/src/views/resource/components/resource/edit/index.tsx
  91. 13
      dolphinscheduler-ui/src/views/resource/components/resource/edit/use-edit.ts
  92. 2
      dolphinscheduler-ui/src/views/resource/components/resource/folder/index.tsx
  93. 2
      dolphinscheduler-ui/src/views/resource/components/resource/folder/use-form.ts
  94. 54
      dolphinscheduler-ui/src/views/resource/components/resource/index.tsx
  95. 10
      dolphinscheduler-ui/src/views/resource/components/resource/rename/index.tsx
  96. 34
      dolphinscheduler-ui/src/views/resource/components/resource/rename/use-form.ts
  97. 8
      dolphinscheduler-ui/src/views/resource/components/resource/rename/use-rename.ts
  98. 59
      dolphinscheduler-ui/src/views/resource/components/resource/table/table-action.tsx
  99. 59
      dolphinscheduler-ui/src/views/resource/components/resource/table/use-table.ts
  100. 59
      dolphinscheduler-ui/src/views/resource/components/resource/types.ts
  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) {

6
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;
} }
if (processDefineCode != 0) {
ProcessDefinition processDefinition = processDefinitionMapper.queryByCode(processDefineCode); ProcessDefinition processDefinition = processDefinitionMapper.queryByCode(processDefineCode);
if (processDefinition == null || projectCode != processDefinition.getProjectCode()) { if (processDefinition == null || projectCode != processDefinition.getProjectCode()) {
log.error("Process definition does not exist, processDefinitionCode:{}.", processDefineCode); log.error("Process definition does not exist, processDefinitionCode:{}.", processDefineCode);
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, String.valueOf(processDefineCode)); putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, String.valueOf(processDefineCode));
return result; 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')}`,

9
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,13 +40,14 @@ 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 = {props.placeholder?props.placeholder:t('input_search.placeholder')} placeholder={
props.placeholder ? props.placeholder : t('input_search.placeholder')
}
onKeydown={withKeys(onKeyDown, ['enter'])} onKeydown={withKeys(onKeyDown, ['enter'])}
onClear = {onClear} onClear={onClear}
/> />
) )
} }

6
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: () => (
<NIcon size='16'>
<SettingOutlined /> <SettingOutlined />
</NIcon>, </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'
} }

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'
} }

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'

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

@ -15,8 +15,8 @@
* 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,
@ -42,4 +42,3 @@ export function renderEnvironmentalDistinctionCell(
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>

48
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,7 +127,8 @@ 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,
@ -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
@ -297,7 +311,11 @@ const DetailModal = defineComponent({
> >
<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

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: () =>

28
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) {
@ -338,7 +337,6 @@ export function useForm(id?: number) {
const getFieldsValue = () => state.detailForm const getFieldsValue = () => state.detailForm
return { return {
state, state,
changeType, changeType,

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

28
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,13 +154,16 @@ 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')}

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
} }
}) })

12
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,7 +116,7 @@ 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}

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 }
}) })
} }
}, },

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

@ -23,7 +23,7 @@ export function useCustomLabels({
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

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 () => {

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

@ -20,7 +20,6 @@ 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 jsonSpan = ref(0)
const destinationLocationArnSpan = ref(0) const destinationLocationArnSpan = ref(0)
const sourceLocationArnSpan = ref(0) const sourceLocationArnSpan = ref(0)

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

@ -14,13 +14,13 @@
* 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')})`,
@ -205,7 +205,7 @@ export function useDataX(model: { [field: string]: any }): IJsonItem[] {
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 }
} }
}, },
{ {
@ -216,7 +216,7 @@ export function useDataX(model: { [field: string]: any }): IJsonItem[] {
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 }
} }
}, },
{ {
@ -251,6 +251,6 @@ export function useDataX(model: { [field: string]: any }): IJsonItem[] {
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 [
{ {

2
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',

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

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) {

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

@ -43,7 +43,7 @@ export function useDatasync({
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[] = []

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)

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

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() {

22
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 }

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: {

11
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()

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>
)
} }
}) })

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

@ -227,11 +227,7 @@ export default defineComponent({
> >
{{ {{
trigger: () => ( trigger: () => (
<NButton <NButton quaternary circle class={Styles['toolbar-btn']}>
quaternary
circle
class={Styles['toolbar-btn']}
>
<NIcon> <NIcon>
<FundViewOutlined /> <FundViewOutlined />
</NIcon> </NIcon>

25
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,17 +289,22 @@ export default defineComponent({
getLogs(logTimer) getLogs(logTimer)
} }
const handleExecuteTask = (startNodeList: number, taskDependType: string) => { const handleExecuteTask = (
executeTask({ startNodeList: number,
taskDependType: string
) => {
executeTask(
{
processInstanceId: Number(route.params.id), processInstanceId: Number(route.params.id),
startNodeList: startNodeList, startNodeList: startNodeList,
taskDependType: taskDependType, taskDependType: taskDependType
}, },
props.projectCode).then(() => { props.projectCode
).then(() => {
window.$message.success(t('project.workflow.success')) window.$message.success(t('project.workflow.success'))
setTimeout(() => { setTimeout(() => {
window.location.reload(); window.location.reload()
}, 1000); }, 1000)
}) })
} }
@ -450,4 +452,3 @@ export default defineComponent({
) )
} }
}) })

15
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
ref='container'
class={styles.container}
onDrop={this.handleDrop} onDrop={this.handleDrop}
onDragenter={this.handlePreventDefault} onDragenter={this.handlePreventDefault}
onDragover={this.handlePreventDefault} onDragover={this.handlePreventDefault}
onDragleave={this.handlePreventDefault}> onDragleave={this.handlePreventDefault}
<div ref='dag-container' class={styles['dag-container']}/> >
<div ref='dag-container' class={styles['dag-container']} />
</div> </div>
<div ref='minimapContainer' class={styles.minimap}/> <div ref='minimapContainer' class={styles.minimap} />
</> </>
) )
} }

12
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 class={styles['task-item']} draggable='true' onDragstart={() => this.handleDragstart(task)}> <div
class={styles['task-item']}
draggable='true'
onDragstart={() => this.handleDragstart(task)}
>
{task.name} {task.name}
</div> </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)}
/> />
} )}
</> </>
) )
} }

69
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}
rules={this.rules}
ref={'taskForm'}>
{
(this.formStructure as Array<any>).map(f => {
return <NFormItem
label={this.t(f.label)}
path={f.field}
> >
{ <NForm model={this.model} rules={this.rules} ref={'taskForm'}>
f.type === 'input' && <NInput {(this.formStructure as Array<any>).map((f) => {
return (
<NFormItem 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
} }

51
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) => {
queryScheduleListPaging(
{ ...params, processDefinitionCode: definitionCode },
variables.projectCode
).then((res: any) => {
variables.totalPage = res.totalPage variables.totalPage = res.totalPage
variables.tableData = res.totalList.map((item: any) => { variables.tableData = res.totalList.map((item: any) => {
return { ...item } return { ...item }
}) })
variables.loadingRef = false 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 }
}) })

17
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(
(res: any) => {
paramsRef.value = res 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)

13
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: {

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

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

54
dolphinscheduler-ui/src/views/resource/components/resource/index.tsx

@ -49,7 +49,6 @@ import Search from '@/components/input-search'
import { ResourceType } from '@/views/resource/components/resource/types' import { ResourceType } from '@/views/resource/components/resource/types'
import { useUserStore } from '@/store/user/user' import { useUserStore } from '@/store/user/user'
const props = { const props = {
resourceType: { resourceType: {
type: String as PropType<ResourceType>, type: String as PropType<ResourceType>,
@ -71,7 +70,7 @@ export default defineComponent({
requestData, requestData,
updateList, updateList,
createColumns, createColumns,
handleCreateFile, handleCreateFile
} = useTable() } = useTable()
const userStore = useUserStore() const userStore = useUserStore()
@ -109,27 +108,41 @@ export default defineComponent({
onMounted(() => { onMounted(() => {
createColumns(variables) createColumns(variables)
fileStore.setCurrentDir(variables.fullName) fileStore.setCurrentDir(variables.fullName)
breadListRef.value = fileStore.getCurrentDir.replace(/\/+$/g, '') breadListRef.value = fileStore.getCurrentDir
.split('/').slice(2) as Array<string> .replace(/\/+$/g, '')
.split('/')
.slice(2) as Array<string>
requestData() requestData()
}) })
const trim = getCurrentInstance()?.appContext.config.globalProperties.trim const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
const handleBread = (index: number) => { const handleBread = (index: number) => {
const breadName = variables.fullName.split('/').slice(0, index+3).join('/')+'/' const breadName =
variables.fullName
.split('/')
.slice(0, index + 3)
.join('/') + '/'
goBread(breadName) goBread(breadName)
} }
const goBread = (fullName: string) => { const goBread = (fullName: string) => {
const { resourceType, tenantCode } = variables const { resourceType, tenantCode } = variables
const baseDir = resourceType === 'UDF' ? userStore.getBaseUdfDir : userStore.getBaseResDir const baseDir =
resourceType === 'UDF'
? userStore.getBaseUdfDir
: userStore.getBaseResDir
if (fullName === '' || !fullName.startsWith(baseDir)) { if (fullName === '' || !fullName.startsWith(baseDir)) {
router.push({ name: resourceType === 'UDF' ? 'resource-manage' : 'file-manage' }) router.push({
name: resourceType === 'UDF' ? 'resource-manage' : 'file-manage'
})
} else { } else {
router.push({ router.push({
name: resourceType === 'UDF' ? 'resource-sub-manage' : 'resource-file-subdirectory', name:
query: { prefix: fullName, tenantCode: tenantCode} resourceType === 'UDF'
? 'resource-sub-manage'
: 'resource-file-subdirectory',
query: { prefix: fullName, tenantCode: tenantCode }
}) })
} }
} }
@ -162,9 +175,10 @@ export default defineComponent({
handleCreateFolder, handleCreateFolder,
handleCreateFile, handleCreateFile,
handleUploadFile, handleUploadFile,
tableWidth, tableWidth
} = this } = this
const manageTitle = this.resourceType === 'UDF' const manageTitle =
this.resourceType === 'UDF'
? t('resource.udf.udf_resources') ? t('resource.udf.udf_resources')
: t('resource.file.file_manage') : t('resource.file.file_manage')
@ -180,27 +194,26 @@ export default defineComponent({
> >
{t('resource.file.create_folder')} {t('resource.file.create_folder')}
</NButton> </NButton>
{this.resourceType !== 'UDF' && {this.resourceType !== 'UDF' && (
<NButton onClick={handleCreateFile} class='btn-create-file'> <NButton onClick={handleCreateFile} class='btn-create-file'>
{t('resource.file.create_file')} {t('resource.file.create_file')}
</NButton> </NButton>
} )}
<NButton onClick={handleUploadFile} class='btn-upload-resource'> <NButton onClick={handleUploadFile} class='btn-upload-resource'>
{this.resourceType === 'UDF' {this.resourceType === 'UDF'
? t('resource.udf.upload_udf_resources') ? t('resource.udf.upload_udf_resources')
: t('resource.file.upload_files') : t('resource.file.upload_files')}
}
</NButton> </NButton>
</NButtonGroup> </NButtonGroup>
<NSpace> <NSpace>
<Search <Search
placeholder = {t('resource.file.enter_keyword_tips')} placeholder={t('resource.file.enter_keyword_tips')}
v-model:value={this.searchRef} v-model:value={this.searchRef}
onSearch={handleConditions} onSearch={handleConditions}
/> />
<NButton size='small' type='primary' onClick={handleConditions}> <NButton size='small' type='primary' onClick={handleConditions}>
<NIcon> <NIcon>
<SearchOutlined/> <SearchOutlined />
</NIcon> </NIcon>
</NButton> </NButton>
</NSpace> </NSpace>
@ -214,9 +227,12 @@ export default defineComponent({
<NBreadcrumbItem> <NBreadcrumbItem>
<NButton <NButton
text text
disabled={index > 0 && index === this.breadListRef!.length - 1} disabled={
index > 0 && index === this.breadListRef!.length - 1
}
onClick={() => this.handleBread(index)} onClick={() => this.handleBread(index)}
>{index === 0 ? manageTitle : item} >
{index === 0 ? manageTitle : item}
</NButton> </NButton>
</NBreadcrumbItem> </NBreadcrumbItem>
))} ))}

10
dolphinscheduler-ui/src/views/resource/components/resource/rename/index.tsx

@ -26,7 +26,7 @@ import { useI18n } from 'vue-i18n'
import Modal from '@/components/modal' import Modal from '@/components/modal'
import { useForm } from './use-form' import { useForm } from './use-form'
import { useRename } from './use-rename' import { useRename } from './use-rename'
import type { ResourceType } from "@/views/resource/components/resource/types"; import type { ResourceType } from '@/views/resource/components/resource/types'
const props = { const props = {
show: { show: {
@ -60,7 +60,13 @@ export default defineComponent({
props, props,
emits: ['updateList', 'update:show'], emits: ['updateList', 'update:show'],
setup(props, ctx) { setup(props, ctx) {
const { state, resetForm } = useForm(props.resourceType!,props.fullName, props.name, props.description, props.userName) const { state, resetForm } = useForm(
props.resourceType!,
props.fullName,
props.name,
props.description,
props.userName
)
const { handleRenameFile } = useRename(state) const { handleRenameFile } = useRename(state)
const hideModal = () => { const hideModal = () => {
ctx.emit('update:show', false) ctx.emit('update:show', false)

34
dolphinscheduler-ui/src/views/resource/components/resource/rename/use-form.ts

@ -18,9 +18,18 @@
import { reactive, ref, unref } from 'vue' import { reactive, ref, unref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import type { FormRules } from 'naive-ui' import type { FormRules } from 'naive-ui'
import { IRenameDefaultValue, ResourceType } from "@/views/resource/components/resource/types"; import {
IRenameDefaultValue,
ResourceType
} from '@/views/resource/components/resource/types'
const defaultValue:IRenameDefaultValue = (type: ResourceType, fullName = '', name = '', description = '', user_name = '') => ({ const defaultValue: IRenameDefaultValue = (
type: ResourceType,
fullName = '',
name = '',
description = '',
user_name = ''
) => ({
fullName, fullName,
name, name,
type: type, type: type,
@ -28,15 +37,30 @@ const defaultValue:IRenameDefaultValue = (type: ResourceType, fullName = '', nam
user_name user_name
}) })
export function useForm(resourceType: ResourceType, fullName: string, name: string, description: string, user_name: string) { export function useForm(
resourceType: ResourceType,
fullName: string,
name: string,
description: string,
user_name: string
) {
const { t } = useI18n() const { t } = useI18n()
const resetForm = () => { const resetForm = () => {
state.renameForm = Object.assign(unref(state.renameForm), defaultValue(resourceType)) state.renameForm = Object.assign(
unref(state.renameForm),
defaultValue(resourceType)
)
} }
const state = reactive({ const state = reactive({
renameFormRef: ref(), renameFormRef: ref(),
renameForm: defaultValue(resourceType,fullName, name, description, user_name), renameForm: defaultValue(
resourceType,
fullName,
name,
description,
user_name
),
saving: false, saving: false,
rules: { rules: {
name: { name: {

8
dolphinscheduler-ui/src/views/resource/components/resource/rename/use-rename.ts

@ -31,12 +31,10 @@ export function useRename(state: any) {
if (state.saving) return if (state.saving) return
state.saving = true state.saving = true
try { try {
await updateResource( await updateResource({
{
...state.renameForm, ...state.renameForm,
tenantCode: state.renameForm.user_name, tenantCode: state.renameForm.user_name
} })
)
window.$message.success(t('resource.file.success')) window.$message.success(t('resource.file.success'))
state.saving = false state.saving = false
emit('updateList') emit('updateList')

59
dolphinscheduler-ui/src/views/resource/components/resource/table/table-action.tsx

@ -28,7 +28,12 @@ import {
} from '@vicons/antd' } from '@vicons/antd'
import _ from 'lodash' import _ from 'lodash'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { ResourceFileTableData, IRenameResource, IRtDisb, IReuploadResource } from '../types' import {
ResourceFileTableData,
IRenameResource,
IRtDisb,
IReuploadResource
} from '../types'
import { fileTypeArr } from '@/common/common' import { fileTypeArr } from '@/common/common'
import { downloadResource, deleteResource } from '@/service/modules/resources' import { downloadResource, deleteResource } from '@/service/modules/resources'
import type { Router } from 'vue-router' import type { Router } from 'vue-router'
@ -43,7 +48,7 @@ const props = {
default: { default: {
name: '', name: '',
description: '', description: '',
user_name: '', user_name: ''
} }
} }
} }
@ -63,19 +68,35 @@ export default defineComponent({
return !(flag && size < 1000000) return !(flag && size < 1000000)
} }
const handleEditFile = (item: {fullName: string, user_name: string }) => { const handleEditFile = (item: { fullName: string; user_name: string }) => {
router.push({ name: 'resource-file-edit', query: {prefix: item.fullName, tenantCode: item.user_name} }) router.push({
name: 'resource-file-edit',
query: { prefix: item.fullName, tenantCode: item.user_name }
})
} }
const handleDeleteFile = (fullNameObj: {fullName: string, tenantCode: string}) => { const handleDeleteFile = (fullNameObj: {
fullName: string
tenantCode: string
}) => {
deleteResource(fullNameObj).then(() => emit('updateList')) deleteResource(fullNameObj).then(() => emit('updateList'))
} }
const handleReuploadFile: IReuploadResource = (name: string, description: string, fullName: string, user_name: string) => { const handleReuploadFile: IReuploadResource = (
name: string,
description: string,
fullName: string,
user_name: string
) => {
emit('reuploadResource', name, description, fullName, user_name) emit('reuploadResource', name, description, fullName, user_name)
} }
const handleRenameFile: IRenameResource = (name: string, description: string, fullName: string, user_name: string) => { const handleRenameFile: IRenameResource = (
name: string,
description: string,
fullName: string,
user_name: string
) => {
emit('renameResource', name, description, fullName, user_name) emit('renameResource', name, description, fullName, user_name)
} }
@ -93,7 +114,7 @@ export default defineComponent({
const { t } = useI18n() const { t } = useI18n()
return ( return (
<NSpace> <NSpace>
{ this.row.type !== 'UDF' && {this.row.type !== 'UDF' && (
<NTooltip trigger={'hover'}> <NTooltip trigger={'hover'}>
{{ {{
default: () => t('resource.file.edit'), default: () => t('resource.file.edit'),
@ -104,7 +125,10 @@ export default defineComponent({
disabled={this.rtDisb(this.row.name, this.row.size)} disabled={this.rtDisb(this.row.name, this.row.size)}
tag='div' tag='div'
onClick={() => { onClick={() => {
this.handleEditFile({fullName:this.row.fullName, user_name:this.row.user_name}) this.handleEditFile({
fullName: this.row.fullName,
user_name: this.row.user_name
})
}} }}
style={{ marginRight: '-5px' }} style={{ marginRight: '-5px' }}
circle circle
@ -117,7 +141,7 @@ export default defineComponent({
) )
}} }}
</NTooltip> </NTooltip>
} )}
<NTooltip trigger={'hover'}> <NTooltip trigger={'hover'}>
{{ {{
default: () => t('resource.file.reupload'), default: () => t('resource.file.reupload'),
@ -139,7 +163,7 @@ export default defineComponent({
class='btn-reupload' class='btn-reupload'
> >
<NIcon> <NIcon>
<UploadOutlined/> <UploadOutlined />
</NIcon> </NIcon>
</NButton> </NButton>
) )
@ -159,9 +183,7 @@ export default defineComponent({
this.row.fullName, this.row.fullName,
this.row.user_name this.row.user_name
) )
} }}
}
style={{ marginRight: '-5px' }} style={{ marginRight: '-5px' }}
circle circle
class='btn-rename' class='btn-rename'
@ -184,7 +206,9 @@ export default defineComponent({
tag='div' tag='div'
circle circle
style={{ marginRight: '-5px' }} style={{ marginRight: '-5px' }}
onClick={() => downloadResource({fullName: this.row.fullName})} onClick={() =>
downloadResource({ fullName: this.row.fullName })
}
class='btn-download' class='btn-download'
> >
<NIcon> <NIcon>
@ -203,7 +227,10 @@ export default defineComponent({
positive-text={t('resource.file.confirm')} positive-text={t('resource.file.confirm')}
negative-text={t('resource.file.cancel')} negative-text={t('resource.file.cancel')}
onPositiveClick={() => { onPositiveClick={() => {
this.handleDeleteFile({fullName: this.row.fullName, tenantCode: this.row.user_name}) this.handleDeleteFile({
fullName: this.row.fullName,
tenantCode: this.row.user_name
})
}} }}
> >
{{ {{

59
dolphinscheduler-ui/src/views/resource/components/resource/table/use-table.ts

@ -29,28 +29,33 @@ import {
DefaultTableWidth DefaultTableWidth
} from '@/common/column-width-config' } from '@/common/column-width-config'
import type { Router } from 'vue-router' import type { Router } from 'vue-router'
import { useFileState } from "@/views/resource/components/resource/use-file"; import { useFileState } from '@/views/resource/components/resource/use-file'
const goSubFolder = (router: Router, item: any) => { const goSubFolder = (router: Router, item: any) => {
if (item.directory) { if (item.directory) {
router.push({ router.push({
name: item.type === 'UDF' ? 'resource-sub-manage' : 'resource-file-subdirectory', name:
query: { prefix: item.fullName, tenantCode: item.user_name} item.type === 'UDF'
? 'resource-sub-manage'
: 'resource-file-subdirectory',
query: { prefix: item.fullName, tenantCode: item.user_name }
}) })
} else if (item.type === 'FILE') { } else if (item.type === 'FILE') {
router.push({ name: 'resource-file-list', query: {prefix: item.fullName, tenantCode: item.user_name}} ) router.push({
name: 'resource-file-list',
query: { prefix: item.fullName, tenantCode: item.user_name }
})
} }
} }
export function useTable() { export function useTable() {
const { t } = useI18n() const { t } = useI18n()
const router: Router = useRouter() const router: Router = useRouter()
const variables = reactive({ const variables = reactive({
columns: [], columns: [],
fullName: ref(String(router.currentRoute.value.query.prefix || "")), fullName: ref(String(router.currentRoute.value.query.prefix || '')),
tenantCode: ref(String(router.currentRoute.value.query.tenantCode || "")), tenantCode: ref(String(router.currentRoute.value.query.tenantCode || '')),
resourceType: ref<ResourceType>(), resourceType: ref<ResourceType>(),
resourceList: ref(), resourceList: ref(),
folderShowRef: ref(false), folderShowRef: ref(false),
@ -75,7 +80,6 @@ export function useTable() {
pageSize: 10, pageSize: 10,
itemCount: 0, itemCount: 0,
pageSizes: [10, 30, 50] pageSizes: [10, 30, 50]
}) })
}) })
@ -154,45 +158,55 @@ export function useTable() {
render: (row: any) => render: (row: any) =>
h(TableAction, { h(TableAction, {
row, row,
onReuploadResource: ( name, description, fullName, user_name ) => onReuploadResource: (name, description, fullName, user_name) =>
reuploadResource( name, description, fullName, user_name ), reuploadResource(name, description, fullName, user_name),
onRenameResource: ( name, description, fullName, user_name ) => onRenameResource: (name, description, fullName, user_name) =>
renameResource( name, description, fullName, user_name ), renameResource(name, description, fullName, user_name),
onUpdateList: () => updateList() onUpdateList: () => updateList()
}), }),
...COLUMN_WIDTH_CONFIG['operation'](variables.resourceType === 'UDF' ? 4 : 5) ...COLUMN_WIDTH_CONFIG['operation'](
variables.resourceType === 'UDF' ? 4 : 5
)
} }
] ]
} }
const createFile = () => { const createFile = () => {
const { fullName } = variables const { fullName } = variables
const name = fullName const name = fullName ? 'resource-subfile-create' : 'resource-file-create'
? 'resource-subfile-create'
: 'resource-file-create'
router.push({ router.push({
name, name,
params: { id: fullName} params: { id: fullName }
}) })
} }
const reuploadResource: IReuploadResource = ( name, description, fullName, user_name ) => { const reuploadResource: IReuploadResource = (
name,
description,
fullName,
user_name
) => {
variables.reuploadInfo = { variables.reuploadInfo = {
name: name, name: name,
description: description, description: description,
fullName: fullName, fullName: fullName,
user_name:user_name user_name: user_name
} }
variables.isReupload = true variables.isReupload = true
variables.uploadShowRef = true variables.uploadShowRef = true
} }
const renameResource: IRenameResource = ( name, description, fullName, user_name ) => { const renameResource: IRenameResource = (
name,
description,
fullName,
user_name
) => {
variables.renameInfo = { variables.renameInfo = {
name: name, name: name,
description: description, description: description,
fullName: fullName, fullName: fullName,
user_name:user_name user_name: user_name
} }
variables.renameShowRef = true variables.renameShowRef = true
} }
@ -214,7 +228,6 @@ export function useTable() {
) )
} }
const updateList = () => { const updateList = () => {
variables.pagination.page = 1 variables.pagination.page = 1
requestData() requestData()
@ -226,6 +239,6 @@ export function useTable() {
requestData, requestData,
updateList, updateList,
createColumns, createColumns,
handleCreateFile: createFile, handleCreateFile: createFile
} }
} }

59
dolphinscheduler-ui/src/views/resource/components/resource/types.ts

@ -46,7 +46,14 @@ export interface IRtDisb {
} }
export interface IResourceListState { export interface IResourceListState {
(type: ResourceType, searchVal?: string, fullName?: string, tenantCode?: string, pageNo?: number, pageSize?: number): any (
type: ResourceType,
searchVal?: string,
fullName?: string,
tenantCode?: string,
pageNo?: number,
pageSize?: number
): any
} }
export interface BasicTableProps { export interface BasicTableProps {
@ -81,23 +88,22 @@ export interface BreadcrumbItem {
export interface ICreateFileDefaultValue { export interface ICreateFileDefaultValue {
(): { (): {
pid: number, pid: number
type: ResourceType, type: ResourceType
suffix: string, suffix: string
fileName: string, fileName: string
description: string, description: string
content: string, content: string
currentDir: string currentDir: string
} }
} }
export interface IFolderDefaultValue { export interface IFolderDefaultValue {
(): (): {
{ pid: number
pid: number, type: ResourceType
type: ResourceType, name: string
name: string, description: string
description: string,
currentDir: string currentDir: string
} }
} }
@ -109,20 +115,25 @@ export interface IRenameDefaultValue {
name?: string, name?: string,
description?: string, description?: string,
user_name?: string user_name?: string
): {fullName: string, name: string, type: ResourceType, description: string, user_name: string} ): {
fullName: string
name: string
type: ResourceType
description: string
user_name: string
}
} }
export interface IUploadDefaultValue { export interface IUploadDefaultValue {
(): (): {
{ isReupload: boolean
isReupload: boolean, fullName: string
fullName: string, user_name: string
user_name: string, name: string
name: string, file: string
file: string, description: string
description: string, type: ResourceType
type: ResourceType, pid: number
pid: number,
currentDir: string currentDir: string
} }
} }

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

Loading…
Cancel
Save