You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by so...@apache.org on 2022/03/07 09:15:11 UTC
[dolphinscheduler] branch dev updated: [Refactor][UI Next][V1.0.0-Alpha] Refactor the list of projects under the project module (#8738)
This is an automated email from the ASF dual-hosted git repository.
songjian pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new a6bfb58 [Refactor][UI Next][V1.0.0-Alpha] Refactor the list of projects under the project module (#8738)
a6bfb58 is described below
commit a6bfb5847e246acb1237367b1920082588d88360
Author: labbomb <73...@qq.com>
AuthorDate: Mon Mar 7 17:15:04 2022 +0800
[Refactor][UI Next][V1.0.0-Alpha] Refactor the list of projects under the project module (#8738)
---
.../projects/list/components/project-modal.tsx | 89 +++++----
.../projects/list/components/table-action.tsx | 121 -------------
.../projects/list/{ => components}/use-form.ts | 40 +++-
.../src/views/projects/list/index.tsx | 176 ++++++------------
.../src/views/projects/list/use-table.ts | 201 ++++++++++++++-------
5 files changed, 275 insertions(+), 352 deletions(-)
diff --git a/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx b/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx
index 60bfae2..f5b98c0 100644
--- a/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx
+++ b/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx
@@ -15,84 +15,95 @@
* limitations under the License.
*/
-import { defineComponent, PropType, toRefs, onMounted } from 'vue'
+import { defineComponent, PropType, toRefs, onMounted, watch } from 'vue'
import { NForm, NFormItem, NInput } from 'naive-ui'
-import { useForm } from '../use-form'
+import { useForm } from './use-form'
import Modal from '@/components/modal'
-import { createProject, updateProject } from '@/service/modules/projects'
const props = {
- show: {
+ showModalRef: {
type: Boolean as PropType<boolean>,
default: false
},
- data: {
- type: Object as PropType<any>
- },
- status: {
+ statusRef: {
type: Number as PropType<number>,
default: 0
+ },
+ row: {
+ type: Object as PropType<any>,
+ default: {}
}
}
const ProjectModal = defineComponent({
name: 'ProjectModal',
props,
- emits: ['confirm', 'cancel'],
- setup(props, { emit }) {
- const { state, t } = useForm()
+ emits: ['cancelModal', 'confirmModal'],
+ setup(props, ctx) {
+ const { variables, t, handleValidate } = useForm(props, ctx)
- onMounted(() => {
- if (props.status === 1) {
- state.projectForm.projectName = props.data.projectName
- state.projectForm.description = props.data.description
+ const cancelModal = () => {
+ if (props.statusRef === 0) {
+ variables.model.projectName = ''
+ variables.model.description = ''
}
- })
-
- const onConfirm = () => {
- ;(props.status === 1
- ? updateProject(state.projectForm, props.data.code)
- : createProject(state.projectForm)
- ).then(() => {
- emit('confirm')
- })
+ ctx.emit('cancelModal', props.showModalRef)
}
- const onCancel = () => {
- state.projectForm.projectName = ''
- state.projectForm.description = ''
- state.projectForm.userName = ''
- emit('cancel')
+ const confirmModal = () => {
+ handleValidate(props.statusRef)
}
- return { ...toRefs(state), t, onConfirm, onCancel }
+ watch(
+ () => props.statusRef,
+ () => {
+ if (props.statusRef === 0) {
+ variables.model.projectName = ''
+ variables.model.description = ''
+ } else {
+ variables.model.projectName = props.row.name
+ variables.model.description = props.row.description
+ }
+ }
+ )
+
+ watch(
+ () => props.row,
+ () => {
+ variables.model.projectName = props.row.name
+ variables.model.description = props.row.description
+ }
+ )
+
+ return { ...toRefs(variables), t, cancelModal, confirmModal }
},
render() {
- const { t, onConfirm, onCancel, show, status } = this
+ const { t } = this
return (
<Modal
title={
- status === 0
+ this.statusRef === 0
? t('project.list.create_project')
: t('project.list.edit_project')
}
- show={show}
- onConfirm={onConfirm}
- onCancel={onCancel}
+ show={this.showModalRef}
+ onConfirm={this.confirmModal}
+ onCancel={this.cancelModal}
confirmDisabled={
- !this.projectForm.projectName || !this.projectForm.userName
+ !this.model.projectName || !this.model.userName
}
>
<NForm rules={this.rules} ref='projectFormRef'>
<NFormItem label={t('project.list.project_name')} path='projectName'>
<NInput
- v-model={[this.projectForm.projectName, 'value']}
+ v-model={[this.model.projectName, 'value']}
placeholder={t('project.list.project_tips')}
/>
</NFormItem>
<NFormItem label={t('project.list.owned_users')} path='userName'>
<NInput
- v-model={[this.projectForm.userName, 'value']}
+ disabled={this.statusRef === 0}
+ v-model={[this.model.userName, 'value']}
placeholder={t('project.list.username_tips')}
/>
</NFormItem>
@@ -101,7 +112,7 @@ const ProjectModal = defineComponent({
path='description'
>
<NInput
- v-model={[this.projectForm.description, 'value']}
+ v-model={[this.model.description, 'value']}
type='textarea'
placeholder={t('project.list.description_tips')}
/>
diff --git a/dolphinscheduler-ui-next/src/views/projects/list/components/table-action.tsx b/dolphinscheduler-ui-next/src/views/projects/list/components/table-action.tsx
deleted file mode 100644
index b66382f..0000000
--- a/dolphinscheduler-ui-next/src/views/projects/list/components/table-action.tsx
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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 } from 'vue'
-import { useI18n } from 'vue-i18n'
-import { NSpace, NTooltip, NButton, NIcon, NPopconfirm } from 'naive-ui'
-import { DeleteOutlined, EditOutlined, InfoCircleFilled } from '@vicons/antd'
-import { deleteProject } from '@/service/modules/projects'
-import type { ProjectList } from '@/service/modules/projects/types'
-
-interface ProjectRow extends ProjectList {
- index: number
-}
-
-const props = {
- row: {
- type: Object as PropType<ProjectRow>,
- default: {}
- }
-}
-
-const TableAction = defineComponent({
- name: 'TableAction',
- props,
- emits: ['resetTableData', 'updateProjectItem'],
- setup(props, { emit }) {
- const { t } = useI18n()
-
- const handleEditProject = (
- code: number,
- projectName: string,
- description: string
- ) => {
- emit('updateProjectItem', code, projectName, description)
- }
-
- const handleDeleteProject = (code: number) => {
- deleteProject(code).then(() => {
- emit('resetTableData')
- })
- }
-
- return { t, handleEditProject, handleDeleteProject }
- },
- render() {
- const { t, handleEditProject, handleDeleteProject } = this
-
- return (
- <NSpace>
- <NTooltip trigger={'hover'}>
- {{
- default: () => t('project.list.edit'),
- trigger: () => (
- <NButton
- size='small'
- type='info'
- tag='div'
- onClick={() =>
- handleEditProject(
- this.row.code,
- this.row.name,
- this.row.description
- )
- }
- circle
- >
- <NIcon>
- <EditOutlined />
- </NIcon>
- </NButton>
- )
- }}
- </NTooltip>
- <NTooltip trigger={'hover'}>
- {{
- default: () => t('project.list.delete'),
- trigger: () => (
- <NButton size='small' type='error' circle>
- <NPopconfirm
- positive-text={t('project.list.confirm')}
- negative-text={t('project.list.cancel')}
- onPositiveClick={() => handleDeleteProject(this.row.code)}
- >
- {{
- default: () => t('project.list.delete_confirm'),
- icon: () => (
- <NIcon>
- <InfoCircleFilled />
- </NIcon>
- ),
- trigger: () => (
- <NIcon>
- <DeleteOutlined />
- </NIcon>
- )
- }}
- </NPopconfirm>
- </NButton>
- )
- }}
- </NTooltip>
- </NSpace>
- )
- }
-})
-
-export default TableAction
diff --git a/dolphinscheduler-ui-next/src/views/projects/list/use-form.ts b/dolphinscheduler-ui-next/src/views/projects/list/components/use-form.ts
similarity index 62%
rename from dolphinscheduler-ui-next/src/views/projects/list/use-form.ts
rename to dolphinscheduler-ui-next/src/views/projects/list/components/use-form.ts
index cf8d03d..29f41a8 100644
--- a/dolphinscheduler-ui-next/src/views/projects/list/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/list/components/use-form.ts
@@ -16,18 +16,22 @@
*/
import { useI18n } from 'vue-i18n'
-import { reactive, ref } from 'vue'
+import { reactive, ref, SetupContext } from 'vue'
import { useUserStore } from '@/store/user/user'
import type { FormRules } from 'naive-ui'
import type { UserInfoRes } from '@/service/modules/users/types'
+import { createProject, updateProject } from '@/service/modules/projects'
-export function useForm() {
+export function useForm(
+ props: any,
+ ctx: SetupContext<('cancelModal' | 'confirmModal')[]>
+) {
const { t } = useI18n()
const userStore = useUserStore()
- const state = reactive({
+ const variables = reactive({
projectFormRef: ref(),
- projectForm: {
+ model: {
projectName: '',
description: '',
userName: (userStore.getUserInfo as UserInfoRes).userName
@@ -37,7 +41,7 @@ export function useForm() {
required: true,
trigger: ['input', 'blur'],
validator() {
- if (state.projectForm.projectName === '') {
+ if (variables.model.projectName === '') {
return new Error(t('project.list.project_tips'))
}
}
@@ -46,7 +50,7 @@ export function useForm() {
required: true,
trigger: ['input', 'blur'],
validator() {
- if (state.projectForm.userName === '') {
+ if (variables.model.userName === '') {
return new Error(t('project.list.username_tips'))
}
}
@@ -54,5 +58,27 @@ export function useForm() {
} as FormRules
})
- return { state, t }
+ const handleValidate = (statusRef: number) => {
+ variables.projectFormRef.validate((errors: any) => {
+ if (!errors) {
+ statusRef === 0 ? submitProjectModal() : updateProjectModal()
+ } else {
+ return
+ }
+ })
+ }
+
+ const submitProjectModal = () => {
+ createProject(variables.model).then(() => {
+ ctx.emit('confirmModal', props.showModalRef)
+ })
+ }
+
+ const updateProjectModal = () => {
+ updateProject(variables.model, props.row.code).then(() => {
+ ctx.emit('confirmModal', props.showModalRef)
+ })
+ }
+
+ return { variables, t, handleValidate }
}
diff --git a/dolphinscheduler-ui-next/src/views/projects/list/index.tsx b/dolphinscheduler-ui-next/src/views/projects/list/index.tsx
index 229e571..f6b0156 100644
--- a/dolphinscheduler-ui-next/src/views/projects/list/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/projects/list/index.tsx
@@ -15,34 +15,21 @@
* limitations under the License.
*/
-import { defineComponent, onMounted, ref, toRefs, reactive } from 'vue'
-import {
- NCard,
- NButton,
- NInput,
- NIcon,
- NDataTable,
- NPagination
-} from 'naive-ui'
+
+import Card from '@/components/card'
import { SearchOutlined } from '@vicons/antd'
+import { NButton, NCard, NDataTable, NIcon, NInput, NPagination, NSpace } from 'naive-ui'
+import { defineComponent, onMounted, ref, toRefs, reactive, watch } from 'vue'
import { useI18n } from 'vue-i18n'
-import { useTable } from './use-table'
-import styles from './index.module.scss'
-import Card from '@/components/card'
import ProjectModal from './components/project-modal'
+import styles from './index.module.scss'
+import { useTable } from './use-table'
const list = defineComponent({
name: 'list',
setup() {
- const showModalRef = ref(false)
- const modelStatusRef = ref(0)
const { t } = useI18n()
- const { variables, getTableData } = useTable()
- let updateProjectData = reactive({
- code: 0,
- projectName: '',
- description: ''
- })
+ const { variables, getTableData, createColumns } = useTable()
const requestData = () => {
getTableData({
@@ -52,120 +39,68 @@ const list = defineComponent({
})
}
- const onCancel = () => {
- showModalRef.value = false
+ const handleModalChange = () => {
+ variables.showModalRef = true
+ variables.statusRef = 0
}
- const onConfirm = () => {
- showModalRef.value = false
- updateProjectData = {
- code: 0,
- projectName: '',
- description: ''
- }
- resetTableData()
- }
-
- const onOpen = () => {
- modelStatusRef.value = 0
- showModalRef.value = true
+ const handleSearch = () => {
+ variables.page = 1
+ requestData()
}
- const resetTableData = () => {
- getTableData({
- pageSize: variables.pageSize,
- pageNo: variables.page,
- searchVal: variables.searchVal
- })
+ const onCancelModal = () => {
+ variables.showModalRef = false
}
- const onSearch = () => {
- variables.page = 1
- getTableData({
- pageSize: variables.pageSize,
- pageNo: variables.page,
- searchVal: variables.searchVal
- })
+ const onConfirmModal = () => {
+ variables.showModalRef = false
+ requestData()
}
- const onUpdatePageSize = () => {
+ const handleChangePageSize = () => {
variables.page = 1
- resetTableData()
- }
-
- const updateProjectItem = (
- code: number,
- projectName: string,
- description: string
- ) => {
- modelStatusRef.value = 1
- showModalRef.value = true
- updateProjectData.code = code
- updateProjectData.projectName = projectName
- updateProjectData.description = description
+ requestData()
}
onMounted(() => {
+ createColumns(variables)
requestData()
})
- return {
- t,
- showModalRef,
- ...toRefs(variables),
- onCancel,
- onConfirm,
- onOpen,
- updateProjectItem,
- resetTableData,
- onUpdatePageSize,
- onSearch,
- updateProjectData,
- modelStatusRef
- }
+ watch(useI18n().locale, () => {
+ createColumns(variables)
+ })
+
+ return { t, ...toRefs(variables), requestData, handleModalChange, handleSearch, onCancelModal, onConfirmModal, handleChangePageSize }
},
render() {
- const {
- t,
- showModalRef,
- onCancel,
- onConfirm,
- onOpen,
- updateProjectItem,
- resetTableData,
- onUpdatePageSize,
- onSearch,
- updateProjectData,
- modelStatusRef
- } = this
- const { columns } = useTable(updateProjectItem, resetTableData)
-
+ const { t } = this
return (
<div>
<NCard>
<div class={styles['search-card']}>
- <div>
- <NButton size='small' type='primary' onClick={onOpen}>
- {t('project.list.create_project')}
- </NButton>
- </div>
- <div class={styles.box}>
+ <NButton
+ size='small'
+ onClick={this.handleModalChange}
+ type='primary'
+ class='btn-create-tenant'
+ >
+ {t('project.list.create_project')}
+ </NButton>
+ <NSpace>
<NInput
size='small'
- v-model:value={this.searchVal}
+ v-model={[this.searchVal, 'value']}
placeholder={t('project.list.project_tips')}
clearable
/>
- <NButton size='small' type='primary' onClick={onSearch}>
- {{
- icon: () => (
- <NIcon>
- <SearchOutlined />
- </NIcon>
- )
- }}
+ <NButton size='small' type='primary' onClick={this.handleSearch}>
+ <NIcon>
+ <SearchOutlined />
+ </NIcon>
</NButton>
- </div>
+ </NSpace>
</div>
</NCard>
<Card
@@ -173,10 +108,9 @@ const list = defineComponent({
class={styles['table-card']}
>
<NDataTable
- columns={columns}
- size={'small'}
+ columns={this.columns}
data={this.tableData}
- striped
+ row-class-name='items'
/>
<div class={styles.pagination}>
<NPagination
@@ -186,23 +120,21 @@ const list = defineComponent({
show-size-picker
page-sizes={[10, 30, 50]}
show-quick-jumper
- onUpdatePage={resetTableData}
- onUpdatePageSize={onUpdatePageSize}
+ onUpdatePage={this.requestData}
+ onUpdatePageSize={this.handleChangePageSize}
/>
</div>
</Card>
- {showModalRef && (
- <ProjectModal
- show={showModalRef}
- onCancel={onCancel}
- onConfirm={onConfirm}
- data={updateProjectData}
- status={modelStatusRef}
- />
- )}
+ <ProjectModal
+ showModalRef={this.showModalRef}
+ statusRef={this.statusRef}
+ row={this.row}
+ onCancelModal={this.onCancelModal}
+ onConfirmModal={this.onConfirmModal}
+ />
</div>
)
}
})
-export default list
+export default list
\ No newline at end of file
diff --git a/dolphinscheduler-ui-next/src/views/projects/list/use-table.ts b/dolphinscheduler-ui-next/src/views/projects/list/use-table.ts
index e78e212..28fb489 100644
--- a/dolphinscheduler-ui-next/src/views/projects/list/use-table.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/list/use-table.ts
@@ -19,90 +19,161 @@ import { h, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAsyncState } from '@vueuse/core'
import { queryProjectListPaging } from '@/service/modules/projects'
+import { parseTime } from '@/utils/common'
+import { deleteProject } from '@/service/modules/projects'
import { format } from 'date-fns'
import { useRouter } from 'vue-router'
import { useMenuStore } from '@/store/menu/menu'
-import { NEllipsis } from 'naive-ui'
-import TableAction from './components/table-action'
-import { parseTime } from '@/utils/common'
+import { NButton, NEllipsis, NIcon, NPopconfirm, NSpace, NTooltip } from 'naive-ui'
import type { Router } from 'vue-router'
-import type { TableColumns } from 'naive-ui/es/data-table/src/interface'
import type { ProjectRes } from '@/service/modules/projects/types'
+import { DeleteOutlined, EditOutlined } from '@vicons/antd'
-export function useTable(
- updateProjectItem = (
- unusedCode: number,
- unusedName: string,
- unusedDescription: string
- ): void => {},
- resetTableData = () => {}
-) {
+export function useTable() {
const { t } = useI18n()
const router: Router = useRouter()
const menuStore = useMenuStore()
- const columns: TableColumns<any> = [
- { title: '#', key: 'index', render: (row, index) => index + 1 },
- {
- title: t('project.list.project_name'),
- key: 'name',
- render: (row) =>
- h(
- NEllipsis,
- { style: 'max-width: 200px; color: #2080f0' },
- {
- default: () =>
+ const handleEdit = (row: any) => {
+ variables.showModalRef = true
+ variables.statusRef = 1
+ variables.row = row
+ }
+
+ const handleDelete = (row: any) => {
+ deleteProject(row.code).then(() => {
+ getTableData({
+ pageSize: variables.pageSize,
+ pageNo:
+ variables.tableData.length === 1 && variables.page > 1
+ ? variables.page - 1
+ : variables.page,
+ searchVal: variables.searchVal
+ })
+ })
+ }
+
+ const createColumns = (variables: any) => {
+ variables.columns = [
+ { title: '#', key: 'index', render: (row: any, index: number) => index + 1 },
+ {
+ title: t('project.list.project_name'),
+ key: 'name',
+ render: (row: { code: string; name: any }) =>
+ h(
+ NEllipsis,
+ { style: 'max-width: 200px; color: #2080f0' },
+ {
+ default: () =>
+ h(
+ 'a',
+ {
+ onClick: () => {
+ menuStore.setProjectCode(row.code)
+ router.push({ path: `/projects/${row.code}` })
+ }
+ },
+ {
+ default: () => {
+ return row.name
+ }
+ }
+ ),
+ tooltip: () => row.name
+ }
+ )
+ },
+ { title: t('project.list.owned_users'), key: 'userName' },
+ { title: t('project.list.workflow_define_count'), key: 'defCount' },
+ {
+ title: t('project.list.process_instance_running_count'),
+ key: 'instRunningCount'
+ },
+ { title: t('project.list.description'), key: 'description' },
+ { title: t('project.list.create_time'), key: 'createTime' },
+ { title: t('project.list.update_time'), key: 'updateTime' },
+ {
+ title: t('project.list.operation'),
+ key: 'actions',
+ render(row: any) {
+ return h(NSpace, null, {
+ default: () => [
h(
- 'a',
+ NTooltip,
+ {},
{
- onClick: () => {
- menuStore.setProjectCode(row.code)
- router.push({ path: `/projects/${row.code}` })
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'info',
+ size: 'small',
+ class: 'edit',
+ onClick: () => {
+ handleEdit(row)
+ }
+ },
+ {
+ icon: () =>
+ h(NIcon, null, { default: () => h(EditOutlined) })
+ }
+ ),
+ default: () => t('project.list.edit')
+ }
+ ),
+ h(
+ NPopconfirm,
+ {
+ onPositiveClick: () => {
+ handleDelete(row)
}
},
{
- default: () => {
- return row.name
- }
+ trigger: () =>
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'error',
+ size: 'small',
+ class: 'delete'
+ },
+ {
+ icon: () =>
+ h(NIcon, null, {
+ default: () => h(DeleteOutlined)
+ })
+ }
+ ),
+ default: () => t('project.list.delete')
+ }
+ ),
+ default: () => t('project.list.delete_confirm')
}
- ),
- tooltip: () => row.name
- }
- )
- },
- { title: t('project.list.owned_users'), key: 'userName' },
- { title: t('project.list.workflow_define_count'), key: 'defCount' },
- {
- title: t('project.list.process_instance_running_count'),
- key: 'instRunningCount'
- },
- { title: t('project.list.description'), key: 'description' },
- { title: t('project.list.create_time'), key: 'createTime' },
- { title: t('project.list.update_time'), key: 'updateTime' },
- {
- title: t('project.list.operation'),
- key: 'actions',
- render: (row: any) =>
- h(TableAction, {
- row,
- onResetTableData: () => {
- if (variables.page > 1 && variables.tableData.length === 1) {
- variables.page -= 1
- }
- resetTableData()
- },
- onUpdateProjectItem: (code, name, description) =>
- updateProjectItem(code, name, description)
- })
- }
- ]
+ )
+ ]
+ })
+ }
+ }
+ ]
+ }
const variables = reactive({
+ columns: [],
tableData: [],
page: ref(1),
pageSize: ref(10),
searchVal: ref(null),
- totalPage: ref(1)
+ totalPage: ref(1),
+ showModalRef: ref(false),
+ statusRef: ref(0),
+ row: {}
})
const getTableData = (params: any) => {
@@ -128,5 +199,9 @@ export function useTable(
return state
}
- return { getTableData, variables, columns }
+ return {
+ variables,
+ getTableData,
+ createColumns
+ }
}