Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/daas/src/i18n/langs/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -771,8 +771,12 @@ export default {
role_list_edit: 'Edit roles',
role_list_default_role: 'Default role',
role_list_setting_permissions: 'Set Permissions',
role_list_setting_api: 'Set API access',
role_list_delete_remind: 'Confirm to delete role {0}',
role_list_delete_success: 'Delete the role successfully',
role_list_setting_api_selected: 'Selected {0} APIs',
role_list_setting_api_empty_confirm: 'Are you sure you want to cancel all API access settings?',
role_list_setting_select_api: 'Please select API',
role_form_yes: 'Yes',
role_form_no: 'No',
role_form_selectUser: 'Please select a user name',
Expand Down
4 changes: 4 additions & 0 deletions apps/daas/src/i18n/langs/zh-CN.js
Original file line number Diff line number Diff line change
Expand Up @@ -748,8 +748,12 @@ export default {
role_list_edit: '编辑角色',
role_list_default_role: '默认角色',
role_list_setting_permissions: '设置权限',
role_list_setting_api: '设置API访问',
role_list_delete_remind: '确认删除角色 {0}',
role_list_delete_success: '删除角色成功',
role_list_setting_api_selected: '已选 {0} 个 API',
role_list_setting_select_api: '请选择 API',
role_list_setting_api_empty_confirm: '确定要取消所有 API 的访问设置吗?',
role_form_yes: '是',
role_form_no: '否',
role_form_selectUser: '请选择用户名',
Expand Down
4 changes: 4 additions & 0 deletions apps/daas/src/i18n/langs/zh-TW.js
Original file line number Diff line number Diff line change
Expand Up @@ -743,8 +743,12 @@ export default {
role_list_edit: '編輯角色',
role_list_default_role: '默認角色',
role_list_setting_permissions: '設置權限',
role_list_setting_api: '設置API訪問',
role_list_delete_remind: '確認刪除角色 {0}',
role_list_delete_success: '刪除角色成功',
role_list_setting_api_selected: '已選 {0} 個 API',
role_list_setting_api_empty_confirm: '確定要取消所有 API 的訪問設置嗎?',
role_list_setting_select_api: '請選擇 API',
role_form_yes: '是',
role_form_no: '否',
role_form_selectUser: '請選擇用戶名',
Expand Down
236 changes: 236 additions & 0 deletions apps/daas/src/views/role/ApiAccessDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
<script>
import { isEqual } from 'lodash'
import { modulesApi } from '@tap/api'

export default {
name: 'ApiAccessDialog',
data() {
return {
visible: false,
apiTree: [],
filterText: '',
roleId: '',
roleName: '',
checkedKeys: [],
apiLoading: false,
loading: false
}
},
methods: {
open(roleId, roleName) {
this.visible = true
this.roleId = roleId
this.roleName = roleName

this.fetchApiData()
},
async fetchApiData() {
this.apiLoading = true

const mapApi = item => {
const pathJoin = []
item.apiVersion && pathJoin.push(item.apiVersion)
item.prefix && pathJoin.push(item.prefix)
item.basePath && pathJoin.push(item.basePath)

return {
label: item.name,
id: item.id,
baseUrl: `/${pathJoin.join('/')}`
}
}
const { items: apis } = await modulesApi
.get({
filter: JSON.stringify({
limit: 1000000
})
})
.finally(() => {
this.apiLoading = false
})
const checkedKeys = []

const group = apis.reduce((tree, item) => {
// 获取第一个应用标签
const firstTag = item.listtags?.[0]

if (item.paths[0]?.acl?.includes(this.roleName)) {
checkedKeys.push(item.id)
}

if (!firstTag) {
// 如果没有应用标签,放到"未分组"中
const ungroupedKey = 'ungrouped'
if (!tree[ungroupedKey]) {
tree[ungroupedKey] = {
id: ungroupedKey,
label: 'Ungrouped',
value: ungroupedKey,
children: []
}
}
tree[ungroupedKey].children.push(mapApi(item))
} else {
// 按应用分组
const appKey = firstTag.id

if (!tree[appKey]) {
tree[appKey] = {
id: firstTag.id,
label: firstTag.value,
value: firstTag.id,
children: []
}
} else {
tree[appKey].label = tree[appKey].label || firstTag.value
}

tree[appKey].children.push(mapApi(item))
}

return tree
}, {})

const children = Object.values(group)

this.apiTree = [
{
id: 'ROOT',
label: this.$t('public_all'),
children
}
]

this.originalCheckedKeys = checkedKeys

this.checkedKeys = checkedKeys.concat([])

this.$nextTick(() => {
this.$refs.tree.setCheckedKeys(checkedKeys)
})
},
handleFilter() {
this.$refs.tree.filter(this.filterText)
},
async handleConfirm() {
if (isEqual(this.originalCheckedKeys, this.checkedKeys)) {
this.visible = false
return
}

if (this.checkedKeys.length === 0) {
const flag = await this.$confirm(this.$t('role_list_setting_api_empty_confirm'), {
type: 'warning',
customClass: 'text-break',
zIndex: 3000
})
if (!flag) {
return
}
}

this.loading = true

await modulesApi
.updatePermissions({
moduleIds: this.checkedKeys,
aclName: this.roleName
})
.finally(() => {
this.loading = false
})
this.$message.success(this.$t('public_message_operation_success'))
this.visible = false
},
filterNode(value, data) {
if (!value) return true
const val = value.toLowerCase()
return data.label?.toLowerCase().includes(val)
},
handleCheckApi() {
this.checkedKeys = this.$refs.tree.getCheckedKeys(true)
}
}
}
</script>

<template>
<el-dialog
:visible="visible"
@update:visible="visible = $event"
width="600px"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<template #title>
<div class="flex align-center gap-2">
<span>{{ $t('role_list_setting_api') }}</span>
<span class="font-color-light bg-color-main rounded-4 p-1 fs-8">{{ roleName }}</span>
</div>
</template>
<div>
<div class="bg-light rounded-xl overflow-hidden w-100 lh-base p-2" v-loading="apiLoading">
<div class="px-1 pt-1 pb-3 font-color-dark">{{ $t('role_list_setting_select_api') }}</div>

<div class="bg-white p-1 rounded-xl" style="border: 1px solid #f2f4f7">
<div class="p-2">
<el-input class="api-access-dialog-input" v-model="filterText" clearable @input="handleFilter">
<template #prefix>
<VIcon size="14" class="h-100 ml-1">magnify</VIcon>
</template>
</el-input>
</div>

<div class="overflow-y-auto" style="max-height: 400px">
<el-tree
ref="tree"
show-checkbox
:data="apiTree"
:props="{ label: 'label' }"
node-key="id"
default-expand-all
check-on-click-node
:filter-node-method="filterNode"
@check="handleCheckApi"
>
<template #default="{ node, data }">
<div class="flex align-center gap-1">
<VIcon v-if="!node.isLeaf" size="16">{{ node.expanded ? 'folder-open' : 'folder-close' }}</VIcon>
<span>{{ node.label || '--' }}</span>

<span v-if="node.isLeaf" class="font-color-slight ml-2">{{ data.baseUrl }}</span>
</div>
</template>
</el-tree>
</div>
</div>
</div>
</div>

<template #footer>
<div class="flex align-center">
<span class="font-color-light">{{ $t('role_list_setting_api_selected', [checkedKeys.length]) }}</span>
<div class="flex-1"></div>
<el-button @click="visible = false">{{ $t('public_button_cancel') }}</el-button>
<el-button :loading="loading" type="primary" @click="handleConfirm">{{
$t('public_button_confirm')
}}</el-button>
</div>
</template>
</el-dialog>
</template>

<style lang="scss">
.api-access-dialog-input {
.el-input__inner {
border: 0;
border-radius: 8px;
background-color: #f5f5f5;
}
}

.el-message-box.text-break .el-message-box__message {
word-break: break-word !important;
}
</style>
21 changes: 19 additions & 2 deletions apps/daas/src/views/role/Roles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
</ElSwitch>
</template>
</ElTableColumn>
<ElTableColumn :label="$t('public_operation')" width="310">
<ElTableColumn :label="$t('public_operation')" width="340">
<template slot-scope="scope">
<ElButton
type="text"
Expand All @@ -58,6 +58,15 @@
{{ $t('role_list_setting_permissions') }}
</ElButton>
<ElDivider direction="vertical"></ElDivider>
<ElButton
type="text"
v-readonlybtn="'role_edition'"
:disabled="$disabledByPermission('role_edition_all_data', scope.row.user_id)"
@click="handleSettingApi(scope.row.id, scope.row.name)"
>
{{ $t('role_list_setting_api') }}
</ElButton>
<ElDivider direction="vertical"></ElDivider>
<ElButton
type="text"
@click="handleAssociatUsers(scope.row.id)"
Expand Down Expand Up @@ -149,6 +158,8 @@
<ElButton size="mini" type="primary" @click="saveUser">{{ $t('public_button_confirm') }}</ElButton>
</span>
</ElDialog>

<ApiAccessDialog ref="apiAccessDialog" />
</section>
</template>

Expand All @@ -157,11 +168,13 @@ import { escapeRegExp } from 'lodash'
import { roleApi, usersApi, roleMappingsApi, permissionsApi } from '@tap/api'
import { FilterBar } from '@tap/component'
import { TablePage } from '@tap/business'
import ApiAccessDialog from './ApiAccessDialog.vue'

export default {
components: {
TablePage,
FilterBar
FilterBar,
ApiAccessDialog
},
data() {
return {
Expand Down Expand Up @@ -264,6 +277,10 @@ export default {
handleSettingPermissions(id, name) {
this.$router.push({ name: 'role', query: { id: id, name: name } })
},
// 设置API访问
handleSettingApi(id, name) {
this.$refs.apiAccessDialog.open(id, name)
},

// 确认删除角色
handleDelete(item) {
Expand Down
1 change: 1 addition & 0 deletions packages/assets/icons/svg/folder-close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/assets/icons/svg/folder-open.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading