mirror of https://github.com/openspug/spug
update role page
parent
690b84584a
commit
4a856424b9
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
授权访问主机组
|
||||||
|
<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>
|
||||||
|
)
|
||||||
|
})
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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'] || []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue