From 62198fda242801e4acce6a849b74d02f75a23411 Mon Sep 17 00:00:00 2001 From: Devosend Date: Wed, 19 Jan 2022 22:35:47 +0800 Subject: [PATCH] [Feature][UI Next] Add udf function manage (#8126) --- .../src/locales/modules/en_US.ts | 32 +++ .../src/locales/modules/zh_CN.ts | 31 ++ .../src/router/modules/resources.ts | 8 + .../src/service/modules/resources/index.ts | 10 +- .../src/service/modules/resources/types.ts | 2 +- .../function/components/function-modal.tsx | 269 ++++++++++++++++++ .../udf/function/components/use-form.ts | 102 +++++++ .../udf/function/components/use-modal.ts | 184 ++++++++++++ .../resource/udf/function/index.module.scss | 73 +++++ .../src/views/resource/udf/function/index.tsx | 144 ++++++++++ .../src/views/resource/udf/function/types.ts | 38 +++ .../views/resource/udf/function/use-table.ts | 182 ++++++++++++ 12 files changed, 1068 insertions(+), 7 deletions(-) create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/function/index.module.scss create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/function/index.tsx create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/function/types.ts create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/function/use-table.ts diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts index aa058b5e18..604b4a4c53 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts @@ -215,6 +215,38 @@ const resource = { enter_name_tips: 'Please enter name', enter_description_tips: 'Please enter description' }, + function: { + udf_function: 'UDF Function', + create_udf_function: 'Create UDF Function', + edit_udf_function: 'Create UDF Function', + id: '#', + udf_function_name: 'UDF Function Name', + class_name: 'Class Name', + type: 'Type', + description: 'Description', + jar_package: 'Jar Package', + update_time: 'Update Time', + operation: 'Operation', + rename: 'Rename', + edit: 'Edit', + delete: 'Delete', + success: 'Success', + package_name: 'Package Name', + udf_resources: 'UDF Resources', + instructions: 'Instructions', + upload_resources: 'Upload Resources', + udf_resources_directory: 'UDF resources directory', + delete_confirm: 'Delete?', + enter_keyword_tips: 'Please enter keyword', + enter_udf_unction_name_tips: 'Please enter a UDF function name', + enter_package_name_tips: 'Please enter a Package name', + enter_select_udf_resources_tips: 'Please select UDF resources', + enter_select_udf_resources_directory_tips: + 'Please select UDF resources directory', + enter_instructions_tips: 'Please enter a instructions', + enter_name_tips: 'Please enter name', + enter_description_tips: 'Please enter description' + }, task_group_option: { id: 'No.', manage: 'Task group manage', diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts index a77d862552..dcddd80387 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts @@ -217,6 +217,37 @@ const resource = { enter_name_tips: '请输入名称', enter_description_tips: '请输入描述' }, + function: { + udf_function: 'UDF函数', + create_udf_function: '创建UDF函数', + edit_udf_function: '编辑UDF函数', + id: '编号', + udf_function_name: 'UDF函数名称', + class_name: '类名', + type: '类型', + description: '描述', + jar_package: 'jar包', + update_time: '更新时间', + operation: '操作', + rename: '重命名', + edit: '编辑', + delete: '删除', + success: '成功', + package_name: '包名类名', + udf_resources: 'UDF资源', + instructions: '使用说明', + upload_resources: '上传资源', + udf_resources_directory: 'UDF资源目录', + delete_confirm: '确定删除吗?', + enter_keyword_tips: '请输入关键词', + enter_udf_unction_name_tips: '请输入UDF函数名称', + enter_package_name_tips: '请输入包名类名', + enter_select_udf_resources_tips: '请选择UDF资源', + enter_select_udf_resources_directory_tips: '请选择UDF资源目录', + enter_instructions_tips: '请输入使用说明', + enter_name_tips: '请输入名称', + enter_description_tips: '请输入描述' + }, task_group_option: { id: '编号', manage: '任务组管理', diff --git a/dolphinscheduler-ui-next/src/router/modules/resources.ts b/dolphinscheduler-ui-next/src/router/modules/resources.ts index 6fab2c28f3..889e186c93 100644 --- a/dolphinscheduler-ui-next/src/router/modules/resources.ts +++ b/dolphinscheduler-ui-next/src/router/modules/resources.ts @@ -101,6 +101,14 @@ export default { showSide: true } }, + { + path: '/resource/function-manage', + name: 'function-manage', + component: components['function'], + meta: { + title: '函数管理' + } + }, { path: '/resource/task-group', name: 'task-group-manage', diff --git a/dolphinscheduler-ui-next/src/service/modules/resources/index.ts b/dolphinscheduler-ui-next/src/service/modules/resources/index.ts index c6f44f243b..a662ab6095 100644 --- a/dolphinscheduler-ui-next/src/service/modules/resources/index.ts +++ b/dolphinscheduler-ui-next/src/service/modules/resources/index.ts @@ -118,9 +118,7 @@ export function onlineCreateResource( }) } -export function queryResourceByProgramType( - params: ResourceTypeReq & ProgramTypeReq -): any { +export function queryResourceByProgramType(params: ResourceTypeReq): any { return axios({ url: '/resources/query-by-type', method: 'get', @@ -136,7 +134,7 @@ export function queryUdfFuncListPaging(params: ListReq): any { }) } -export function queryUdfFuncList(params: UdfTypeReq): any { +export function queryUdfFuncList(params: IdReq & ListReq): any { return axios({ url: '/resources/udf-func/list', method: 'get', @@ -152,7 +150,7 @@ export function verifyUdfFuncName(params: NameReq): any { }) } -export function deleteUdfFunc(id: IdReq): any { +export function deleteUdfFunc(id: number): any { return axios({ url: `/resources/udf-func/${id}`, method: 'delete' @@ -245,7 +243,7 @@ export function createUdfFunc( export function updateUdfFunc( data: UdfFuncReq, resourceId: ResourceIdReq, - id: IdReq + id: number ): any { return axios({ url: `/resources/${resourceId}/udf-func/${id}`, diff --git a/dolphinscheduler-ui-next/src/service/modules/resources/types.ts b/dolphinscheduler-ui-next/src/service/modules/resources/types.ts index c38e1e3c27..3d7b4e6626 100644 --- a/dolphinscheduler-ui-next/src/service/modules/resources/types.ts +++ b/dolphinscheduler-ui-next/src/service/modules/resources/types.ts @@ -83,7 +83,7 @@ interface ResourceIdReq { resourceId: number } -interface UdfFuncReq extends UdfTypeReq, DescriptionReq { +interface UdfFuncReq extends UdfTypeReq, DescriptionReq, ResourceIdReq { className: string funcName: string argTypes?: string diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx new file mode 100644 index 0000000000..3d86780997 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx @@ -0,0 +1,269 @@ +/* + * 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, toRefs, PropType, watch, onMounted, ref } from 'vue' +import { + NUpload, + NIcon, + NForm, + NFormItem, + NInput, + NInputGroup, + NRadio, + NTreeSelect, + NButton, + NRadioGroup +} from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { CloudUploadOutlined } from '@vicons/antd' +import Modal from '@/components/modal' +import { useForm } from './use-form' +import { useModal } from './use-modal' +import type { IUdf } from '../types' + +const props = { + row: { + type: Object as PropType, + default: {} + }, + show: { + type: Boolean as PropType, + default: false + } +} + +export default defineComponent({ + name: 'ResourceFileFolder', + props, + emits: ['update:show', 'updateList'], + setup(props, ctx) { + const treeRef = ref() + const { state, uploadState } = useForm() + + const { + variables, + handleCreateFunc, + handleRenameFunc, + getUdfList, + handleUploadFile + } = useModal(state, uploadState, ctx) + + const hideModal = () => { + ctx.emit('update:show') + } + + const handleCreate = () => { + handleCreateFunc() + } + + const handleRename = () => { + handleRenameFunc(props.row.id) + } + + const handleUpload = () => { + uploadState.uploadForm.currentDir = `/${treeRef.value.selectedOption?.fullName}` + handleUploadFile() + } + + const customRequest = ({ file }: any) => { + uploadState.uploadForm.name = file.name + uploadState.uploadForm.file = file.file + } + + onMounted(() => { + getUdfList() + }) + + watch( + () => props.row, + () => { + variables.uploadShow = false + state.functionForm.type = props.row.type + state.functionForm.funcName = props.row.funcName + state.functionForm.className = props.row.className + state.functionForm.resourceId = props.row.resourceId || -1 + state.functionForm.description = props.row.description + } + ) + return { + treeRef, + hideModal, + handleCreate, + handleRename, + customRequest, + handleUpload, + ...toRefs(state), + ...toRefs(uploadState), + ...toRefs(variables) + } + }, + render() { + const { t } = useI18n() + + return ( + + + + + HIVE UDF + + + + + + + + + + + + (this.uploadShow = !this.uploadShow)} + > + {t('resource.function.upload_resources')} + + + + {this.uploadShow && ( + + + + + + + + + + + 上传 + + + + + + + + + + + + + 上传UDF资源 + + + )} + + + + + + + ) + } +}) diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts new file mode 100644 index 0000000000..2850ae6dae --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts @@ -0,0 +1,102 @@ +/* + * 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 } from 'vue' +import { useI18n } from 'vue-i18n' +import type { FormRules } from 'naive-ui' + +export const useForm = () => { + const { t } = useI18n() + + const state = reactive({ + functionFormRef: ref(), + functionForm: { + type: 'HIVE', + funcName: '', + className: '', + argTypes: '', + database: '', + description: '', + resourceId: -1 + }, + rules: { + type: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (!state.functionForm.type) { + return new Error(t('resource.function.enter_name_tips')) + } + } + }, + funcName: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (!state.functionForm.funcName) { + return new Error(t('resource.function.enter_name_tips')) + } + } + }, + className: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (!state.functionForm.className) { + return new Error(t('resource.function.enter_name_tips')) + } + } + }, + resourceId: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (state.functionForm.resourceId === -1) { + return new Error(t('resource.function.enter_name_tips')) + } + } + } + } as FormRules + }) + + const uploadState = reactive({ + uploadFormRef: ref(), + uploadForm: { + name: '', + file: '', + description: '', + pid: -1, + currentDir: '/' + }, + uploadRules: { + pid: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (uploadState.uploadForm.pid === -1) { + return new Error(t('resource.function.enter_name_tips')) + } + } + } + } as FormRules + }) + + return { + state, + uploadState + } +} diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts new file mode 100644 index 0000000000..b7609d48be --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts @@ -0,0 +1,184 @@ +/* + * 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 _ from 'lodash' +import { ref, reactive, SetupContext } from 'vue' +import { useI18n } from 'vue-i18n' +import { + createResource, + createUdfFunc, + queryResourceList, + updateUdfFunc +} from '@/service/modules/resources' +import { useAsyncState } from '@vueuse/core' + +export function useModal( + state: any, + uploadState: any, + ctx: SetupContext<('update:show' | 'updateList')[]> +) { + const { t } = useI18n() + + const handleCreateFunc = async () => { + submitRequest( + async () => + await createUdfFunc( + { + ...state.functionForm + }, + state.functionForm.resourceId + ) + ) + } + + const handleRenameFunc = async (id: number) => { + submitRequest(async () => { + await updateUdfFunc( + { + ...state.functionForm, + id + }, + state.functionForm.resourceId, + id + ) + }) + } + + const submitRequest = (serviceHandle: any) => { + state.functionFormRef.validate(async (valid: any) => { + if (!valid) { + try { + await serviceHandle() + window.$message.success(t('resource.udf.success')) + ctx.emit('updateList') + ctx.emit('update:show') + } catch (error: any) { + window.$message.error(error.message) + } + } + }) + } + + const variables = reactive({ + uploadShow: ref(false), + udfResourceList: [], + udfResourceDirList: [] + }) + + const filterEmptyDirectory = (list: any) => { + for (const item of list) { + if (item.children) { + if (!/\.jar$/.test(item.name)) { + item.disabled = true + } + filterEmptyDirectory(item.children) + } + } + return list.filter( + (n: any) => + (/\.jar$/.test(n.name) && n.children.length === 0) || + (!/\.jar$/.test(n.name) && n.children.length > 0) + ) + } + + // filterJarFile + const filterJarFile = (array: any) => { + for (const item of array) { + if (item.children) { + item.children = filterJarFile(item.children) + } + } + return array.filter((n: any) => !/\.jar$/.test(n.name)) + } + + // recursiveTree + const recursiveTree = (item: any) => { + // Recursive convenience tree structure + item.forEach((item: any) => { + item.children === '' || + item.children === undefined || + item.children === null || + item.children.length === 0 + ? delete item.children + : recursiveTree(item.children) + }) + } + + const getUdfList = () => { + const { state } = useAsyncState( + queryResourceList({ type: 'UDF' }).then((res: any) => { + let item = res + let item1 = _.cloneDeep(res) + + filterEmptyDirectory(item) + item = filterEmptyDirectory(item) + recursiveTree(item) + recursiveTree(filterJarFile(item1)) + item1 = item1.filter((item: any) => { + if (item.dirctory) { + return item + } + }) + variables.udfResourceList = item + variables.udfResourceDirList = item1 + }), + {} + ) + return state + } + + const resetUploadForm = () => { + uploadState.uploadForm.name = '' + uploadState.uploadForm.file = '' + uploadState.uploadForm.pid = -1 + uploadState.uploadForm.currentDir = '/' + uploadState.uploadForm.description = '' + } + + const handleUploadFile = () => { + uploadState.uploadFormRef.validate(async (valid: any) => { + if (!valid) { + const formData = new FormData() + formData.append('file', uploadState.uploadForm.file) + formData.append('type', 'UDF') + formData.append('name', uploadState.uploadForm.name) + formData.append('pid', uploadState.uploadForm.pid) + formData.append('currentDir', uploadState.uploadForm.currentDir) + formData.append('description', uploadState.uploadForm.description) + + try { + const res = await createResource(formData as any) + window.$message.success(t('resource.function.success')) + variables.uploadShow = false + resetUploadForm() + getUdfList() + state.functionForm.resourceId = res.id + } catch (error: any) { + window.$message.error(error.message) + } + } + }) + } + + return { + variables, + getUdfList, + handleCreateFunc, + handleRenameFunc, + handleUploadFile + } +} diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/function/index.module.scss b/dolphinscheduler-ui-next/src/views/resource/udf/function/index.module.scss new file mode 100644 index 0000000000..a786d64488 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/function/index.module.scss @@ -0,0 +1,73 @@ +/* + * 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. + */ + +.content { + width: 100%; + + .card { + margin-bottom: 8px; + } + + .header { + display: flex; + justify-content: space-between; + align-items: center; + margin: 10px 0; + .right { + > .search { + .list { + float: right; + margin: 3px 0 3px 4px; + } + } + } + } + + .table { + table { + width: 100%; + tr { + height: 40px; + font-size: 12px; + th, + td { + &:nth-child(1) { + width: 50px; + text-align: center; + } + } + th { + &:nth-child(1) { + width: 60px; + text-align: center; + } + > span { + font-size: 12px; + color: #555; + } + } + } + } + } + + .pagination { + display: flex; + justify-content: center; + align-items: center; + margin-top: 20px; + } +} diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/function/index.tsx b/dolphinscheduler-ui-next/src/views/resource/udf/function/index.tsx new file mode 100644 index 0000000000..4aa083fecd --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/function/index.tsx @@ -0,0 +1,144 @@ +/* + * 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, Ref, toRefs, onMounted, toRef } from 'vue' +import { + NIcon, + NSpace, + NDataTable, + NButton, + NPagination, + NInput +} from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { SearchOutlined } from '@vicons/antd' +import Card from '@/components/card' +import FolderModal from './components/function-modal' +import { useTable } from './use-table' +import styles from './index.module.scss' + +export default defineComponent({ + name: 'function-manage', + setup() { + const { variables, getTableData } = useTable() + + const requestData = () => { + getTableData({ + id: variables.id, + pageSize: variables.pageSize, + pageNo: variables.page, + searchVal: variables.searchVal + }) + } + + const handleUpdateList = () => { + requestData() + } + + const handleChangePageSize = () => { + variables.page = 1 + requestData() + } + + const handleSearch = () => { + variables.page = 1 + requestData() + } + + const handleShowModal = (showRef: Ref) => { + showRef.value = true + } + + const handleCreateFolder = () => { + variables.row = {} + handleShowModal(toRef(variables, 'showRef')) + } + + onMounted(() => { + requestData() + }) + + return { + requestData, + handleSearch, + handleUpdateList, + handleCreateFolder, + handleChangePageSize, + ...toRefs(variables) + } + }, + render() { + const { t } = useI18n() + + return ( +
+ +
+ + + {t('resource.function.create_udf_function')} + + +
+
+
+ + + + + +
+
+ +
+
+
+
+
+ + +
+ +
+
+ +
+ ) + } +}) diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/function/types.ts b/dolphinscheduler-ui-next/src/views/resource/udf/function/types.ts new file mode 100644 index 0000000000..2035418d89 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/function/types.ts @@ -0,0 +1,38 @@ +/* + * 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. + */ + +export interface IUdfFunctionParam { + id: number + pageSize: number + pageNo: number + searchVal: string | undefined +} + +export interface IUdf { + id: number + userId: number + type: 'HIVE' + funcName: string + className: string + resourceId: number + resourceName: string + argTypes: string + database: string + description: string + createTime: string + updateTime: string +} diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/function/use-table.ts b/dolphinscheduler-ui-next/src/views/resource/udf/function/use-table.ts new file mode 100644 index 0000000000..a2bf764906 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/function/use-table.ts @@ -0,0 +1,182 @@ +/* + * 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 { h, ref, reactive } from 'vue' +import { useI18n } from 'vue-i18n' +import { useRouter } from 'vue-router' +import type { Router } from 'vue-router' +import type { TableColumns } from 'naive-ui/es/data-table/src/interface' +import { NSpace, NTooltip, NButton, NPopconfirm } from 'naive-ui' +import { EditOutlined, DeleteOutlined } from '@vicons/antd' +import { useAsyncState } from '@vueuse/core' +import { + queryUdfFuncListPaging, + deleteUdfFunc +} from '@/service/modules/resources' +import { IUdfFunctionParam } from './types' + +export function useTable() { + const { t } = useI18n() + const router: Router = useRouter() + + const columns: TableColumns = [ + { + title: t('resource.function.id'), + key: 'id', + width: 50, + render: (_row, index) => index + 1 + }, + { + title: t('resource.function.udf_function_name'), + key: 'funcName' + }, + { + title: t('resource.function.class_name'), + key: 'className' + }, + { + title: t('resource.function.type'), + key: 'type' + }, + { + title: t('resource.function.description'), + key: 'description' + }, + { + title: t('resource.function.jar_package'), + key: 'resourceName' + }, + { + title: t('resource.function.update_time'), + key: 'updateTime' + }, + { + title: t('resource.function.operation'), + key: 'operation', + render: (row) => { + return h(NSpace, null, { + default: () => [ + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'info', + size: 'tiny', + onClick: () => { + handleEdit(row) + } + }, + { + icon: () => h(EditOutlined) + } + ), + default: () => t('resource.function.edit') + } + ), + h( + NPopconfirm, + { + onPositiveClick: () => { + handleDelete(row.id) + } + }, + { + trigger: () => + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'error', + size: 'tiny' + }, + { + icon: () => h(DeleteOutlined) + } + ), + default: () => t('resource.function.delete') + } + ), + default: () => t('resource.function.delete_confirm') + } + ) + ] + }) + } + } + ] + + const variables = reactive({ + columns, + row: {}, + tableData: [], + id: ref(Number(router.currentRoute.value.params.id) || -1), + page: ref(1), + pageSize: ref(10), + searchVal: ref(), + totalPage: ref(1), + showRef: ref(false) + }) + + const getTableData = (params: IUdfFunctionParam) => { + const { state } = useAsyncState( + queryUdfFuncListPaging({ ...params }).then((res: any) => { + variables.totalPage = res.totalPage + variables.tableData = res.totalList.map((item: any) => { + return { ...item } + }) + }), + { total: 0, table: [] } + ) + return state + } + + const handleEdit = (row: any) => { + variables.showRef = true + variables.row = row + } + + const handleDelete = (id: number) => { + /* after deleting data from the current page, you need to jump forward when the page is empty. */ + if (variables.tableData.length === 1 && variables.page > 1) { + variables.page -= 1 + } + + deleteUdfFunc(id).then(() => + getTableData({ + id: variables.id, + pageSize: variables.pageSize, + pageNo: variables.page, + searchVal: variables.searchVal + }) + ) + } + + return { + variables, + getTableData + } +}