From 7d5ab53d0d041f93afd6b062400d5e875c7d6be3 Mon Sep 17 00:00:00 2001 From: songjianet <1778651752@qq.com> Date: Fri, 14 Jan 2022 14:29:16 +0800 Subject: [PATCH] [Feature][UI Next] Add security yarn queue manage. (#8040) --- .../src/locales/modules/en_US.ts | 14 ++ .../src/locales/modules/zh_CN.ts | 14 ++ .../src/router/modules/security.ts | 8 + .../src/service/modules/queues/index.ts | 4 +- .../src/service/modules/queues/types.ts | 19 ++- .../project/list/components/project-modal.tsx | 8 +- .../src/views/project/list/index.tsx | 14 +- .../src/views/project/list/use-table.ts | 7 +- .../src/views/resource/file/index.tsx | 1 + .../views/security/tenant-manage/index.tsx | 2 +- .../yarn-queue-manage/components/use-modal.ts | 89 ++++++++++ .../components/yarn-queue-modal.tsx | 131 +++++++++++++++ .../yarn-queue-manage/index.module.scss | 43 +++++ .../security/yarn-queue-manage/index.tsx | 158 ++++++++++++++++++ .../security/yarn-queue-manage/use-table.ts | 122 ++++++++++++++ 15 files changed, 626 insertions(+), 8 deletions(-) create mode 100644 dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts create mode 100644 dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx create mode 100644 dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/index.module.scss create mode 100644 dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/index.tsx create mode 100644 dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/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 ed1bab2530..a230b07670 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/en_US.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/en_US.ts @@ -192,6 +192,7 @@ const resource = { const project = { list: { create_project: 'Create Project', + edit_project: 'Edit Project', project_list: 'Project List', project_tips: 'Please enter your project', description_tips: 'Please enter your description', @@ -232,6 +233,19 @@ const security = { delete_confirm: 'Delete?', edit: 'Edit', delete: 'Delete' + }, + yarn_queue: { + create_queue: 'Create Queue', + edit_queue: 'Edit Queue', + search_tips: 'Please enter keywords', + queue_name: 'Queue Name', + queue_value: 'Queue Value', + create_time: 'Create Time', + update_time: 'Update Time', + operation: 'Operation', + edit: 'Edit', + queue_name_tips: 'Please enter your queue name', + queue_value_tips: 'Please enter your queue value' } } diff --git a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts index a01b709ac8..63a8cbb677 100644 --- a/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts +++ b/dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts @@ -191,6 +191,7 @@ const resource = { const project = { list: { create_project: '创建项目', + edit_project: '编辑项目', project_list: '项目列表', project_tips: '请输入项目名称', description_tips: '请输入项目描述', @@ -231,6 +232,19 @@ const security = { delete_confirm: '确定删除吗?', edit: '编辑', delete: '删除' + }, + yarn_queue: { + create_queue: '创建队列', + edit_queue: '编辑队列', + search_tips: '请输入关键词', + queue_name: '队列名', + queue_value: '队列值', + create_time: '创建时间', + update_time: '更新时间', + operation: '操作', + edit: '编辑', + queue_name_tips: '请输入队列名称', + queue_value_tips: '请输入队列值' } } diff --git a/dolphinscheduler-ui-next/src/router/modules/security.ts b/dolphinscheduler-ui-next/src/router/modules/security.ts index 4b458b35c8..7e3c161b92 100644 --- a/dolphinscheduler-ui-next/src/router/modules/security.ts +++ b/dolphinscheduler-ui-next/src/router/modules/security.ts @@ -44,6 +44,14 @@ export default { meta: { title: '用户管理' } + }, + { + path: '/security/yarn-queue-manage', + name: 'yarn-queue-manage', + component: components['yarn-queue-manage'], + meta: { + title: 'Yarn队列管理' + } } ] } diff --git a/dolphinscheduler-ui-next/src/service/modules/queues/index.ts b/dolphinscheduler-ui-next/src/service/modules/queues/index.ts index 68ce04fe3c..ef93de6151 100644 --- a/dolphinscheduler-ui-next/src/service/modules/queues/index.ts +++ b/dolphinscheduler-ui-next/src/service/modules/queues/index.ts @@ -49,9 +49,9 @@ export function verifyQueue(data: QueueReq): any { }) } -export function updateQueue(data: QueueReq, id: IdReq): any { +export function updateQueue(data: QueueReq, idReq: IdReq): any { return axios({ - url: `/queues/${id}`, + url: `/queues/${idReq.id}`, method: 'put', data }) diff --git a/dolphinscheduler-ui-next/src/service/modules/queues/types.ts b/dolphinscheduler-ui-next/src/service/modules/queues/types.ts index 11b34b80f4..20d563e8d3 100644 --- a/dolphinscheduler-ui-next/src/service/modules/queues/types.ts +++ b/dolphinscheduler-ui-next/src/service/modules/queues/types.ts @@ -30,4 +30,21 @@ interface IdReq { id: number } -export { ListReq, QueueReq, IdReq } +interface QueueList { + id: number + queueName: string + queue: string + createTime: string + updateTime: string +} + +interface QueueRes { + totalList: QueueList[] + total: number + totalPage: number + pageSize: number + currentPage: number + start: number +} + +export { ListReq, QueueReq, IdReq, QueueRes } diff --git a/dolphinscheduler-ui-next/src/views/project/list/components/project-modal.tsx b/dolphinscheduler-ui-next/src/views/project/list/components/project-modal.tsx index 7a9b54a55a..60bfae2afb 100644 --- a/dolphinscheduler-ui-next/src/views/project/list/components/project-modal.tsx +++ b/dolphinscheduler-ui-next/src/views/project/list/components/project-modal.tsx @@ -68,10 +68,14 @@ const ProjectModal = defineComponent({ return { ...toRefs(state), t, onConfirm, onCancel } }, render() { - const { t, onConfirm, onCancel, show } = this + const { t, onConfirm, onCancel, show, status } = this return ( { + variables.page = 1 + getTableData({ + pageSize: variables.pageSize, + pageNo: variables.page, + searchVal: variables.searchVal + }) + } + const onUpdatePageSize = () => { variables.page = 1 resetTableData() @@ -110,6 +119,7 @@ const list = defineComponent({ updateProjectItem, resetTableData, onUpdatePageSize, + onSearch, updateProjectData, modelStatusRef } @@ -124,6 +134,7 @@ const list = defineComponent({ updateProjectItem, resetTableData, onUpdatePageSize, + onSearch, updateProjectData, modelStatusRef } = this @@ -143,8 +154,9 @@ const list = defineComponent({ size='small' v-model:value={this.searchVal} placeholder={t('project.list.project_tips')} + clearable /> - + {{ icon: () => ( diff --git a/dolphinscheduler-ui-next/src/views/project/list/use-table.ts b/dolphinscheduler-ui-next/src/views/project/list/use-table.ts index cd786794f9..74107c6268 100644 --- a/dolphinscheduler-ui-next/src/views/project/list/use-table.ts +++ b/dolphinscheduler-ui-next/src/views/project/list/use-table.ts @@ -73,7 +73,12 @@ export function useTable( render: (row: any) => h(TableAction, { row, - onResetTableData: () => resetTableData(), + onResetTableData: () => { + if (variables.page > 1 && variables.tableData.length === 1) { + variables.page -= 1 + } + resetTableData() + }, onUpdateProjectItem: (code, name, description) => updateProjectItem(code, name, description) }) diff --git a/dolphinscheduler-ui-next/src/views/resource/file/index.tsx b/dolphinscheduler-ui-next/src/views/resource/file/index.tsx index 414ea7f8f5..c21ae0d854 100644 --- a/dolphinscheduler-ui-next/src/views/resource/file/index.tsx +++ b/dolphinscheduler-ui-next/src/views/resource/file/index.tsx @@ -149,6 +149,7 @@ export default defineComponent({ watch( () => router.currentRoute.value.params.id, + // @ts-ignore () => reload() ) diff --git a/dolphinscheduler-ui-next/src/views/security/tenant-manage/index.tsx b/dolphinscheduler-ui-next/src/views/security/tenant-manage/index.tsx index 7b80ca534a..86bc241142 100644 --- a/dolphinscheduler-ui-next/src/views/security/tenant-manage/index.tsx +++ b/dolphinscheduler-ui-next/src/views/security/tenant-manage/index.tsx @@ -139,7 +139,7 @@ const tenementManage = defineComponent({ row={this.row} onCancelModal={this.onCancelModal} onConfirmModal={this.onConfirmModal} - > + /> ) } diff --git a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts new file mode 100644 index 0000000000..4f128436c2 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts @@ -0,0 +1,89 @@ +/* + * 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 { verifyQueue, createQueue, updateQueue } from '@/service/modules/queues' + +export function useModal( + props: any, + ctx: SetupContext<('cancelModal' | 'confirmModal')[]> +) { + const { t } = useI18n() + + const variables = reactive({ + yarnQueueFormRef: ref(), + model: { + id: ref(-1), + queue: ref(''), + queueName: ref('') + }, + rules: { + queue: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (variables.model.queue === '') { + return new Error(t('security.yarn_queue.queue_value_tips')) + } + } + }, + queueName: { + required: true, + trigger: ['input', 'blur'], + validator() { + if (variables.model.queueName === '') { + return new Error(t('security.yarn_queue.queue_name_tips')) + } + } + } + } + }) + + const handleValidate = (statusRef: number) => { + variables.yarnQueueFormRef.validate((errors: any) => { + if (!errors) { + statusRef === 0 ? submitYarnQueueModal() : updateYarnQueueModal() + } else { + return + } + }) + } + + const submitYarnQueueModal = () => { + verifyQueue({ ...variables.model }).then(() => { + createQueue({ ...variables.model }).then(() => { + variables.model.queue = '' + variables.model.queueName = '' + ctx.emit('confirmModal', props.showModalRef) + }) + }) + } + + const updateYarnQueueModal = () => { + updateQueue({ ...variables.model }, { id: variables.model.id }).then( + (res: any) => { + ctx.emit('confirmModal', props.showModalRef) + } + ) + } + + return { + variables, + handleValidate + } +} diff --git a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx new file mode 100644 index 0000000000..7e58534251 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx @@ -0,0 +1,131 @@ +/* + * 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 } from 'naive-ui' +import { useModal } from './use-modal' +import { useI18n } from 'vue-i18n' + +const YarnQueueModal = defineComponent({ + name: 'YarnQueueModal', + props: { + showModalRef: { + type: Boolean as PropType, + default: false + }, + statusRef: { + type: Number as PropType, + default: 0 + }, + row: { + type: Object as PropType, + default: {} + } + }, + emits: ['cancelModal', 'confirmModal'], + setup(props, ctx) { + const { variables, handleValidate } = useModal(props, ctx) + const { t } = useI18n() + + const cancelModal = () => { + if (props.statusRef === 0) { + variables.model.queue = '' + variables.model.queueName = '' + } + ctx.emit('cancelModal', props.showModalRef) + } + + const confirmModal = () => { + handleValidate(props.statusRef) + } + + watch( + () => props.statusRef, + () => { + if (props.statusRef === 0) { + variables.model.queue = '' + variables.model.queueName = '' + } else { + variables.model.id = props.row.id + variables.model.queue = props.row.queue + variables.model.queueName = props.row.queueName + } + } + ) + + watch( + () => props.row, + () => { + variables.model.id = props.row.id + variables.model.queue = props.row.queue + variables.model.queueName = props.row.queueName + } + ) + + return { t, ...toRefs(variables), cancelModal, confirmModal } + }, + render() { + const { t } = this + return ( +
+ + {{ + default: () => ( + + + + + + + + + ) + }} + +
+ ) + } +}) + +export default YarnQueueModal diff --git a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/index.module.scss b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/index.module.scss new file mode 100644 index 0000000000..de6cf70c65 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/index.module.scss @@ -0,0 +1,43 @@ +/* + * 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. + */ + +.search-card { + display: flex; + justify-content: space-between; + align-items: center; + + .box { + display: flex; + justify-content: flex-end; + align-items: center; + width: 300px; + + button { + margin-left: 10px; + } + } +} + +.table-card { + margin-top: 8px; + + .pagination { + margin-top: 20px; + display: flex; + justify-content: center; + } +} diff --git a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/index.tsx b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/index.tsx new file mode 100644 index 0000000000..34ae02364f --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/security/yarn-queue-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 YarnQueueModal from './components/yarn-queue-modal' +import styles from './index.module.scss' + +const yarnQueueManage = defineComponent({ + name: 'yarn-queue-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 ( +
+ +
+
+ + {t('security.yarn_queue.create_queue')} + +
+
+ + + {{ + icon: () => ( + + + + ) + }} + +
+
+
+ + +
+ +
+
+ +
+ ) + } +}) + +export default yarnQueueManage diff --git a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/use-table.ts b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/use-table.ts new file mode 100644 index 0000000000..17d6f8ae83 --- /dev/null +++ b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/use-table.ts @@ -0,0 +1,122 @@ +/* + * 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, NTooltip } from 'naive-ui' +import { useI18n } from 'vue-i18n' +import { queryQueueListPaging } from '@/service/modules/queues' +import { EditOutlined } from '@vicons/antd' +import type { QueueRes } from '@/service/modules/queues/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.yarn_queue.queue_name'), + key: 'queueName' + }, + { + title: t('security.yarn_queue.queue_value'), + key: 'queue' + }, + { + title: t('security.yarn_queue.create_time'), + key: 'createTime' + }, + { + title: t('security.yarn_queue.update_time'), + key: 'updateTime' + }, + { + title: t('security.yarn_queue.operation'), + key: 'operation', + render(row: any) { + return h( + NTooltip, + {}, + { + trigger: () => + h( + NButton, + { + circle: true, + type: 'info', + size: 'small', + onClick: () => { + handleEdit(row) + } + }, + { + icon: () => h(EditOutlined) + } + ), + default: () => t('security.yarn_queue.edit') + } + ) + } + } + ] + } + + 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 getTableData = (params: any) => { + const { state } = useAsyncState( + queryQueueListPaging({ ...params }).then((res: QueueRes) => { + variables.tableData = res.totalList.map((item, index) => { + return { + index: index + 1, + ...item + } + }) as any + variables.totalPage = res.totalPage + }), + {} + ) + + return state + } + + return { + variables, + getTableData, + createColumns + } +}