Browse Source

[Feature][UI Next] Add task definition. (#8297)

* [Feature][UI Next] Add task definition.

* [Feature][UI Next] Add task definition.
3.0.0/version-upgrade
songjianet 3 years ago committed by GitHub
parent
commit
1d6c509119
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      dolphinscheduler-ui-next/src/locales/modules/en_US.ts
  2. 17
      dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
  3. 4
      dolphinscheduler-ui-next/src/router/modules/projects.ts
  4. 2
      dolphinscheduler-ui-next/src/service/modules/process-definition/index.ts
  5. 10
      dolphinscheduler-ui-next/src/service/modules/process-definition/types.ts
  6. 2
      dolphinscheduler-ui-next/src/service/modules/process-task-relation/index.ts
  7. 16
      dolphinscheduler-ui-next/src/service/modules/task-definition/index.ts
  8. 78
      dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts
  9. 108
      dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx
  10. 98
      dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts
  11. 209
      dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-version.ts
  12. 112
      dolphinscheduler-ui-next/src/views/projects/task/definition/components/version-modal.tsx
  13. 13
      dolphinscheduler-ui-next/src/views/projects/task/definition/components/version.module.scss
  14. 43
      dolphinscheduler-ui-next/src/views/projects/task/definition/index.module.scss
  15. 150
      dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx
  16. 282
      dolphinscheduler-ui-next/src/views/projects/task/definition/use-table.ts
  17. 1
      dolphinscheduler-ui-next/src/views/projects/task/instance/use-table.ts

18
dolphinscheduler-ui-next/src/locales/modules/en_US.ts

@ -429,24 +429,40 @@ const project = {
crontab: 'Crontab', crontab: 'Crontab',
delete_confirm: 'Delete?', delete_confirm: 'Delete?',
enter_name_tips: 'Please enter name', enter_name_tips: 'Please enter name',
switch_version: 'Switch To This Version',
confirm_switch_version: 'Confirm Switch To This Version?', confirm_switch_version: 'Confirm Switch To This Version?',
current_version: 'Current Version' current_version: 'Current Version'
}, },
task: { task: {
task_name: 'Task Name', task_name: 'Task Name',
task_type: 'Task Type',
create_task: 'Create Task',
workflow_instance: 'Workflow Instance', 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', executor: 'Executor',
node_type: 'Node Type', node_type: 'Node Type',
state: 'State', state: 'State',
submit_time: 'Submit Time', submit_time: 'Submit Time',
start_time: 'Start Time', start_time: 'Start Time',
create_time: 'Create Time',
update_time: 'Update Time',
end_time: 'End Time', end_time: 'End Time',
duration: 'Duration', duration: 'Duration',
retry_count: 'Retry Count', retry_count: 'Retry Count',
dry_run_flag: 'Dry Run Flag', dry_run_flag: 'Dry Run Flag',
host: 'Host', host: 'Host',
operation: 'Operation', operation: 'Operation',
edit: 'Edit',
delete: 'Delete',
delete_confirm: 'Delete?',
submitted_success: 'Submitted Success', submitted_success: 'Submitted Success',
running_execution: 'Running Execution', running_execution: 'Running Execution',
ready_pause: 'Ready Pause', ready_pause: 'Ready Pause',

17
dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts

@ -433,18 +433,35 @@ const project = {
}, },
task: { task: {
task_name: '任务名称', task_name: '任务名称',
task_type: '任务类型',
create_task: '创建任务',
workflow_instance: '工作流实例', workflow_instance: '工作流实例',
workflow_name: '工作流名称',
workflow_name_tips: '请选择工作流名称',
workflow_state: '工作流状态',
version: '版本',
current_version: '当前版本',
switch_version: '切换到该版本',
confirm_switch_version: '确定切换到该版本吗?',
description: '描述',
move: '移动',
upstream_tasks: '上游任务',
executor: '执行用户', executor: '执行用户',
node_type: '节点类型', node_type: '节点类型',
state: '状态', state: '状态',
submit_time: '提交时间', submit_time: '提交时间',
start_time: '开始时间', start_time: '开始时间',
create_time: '创建时间',
update_time: '更新时间',
end_time: '结束时间', end_time: '结束时间',
duration: '运行时间', duration: '运行时间',
retry_count: '重试次数', retry_count: '重试次数',
dry_run_flag: '空跑标识', dry_run_flag: '空跑标识',
host: '主机', host: '主机',
operation: '操作', operation: '操作',
edit: '编辑',
delete: '删除',
delete_confirm: '确定删除吗?',
submitted_success: '提交成功', submitted_success: '提交成功',
running_execution: '正在运行', running_execution: '正在运行',
ready_pause: '准备暂停', ready_pause: '准备暂停',

4
dolphinscheduler-ui-next/src/router/modules/projects.ts

@ -115,7 +115,7 @@ export default {
}, },
{ {
path: '/projects/:projectCode/task/definitions', path: '/projects/:projectCode/task/definitions',
name: 'task-definition-list', name: 'task-definition',
component: components['projects-task-definition'], component: components['projects-task-definition'],
meta: { meta: {
title: '任务定义', title: '任务定义',
@ -124,7 +124,7 @@ export default {
}, },
{ {
path: '/projects/:projectCode/task/instances', path: '/projects/:projectCode/task/instances',
name: 'task-instance-list', name: 'task-instance',
component: components['projects-task-instance'], component: components['projects-task-instance'],
meta: { meta: {
title: '任务实例', title: '任务实例',

2
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({ return axios({
url: `/projects/${code}/process-definition/simple-list`, url: `/projects/${code}/process-definition/simple-list`,
method: 'get' method: 'get'

10
dolphinscheduler-ui-next/src/service/modules/process-definition/types.ts

@ -67,6 +67,13 @@ interface TargetCodeReq {
targetProjectCode: number targetProjectCode: number
} }
interface SimpleListRes {
id: number
code: any
name: string
projectCode: any
}
export { export {
CodeReq, CodeReq,
CodesReq, CodesReq,
@ -78,5 +85,6 @@ export {
PageReq, PageReq,
ListReq, ListReq,
ProcessDefinitionReq, ProcessDefinitionReq,
TargetCodeReq TargetCodeReq,
SimpleListRes
} }

2
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({ return axios({
url: `/projects/${projectCode}/process-task-relation/move`, url: `/projects/${projectCode}/process-task-relation/move`,
method: 'post', method: 'post',

16
dolphinscheduler-ui-next/src/service/modules/task-definition/index.ts

@ -32,7 +32,7 @@ export function queryTaskDefinitionListPaging(
projectCode: ProjectCodeReq projectCode: ProjectCodeReq
): any { ): any {
return axios({ return axios({
url: `/projects/${projectCode}/task-definition`, url: `/projects/${projectCode.projectCode}/task-definition`,
method: 'get', method: 'get',
params params
}) })
@ -82,14 +82,12 @@ export function update(
} }
export function deleteTaskDefinition( export function deleteTaskDefinition(
data: TaskDefinitionJsonObjReq,
code: CodeReq, code: CodeReq,
projectCode: ProjectCodeReq projectCode: ProjectCodeReq
): any { ): any {
return axios({ return axios({
url: `/projects/${projectCode}/task-definition/${code}`, url: `/projects/${projectCode.projectCode}/task-definition/${code.code}`,
method: 'put', method: 'delete'
data
}) })
} }
@ -105,13 +103,13 @@ export function releaseTaskDefinition(
}) })
} }
export function queryVersions( export function queryTaskVersions(
params: PageReq, params: PageReq,
code: CodeReq, code: CodeReq,
projectCode: ProjectCodeReq projectCode: ProjectCodeReq
): any { ): any {
return axios({ return axios({
url: `/projects/${projectCode}/task-definition/${code}/versions`, url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions`,
method: 'get', method: 'get',
params params
}) })
@ -123,7 +121,7 @@ export function switchVersion(
projectCode: ProjectCodeReq projectCode: ProjectCodeReq
): any { ): any {
return axios({ return axios({
url: `/projects/${projectCode}/task-definition/${code}/versions/${version}`, url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`,
method: 'get' method: 'get'
}) })
} }
@ -134,7 +132,7 @@ export function deleteVersion(
projectCode: ProjectCodeReq projectCode: ProjectCodeReq
): any { ): any {
return axios({ return axios({
url: `/projects/${projectCode}/task-definition/${code}/versions/${version}`, url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`,
method: 'delete' method: 'delete'
}) })
} }

78
dolphinscheduler-ui-next/src/service/modules/task-definition/types.ts

@ -38,7 +38,7 @@ interface TaskDefinitionJsonReq {
} }
interface CodeReq { interface CodeReq {
code: number code: any
} }
interface TaskDefinitionJsonObjReq { interface TaskDefinitionJsonObjReq {
@ -53,15 +53,87 @@ interface VersionReq {
version: number 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 { export {
PageReq, PageReq,
ListReq, ListReq,
ProjectCodeReq, ProjectCodeReq,
TaskDefinitionListReq, TaskDefinitionListReq,
TaskDefinitionJsonReq, TaskDefinitionJsonReq,
GenNumReq,
CodeReq, CodeReq,
TaskDefinitionJsonObjReq, TaskDefinitionJsonObjReq,
ReleaseStateReq, ReleaseStateReq,
VersionReq VersionReq,
TaskDefinitionItem,
TaskDefinitionRes,
TaskDefinitionVersionItem,
TaskDefinitionVersionRes
} }

108
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<boolean>,
default: false
},
row: {
type: Object as PropType<any>,
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 (
<Modal
title={t('project.task.move')}
show={show}
onCancel={cancelModal}
onConfirm={confirmModal}
confirmDisabled={!this.model.targetProcessDefinitionCode}
>
<NForm
model={this.model}
rules={this.rules}
ref='taskDefinitionFormRef'
>
<NFormItem
label={t('project.task.workflow_name')}
path='alertInstanceIds'
>
<NSelect
placeholder={t('project.task.workflow_name_tips')}
options={this.model.generalOptions}
v-model={[this.model.targetProcessDefinitionCode, 'value']}
/>
</NFormItem>
</NForm>
</Modal>
)
}
})
export default MoveModal

98
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<SimpleListRes>) => {
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
}
}

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

112
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<boolean>,
default: false
},
row: {
type: Object as PropType<any>,
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 (
<Modal
show={show}
title={t('project.task.version')}
cancelShow={false}
onConfirm={onConfirm}
>
<NDataTable columns={this.columns} data={this.tableData} />
<div class={styles.pagination}>
<NPagination
v-model:page={this.page}
v-model:page-size={this.pageSize}
page-count={this.totalPage}
onUpdatePage={requestData}
/>
</div>
</Modal>
)
}
})
export default VersionModal

13
dolphinscheduler-ui-next/src/views/projects/task/definition/detail/index.tsx → dolphinscheduler-ui-next/src/views/projects/task/definition/components/version.module.scss

@ -15,11 +15,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineComponent } from 'vue' .pagination {
margin-top: 20px;
export default defineComponent({ display: flex;
name: 'TaskConfigModal', justify-content: center;
setup() { }
return () => <div>TaskConfigModal</div>
}
})

43
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;
}
}

150
dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx

@ -15,11 +15,153 @@
* limitations under the License. * 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({ const TaskDefinition = defineComponent({
name: 'TaskDefinitionList', name: 'task-definition',
setup() { setup() {
return () => <div>TaskDefinitionList</div> 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 (
<>
<NCard>
<div class={styles['search-card']}>
<div>
<NButton size='small' type='primary'>
{t('project.task.create_task')}
</NButton>
</div>
<NSpace justify='end'>
<NInput
size='small'
clearable
v-model={[this.searchTaskName, 'value']}
placeholder={t('project.task.task_name')}
/>
<NInput
size='small'
clearable
v-model={[this.searchWorkflowName, 'value']}
placeholder={t('project.task.workflow_name')}
/>
<NSelect
v-model={[this.taskType, 'value']}
size='small'
options={Object.keys(ALL_TASK_TYPES).map((item) => {
return { value: item, label: item }
})}
placeholder={t('project.task.task_type')}
style={{ width: '180px' }}
clearable
/>
<NButton size='small' type='primary' onClick={onSearch}>
{{
icon: () => (
<NIcon>
<SearchOutlined />
</NIcon>
)
}}
</NButton>
</NSpace>
</div>
</NCard>
<Card class={styles['table-card']}>
<NDataTable columns={this.columns} data={this.tableData} />
<div class={styles.pagination}>
<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={requestData}
onUpdatePageSize={onUpdatePageSize}
/>
</div>
</Card>
<VersionModal
show={this.showVersionModalRef}
row={this.row}
onConfirm={() => (this.showVersionModalRef = false)}
onRefresh={onRefresh}
/>
<MoveModal
show={this.showMoveModalRef}
row={this.row}
onCancel={() => (this.showMoveModalRef = false)}
onRefresh={onRefresh}
/>
</>
)
} }
}) })
export default TaskDefinition

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

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

@ -53,7 +53,6 @@ export function useTable() {
processInstanceName: ref(null), processInstanceName: ref(null),
totalPage: ref(1), totalPage: ref(1),
showModalRef: ref(false), showModalRef: ref(false),
statusRef: ref(0),
row: {} row: {}
}) })

Loading…
Cancel
Save