This is an automated email from the ASF dual-hosted git repository.
nicholasjiang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-webui.git
The following commit(s) were added to refs/heads/main by this push:
new 5b3805b [Feature] Support show and mock system role management (#221)
5b3805b is described below
commit 5b3805be987885f8b42f130ef9eb455829f58aa1
Author: xiaomo <[email protected]>
AuthorDate: Wed May 15 11:27:49 2024 +0800
[Feature] Support show and mock system role management (#221)
---
paimon-web-ui/mock/modules/system.js | 139 +++++++++++++++++++++
paimon-web-ui/src/api/models/catalog/index.ts | 2 +-
paimon-web-ui/src/api/models/role/index.ts | 22 +++-
paimon-web-ui/src/api/models/role/types/role.ts | 37 +++++-
paimon-web-ui/src/locales/en/modules/system.ts | 22 +++-
paimon-web-ui/src/locales/zh/modules/system.ts | 23 +++-
paimon-web-ui/src/views/login/use-form.ts | 10 +-
.../views/metadata/components/table-form/index.tsx | 5 +-
.../system/role/components/role-detail/index.tsx | 77 ++++++++++++
.../system/role/components/role-form/index.tsx | 0
paimon-web-ui/src/views/system/role/index.tsx | 25 +++-
.../src/views/system/role/use-constants.ts | 52 --------
.../src/views/system/role/use-constants.tsx | 72 +++++++++++
paimon-web-ui/src/views/system/role/use-table.ts | 70 ++++++-----
14 files changed, 446 insertions(+), 110 deletions(-)
diff --git a/paimon-web-ui/mock/modules/system.js
b/paimon-web-ui/mock/modules/system.js
new file mode 100644
index 0000000..49b6e9e
--- /dev/null
+++ b/paimon-web-ui/mock/modules/system.js
@@ -0,0 +1,139 @@
+/* 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. */
+
+module.exports = (mockUtil) => ({
+ '/role/list': mockUtil({
+ "total": "2",
+ "success": true,
+ "data": [
+ {
+ "id": 1,
+ "createTime": "2024-05-11T13:49:27",
+ "updateTime": null,
+ "roleName": "admin",
+ "roleKey": "admin",
+ "sort": 1,
+ "enabled": true,
+ "isDelete": false,
+ "remark": null,
+ "flag": false,
+ "menuIds": null,
+ "permissions": null
+ },
+ {
+ "id": 2,
+ "createTime": "2024-05-11T13:49:27",
+ "updateTime": null,
+ "roleName": "common",
+ "roleKey": "common",
+ "sort": 2,
+ "enabled": true,
+ "isDelete": false,
+ "remark": null,
+ "flag": false,
+ "menuIds": null,
+ "permissions": null
+ }
+ ]
+ }),
+
+ '/menu/roleMenuTreeselect/:roleId': mockUtil({
+ "code": 200,
+ "msg": "Successfully",
+ "data": {
+ "checkedKeys": [],
+ "menus": [
+ {
+ "id": 1,
+ "label": "system",
+ "children": [
+ {
+ "id": 300,
+ "label": "menu_manager",
+ "children": [
+ {
+ "id": 3000,
+ "label": "menu_query"
+ },
+ {
+ "id": 3001,
+ "label": "menu_add"
+ },
+ {
+ "id": 3002,
+ "label": "menu_update"
+ },
+ {
+ "id": 3003,
+ "label": "menu_delete"
+ }
+ ]
+ },
+ {
+ "id": 100,
+ "label": "user_manager",
+ "children": [
+ {
+ "id": 1000,
+ "label": "user_query"
+ },
+ {
+ "id": 1001,
+ "label": "user_add"
+ },
+ {
+ "id": 1002,
+ "label": "user_update"
+ },
+ {
+ "id": 1003,
+ "label": "user_delete"
+ },
+ {
+ "id": 1004,
+ "label": "user_reset"
+ }
+ ]
+ },
+ {
+ "id": 200,
+ "label": "role_manager",
+ "children": [
+ {
+ "id": 2000,
+ "label": "role_query"
+ },
+ {
+ "id": 2001,
+ "label": "role_add"
+ },
+ {
+ "id": 2002,
+ "label": "role_update"
+ },
+ {
+ "id": 2003,
+ "label": "role_delete"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ })
+})
diff --git a/paimon-web-ui/src/api/models/catalog/index.ts
b/paimon-web-ui/src/api/models/catalog/index.ts
index a9856a8..f3f84dd 100644
--- a/paimon-web-ui/src/api/models/catalog/index.ts
+++ b/paimon-web-ui/src/api/models/catalog/index.ts
@@ -148,7 +148,7 @@ export const createColumns = () => {
*/
export const deleteColumns = (query: ColumnParams) => {
const { catalogName, databaseName, name, columnName } = query
-
+
return httpRequest.delete!<unknown,
unknown>(`/table/column/drop/${catalogName}/${databaseName}/${name}/${columnName}`)
}
diff --git a/paimon-web-ui/src/api/models/role/index.ts
b/paimon-web-ui/src/api/models/role/index.ts
index ffc0b3f..758c186 100644
--- a/paimon-web-ui/src/api/models/role/index.ts
+++ b/paimon-web-ui/src/api/models/role/index.ts
@@ -17,13 +17,31 @@ under the License. */
import httpRequest from '../../request'
import type { ResponseOptions } from '@/api/types'
-import type { Role } from './types/role'
+import type { Role, RoleDetail, RoleParams } from './types/role'
+
+/**
+ * # permission tree
+ */
+export const getPermissionTree = () => {
+ return httpRequest.createHooks!<ResponseOptions<Role[]>>({
+ url: '/menu/treeselect',
+ method: 'get',
+ })
+}
+
+
+/**
+ * # permission tree by role Id
+ */
+export const getPermissionByRoleId = (roleId: number) => {
+ return httpRequest.get!<string,
ResponseOptions<RoleDetail>>(`/menu/roleMenuTreeselect/${roleId}`)
+}
/**
* # List roles
*/
export const listRoles = () => {
- return httpRequest.createHooks!<ResponseOptions<Role[]>, any[]>({
+ return httpRequest.createHooks!<ResponseOptions<Role[]>, RoleParams>({
url: '/role/list',
method: 'get',
})
diff --git a/paimon-web-ui/src/api/models/role/types/role.ts
b/paimon-web-ui/src/api/models/role/types/role.ts
index 79bde09..386e970 100644
--- a/paimon-web-ui/src/api/models/role/types/role.ts
+++ b/paimon-web-ui/src/api/models/role/types/role.ts
@@ -15,11 +15,40 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License. */
+export interface RoleDetail {
+ checkedKeys: number[];
+ menus: RoleMenu[];
+}
+
+export interface RoleMenu {
+ id: number;
+ label: string;
+ children: RoleMenuChild[];
+}
+
+export interface RoleMenuChild {
+ id: number;
+ label: string;
+ children: Omit<RoleMenuChild, 'children'>[];
+}
+
export interface Role {
+ id: number;
+ createTime: string;
+ updateTime?: string;
roleName: string;
- roleKey?: string;
- sort?: number;
+ roleKey: string;
+ sort: number;
enabled: boolean;
- remark?: string;
- menuIds?: number[]
+ isDelete: boolean;
+ remark: null;
+ flag: boolean;
+ menuIds: null;
+ permissions: null;
+}
+
+export interface RoleParams {
+ roleName?: string,
+ currentPage: number,
+ pageSize: number
}
diff --git a/paimon-web-ui/src/locales/en/modules/system.ts
b/paimon-web-ui/src/locales/en/modules/system.ts
index c1c5c31..7d8ea8f 100644
--- a/paimon-web-ui/src/locales/en/modules/system.ts
+++ b/paimon-web-ui/src/locales/en/modules/system.ts
@@ -29,4 +29,24 @@ const role = {
enabled: 'Enabled'
}
-export default { user, role }
+const roleKey = {
+ system: 'System',
+ menu_manager: 'Menu Manager',
+ user_manager: 'User Manager',
+ role_manager: 'Role Manager',
+ menu_query: 'Menu Query',
+ menu_add: 'Menu Add',
+ menu_update: 'Menu Update',
+ menu_delete: 'Menu Delete',
+ user_query: 'User Query',
+ user_add: 'User Add',
+ user_update: 'User Update',
+ user_delete: 'User Delete',
+ user_reset: 'User Reset',
+ role_query: 'Role Query',
+ role_add: 'Role Add',
+ role_update: 'Role Update',
+ role_delete: 'Role Delete'
+}
+
+export default { user, role, roleKey }
diff --git a/paimon-web-ui/src/locales/zh/modules/system.ts
b/paimon-web-ui/src/locales/zh/modules/system.ts
index 578d752..6f91956 100644
--- a/paimon-web-ui/src/locales/zh/modules/system.ts
+++ b/paimon-web-ui/src/locales/zh/modules/system.ts
@@ -28,4 +28,25 @@ const role = {
role_key: '角色编码',
enabled: '是否启用'
}
-export default { user, role }
+
+const roleKey = {
+ system: '系统管理',
+ menu_manager: '菜单管理',
+ user_manager: '用户管理',
+ role_manager: '角色管理',
+ menu_query: '菜单查询',
+ menu_add: '菜单新增',
+ menu_update: '菜单修改',
+ menu_delete: '菜单删除',
+ user_query: '用户查询',
+ user_add: '用户新增',
+ user_update: '用户修改',
+ user_delete: '用户删除',
+ user_reset: '用户重置密码',
+ role_query: '角色查询',
+ role_add: '角色新增',
+ role_update: '角色修改',
+ role_delete: '角色删除'
+}
+
+export default { user, role, roleKey }
diff --git a/paimon-web-ui/src/views/login/use-form.ts
b/paimon-web-ui/src/views/login/use-form.ts
index daf822c..df6ad88 100644
--- a/paimon-web-ui/src/views/login/use-form.ts
+++ b/paimon-web-ui/src/views/login/use-form.ts
@@ -34,12 +34,10 @@ export function useForm() {
state.loginForm.validate(async (errors: Array<FormValidationError>) => {
if (!errors) {
onLogin({
- params: {
- username: state.model.username,
- password: state.model.password,
- ldapLogin: false,
- rememberMe: true
- }
+ username: state.model.username,
+ password: state.model.password,
+ ldapLogin: false,
+ rememberMe: true
})
router.push({ path: '/' })
}
diff --git a/paimon-web-ui/src/views/metadata/components/table-form/index.tsx
b/paimon-web-ui/src/views/metadata/components/table-form/index.tsx
index a8fef4f..32932b4 100644
--- a/paimon-web-ui/src/views/metadata/components/table-form/index.tsx
+++ b/paimon-web-ui/src/views/metadata/components/table-form/index.tsx
@@ -176,10 +176,7 @@ export default defineComponent({
</n-button>
</n-space>
<ColumnFormContent
- onUpdateColumns={(value) => {
- this.formValue.tableColumns = value
- }}
- data={this.formValue.tableColumns}
+ v-model:data={this.formValue.tableColumns}
/>
<div
class={styles.form_title}>{this.t('metadata.partition_columns')}</div>
<n-form-item showLabel={false} path="type">
diff --git
a/paimon-web-ui/src/views/system/role/components/role-detail/index.tsx
b/paimon-web-ui/src/views/system/role/components/role-detail/index.tsx
new file mode 100644
index 0000000..c927c03
--- /dev/null
+++ b/paimon-web-ui/src/views/system/role/components/role-detail/index.tsx
@@ -0,0 +1,77 @@
+/* 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 { getPermissionByRoleId } from "@/api/models/role"
+import type { Role, RoleMenu } from "@/api/models/role/types/role"
+
+export default defineComponent({
+ name: 'RoleDetail',
+ props: {
+ roleRecord: {
+ type: Object as PropType<Role>,
+ default: () => ({}),
+ require: true
+ }
+ },
+ setup(props) {
+ const { t } = useLocaleHooks()
+
+ const rolePermissionDetail = ref<RoleMenu[]>([])
+ const loading = ref(false)
+ onMounted(initDetail)
+
+ async function initDetail() {
+ loading.value = true
+ const res = await getPermissionByRoleId(props.roleRecord.id)
+ rolePermissionDetail.value = res?.data?.menus
+ loading.value = false
+ }
+
+ return {
+ loading,
+ rolePermissionDetail,
+ t,
+ }
+ },
+ render() {
+ return <n-spin show={this.loading}>
+ <n-list hoverable clickable>
+ {
+ this.rolePermissionDetail?.map((item) => (
+ <n-list-item key={item.id}>
+ <n-thing title={this.t(`system.roleKey.${item.label}`)}
content-style="margin-top: 10px;">
+ {
+ item.children?.map((child) => (
+ <n-thing
description={this.t(`system.roleKey.${child.label}`)} style="margin-top: 20px;">
+ <n-space>
+ {
+ child.children?.map((buttonPermission) => (
+ <n-tag key={child.id}
type="info">{this.t(`system.roleKey.${buttonPermission.label}`)}</n-tag>
+ ))
+ }
+ </n-space>
+ </n-thing>
+ ))
+ }
+ </n-thing>
+ </n-list-item>
+ ))
+ }
+ </n-list>
+ </n-spin>
+ }
+})
diff --git a/paimon-web-ui/src/views/system/role/components/role-form/index.tsx
b/paimon-web-ui/src/views/system/role/components/role-form/index.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/paimon-web-ui/src/views/system/role/index.tsx
b/paimon-web-ui/src/views/system/role/index.tsx
index b8e504a..0b5ae86 100644
--- a/paimon-web-ui/src/views/system/role/index.tsx
+++ b/paimon-web-ui/src/views/system/role/index.tsx
@@ -15,6 +15,7 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License. */
+import type { Role } from '@/api/models/role/types/role';
import styles from './index.module.scss';
import { useConstants } from './use-constants';
import { useTable } from './use-table';
@@ -23,10 +24,21 @@ export default defineComponent({
name: 'RolePage',
setup() {
const { t } = useLocaleHooks()
- const { tableVariables, getTableData, roleList,loading} = useTable()
+ const { tableVariables, getTableData, roleList, loading } = useTable()
const { columns } = useConstants()
- getTableData()
- return { ...toRefs(tableVariables), getTableData, t, columns,
roleList,loading }
+
+ onMounted(getTableData)
+
+ const rowKey = (rowData: Role) => rowData.id
+
+ return {
+ ...toRefs(tableVariables),
+ t,
+ columns: toRef([...columns]),
+ roleList,
+ loading,
+ rowKey,
+ }
},
render() {
return (
@@ -43,10 +55,11 @@ export default defineComponent({
</n-space>
<n-data-table
columns={this.columns}
- data={this.roleList?.data || []}
- remote
- loading={this.loading}
+ data={this.roleList || []}
pagination={this.pagination}
+ loading={this.loading}
+ remote
+ rowKey={this.rowKey}
/>
</n-space>
</n-card>
diff --git a/paimon-web-ui/src/views/system/role/use-constants.ts
b/paimon-web-ui/src/views/system/role/use-constants.ts
deleted file mode 100644
index ffb250f..0000000
--- a/paimon-web-ui/src/views/system/role/use-constants.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License. */
-
-export const useConstants = () => {
- const { t } = useLocaleHooks()
- const columns = [
- {
- title: t('system.role.role_name'),
- key: 'roleName',
- resizable: true
- },
- {
- title: t('system.role.role_key'),
- key: 'roleKey',
- resizable: true
- },
- {
- title: t('system.role.enabled'),
- key: 'enabled',
- resizable: true,
- render: (row: any) => {
- return row.enabled ? t('common.yes') : t('common.no')
- }
- },
- {
- title: t('common.create_time'),
- key: 'createTime',
- resizable: true
- },
- {
- title: t('common.update_time'),
- key: 'updateTime',
- resizable: true
- },
- ]
-
- return { columns }
-}
diff --git a/paimon-web-ui/src/views/system/role/use-constants.tsx
b/paimon-web-ui/src/views/system/role/use-constants.tsx
new file mode 100644
index 0000000..ce2ae81
--- /dev/null
+++ b/paimon-web-ui/src/views/system/role/use-constants.tsx
@@ -0,0 +1,72 @@
+/* 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 type { Role } from "@/api/models/role/types/role"
+import dayjs from "dayjs"
+
+import RoleDetail from "./components/role-detail"
+
+export const useConstants = () => {
+ const { t } = useLocaleHooks()
+ const columns = [
+ {
+ type: 'expand',
+ resizable: true,
+ renderExpand: (row: Role) => {
+ return (
+ <RoleDetail roleRecord={row} />
+ )
+ }
+ },
+ {
+ title: () => t('system.role.role_name'),
+ key: 'roleName',
+ resizable: true
+ },
+ {
+ title: () => t('system.role.role_key'),
+ key: 'roleKey',
+ resizable: true
+ },
+ {
+ title: () => t('system.role.enabled'),
+ key: 'enabled',
+ resizable: true,
+ render: (row: Role) => {
+ return row.enabled ? t('common.yes') : t('common.no')
+ }
+ },
+ {
+ title: () => t('common.create_time'),
+ key: 'createTime',
+ resizable: true,
+ render: (row: Role) => {
+ return row?.createTime ? dayjs(row?.createTime).format('YYYY-MM-DD
HH:mm') : '-'
+ }
+ },
+ {
+ title: () => t('common.update_time'),
+ key: 'updateTime',
+ resizable: true,
+ render: (row: Role) => {
+ return row?.updateTime ? dayjs(row?.updateTime).format('YYYY-MM-DD
HH:mm') : '-'
+ }
+ },
+ ]
+
+ return { columns }
+}
diff --git a/paimon-web-ui/src/views/system/role/use-table.ts
b/paimon-web-ui/src/views/system/role/use-table.ts
index c9d52ea..73980c1 100644
--- a/paimon-web-ui/src/views/system/role/use-table.ts
+++ b/paimon-web-ui/src/views/system/role/use-table.ts
@@ -17,40 +17,44 @@ under the License. */
import { listRoles } from '@/api/models/role';
export const useTable = () => {
- const tableVariables = reactive({
- searchForm: {
- roleName: ''
- },
- pagination: {
- showQuickJumper: true,
- showSizePicker: true,
- pageSize: 10,
- page: 1,
- itemCount: 0,
- onUpdatePage: (page: number) => {
- tableVariables.pagination.page = page
- getTableData()
- },
- }
- })
- const [roleList, useRoleList, { loading }] = listRoles()
- const getTableData = () => {
- let params = {
- roleName: tableVariables.searchForm.roleName,
- currentPage: tableVariables.pagination.page,
- pageSize: tableVariables.pagination.pageSize
- }
- useRoleList({ params })
- }
- const handleResetage = () => {
- tableVariables.pagination.page = 1
+ const tableVariables = reactive({
+ searchForm: {
+ roleName: ''
+ },
+ pagination: {
+ showQuickJumper: true,
+ showSizePicker: true,
+ pageSize: 10,
+ page: 1,
+ itemCount: 0,
+ onUpdatePage: (page: number) => {
+ tableVariables.pagination.page = page
getTableData()
+ },
}
- return {
- tableVariables,
- getTableData,
- handleResetage,
- roleList,
- loading
+ })
+
+ const [roleList, useRoleList, { loading }] = listRoles()
+
+ const getTableData = () => {
+ const params = {
+ roleName: tableVariables.searchForm.roleName,
+ currentPage: tableVariables.pagination.page,
+ pageSize: tableVariables.pagination.pageSize
}
+ useRoleList({ params })
+ }
+
+ const handleResetage = () => {
+ tableVariables.pagination.page = 1
+ getTableData()
+ }
+
+ return {
+ tableVariables,
+ roleList,
+ loading,
+ getTableData,
+ handleResetage,
+ }
}