You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by zh...@apache.org on 2022/01/17 11:03:54 UTC

[dolphinscheduler] branch dev updated: [Feature][UI Next] Feat worker group manage (#8087)

This is an automated email from the ASF dual-hosted git repository.

zhongjiajie 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 2a77380  [Feature][UI Next] Feat worker group manage (#8087)
2a77380 is described below

commit 2a773802ef7134c4faa93edd8eaacabbea7aabe2
Author: songjianet <17...@qq.com>
AuthorDate: Mon Jan 17 19:03:41 2022 +0800

    [Feature][UI Next] Feat worker group manage (#8087)
    
    * [Feature][UI Next] Add worker group manage.
    
    * [Feature][UI Next] Add worker group manage table tag.
---
 .../src/locales/modules/en_US.ts                   |  15 ++
 .../src/locales/modules/zh_CN.ts                   |  16 +-
 .../src/router/modules/security.ts                 |   8 +
 .../src/service/modules/worker-groups/index.ts     |   5 +-
 .../src/service/modules/worker-groups/types.ts     |  20 ++-
 .../worker-group-manage/components/use-modal.ts    | 120 +++++++++++++
 .../components/worker-group-modal.tsx              | 142 +++++++++++++++
 .../worker-group-manage/index.module.scss}         |  35 ++--
 .../views/security/worker-group-manage/index.tsx   | 158 +++++++++++++++++
 .../security/worker-group-manage/use-table.ts      | 193 +++++++++++++++++++++
 10 files changed, 695 insertions(+), 17 deletions(-)

diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
index 700d04d..e0f0d34 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts
@@ -326,6 +326,21 @@ const security = {
     edit: 'Edit',
     delete: 'Delete'
   },
+  worker_group: {
+    create_worker_group: 'Create Worker Group',
+    edit_worker_group: 'Edit Worker Group',
+    search_tips: 'Please enter keywords',
+    operation: 'Operation',
+    delete_confirm: 'Delete?',
+    edit: 'Edit',
+    delete: 'Delete',
+    group_name: 'Group Name',
+    group_name_tips: 'Please enter your group name',
+    worker_addresses: 'Worker Addresses',
+    worker_addresses_tips: 'Please select worker addresses',
+    create_time: 'Create Time',
+    update_time: 'Update Time'
+  },
   yarn_queue: {
     create_queue: 'Create Queue',
     edit_queue: 'Edit Queue',
diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
index dfc5035..d456a81 100644
--- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
+++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts
@@ -321,12 +321,26 @@ const security = {
     alarm_group_description: '告警组描述',
     create_time: '创建时间',
     update_time: '更新时间',
-    actions: '操作',
     operation: '操作',
     delete_confirm: '确定删除吗?',
     edit: '编辑',
     delete: '删除'
   },
+  worker_group: {
+    create_worker_group: '创建Worker分组',
+    edit_worker_group: '编辑Worker分组',
+    search_tips: '请输入关键词',
+    operation: '操作',
+    delete_confirm: '确定删除吗?',
+    edit: '编辑',
+    delete: '删除',
+    group_name: '分组名称',
+    group_name_tips: '请输入分组名称',
+    worker_addresses: 'Worker地址',
+    worker_addresses_tips: '请选择Worker地址',
+    create_time: '创建时间',
+    update_time: '更新时间'
+  },
   yarn_queue: {
     create_queue: '创建队列',
     edit_queue: '编辑队列',
diff --git a/dolphinscheduler-ui-next/src/router/modules/security.ts b/dolphinscheduler-ui-next/src/router/modules/security.ts
index 6677a7c..521d9a3 100644
--- a/dolphinscheduler-ui-next/src/router/modules/security.ts
+++ b/dolphinscheduler-ui-next/src/router/modules/security.ts
@@ -54,6 +54,14 @@ export default {
       }
     },
     {
+      path: '/security/worker-group-manage',
+      name: 'worker-group-manage',
+      component: components['worker-group-manage'],
+      meta: {
+        title: 'Worker分组管理'
+      }
+    },
+    {
       path: '/security/yarn-queue-manage',
       name: 'yarn-queue-manage',
       component: components['yarn-queue-manage'],
diff --git a/dolphinscheduler-ui-next/src/service/modules/worker-groups/index.ts b/dolphinscheduler-ui-next/src/service/modules/worker-groups/index.ts
index 0cedd07..acc6eb5 100644
--- a/dolphinscheduler-ui-next/src/service/modules/worker-groups/index.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/worker-groups/index.ts
@@ -50,7 +50,8 @@ export function queryWorkerAddressList(): any {
 
 export function deleteById(id: IdReq): any {
   return axios({
-    url: `/worker-groups/${id}`,
-    method: 'delete'
+    url: `/worker-groups/${id.id}`,
+    method: 'delete',
+    params: id
   })
 }
diff --git a/dolphinscheduler-ui-next/src/service/modules/worker-groups/types.ts b/dolphinscheduler-ui-next/src/service/modules/worker-groups/types.ts
index 4520a2d..0a19754 100644
--- a/dolphinscheduler-ui-next/src/service/modules/worker-groups/types.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/worker-groups/types.ts
@@ -31,4 +31,22 @@ interface IdReq {
   id: number
 }
 
-export { ListReq, WorkerGroupReq, IdReq }
+interface WorkerGroupItem {
+  id: number
+  name: string
+  addrList: string
+  createTime: string
+  updateTime: string
+  systemDefault: boolean
+}
+
+interface WorkerGroupRes {
+  totalList: WorkerGroupItem[]
+  total: number
+  totalPage: number
+  pageSize: number
+  currentPage: number
+  start: number
+}
+
+export { ListReq, WorkerGroupReq, IdReq, WorkerGroupItem, WorkerGroupRes }
diff --git a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/use-modal.ts b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/use-modal.ts
new file mode 100644
index 0000000..9330562
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/use-modal.ts
@@ -0,0 +1,120 @@
+/*
+ * 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 {
+  queryWorkerAddressList,
+  saveWorkerGroup
+} from '@/service/modules/worker-groups'
+
+export function useModal(
+  props: any,
+  ctx: SetupContext<('cancelModal' | 'confirmModal')[]>
+) {
+  const { t } = useI18n()
+
+  const variables = reactive({
+    workerGroupFormRef: ref(),
+    model: {
+      id: ref<number>(-1),
+      name: ref(''),
+      addrList: ref<Array<number>>([]),
+      generalOptions: []
+    },
+    rules: {
+      name: {
+        required: true,
+        trigger: ['input', 'blur'],
+        validator() {
+          if (variables.model.name === '') {
+            return new Error(t('security.worker_group.group_name_tips'))
+          }
+        }
+      },
+      addrList: {
+        required: true,
+        trigger: ['input', 'blur'],
+        validator() {
+          if (variables.model.addrList.length < 1) {
+            return new Error(t('security.worker_group.worker_addresses_tips'))
+          }
+        }
+      }
+    }
+  })
+
+  const getListData = () => {
+    const { state } = useAsyncState(
+      queryWorkerAddressList().then((res: Array<string>) => {
+        variables.model.generalOptions = res.map(
+          (item): { label: string; value: string } => {
+            return {
+              label: item,
+              value: item
+            }
+          }
+        ) as any
+      }),
+      {}
+    )
+
+    return state
+  }
+
+  const handleValidate = (statusRef: number) => {
+    variables.workerGroupFormRef.validate((errors: any) => {
+      if (!errors) {
+        statusRef === 0 ? submitWorkerGroupModal() : updateWorkerGroupModal()
+      } else {
+        return
+      }
+    })
+  }
+
+  const submitWorkerGroupModal = () => {
+    const data = {
+      name: variables.model.name,
+      addrList: variables.model.addrList.toString()
+    }
+
+    saveWorkerGroup(data).then(() => {
+      variables.model.name = ''
+      variables.model.addrList = []
+      ctx.emit('confirmModal', props.showModalRef)
+    })
+  }
+
+  const updateWorkerGroupModal = () => {
+    const data = {
+      id: variables.model.id,
+      name: variables.model.name,
+      addrList: variables.model.addrList.toString()
+    }
+
+    saveWorkerGroup(data).then(() => {
+      ctx.emit('confirmModal', props.showModalRef)
+    })
+  }
+
+  return {
+    variables,
+    handleValidate,
+    getListData
+  }
+}
diff --git a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/worker-group-modal.tsx b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/worker-group-modal.tsx
new file mode 100644
index 0000000..bdc2ed2
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/worker-group-modal.tsx
@@ -0,0 +1,142 @@
+/*
+ * 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, NInput, NSelect } from 'naive-ui'
+import { useModal } from './use-modal'
+import { useI18n } from 'vue-i18n'
+
+const WorkerGroupModal = defineComponent({
+  name: 'WorkerQueueModal',
+  props: {
+    showModalRef: {
+      type: Boolean as PropType<boolean>,
+      default: false
+    },
+    statusRef: {
+      type: Number as PropType<number>,
+      default: 0
+    },
+    row: {
+      type: Object as PropType<any>,
+      default: {}
+    }
+  },
+  emits: ['cancelModal', 'confirmModal'],
+  setup(props, ctx) {
+    const { variables, handleValidate, getListData } = useModal(props, ctx)
+    const { t } = useI18n()
+
+    const cancelModal = () => {
+      if (props.statusRef === 0) {
+        variables.model.name = ''
+        variables.model.addrList = []
+      }
+      ctx.emit('cancelModal', props.showModalRef)
+    }
+
+    const confirmModal = () => {
+      handleValidate(props.statusRef)
+    }
+
+    watch(
+      () => props.showModalRef,
+      () => {
+        props.showModalRef && getListData()
+      }
+    )
+
+    watch(
+      () => props.statusRef,
+      () => {
+        if (props.statusRef === 0) {
+          variables.model.name = ''
+          variables.model.addrList = []
+        } else {
+          variables.model.id = props.row.id
+          variables.model.name = props.row.name
+          variables.model.addrList = props.row.addrList.split(',')
+        }
+      }
+    )
+
+    watch(
+      () => props.row,
+      () => {
+        variables.model.id = props.row.id
+        variables.model.name = props.row.name
+        variables.model.addrList = props.row.addrList.split(',')
+      }
+    )
+
+    return { t, ...toRefs(variables), cancelModal, confirmModal }
+  },
+  render() {
+    const { t } = this
+    return (
+      <div>
+        <Modal
+          title={
+            this.statusRef === 0
+              ? t('security.worker_group.create_worker_group')
+              : t('security.worker_group.edit_worker_group')
+          }
+          show={this.showModalRef}
+          onCancel={this.cancelModal}
+          onConfirm={this.confirmModal}
+          confirmDisabled={!this.model.name || this.model.addrList.length < 1}
+        >
+          {{
+            default: () => (
+              <NForm
+                model={this.model}
+                rules={this.rules}
+                ref='workerGroupFormRef'
+              >
+                <NFormItem
+                  label={t('security.worker_group.group_name')}
+                  path='name'
+                >
+                  <NInput
+                    placeholder={t('security.worker_group.group_name_tips')}
+                    v-model={[this.model.name, 'value']}
+                  />
+                </NFormItem>
+                <NFormItem
+                  label={t('security.worker_group.worker_addresses')}
+                  path='addrList'
+                >
+                  <NSelect
+                    multiple
+                    placeholder={t(
+                      'security.worker_group.worker_addresses_tips'
+                    )}
+                    options={this.model.generalOptions}
+                    v-model={[this.model.addrList, 'value']}
+                  />
+                </NFormItem>
+              </NForm>
+            )
+          }}
+        </Modal>
+      </div>
+    )
+  }
+})
+
+export default WorkerGroupModal
diff --git a/dolphinscheduler-ui-next/src/service/modules/worker-groups/types.ts b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/index.module.scss
similarity index 69%
copy from dolphinscheduler-ui-next/src/service/modules/worker-groups/types.ts
copy to dolphinscheduler-ui-next/src/views/security/worker-group-manage/index.module.scss
index 4520a2d..de6cf70 100644
--- a/dolphinscheduler-ui-next/src/service/modules/worker-groups/types.ts
+++ b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/index.module.scss
@@ -15,20 +15,29 @@
  * limitations under the License.
  */
 
-interface ListReq {
-  pageNo: number
-  pageSize: number
-  searchVal?: string
-}
+.search-card {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
 
-interface WorkerGroupReq {
-  addrList: string
-  name: string
-  id?: number
-}
+  .box {
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+    width: 300px;
 
-interface IdReq {
-  id: number
+    button {
+      margin-left: 10px;
+    }
+  }
 }
 
-export { ListReq, WorkerGroupReq, IdReq }
+.table-card {
+  margin-top: 8px;
+
+  .pagination {
+    margin-top: 20px;
+    display: flex;
+    justify-content: center;
+  }
+}
diff --git a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/index.tsx b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/index.tsx
new file mode 100644
index 0000000..869cc24
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/index.tsx
@@ -0,0 +1,158 @@
+/*
+ * 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, toRefs, watch } from 'vue'
+import {
+  NButton,
+  NCard,
+  NDataTable,
+  NIcon,
+  NInput,
+  NPagination
+} from 'naive-ui'
+import { SearchOutlined } from '@vicons/antd'
+import { useI18n } from 'vue-i18n'
+import { useTable } from './use-table'
+import Card from '@/components/card'
+import WorkerGroupModal from './components/worker-group-modal'
+import styles from './index.module.scss'
+
+const workerGroupManage = defineComponent({
+  name: 'worker-group-manage',
+  setup() {
+    const { t } = useI18n()
+    const { variables, getTableData, createColumns } = useTable()
+
+    const requestData = () => {
+      getTableData({
+        pageSize: variables.pageSize,
+        pageNo: variables.page,
+        searchVal: variables.searchVal
+      })
+    }
+
+    const onUpdatePageSize = () => {
+      variables.page = 1
+      requestData()
+    }
+
+    const onSearch = () => {
+      variables.page = 1
+      requestData()
+    }
+
+    const handleModalChange = () => {
+      variables.showModalRef = true
+      variables.statusRef = 0
+    }
+
+    const onCancelModal = () => {
+      variables.showModalRef = false
+    }
+
+    const onConfirmModal = () => {
+      variables.showModalRef = false
+      requestData()
+    }
+
+    onMounted(() => {
+      createColumns(variables)
+      requestData()
+    })
+
+    watch(useI18n().locale, () => {
+      createColumns(variables)
+    })
+
+    return {
+      t,
+      ...toRefs(variables),
+      requestData,
+      onCancelModal,
+      onConfirmModal,
+      onUpdatePageSize,
+      handleModalChange,
+      onSearch
+    }
+  },
+  render() {
+    const {
+      t,
+      requestData,
+      onUpdatePageSize,
+      onCancelModal,
+      onConfirmModal,
+      handleModalChange,
+      onSearch
+    } = this
+
+    return (
+      <div>
+        <NCard>
+          <div class={styles['search-card']}>
+            <div>
+              <NButton size='small' type='primary' onClick={handleModalChange}>
+                {t('security.worker_group.create_worker_group')}
+              </NButton>
+            </div>
+            <div class={styles.box}>
+              <NInput
+                size='small'
+                clearable
+                v-model={[this.searchVal, 'value']}
+                placeholder={t('security.worker_group.search_tips')}
+              />
+              <NButton size='small' type='primary' onClick={onSearch}>
+                {{
+                  icon: () => (
+                    <NIcon>
+                      <SearchOutlined />
+                    </NIcon>
+                  )
+                }}
+              </NButton>
+            </div>
+          </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>
+        <WorkerGroupModal
+          showModalRef={this.showModalRef}
+          statusRef={this.statusRef}
+          row={this.row}
+          onCancelModal={onCancelModal}
+          onConfirmModal={onConfirmModal}
+        />
+      </div>
+    )
+  }
+})
+
+export default workerGroupManage
diff --git a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/use-table.ts b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/use-table.ts
new file mode 100644
index 0000000..17dda3e
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/use-table.ts
@@ -0,0 +1,193 @@
+/*
+ * 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 } from '@vicons/antd'
+import {
+  queryAllWorkerGroupsPaging,
+  deleteById
+} from '@/service/modules/worker-groups'
+import type {
+  WorkerGroupRes,
+  WorkerGroupItem
+} from '@/service/modules/worker-groups/types'
+
+export function useTable() {
+  const { t } = useI18n()
+
+  const handleEdit = (row: any) => {
+    variables.showModalRef = true
+    variables.statusRef = 1
+    variables.row = row
+  }
+
+  const createColumns = (variables: any) => {
+    variables.columns = [
+      {
+        title: '#',
+        key: 'index'
+      },
+      {
+        title: t('security.worker_group.group_name'),
+        key: 'name'
+      },
+      {
+        title: t('security.worker_group.worker_addresses'),
+        key: 'addrList',
+        render: (row: WorkerGroupItem) =>
+          h(NSpace, null, {
+            default: () =>
+              row.addrList
+                .split(',')
+                .map((item: string) =>
+                  h(
+                    NTag,
+                    { type: 'success', size: 'small' },
+                    { default: () => item }
+                  )
+                )
+          })
+      },
+      {
+        title: t('security.worker_group.create_time'),
+        key: 'createTime'
+      },
+      {
+        title: t('security.worker_group.update_time'),
+        key: 'updateTime'
+      },
+      {
+        title: t('security.worker_group.operation'),
+        key: 'operation',
+        render(row: any) {
+          if (row.systemDefault) {
+            return false
+          }
+
+          return h(NSpace, null, {
+            default: () => [
+              h(
+                NTooltip,
+                {},
+                {
+                  trigger: () =>
+                    h(
+                      NButton,
+                      {
+                        circle: true,
+                        type: 'info',
+                        size: 'small',
+                        onClick: () => {
+                          handleEdit(row)
+                        }
+                      },
+                      {
+                        icon: () => h(EditOutlined)
+                      }
+                    ),
+                  default: () => t('security.worker_group.edit')
+                }
+              ),
+              h(
+                NPopconfirm,
+                {
+                  onPositiveClick: () => {
+                    handleDelete(row)
+                  }
+                },
+                {
+                  trigger: () =>
+                    h(
+                      NTooltip,
+                      {},
+                      {
+                        trigger: () =>
+                          h(
+                            NButton,
+                            {
+                              circle: true,
+                              type: 'error',
+                              size: 'small'
+                            },
+                            {
+                              icon: () => h(DeleteOutlined)
+                            }
+                          ),
+                        default: () => t('security.worker_group.delete')
+                      }
+                    ),
+                  default: () => t('security.worker_group.delete_confirm')
+                }
+              )
+            ]
+          })
+        }
+      }
+    ]
+  }
+
+  const variables = reactive({
+    columns: [],
+    tableData: [],
+    page: ref(1),
+    pageSize: ref(10),
+    searchVal: ref(null),
+    totalPage: ref(1),
+    showModalRef: ref(false),
+    statusRef: ref(0),
+    row: {}
+  })
+
+  const handleDelete = (row: any) => {
+    deleteById({ id: row.id }).then(() => {
+      getTableData({
+        pageSize: variables.pageSize,
+        pageNo:
+          variables.tableData.length === 1 && variables.page > 1
+            ? variables.page - 1
+            : variables.page,
+        searchVal: variables.searchVal
+      })
+    })
+  }
+
+  const getTableData = (params: any) => {
+    const { state } = useAsyncState(
+      queryAllWorkerGroupsPaging({ ...params }).then((res: WorkerGroupRes) => {
+        variables.tableData = res.totalList.map((item, index) => {
+          return {
+            index: index + 1,
+            ...item
+          }
+        }) as any
+        variables.totalPage = res.totalPage
+      }),
+      {}
+    )
+
+    return state
+  }
+
+  return {
+    variables,
+    getTableData,
+    createColumns
+  }
+}