diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts index dd49a2190..240ee1408 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts @@ -429,24 +429,40 @@ const project = { crontab: 'Crontab', delete_confirm: 'Delete?', enter_name_tips: 'Please enter name', - switch_version: 'Switch To This Version', confirm_switch_version: 'Confirm Switch To This Version?', current_version: 'Current Version' }, task: { task_name: 'Task Name', + task_type: 'Task Type', + create_task: 'Create Task', workflow_instance: 'Workflow Instance', + workflow_name: 'Workflow Name', + workflow_name_tips: 'Please select workflow name', + workflow_state: 'Workflow State', + version: 'Version', + current_version: 'Current Version', + switch_version: 'Switch To This Version', + confirm_switch_version: 'Confirm Switch To This Version?', + description: 'Description', + move: 'Move', + upstream_tasks: 'Upstream Tasks', executor: 'Executor', node_type: 'Node Type', state: 'State', submit_time: 'Submit Time', start_time: 'Start Time', + create_time: 'Create Time', + update_time: 'Update Time', end_time: 'End Time', duration: 'Duration', retry_count: 'Retry Count', dry_run_flag: 'Dry Run Flag', host: 'Host', operation: 'Operation', + edit: 'Edit', + delete: 'Delete', + delete_confirm: 'Delete?', submitted_success: 'Submitted Success', running_execution: 'Running Execution', ready_pause: 'Ready Pause', diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts index 3878cddc9..2aa892682 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts @@ -433,18 +433,35 @@ const project = { }, task: { task_name: '任务名称', + task_type: '任务类型', + create_task: '创建任务', workflow_instance: '工作流实例', + workflow_name: '工作流名称', + workflow_name_tips: '请选择工作流名称', + workflow_state: '工作流状态', + version: '版本', + current_version: '当前版本', + switch_version: '切换到该版本', + confirm_switch_version: '确定切换到该版本吗?', + description: '描述', + move: '移动', + upstream_tasks: '上游任务', executor: '执行用户', node_type: '节点类型', state: '状态', submit_time: '提交时间', start_time: '开始时间', + create_time: '创建时间', + update_time: '更新时间', end_time: '结束时间', duration: '运行时间', retry_count: '重试次数', dry_run_flag: '空跑标识', host: '主机', operation: '操作', + edit: '编辑', + delete: '删除', + delete_confirm: '确定删除吗?', submitted_success: '提交成功', running_execution: '正在运行', ready_pause: '准备暂停', diff --git a/dolphinscheduler-ui-next/src/router/modules/projects.ts b/dolphinscheduler-ui-next/src/router/modules/projects.ts index 03f469e95..9c0b2a4ed 100644 --- a/dolphinscheduler-ui-next/src/router/modules/projects.ts +++ b/dolphinscheduler-ui-next/src/router/modules/projects.ts @@ -115,7 +115,7 @@ export default { }, { path: '/projects/:projectCode/task/definitions', - name: 'task-definition-list', + name: 'task-definition', component: components['projects-task-definition'], meta: { title: '任务定义', @@ -124,7 +124,7 @@ export default { }, { path: '/projects/:projectCode/task/instances', - name: 'task-instance-list', + name: 'task-instance', component: components['projects-task-instance'], meta: { title: '任务实例', diff --git a/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts b/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts index 2d255480e..c2a888584 100644 --- a/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts +++ b/dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts @@ -132,7 +132,7 @@ export function queryProcessDefinitionByName( }) } -export function querySimpleList(code: CodeReq): any { +export function querySimpleList(code: number): any { return axios({ url: `/projects/${code}/process-definition/simple-list`, method: 'get' diff --git a/dolphinscheduler-ui-next/src/service/modules/process-definition/types.ts b/dolphinscheduler-ui-next/src/service/modules/process-definition/types.ts index 97a5ea0a4..2e9949a25 100644 --- a/dolphinscheduler-ui-next/src/service/modules/process-definition/types.ts +++ b/dolphinscheduler-ui-next/src/service/modules/process-definition/types.ts @@ -67,6 +67,13 @@ interface TargetCodeReq { targetProjectCode: number } +interface SimpleListRes { + id: number + code: any + name: string + projectCode: any +} + export { CodeReq, CodesReq, @@ -78,5 +85,6 @@ export { PageReq, ListReq, ProcessDefinitionReq, - TargetCodeReq + TargetCodeReq, + SimpleListRes } diff --git a/dolphinscheduler-ui-next/src/service/modules/process-task-relation/index.ts b/dolphinscheduler-ui-next/src/service/modules/process-task-relation/index.ts index e40b03fc7..c15ebf520 100644 --- a/dolphinscheduler-ui-next/src/service/modules/process-task-relation/index.ts +++ b/dolphinscheduler-ui-next/src/service/modules/process-task-relation/index.ts @@ -34,7 +34,7 @@ export function save(data: SaveReq, projectCode: ProjectCodeReq): any { }) } -export function moveRelation(data: MoveReq, projectCode: ProjectCodeReq): any { +export function moveRelation(data: MoveReq, projectCode: number): any { return axios({ url: `/projects/${projectCode}/process-task-relation/move`, method: 'post', diff --git a/dolphinscheduler-ui-next/src/service/modules/task-definition/index.ts b/dolphinscheduler-ui-next/src/service/modules/task-definition/index.ts index bc501f923..2b532ae8b 100644 --- a/dolphinscheduler-ui-next/src/service/modules/task-definition/index.ts +++ b/dolphinscheduler-ui-next/src/service/modules/task-definition/index.ts @@ -32,7 +32,7 @@ export function queryTaskDefinitionListPaging( projectCode: ProjectCodeReq ): any { return axios({ - url: `/projects/${projectCode}/task-definition`, + url: `/projects/${projectCode.projectCode}/task-definition`, method: 'get', params }) @@ -82,14 +82,12 @@ export function update( } export function deleteTaskDefinition( - data: TaskDefinitionJsonObjReq, code: CodeReq, projectCode: ProjectCodeReq ): any { return axios({ - url: `/projects/${projectCode}/task-definition/${code}`, - method: 'put', - data + url: `/projects/${projectCode.projectCode}/task-definition/${code.code}`, + method: 'delete' }) } @@ -105,13 +103,13 @@ export function releaseTaskDefinition( }) } -export function queryVersions( +export function queryTaskVersions( params: PageReq, code: CodeReq, projectCode: ProjectCodeReq ): any { return axios({ - url: `/projects/${projectCode}/task-definition/${code}/versions`, + url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions`, method: 'get', params }) @@ -123,7 +121,7 @@ export function switchVersion( projectCode: ProjectCodeReq ): any { return axios({ - url: `/projects/${projectCode}/task-definition/${code}/versions/${version}`, + url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`, method: 'get' }) } @@ -134,7 +132,7 @@ export function deleteVersion( projectCode: ProjectCodeReq ): any { return axios({ - url: `/projects/${projectCode}/task-definition/${code}/versions/${version}`, + url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`, method: 'delete' }) } diff --git a/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts b/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts index 2207e540d..51a08b9f6 100644 --- a/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts +++ b/dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts @@ -38,7 +38,7 @@ interface TaskDefinitionJsonReq { } interface CodeReq { - code: number + code: any } interface TaskDefinitionJsonObjReq { @@ -53,15 +53,87 @@ interface VersionReq { version: number } +interface TaskDefinitionItem { + taskName: string + taskCode: any + taskVersion: number + taskType: string + taskCreateTime: string + taskUpdateTime: string + processDefinitionCode: any + processDefinitionVersion: number + processDefinitionName: string + processReleaseState: string + upstreamTaskMap: any + upstreamTaskCode: number + upstreamTaskName: string +} + +interface TaskDefinitionRes { + totalList: TaskDefinitionItem[] + total: number + totalPage: number + pageSize: number + currentPage: number + start: number +} + +interface TaskDefinitionVersionItem { + id: number + code: number + name: string + version: number + description: string + projectCode: number + userId: number + taskType: string + taskParams: any + taskParamList: any[] + taskParamMap: any + flag: string + taskPriority: string + userName?: any + projectName?: any + workerGroup: string + environmentCode: number + failRetryTimes: number + failRetryInterval: number + timeoutFlag: string + timeoutNotifyStrategy?: any + timeout: number + delayTime: number + resourceIds: string + createTime: string + updateTime: string + modifyBy?: any + taskGroupId: number + taskGroupPriority: number + operator: number + operateTime: string + dependence: string +} + +interface TaskDefinitionVersionRes { + totalList: TaskDefinitionVersionItem[] + total: number + totalPage: number + pageSize: number + currentPage: number + start: number +} + export { PageReq, ListReq, ProjectCodeReq, TaskDefinitionListReq, TaskDefinitionJsonReq, - GenNumReq, CodeReq, TaskDefinitionJsonObjReq, ReleaseStateReq, - VersionReq + VersionReq, + TaskDefinitionItem, + TaskDefinitionRes, + TaskDefinitionVersionItem, + TaskDefinitionVersionRes } diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx new file mode 100644 index 000000000..4e752c4a4 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineComponent, PropType, toRefs, watch } from 'vue' +import Modal from '@/components/modal' +import { NForm, NFormItem, NSelect } from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { useMove } from './use-move' + +const props = { + show: { + type: Boolean as PropType, + default: false + }, + row: { + type: Object as PropType, + default: {} + } +} + +const MoveModal = defineComponent({ + name: 'MoveModal', + props, + emits: ['refresh', 'cancel'], + setup(props, ctx) { + const { t } = useI18n() + const { variables, handleValidate, getListData } = useMove() + + const cancelModal = () => { + variables.model.targetProcessDefinitionCode = '' + ctx.emit('cancel') + } + + const confirmModal = () => { + handleValidate() + } + + watch( + () => props.show, + () => { + variables.taskCode = props.row.taskCode + variables.processDefinitionCode = props.row.processDefinitionCode + variables.model.targetProcessDefinitionCode = + props.row.processDefinitionCode + + props.show && getListData() + } + ) + + watch( + () => variables.refreshTaskDefinition, + () => { + if (variables.refreshTaskDefinition) { + ctx.emit('refresh') + variables.refreshTaskDefinition = false + } + } + ) + + return { t, ...toRefs(variables), cancelModal, confirmModal } + }, + render() { + const { t, show, cancelModal, confirmModal } = this + + return ( + + + + + + + + ) + } +}) + +export default MoveModal diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts new file mode 100644 index 000000000..7dc5bbfab --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { reactive, ref, SetupContext } from 'vue' +import { useI18n } from 'vue-i18n' +import { useAsyncState } from '@vueuse/core' +import { querySimpleList } from '@/service/modules/process-definition' +import { useRoute } from 'vue-router' +import { moveRelation } from '@/service/modules/process-task-relation' +import type { SimpleListRes } from '@/service/modules/process-definition/types' + +export function useMove() { + const { t } = useI18n() + const route = useRoute() + const projectCode = Number(route.params.projectCode) + + const variables = reactive({ + taskCode: ref(''), + processDefinitionCode: ref(''), + refreshTaskDefinition: ref(false), + taskDefinitionFormRef: ref(), + model: { + targetProcessDefinitionCode: ref(''), + generalOptions: [] + }, + rules: { + targetProcessDefinitionCode: { + required: true, + trigger: ['change', 'blur'], + validator() { + if (!variables.model.targetProcessDefinitionCode) { + return new Error(t('project.task.workflow_name_tips')) + } + } + } + } + }) + + const getListData = () => { + const { state } = useAsyncState( + querySimpleList(projectCode).then((res: Array) => { + variables.model.generalOptions = res.map( + (item): { label: string; value: number } => { + return { + label: item.name, + value: item.code + } + } + ) as any + }), + {} + ) + + return state + } + + const handleValidate = () => { + variables.taskDefinitionFormRef.validate((errors: any) => { + if (errors) { + return + } + moveTask() + }) + } + + const moveTask = () => { + const data = { + targetProcessDefinitionCode: variables.model.targetProcessDefinitionCode, + taskCode: variables.taskCode, + processDefinitionCode: variables.processDefinitionCode + } + + moveRelation(data, projectCode).then(() => { + variables.model.targetProcessDefinitionCode = '' + variables.refreshTaskDefinition = true + }) + } + + return { + variables, + handleValidate, + getListData + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-version.ts b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-version.ts new file mode 100644 index 000000000..64fd56ffc --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-version.ts @@ -0,0 +1,209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useI18n } from 'vue-i18n' +import { h, reactive, ref } from 'vue' +import { NButton, NPopconfirm, NSpace, NTag, NTooltip } from 'naive-ui' +import { DeleteOutlined, CheckOutlined } from '@vicons/antd' +import { useAsyncState } from '@vueuse/core' +import { + queryTaskVersions, + switchVersion, + deleteVersion +} from '@/service/modules/task-definition' +import { useRoute } from 'vue-router' +import type { + TaskDefinitionVersionRes, + TaskDefinitionVersionItem +} from '@/service/modules/task-definition/types' + +export function useVersion() { + const { t } = useI18n() + const route = useRoute() + const projectCode = Number(route.params.projectCode) + + const createColumns = (variables: any) => { + variables.columns = [ + { + title: '#', + key: 'index' + }, + { + title: t('project.task.version'), + key: 'version', + render: (row: TaskDefinitionVersionItem) => + h( + 'span', + null, + row.version !== variables.taskVersion + ? 'v' + row.version + : h( + NTag, + { type: 'success', size: 'small' }, + { + default: () => + `v${row.version} ${t('project.task.current_version')}` + } + ) + ) + }, + { + title: t('project.task.description'), + key: 'description', + render: (row: TaskDefinitionVersionItem) => + h('span', null, row.description ? row.description : '-') + }, + { + title: t('project.task.create_time'), + key: 'createTime' + }, + { + title: t('project.task.operation'), + key: 'operation', + render(row: TaskDefinitionVersionItem) { + return h(NSpace, null, { + default: () => [ + h( + NPopconfirm, + { + onPositiveClick: () => { + handleSwitchVersion(row) + } + }, + { + trigger: () => + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'info', + size: 'small', + disabled: row.version === variables.taskVersion + }, + { + icon: () => h(CheckOutlined) + } + ), + default: () => t('project.task.switch_version') + } + ), + default: () => t('project.task.confirm_switch_version') + } + ), + h( + NPopconfirm, + { + onPositiveClick: () => { + handleDelete(row) + } + }, + { + trigger: () => + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'error', + size: 'small', + disabled: row.version === variables.taskVersion + }, + { + icon: () => h(DeleteOutlined) + } + ), + default: () => t('project.task.delete') + } + ), + default: () => t('project.task.delete_confirm') + } + ) + ] + }) + } + } + ] + } + + const variables = reactive({ + columns: [], + tableData: [], + page: ref(1), + pageSize: ref(10), + totalPage: ref(1), + taskVersion: ref(null), + taskCode: ref(null), + refreshTaskDefinition: ref(false), + row: {} + }) + + const handleSwitchVersion = (row: TaskDefinitionVersionItem) => { + switchVersion( + { version: row.version }, + { code: variables.taskCode }, + { projectCode } + ).then(() => { + variables.refreshTaskDefinition = true + }) + } + + const handleDelete = (row: TaskDefinitionVersionItem) => { + deleteVersion( + { version: row.version }, + { code: variables.taskCode }, + { projectCode } + ).then(() => { + variables.refreshTaskDefinition = true + }) + } + + const getTableData = (params: any) => { + const { state } = useAsyncState( + queryTaskVersions( + { ...params }, + { code: variables.taskCode }, + { projectCode } + ).then((res: TaskDefinitionVersionRes) => { + variables.tableData = res.totalList.map((item, index) => { + return { + index: index + 1, + ...item + } + }) as any + variables.totalPage = res.totalPage + }), + {} + ) + + return state + } + + return { + variables, + getTableData, + createColumns + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/version-modal.tsx b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/version-modal.tsx new file mode 100644 index 000000000..ca148bf68 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/version-modal.tsx @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineComponent, onMounted, PropType, toRefs, watch } from 'vue' +import Modal from '@/components/modal' +import { NDataTable, NPagination, useThemeVars } from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { useVersion } from './use-version' +import styles from './version.module.scss' + +const props = { + show: { + type: Boolean as PropType, + default: false + }, + row: { + type: Object as PropType, + default: {} + } +} + +const VersionModal = defineComponent({ + name: 'VersionModal', + props, + emits: ['confirm', 'refresh'], + setup(props, ctx) { + const { t } = useI18n() + const { variables, getTableData, createColumns } = useVersion() + + const requestData = () => { + getTableData({ + pageSize: variables.pageSize, + pageNo: variables.page + }) + } + + onMounted(() => { + variables.taskVersion = props.row?.taskVersion + variables.taskCode = props.row?.taskCode + + createColumns(variables) + requestData() + }) + + watch( + () => props.show, + () => { + variables.taskVersion = props.row?.taskVersion + variables.taskCode = props.row?.taskCode + + if (props.show) { + createColumns(variables) + requestData() + } + } + ) + + watch( + () => variables.refreshTaskDefinition, + () => { + if (variables.refreshTaskDefinition) { + ctx.emit('refresh') + variables.refreshTaskDefinition = false + } + } + ) + + const onConfirm = () => { + ctx.emit('confirm') + } + + return { t, ...toRefs(variables), requestData, onConfirm } + }, + render() { + const { t, requestData, onConfirm, show } = this + + return ( + + +
+ +
+
+ ) + } +}) + +export default VersionModal diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/detail/index.tsx b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/version.module.scss similarity index 83% rename from dolphinscheduler-ui-next/src/views/projects/task/definition/detail/index.tsx rename to dolphinscheduler-ui-next/src/views/projects/task/definition/components/version.module.scss index 31df000f3..2da65cac8 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/definition/detail/index.tsx +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/version.module.scss @@ -15,11 +15,8 @@ * limitations under the License. */ -import { defineComponent } from 'vue' - -export default defineComponent({ - name: 'TaskConfigModal', - setup() { - return () =>
TaskConfigModal
- } -}) +.pagination { + margin-top: 20px; + display: flex; + justify-content: center; +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/index.module.scss b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.module.scss new file mode 100644 index 000000000..7713e3b03 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.module.scss @@ -0,0 +1,43 @@ +/* + * 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. + */ + +.search-card { + display: flex; + justify-content: space-between; + align-items: center; + + .box { + display: flex; + justify-content: flex-end; + align-items: center; + width: 300px; + + button, input { + margin-left: 10px; + } + } +} + +.table-card { + margin-top: 8px; + + .pagination { + margin-top: 20px; + display: flex; + justify-content: center; + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx index c14060b52..cf362e888 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx @@ -15,11 +15,153 @@ * limitations under the License. */ -import { defineComponent } from 'vue' +import { defineComponent, onMounted, toRefs, watch } from 'vue' +import { + NButton, + NCard, + NDataTable, + NIcon, + NInput, + NPagination, + NSelect, + NSpace +} from 'naive-ui' +import { SearchOutlined } from '@vicons/antd' +import { useI18n } from 'vue-i18n' +import { useTable } from './use-table' +import { ALL_TASK_TYPES } from '@/views/projects/task/constants/task-type' +import Card from '@/components/card' +import VersionModal from './components/version-modal' +import MoveModal from './components/move-modal' +import styles from './index.module.scss' -export default defineComponent({ - name: 'TaskDefinitionList', +const TaskDefinition = defineComponent({ + name: 'task-definition', setup() { - return () =>
TaskDefinitionList
+ const { t } = useI18n() + const { variables, getTableData, createColumns } = useTable() + + const requestData = () => { + getTableData({ + pageSize: variables.pageSize, + pageNo: variables.page, + searchTaskName: variables.searchTaskName, + searchWorkflowName: variables.searchWorkflowName, + taskType: variables.taskType + }) + } + + const onUpdatePageSize = () => { + variables.page = 1 + requestData() + } + + const onSearch = () => { + variables.page = 1 + requestData() + } + + const onRefresh = () => { + variables.showVersionModalRef = false + variables.showMoveModalRef = false + requestData() + } + + onMounted(() => { + createColumns(variables) + requestData() + }) + + watch(useI18n().locale, () => { + createColumns(variables) + }) + + return { + t, + ...toRefs(variables), + onSearch, + requestData, + onUpdatePageSize, + onRefresh + } + }, + render() { + const { t, onSearch, requestData, onUpdatePageSize, onRefresh } = this + + return ( + <> + +
+
+ + {t('project.task.create_task')} + +
+ + + + { + return { value: item, label: item } + })} + placeholder={t('project.task.task_type')} + style={{ width: '180px' }} + clearable + /> + + {{ + icon: () => ( + + + + ) + }} + + +
+
+ + +
+ +
+
+ (this.showVersionModalRef = false)} + onRefresh={onRefresh} + /> + (this.showMoveModalRef = false)} + onRefresh={onRefresh} + /> + + ) } }) + +export default TaskDefinition diff --git a/dolphinscheduler-ui-next/src/views/projects/task/definition/use-table.ts b/dolphinscheduler-ui-next/src/views/projects/task/definition/use-table.ts new file mode 100644 index 000000000..94f3e95a9 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/use-table.ts @@ -0,0 +1,282 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useAsyncState } from '@vueuse/core' +import { reactive, h, ref } from 'vue' +import { NButton, NPopconfirm, NSpace, NTag, NTooltip } from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { + DeleteOutlined, + EditOutlined, + DragOutlined, + ExclamationCircleOutlined +} from '@vicons/antd' +import { + queryTaskDefinitionListPaging, + deleteTaskDefinition +} from '@/service/modules/task-definition' +import { useRoute } from 'vue-router' +import type { + TaskDefinitionItem, + TaskDefinitionRes +} from '@/service/modules/task-definition/types' + +export function useTable() { + const { t } = useI18n() + const route = useRoute() + const projectCode = Number(route.params.projectCode) + + const createColumns = (variables: any) => { + variables.columns = [ + { + title: '#', + key: 'index' + }, + { + title: t('project.task.task_name'), + key: 'taskName' + }, + { + title: t('project.task.workflow_name'), + key: 'processDefinitionName' + }, + { + title: t('project.task.workflow_state'), + key: 'processReleaseState' + }, + { + title: t('project.task.task_type'), + key: 'taskType' + }, + { + title: t('project.task.version'), + key: 'taskVersion', + render: (row: TaskDefinitionItem) => + h('span', null, 'v' + row.taskVersion) + }, + { + title: t('project.task.upstream_tasks'), + key: 'upstreamTaskMap', + render: (row: TaskDefinitionItem) => + h( + 'span', + null, + row.upstreamTaskMap.length < 1 + ? '-' + : h(NSpace, null, { + default: () => row.upstreamTaskMap.map((item: string) => { + return h( + NTag, + { type: 'info', size: 'small' }, + { default: () => item } + ) + }) + }) + ) + }, + { + title: t('project.task.create_time'), + key: 'taskCreateTime' + }, + { + title: t('project.task.update_time'), + key: 'taskUpdateTime' + }, + { + title: t('project.task.operation'), + key: 'operation', + render(row: any) { + return h(NSpace, null, { + default: () => [ + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'info', + size: 'small', + disabled: + ['CONDITIONS', 'SWITCH'].includes(row.taskType) || + (row.processDefinitionCode && + row.processReleaseState === 'ONLINE'), + onClick: () => { + // handleEdit(row) + } + }, + { + icon: () => h(EditOutlined) + } + ), + default: () => t('project.task.edit') + } + ), + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'info', + size: 'small', + disabled: + row.processDefinitionCode && + row.processReleaseState === 'ONLINE', + onClick: () => { + variables.showMoveModalRef = true + variables.row = row + } + }, + { + icon: () => h(DragOutlined) + } + ), + default: () => t('project.task.move') + } + ), + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'info', + size: 'small', + onClick: () => { + variables.showVersionModalRef = true + variables.row = row + } + }, + { + icon: () => h(ExclamationCircleOutlined) + } + ), + default: () => t('project.task.version') + } + ), + h( + NPopconfirm, + { + onPositiveClick: () => { + handleDelete(row) + } + }, + { + trigger: () => + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'error', + size: 'small', + disabled: + row.processDefinitionCode && + row.processReleaseState === 'ONLINE' + }, + { + icon: () => h(DeleteOutlined) + } + ), + default: () => t('project.task.delete') + } + ), + default: () => t('project.task.delete_confirm') + } + ) + ] + }) + } + } + ] + } + + const variables = reactive({ + columns: [], + tableData: [], + page: ref(1), + pageSize: ref(10), + searchTaskName: ref(null), + searchWorkflowName: ref(null), + totalPage: ref(1), + taskType: ref(null), + showVersionModalRef: ref(false), + showMoveModalRef: ref(false), + row: {} + }) + + const handleDelete = (row: any) => { + deleteTaskDefinition({ code: row.taskCode }, { projectCode }).then(() => { + getTableData({ + pageSize: variables.pageSize, + pageNo: + variables.tableData.length === 1 && variables.page > 1 + ? variables.page - 1 + : variables.page, + searchTaskName: variables.searchTaskName, + searchWorkflowName: variables.searchWorkflowName, + taskType: variables.taskType + }) + }) + } + + const getTableData = (params: any) => { + const { state } = useAsyncState( + queryTaskDefinitionListPaging({ ...params }, { projectCode }).then( + (res: TaskDefinitionRes) => { + variables.tableData = res.totalList.map((item, index) => { + if (Object.keys(item.upstreamTaskMap).length > 0) { + item.upstreamTaskMap = Object.keys(item.upstreamTaskMap).map( + (code) => item.upstreamTaskMap[code] + ) + } else { + item.upstreamTaskMap = [] + } + + return { + index: index + 1, + ...item + } + }) as any + variables.totalPage = res.totalPage + } + ), + {} + ) + + return state + } + + return { + variables, + getTableData, + createColumns + } +} diff --git a/dolphinscheduler-ui-next/src/views/projects/task/instance/use-table.ts b/dolphinscheduler-ui-next/src/views/projects/task/instance/use-table.ts index ecff49d31..3a7a914d1 100644 --- a/dolphinscheduler-ui-next/src/views/projects/task/instance/use-table.ts +++ b/dolphinscheduler-ui-next/src/views/projects/task/instance/use-table.ts @@ -53,7 +53,6 @@ export function useTable() { processInstanceName: ref(null), totalPage: ref(1), showModalRef: ref(false), - statusRef: ref(0), row: {} })