From 7f362464b326aafae53121d87276a34ec38064f0 Mon Sep 17 00:00:00 2001 From: Devosend Date: Mon, 17 Jan 2022 10:43:03 +0800 Subject: [PATCH] [Feature][UI Next] Add Udf resource manage (#8076) * add resource manange * add resource delete * modify rename * support sub udf resource mannage * add Bread * adjust style --- .../src/layouts/content/index.tsx | 2 +- .../src/locales/modules/en_US.ts | 28 ++ .../src/locales/modules/zh_CN.ts | 28 ++ .../src/router/modules/resources.ts | 16 + .../src/service/modules/resources/index.ts | 11 + .../datasource/datasource-list/index.tsx | 4 +- .../datasource-list/json-highlight.tsx | 2 +- .../udf/resource/components/folder-modal.tsx | 106 +++++++ .../udf/resource/components/upload-modal.tsx | 106 +++++++ .../udf/resource/components/use-form.ts | 73 +++++ .../udf/resource/components/use-modal.ts | 114 +++++++ .../resource/udf/resource/index.module.scss | 81 +++++ .../src/views/resource/udf/resource/index.tsx | 197 +++++++++++++ .../src/views/resource/udf/resource/types.ts | 38 +++ .../views/resource/udf/resource/use-table.ts | 279 ++++++++++++++++++ 15 files changed, 1081 insertions(+), 4 deletions(-) create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/index.module.scss create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/index.tsx create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/types.ts create mode 100644 dolphinscheduler-ui-next/src/views/resource/udf/resource/use-table.ts diff --git a/dolphinscheduler-ui-next/src/layouts/content/index.tsx b/dolphinscheduler-ui-next/src/layouts/content/index.tsx index 402ce44614..88a740230d 100644 --- a/dolphinscheduler-ui-next/src/layouts/content/index.tsx +++ b/dolphinscheduler-ui-next/src/layouts/content/index.tsx @@ -93,7 +93,7 @@ const Content = defineComponent({ )} - + diff --git a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts index 8216a03ea9..700d04ddf4 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts @@ -187,6 +187,34 @@ const resource = { return: 'Return', save: 'Save' }, + udf: { + udf_resources: 'UDF resources', + create_folder: 'Create Folder', + upload_udf_resources: 'Upload UDF Resources', + id: '#', + udf_source_name: 'UDF Resource Name', + whether_directory: 'Whether directory', + file_name: 'File Name', + file_size: 'File Size', + description: 'Description', + create_time: 'Create Time', + update_time: 'Update Time', + operation: 'Operation', + yes: 'Yes', + no: 'No', + edit: 'Edit', + download: 'Download', + delete: 'Delete', + delete_confirm: 'Delete?', + success: 'Success', + folder_name: 'Folder Name', + upload: 'Upload', + upload_files: 'Upload Files', + file_upload: 'File Upload', + enter_keyword_tips: 'Please enter keyword', + 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 2fc5a885bf..dfc5035fdd 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts @@ -189,6 +189,34 @@ const resource = { return: '返回', save: '保存' }, + udf: { + udf_resources: 'UDF资源', + create_folder: '创建文件夹', + upload_udf_resources: '上传UDF资源', + id: '编号', + udf_source_name: 'UDF资源名称', + whether_directory: '是否文件夹', + file_name: '文件名称', + file_size: '文件大小', + description: '描述', + create_time: '创建时间', + update_time: '更新时间', + operation: '操作', + yes: '是', + no: '否', + edit: '编辑', + download: '下载', + delete: '删除', + success: '成功', + folder_name: '文件夹名称', + upload: '上传', + upload_files: '上传文件', + file_upload: '文件上传', + delete_confirm: '确定删除吗?', + enter_keyword_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 d6e0f4b0c1..38147ade39 100644 --- a/dolphinscheduler-ui-next/src/router/modules/resources.ts +++ b/dolphinscheduler-ui-next/src/router/modules/resources.ts @@ -77,6 +77,22 @@ export default { title: '文件创建' } }, + { + path: '/resource/resource-manage', + name: 'resource-manage', + component: components['resource'], + meta: { + title: '资源管理' + } + }, + { + path: '/resource/resource-manage/:id', + name: 'resource-sub-manage', + component: components['resource'], + 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 c3f915f3de..c6f44f243b 100644 --- a/dolphinscheduler-ui-next/src/service/modules/resources/index.ts +++ b/dolphinscheduler-ui-next/src/service/modules/resources/index.ts @@ -45,6 +45,17 @@ export function queryResourceListPaging( }) } +export function queryResourceById( + params: ResourceTypeReq & FullNameReq & IdReq, + id: number +): any { + return axios({ + url: `/resources/${id}`, + method: 'get', + params + }) +} + export function createResource( data: CreateReq & FileNameReq & NameReq & ResourceTypeReq ): any { diff --git a/dolphinscheduler-ui-next/src/views/datasource/datasource-list/index.tsx b/dolphinscheduler-ui-next/src/views/datasource/datasource-list/index.tsx index 01d6d2e050..a59396b3cd 100644 --- a/dolphinscheduler-ui-next/src/views/datasource/datasource-list/index.tsx +++ b/dolphinscheduler-ui-next/src/views/datasource/datasource-list/index.tsx @@ -36,8 +36,8 @@ const list = defineComponent({ name: 'list', setup() { const { t } = useI18n() - let showDetailModal = ref(false) - let selectId = ref() + const showDetailModal = ref(false) + const selectId = ref() const { columnsRef } = useColumns((id: number, type: 'edit' | 'delete') => { if (type === 'edit') { diff --git a/dolphinscheduler-ui-next/src/views/datasource/datasource-list/json-highlight.tsx b/dolphinscheduler-ui-next/src/views/datasource/datasource-list/json-highlight.tsx index 162bcd67ff..c69cf0092e 100644 --- a/dolphinscheduler-ui-next/src/views/datasource/datasource-list/json-highlight.tsx +++ b/dolphinscheduler-ui-next/src/views/datasource/datasource-list/json-highlight.tsx @@ -45,7 +45,7 @@ const syntaxHighlight = (json: string) => { const entries = Object.entries(JSON.parse(json)) for (let i = 0, len = entries.length; i < len; i++) { const [key, value] = entries[i] - let type: string = '' + let type = '' if (isBoolean(value) || value === null) { type = 'info' } else if (isNumber(value)) { diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx new file mode 100644 index 0000000000..ef509cbe6c --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx @@ -0,0 +1,106 @@ +/* + * 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 } from 'vue' +import { NForm, NFormItem, NInput } from 'naive-ui' +import { useI18n } from 'vue-i18n' +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 { folderState: state } = useForm() + + const { handleCreateResource, handleRenameResource } = useModal(state, ctx) + + const hideModal = () => { + ctx.emit('update:show') + } + + const handleCreate = () => { + handleCreateResource() + } + + const handleRename = () => { + handleRenameResource(props.row.id) + } + + watch( + () => props.row, + () => { + state.folderForm.name = props.row.alias + state.folderForm.description = props.row.description + } + ) + + return { + hideModal, + handleCreate, + handleRename, + ...toRefs(state) + } + }, + render() { + const { t } = useI18n() + + return ( + + + + + + + + + + + ) + } +}) diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx new file mode 100644 index 0000000000..1379970a2b --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx @@ -0,0 +1,106 @@ +/* + * 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 } from 'vue' +import { NForm, NFormItem, NInput, NUpload, NButton, NIcon } from 'naive-ui' +import { useI18n } from 'vue-i18n' +import Modal from '@/components/modal' +import { useForm } from './use-form' +import { useModal } from './use-modal' +import { CloudUploadOutlined } from '@vicons/antd' + +const props = { + show: { + type: Boolean as PropType, + default: false + } +} + +export default defineComponent({ + name: 'ResourceFileFolder', + props, + emits: ['update:show', 'updateList'], + setup(props, ctx) { + const { uploadState: state } = useForm() + const { handleUploadFile } = useModal(state, ctx) + + const hideModal = () => { + ctx.emit('update:show') + } + + const handleFolder = () => { + handleUploadFile() + } + + const customRequest = ({ file }: any) => { + state.uploadForm.name = file.name + state.uploadForm.file = file.file + } + + return { + hideModal, + handleFolder, + customRequest, + ...toRefs(state) + } + }, + render() { + const { t } = useI18n() + return ( + + + + + + + + + + + + {t('resource.udf.upload')} + + + + + + + + + ) + } +}) diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts new file mode 100644 index 0000000000..424152365c --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts @@ -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. + */ + +import { reactive, ref } from 'vue' +import { useI18n } from 'vue-i18n' +import type { FormRules } from 'naive-ui' + +export const useForm = () => { + const { t } = useI18n() + + const folderState = reactive({ + folderFormRef: ref(), + folderForm: { + pid: -1, + type: 'UDF', + name: '', + description: '', + currentDir: '/' + }, + rules: { + name: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (folderState.folderForm.name === '') { + return new Error(t('resource.udf.enter_name_tips')) + } + } + } + } as FormRules + }) + + const uploadState = reactive({ + uploadFormRef: ref(), + uploadForm: { + name: '', + file: '', + description: '', + pid: -1, + currentDir: '/' + }, + rules: { + name: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (uploadState.uploadForm.name === '') { + return new Error(t('resource.udf.enter_name_tips')) + } + } + } + } as FormRules + }) + + return { + folderState, + uploadState + } +} diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts new file mode 100644 index 0000000000..c9210bdb78 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts @@ -0,0 +1,114 @@ +/* + * 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 { SetupContext } from 'vue' +import { useI18n } from 'vue-i18n' +import { useRouter } from 'vue-router' +import type { Router } from 'vue-router' +import { useFileStore } from '@/store/file/file' +import { + createDirectory, + createResource, + updateResource +} from '@/service/modules/resources' + +export function useModal( + state: any, + ctx: SetupContext<('update:show' | 'updateList')[]> +) { + const { t } = useI18n() + const router: Router = useRouter() + const fileStore = useFileStore() + + const handleCreateResource = async () => { + const pid = router.currentRoute.value.params.id || -1 + const currentDir = pid === -1 ? '/' : fileStore.getCurrentDir || '/' + + submitRequest( + async () => + await createDirectory({ + ...state.folderForm, + ...{ pid, currentDir } + }) + ) + } + + const handleRenameResource = async (id: number) => { + submitRequest(async () => { + await updateResource( + { + ...state.folderForm, + ...{ id } + }, + id + ) + }) + } + + const submitRequest = (serviceHandle: any) => { + state.folderFormRef.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 resetUploadForm = () => { + state.uploadForm.name = '' + state.uploadForm.file = '' + state.uploadForm.description = '' + } + + const handleUploadFile = () => { + state.uploadFormRef.validate(async (valid: any) => { + const pid = router.currentRoute.value.params.id || -1 + const currentDir = pid === -1 ? '/' : fileStore.getCurrentDir || '/' + if (!valid) { + const formData = new FormData() + formData.append('file', state.uploadForm.file) + formData.append('type', 'UDF') + formData.append('name', state.uploadForm.name) + formData.append('pid', String(pid)) + formData.append('currentDir', currentDir) + formData.append('description', state.uploadForm.description) + + try { + await createResource(formData as any) + window.$message.success(t('resource.udf.success')) + ctx.emit('updateList') + ctx.emit('update:show') + resetUploadForm() + } catch (error: any) { + window.$message.error(error.message) + } + } + }) + } + + return { + handleCreateResource, + handleRenameResource, + handleUploadFile + } +} diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/index.module.scss b/dolphinscheduler-ui-next/src/views/resource/udf/resource/index.module.scss new file mode 100644 index 0000000000..db594602ae --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/index.module.scss @@ -0,0 +1,81 @@ +/* + * 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; + } + + .links { + color: #2080f0; + text-decoration: none; + &:hover { + text-decoration: underline; + } + } +} + diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/index.tsx b/dolphinscheduler-ui-next/src/views/resource/udf/resource/index.tsx new file mode 100644 index 0000000000..bed26cc56e --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/index.tsx @@ -0,0 +1,197 @@ +/* + * 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, + NBreadcrumb, + NBreadcrumbItem +} from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { SearchOutlined } from '@vicons/antd' +import Card from '@/components/card' +import FolderModal from './components/folder-modal' +import UploadModal from './components/upload-modal' +import { useTable } from './use-table' +import styles from './index.module.scss' + +export default defineComponent({ + name: 'resource-manage', + setup() { + const { variables, getTableData, goUdfManage, goBread } = 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, 'folderShowRef')) + } + + const handleUploadFile = () => { + handleShowModal(toRef(variables, 'uploadShowRef')) + } + + const handleBread = (index: number) => { + let breadName = '' + variables.breadList.forEach((item, i) => { + if (i <= index) { + breadName = breadName + '/' + item + } + }) + goBread(breadName) + } + + onMounted(() => { + requestData() + }) + + return { + goUdfManage, + handleBread, + requestData, + handleSearch, + handleUpdateList, + handleCreateFolder, + handleUploadFile, + handleChangePageSize, + ...toRefs(variables) + } + }, + render() { + const { t } = useI18n() + + return ( +
+ +
+ + + {t('resource.udf.create_folder')} + + + {t('resource.udf.upload_udf_resources')} + + +
+
+
+ + + + + +
+
+ +
+
+
+
+
+ + {{ + default: () => ( +
+ +
+ +
+
+ ), + header: () => ( + + + this.goUdfManage()}> + {t('resource.udf.udf_resources')} + + + {this.breadList.map((item, index) => ( + + this.handleBread(index)} + > + {item} + + + ))} + + ) + }} +
+ + +
+ ) + } +}) diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/types.ts b/dolphinscheduler-ui-next/src/views/resource/udf/resource/types.ts new file mode 100644 index 0000000000..b2cfbe57c5 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/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 IUdfResourceParam { + id: number + pageSize: number + pageNo: number + searchVal: string | undefined +} + +export interface IUdf { + id: number + pid: number + userId: number + fileName: string + fullName: string + alias: string + directory: boolean + size: number + type: 'UDF' + description: string + createTime: string + updateTime: string +} diff --git a/dolphinscheduler-ui-next/src/views/resource/udf/resource/use-table.ts b/dolphinscheduler-ui-next/src/views/resource/udf/resource/use-table.ts new file mode 100644 index 0000000000..b7f724303d --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/resource/udf/resource/use-table.ts @@ -0,0 +1,279 @@ +/* + * 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 { bytesToSize } from '@/utils/common' +import { useFileStore } from '@/store/file/file' +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, DownloadOutlined } from '@vicons/antd' +import { useAsyncState } from '@vueuse/core' +import { + queryResourceListPaging, + downloadResource, + deleteResource, + queryResourceById +} from '@/service/modules/resources' +import { IUdfResourceParam } from './types' +import styles from './index.module.scss' + +const goSubFolder = (router: Router, item: any) => { + const fileStore = useFileStore() + fileStore.setFileInfo(`${item.alias}|${item.size}`) + + if (item.directory) { + fileStore.setCurrentDir(`${item.fullName}`) + router.push({ name: 'resource-sub-manage', params: { id: item.id } }) + } +} + +export function useTable() { + const { t } = useI18n() + const router: Router = useRouter() + const fileStore = useFileStore() + + const columns: TableColumns = [ + { + title: t('resource.udf.id'), + key: 'id', + width: 50, + render: (_row, index) => index + 1 + }, + { + title: t('resource.udf.udf_source_name'), + key: 'alias', + render: (row) => { + if (!row.directory) { + return row.alias + } else { + return h( + 'a', + { + href: 'javascript:', + class: styles.links, + onClick: () => goSubFolder(router, row) + }, + { + default: () => { + return row.alias + } + } + ) + } + } + }, + { + title: t('resource.udf.whether_directory'), + key: 'whether_directory', + render: (row) => + row.directory ? t('resource.file.yes') : t('resource.file.no') + }, + { + title: t('resource.udf.file_name'), + key: 'fileName' + }, + { + title: t('resource.udf.file_size'), + key: 'size', + render: (row) => bytesToSize(row.size) + }, + { + title: t('resource.udf.description'), + key: 'description' + }, + { + title: t('resource.udf.create_time'), + key: 'createTime' + }, + { + title: t('resource.udf.update_time'), + key: 'updateTime' + }, + { + title: t('resource.udf.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.udf.edit') + } + ), + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'info', + size: 'tiny', + disabled: row?.directory ? true : false, + onClick: () => downloadResource(row.id) + }, + { + icon: () => h(DownloadOutlined) + } + ), + default: () => t('resource.udf.download') + } + ), + h( + NPopconfirm, + { + onPositiveClick: () => { + handleDelete(row.id) + } + }, + { + trigger: () => + h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'error', + size: 'tiny' + }, + { + icon: () => h(DeleteOutlined) + } + ), + default: () => t('resource.udf.delete') + } + ), + default: () => t('resource.udf.delete_confirm') + } + ) + ] + }) + } + } + ] + + const variables = reactive({ + columns, + row: {}, + tableData: [], + breadList: [], + id: ref(Number(router.currentRoute.value.params.id) || -1), + page: ref(1), + pageSize: ref(10), + searchVal: ref(), + totalPage: ref(1), + folderShowRef: ref(false), + uploadShowRef: ref(false) + }) + + const getTableData = (params: IUdfResourceParam) => { + const { state } = useAsyncState( + queryResourceListPaging({ ...params, type: 'UDF' }).then((res: any) => { + const breadList = + variables.id === -1 + ? [] + : (fileStore.getCurrentDir.split('/') as Array) + breadList.shift() + + variables.breadList = breadList + variables.totalPage = res.totalPage + variables.tableData = res.totalList.map((item: any) => { + return { ...item } + }) + }), + { total: 0, table: [] } + ) + return state + } + + const handleEdit = (row: any) => { + variables.folderShowRef = 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 + } + + deleteResource(id).then(() => + getTableData({ + id: variables.id, + pageSize: variables.pageSize, + pageNo: variables.page, + searchVal: variables.searchVal + }) + ) + } + + const goUdfManage = () => { + router.push({ name: 'resource-manage' }) + } + + const goBread = (fullName: string) => { + const { id } = variables + queryResourceById( + { + id, + type: 'UDF', + fullName + }, + id + ) + .then((res: any) => { + fileStore.setCurrentDir(res.fullName) + router.push({ name: 'resource-sub-manage', params: { id: res.id } }) + }) + .catch((error: any) => { + window.$message.error(error.message) + }) + } + + return { + variables, + getTableData, + goUdfManage, + goBread + } +}