update role page

pull/289/head
vapao 2020-12-23 14:26:33 +08:00
parent 690b84584a
commit 4a856424b9
4 changed files with 92 additions and 73 deletions

View File

@ -84,9 +84,9 @@ class Role(models.Model, ModelMixin):
def to_dict(self, *args, **kwargs): def to_dict(self, *args, **kwargs):
tmp = super().to_dict(*args, **kwargs) tmp = super().to_dict(*args, **kwargs)
tmp['page_perms'] = json.loads(self.page_perms) if self.page_perms else None tmp['page_perms'] = json.loads(self.page_perms) if self.page_perms else {}
tmp['deploy_perms'] = json.loads(self.deploy_perms) if self.deploy_perms else None tmp['deploy_perms'] = json.loads(self.deploy_perms) if self.deploy_perms else {}
tmp['host_perms'] = json.loads(self.host_perms) if self.host_perms else None tmp['host_perms'] = json.loads(self.host_perms) if self.host_perms else []
tmp['used'] = self.user_set.count() tmp['used'] = self.user_set.count()
return tmp return tmp

View File

@ -3,82 +3,88 @@
* Copyright (c) <spug.dev@gmail.com> * Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License. * Released under the AGPL-3.0 License.
*/ */
import React from 'react'; import React, { useState, useEffect } from 'react';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { Modal, Form, Transfer, message, Alert } from 'antd'; import { Modal, Form, Button, Tooltip, message, TreeSelect } from 'antd';
import http from 'libs/http'; import { PlusOutlined, QuestionCircleOutlined, MinusCircleOutlined } from '@ant-design/icons';
import hostStore from 'pages/host/store'; import hostStore from 'pages/host/store';
import http from 'libs/http';
import store from './store'; import store from './store';
import styles from './index.module.css';
@observer export default observer(function () {
class HostPerm extends React.Component { const [loading, setLoading] = useState(false);
constructor(props) { const [groups, setGroups] = useState([...store.record.host_perms]);
super(props);
this.state = { useEffect(() => {
loading: false, if (hostStore.treeData.length === 0) {
hosts: [], hostStore.fetchGroups()
apps: []
} }
} }, [])
componentDidMount() { function handleSubmit() {
if (hostStore.records.length === 0) { setLoading(true);
hostStore.fetchRecords().then( http.patch('/api/account/role/', {id: store.record.id, host_perms: groups})
() => this._updateRecords(hostStore.records)
)
} else {
this._updateRecords(hostStore.records)
}
}
_updateRecords = (records) => {
const hosts = records.map(x => {
return {...x, key: x.id}
});
this.setState({hosts})
};
handleSubmit = () => {
this.setState({loading: true});
http.patch('/api/account/role/', {id: store.record.id, host_perms: store.hostPerms})
.then(res => { .then(res => {
message.success('操作成功'); message.success('操作成功');
store.hostPermVisible = false; store.hostPermVisible = false;
store.fetchRecords() store.fetchRecords()
}, () => this.setState({loading: false})) }, () => setLoading(false))
};
render() {
return (
<Modal
visible
width={800}
maskClosable={false}
title="主机权限设置"
onCancel={() => store.hostPermVisible = false}
confirmLoading={this.state.loading}
onOk={this.handleSubmit}>
<Alert
closable
showIcon
type="info"
message="小提示"
style={{width: 600, margin: '0 auto 20px', color: '#31708f !important'}}
description="主机权限将全局影响属于该角色的用户能够看到的主机。"/>
<Form.Item label="设置可访问的主机" style={{padding: '0 20px'}}>
<Transfer
showSearch
listStyle={{width: 325, maxHeight: 500, minHeight: 300}}
titles={['所有主机', '已选主机']}
dataSource={this.state.hosts}
targetKeys={store.hostPerms}
onChange={keys => store.hostPerms = keys}
filterOption={(inputValue, option) => `${option.zone}${option.name}`.toLowerCase().indexOf(inputValue.toLowerCase()) > -1}
render={item => `${item.zone} - ${item.name}(${item.hostname})`}/>
</Form.Item>
</Modal>
)
} }
}
export default HostPerm function handleChange(index, value) {
const tmp = [...groups];
if (index !== undefined) {
if (value) {
tmp[index] = value;
} else {
tmp.splice(index, 1)
}
} else {
tmp.push(undefined)
}
setGroups(tmp)
}
return (
<Modal
visible
width={400}
maskClosable={false}
title="主机权限设置"
onCancel={() => store.hostPermVisible = false}
confirmLoading={loading}
onOk={handleSubmit}>
<Form layout="vertical">
<Form.Item label={
<span>
授权访问主机组&nbsp;
<Tooltip title="主机权限将全局影响属于该角色的用户能够看到的主机。">
<QuestionCircleOutlined/>
</Tooltip>
</span>
}>
{groups.map((id, index) => (
<div className={styles.groupItem} key={index}>
<TreeSelect
value={id}
showSearch={false}
treeNodeLabelProp="name"
treeData={hostStore.treeData}
onChange={value => handleChange(index, value)}
placeholder="请选择分组"/>
{groups.length > 1 && (
<MinusCircleOutlined className={styles.delIcon} onClick={() => handleChange(index)}/>
)}
</div>
))}
</Form.Item>
<Form.Item>
<Button type="dashed" style={{width: '100%'}} onClick={() => handleChange()}>
<PlusOutlined/>添加授权主机组
</Button>
</Form.Item>
</Form>
</Modal>
)
})

View File

@ -21,4 +21,19 @@
.table td { .table td {
padding: 5px 15px; padding: 5px 15px;
}
.groupItem {
margin-bottom: 12px;
display: flex;
align-items: center;
}
.delIcon {
font-size: 24px;
margin-left: 10px;
}
.delIcon:hover {
color: #f5222d;
} }

View File

@ -15,7 +15,6 @@ class Store {
@observable record = {}; @observable record = {};
@observable permissions = lds.cloneDeep(codes); @observable permissions = lds.cloneDeep(codes);
@observable deployRel = {}; @observable deployRel = {};
@observable hostPerms = [];
@observable isFetching = false; @observable isFetching = false;
@observable formVisible = false; @observable formVisible = false;
@observable pagePermVisible = false; @observable pagePermVisible = false;
@ -70,8 +69,7 @@ class Store {
showHostPerm = (info) => { showHostPerm = (info) => {
this.record = info; this.record = info;
this.hostPermVisible = true; this.hostPermVisible = true
this.hostPerms = info['host_perms'] || []
} }
} }