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