feat: Support role actions

Support create/edit/delete role

Change-Id: Ib8c71b2bb193b061ad6db397727fef0129f3bc44
This commit is contained in:
Jingwei.Zhang 2022-06-06 16:46:35 +08:00
parent 55841fa520
commit 083e44a401
10 changed files with 257 additions and 5 deletions

View File

@ -484,6 +484,7 @@
"Create Project": "Create Project",
"Create QoS Policy": "Create QoS Policy",
"Create QoS Spec": "Create QoS Spec",
"Create Role": "Create Role",
"Create Router": "Create Router",
"Create Rule": "Create Rule",
"Create Security Group": "Create Security Group",
@ -638,6 +639,7 @@
"Delete Project": "Delete Project",
"Delete QoS Policy": "Delete QoS Policy",
"Delete QoS Spec": "Delete QoS Spec",
"Delete Role": "Delete Role",
"Delete Router": "Delete Router",
"Delete Rule": "Delete Rule",
"Delete Security Group": "Delete Security Group",
@ -782,6 +784,7 @@
"Edit Project": "Edit Project",
"Edit QoS Policy": "Edit QoS Policy",
"Edit Quota": "Edit Quota",
"Edit Role": "Edit Role",
"Edit Router": "Edit Router",
"Edit Rule": "Edit Rule",
"Edit Share Metadata": "Edit Share Metadata",
@ -2592,6 +2595,7 @@
"delete network": "delete network",
"delete project": "delete project",
"delete qos policy": "delete qos policy",
"delete role": "delete role",
"delete router": "delete router",
"delete snapshot": "delete snapshot",
"delete stack": "delete stack",

View File

@ -484,6 +484,7 @@
"Create Project": "创建项目",
"Create QoS Policy": "创建QoS策略",
"Create QoS Spec": "创建QoS规格",
"Create Role": "创建角色",
"Create Router": "创建路由器",
"Create Rule": "创建规则",
"Create Security Group": "创建安全组",
@ -638,6 +639,7 @@
"Delete Project": "删除项目",
"Delete QoS Policy": "删除QoS策略",
"Delete QoS Spec": "删除QoS规格",
"Delete Role": "删除角色",
"Delete Router": "删除路由器",
"Delete Rule": "删除规则",
"Delete Security Group": "删除安全组",
@ -782,6 +784,7 @@
"Edit Project": "编辑项目",
"Edit QoS Policy": "编辑",
"Edit Quota": "编辑配额",
"Edit Role": "编辑角色",
"Edit Router": "编辑路由器",
"Edit Rule": "编辑规则",
"Edit Share Metadata": "编辑共享元数据",
@ -2592,6 +2595,7 @@
"delete network": "删除网络",
"delete project": "删除项目",
"delete qos policy": "删除QoS策略",
"delete role": "删除角色",
"delete router": "删除路由器",
"delete snapshot": "删除快照",
"delete stack": "删除stack",

View File

@ -0,0 +1,60 @@
// Copyright 2021 99cloud
//
// Licensed 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 { inject, observer } from 'mobx-react';
import globalRoleStore from 'stores/keystone/role';
import { ModalAction } from 'containers/Action';
export class Create extends ModalAction {
init() {
this.store = globalRoleStore;
}
static id = 'role-create';
static title = t('Create Role');
static policy = 'identity:create_role';
static allowed() {
return Promise.resolve(true);
}
get name() {
return t('Create Role');
}
get formItems() {
return [
{
name: 'name',
label: t('Name'),
type: 'input',
placeholder: t('Please input name'),
required: true,
},
{
name: 'description',
label: t('Description'),
type: 'textarea',
},
];
}
onSubmit = (values) => {
return this.store.create(values);
};
}
export default inject('rootStore')(observer(Create));

View File

@ -0,0 +1,48 @@
// Copyright 2021 99cloud
//
// Licensed 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 { ConfirmAction } from 'containers/Action';
import globalRoleStore from 'stores/keystone/role';
import { editable } from 'resources/keystone/role';
export default class DeleteAction extends ConfirmAction {
get id() {
return 'delete';
}
get title() {
return t('Delete Role');
}
get isDanger() {
return true;
}
get buttonText() {
return t('Delete');
}
get actionName() {
return t('delete role');
}
policy = 'identity:delete_role';
allowedCheckFunc = (data) => editable(data);
onSubmit = (data) => {
const { id } = data;
return globalRoleStore.delete({ id });
};
}

View File

@ -0,0 +1,67 @@
// Copyright 2021 99cloud
//
// Licensed 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 { inject, observer } from 'mobx-react';
import { ModalAction } from 'containers/Action';
import globalRoleStore from 'stores/keystone/role';
import { editable } from 'resources/keystone/role';
export class Edit extends ModalAction {
init() {
this.store = globalRoleStore;
}
static id = 'role-edit';
static title = t('Edit Role');
static buttonText = t('Edit');
static policy = 'identity:update_role';
static allowed = (item) => {
return Promise.resolve(editable(item));
};
get defaultValue() {
const { name, description } = this.item;
return {
name,
description,
};
}
get formItems() {
return [
{
name: 'name',
label: t('Name'),
type: 'input',
required: true,
},
{
name: 'description',
label: t('Description'),
type: 'textarea',
},
];
}
onSubmit = async (values) => {
const { id } = this.item;
return this.store.update({ id }, values);
};
}
export default inject('rootStore')(observer(Edit));

View File

@ -0,0 +1,32 @@
// Copyright 2021 99cloud
//
// Licensed 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 Create from './Create';
import Delete from './Delete';
import Edit from './Edit';
const actionConfigs = {
rowActions: {
firstAction: Edit,
moreActions: [
{
action: Delete,
},
],
},
batchActions: [Delete],
primaryActions: [Create],
};
export default actionConfigs;

View File

@ -15,16 +15,13 @@
import { observer, inject } from 'mobx-react';
import Base from 'containers/List';
import globalRoleStore from 'stores/keystone/role';
import actionConfigs from './actions';
export class Role extends Base {
init() {
this.store = globalRoleStore;
}
get tabs() {
return [];
}
get policy() {
return 'identity:list_roles';
}
@ -37,6 +34,10 @@ export class Role extends Base {
return false;
}
get actionConfigs() {
return actionConfigs;
}
getColumns = () => [
{
title: t('Role Name'),

View File

@ -23,4 +23,12 @@ const rolePermission = {
member: t('Member'),
};
export const editable = (item) => {
const { options: { immutable } = {} } = item || {};
if (immutable || immutable === 'true' || immutable === 'True') {
return false;
}
return true;
};
export default rolePermission;

View File

@ -15,6 +15,7 @@
import { action, observable } from 'mobx';
import client from 'client';
import Base from 'stores/base';
import List from 'stores/base-list';
export class RoleStore extends Base {
get client() {
@ -24,6 +25,9 @@ export class RoleStore extends Base {
@observable
implyRoles = {};
@observable
systemRoles = new List();
@action
async fetchImpliedRoles({ id }) {
const rolesResult = await this.client.implies.list(id);
@ -53,6 +57,30 @@ export class RoleStore extends Base {
this.isLoading = false;
this.implyRoles = sourceRole;
}
checkSystemRole = (roleItem) => {
return roleItem.name === 'admin' || roleItem.name === 'reader';
};
@action
async fetchSystemRoles() {
this.systemRoles.isLoading = true;
const result = await this.client.list();
const { roles = [] } = result;
const systemRoles = roles.filter((it) => {
return this.checkSystemRole(it);
});
this.systemRoles.data = systemRoles;
this.systemRoles.isLoading = false;
return systemRoles;
}
@action
update({ id }, newObject) {
const body = {};
body[this.responseKey] = newObject;
return this.submitting(this.client.patch(id, body));
}
}
const globalRoleStore = new RoleStore();

View File

@ -24,7 +24,7 @@ describe('The Role Page', () => {
it('successfully detail', () => {
cy.tableSearchText(name)
.goToDetail(0)
.goToDetail()
.clickDetailTab('Binding User', 'user')
.clickDetailTab('Binding Group', 'group');
cy.goBackToList(listUrl);