feat: 分组设置功能放入Tab中

This commit is contained in:
wenbo.dong 2017-11-08 22:44:05 +08:00
parent 5863738f77
commit 4552bf0fa6
4 changed files with 266 additions and 144 deletions

View File

@ -3,6 +3,7 @@ import GroupList from './GroupList/GroupList.js';
import ProjectList from './ProjectList/ProjectList.js';
import MemberList from './MemberList/MemberList.js';
import GroupLog from './GroupLog/GroupLog.js';
import GroupSetting from './GroupSetting/GroupSetting.js';
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Route, Switch, Redirect } from 'react-router-dom';
@ -54,6 +55,7 @@ export default class Group extends Component {
<TabPane tab="项目列表" key="1"><ProjectList/></TabPane>
{this.props.currGroup.type === 'public'?<TabPane tab="成员列表" key="2"><MemberList/></TabPane>:null}
{["admin","owner","guest","dev"].indexOf(this.props.curUserRoleInGroup)>-1 || this.props.curUserRole === "admin"?<TabPane tab="分组动态" key="3"><GroupLog/></TabPane>:""}
{(this.props.curUserRole === "admin" || this.props.curUserRoleInGroup === 'owner') && this.props.currGroup.type !== 'private' ? <TabPane tab="分组设置" key="4"><GroupSetting/></TabPane> : null}
</Tabs>
</Content>
</Layout>

View File

@ -1,14 +1,12 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Icon, Modal, Alert, Input, message, Menu, Row, Col, Dropdown, Popover } from 'antd'
import { Icon, Modal, Input, message, Row, Menu, Col, Popover, Tooltip } from 'antd'
import { autobind } from 'core-decorators';
import axios from 'axios';
import { withRouter } from 'react-router-dom';
const { TextArea } = Input;
const Search = Input.Search;
const TYPE_EDIT = 'edit';
const confirm = Modal.confirm;
import UsernameAutoComplete from '../../../components/UsernameAutoComplete/UsernameAutoComplete.js';
import GuideBtns from '../../../components/GuideBtns/GuideBtns.js';
import { fetchNewsData } from '../../../reducer/modules/news.js';
@ -65,7 +63,6 @@ export default class GroupList extends Component {
state = {
addGroupModalVisible: false,
editGroupModalVisible: false,
newGroupName: '',
newGroupDesc: '',
currGroupName: '',
@ -100,34 +97,19 @@ export default class GroupList extends Component {
}
@autobind
showModal(type) {
if (type === 'edit') {
const { currGroup } = this.props;
this.setState({
currGroupName: currGroup.group_name,
currGroupDesc: currGroup.group_desc,
editGroupModalVisible: true
});
} else {
this.setState({
addGroupModalVisible: true
});
}
showModal() {
this.setState({
addGroupModalVisible: true
});
}
@autobind
hideModal(type) {
if (type === TYPE_EDIT) {
this.setState({
editGroupModalVisible: false
});
} else {
this.setState({
newGroupName: '',
group_name: '',
owner_uids: [],
addGroupModalVisible: false
});
}
hideModal() {
this.setState({
newGroupName: '',
group_name: '',
owner_uids: [],
addGroupModalVisible: false
});
}
@autobind
async addGroup() {
@ -159,9 +141,6 @@ export default class GroupList extends Component {
if (res.data.errcode) {
message.error(res.data.errmsg);
} else {
this.setState({
editGroupModalVisible: false
});
await this.props.fetchGroupList();
this.setState({ groupList: this.props.groupList });
@ -174,20 +153,12 @@ export default class GroupList extends Component {
}
}
@autobind
inputNewGroupName(e, type) {
if (type === TYPE_EDIT) {
this.setState({ currGroupName: e.target.value })
} else {
this.setState({ newGroupName: e.target.value });
}
inputNewGroupName(e) {
this.setState({ newGroupName: e.target.value });
}
@autobind
inputNewGroupDesc(e, type) {
if (type === TYPE_EDIT) {
this.setState({ currGroupDesc: e.target.value })
} else {
this.setState({ newGroupDesc: e.target.value });
}
inputNewGroupDesc(e) {
this.setState({ newGroupDesc: e.target.value });
}
@autobind
@ -207,50 +178,6 @@ export default class GroupList extends Component {
})
}
showConfirm = () => {
let that = this;
confirm({
title: "确认删除 " + that.props.currGroup.group_name + " 分组吗?",
content: <div style={{ marginTop: '10px', fontSize: '13px', lineHeight: '25px' }}>
<Alert message="警告:此操作非常危险,会删除该分组下面所有项目和接口,并且无法恢复!" type="warning" />
<div style={{ marginTop: '16px' }}>
<p><b>请输入分组名称确认此操作:</b></p>
<Input id="group_name" />
</div>
</div>,
onOk() {
let groupName = document.getElementById('group_name').value;
if (that.props.currGroup.group_name !== groupName) {
message.error('分组名称有误')
return new Promise((resolve, reject) => {
reject('error')
})
} else {
that.deleteGroup()
}
},
iconType: 'delete',
onCancel() { }
});
}
@autobind
async deleteGroup() {
const self = this;
const { currGroup } = self.props;
const res = await axios.post('/api/group/del', { id: currGroup._id })
if (res.data.errcode) {
message.error(res.data.errmsg);
} else {
message.success('删除成功')
await self.props.fetchGroupList()
const currGroup = self.props.groupList[0] || { group_name: '', group_desc: '' };
self.setState({ groupList: self.props.groupList });
self.props.setCurrGroup(currGroup)
}
}
@autobind
searchGroup(e, value) {
const v = value || e.target.value;
@ -262,40 +189,17 @@ export default class GroupList extends Component {
}
}
componentWillReceiveProps(nextProps) {
// GroupSetting 组件设置的分组信息通过redux同步到左侧分组菜单中
if (this.props.groupList !== nextProps.groupList) {
this.setState({
groupList: nextProps.groupList
})
}
}
render() {
const { currGroup } = this.props;
const delmark = <Menu.Item>
<span onClick={() => this.showModal(TYPE_EDIT)}>编辑分组</span>
</Menu.Item>
const editmark = <Menu.Item>
<span onClick={() => { this.showConfirm() }}>删除分组</span>
</Menu.Item>
const addmark = <Menu.Item>
<span onClick={this.showModal}>添加分组</span>
</Menu.Item>
let menu = <Menu>
{
this.props.curUserRole === "admin" && this.props.currGroup.type !== 'private' ? (editmark) : ''
}
{
(this.props.curUserRole === "admin" || this.props.curUserRoleInGroup === 'owner') && this.props.currGroup.type !== 'private' ? (delmark) : ''
}
{
this.props.curUserRole === 'admin' ? (addmark) : ''
}
</Menu>;
menu = (this.props.curUserRoleInGroup === 'owner' && this.props.curUserRole !== 'admin') ? <a className="editSet"><Icon type="setting" onClick={() => this.showModal(TYPE_EDIT)} /></a> : <Dropdown overlay={menu}>
<a className="ant-dropdown-link" href="#">
<Icon type="setting" />
</a>
</Dropdown>;
// console.log(this.props.currGroup.type,this.props.curUserRoleInGroup,this.props.curUserRole);
// if(!(this.props.currGroup.type !=='private') && !(this.props.curUserRoleInGroup === 'owner' || this.props.curUserRole === 'admin')){
// menu = null;
// }
return (
<div className="m-group">
{!this.props.study ? <div className="study-mask"></div> : null}
@ -303,7 +207,10 @@ export default class GroupList extends Component {
<div className="curr-group">
<div className="curr-group-name">
<span className="name">{currGroup.group_name}</span>
{this.props.curUserRole === "admin" || this.props.curUserRoleInGroup === 'owner' ? (menu) : ''}
{/* this.props.curUserRole === "admin" || this.props.curUserRoleInGroup === 'owner' ? (menu) : '' */}
{ /* 只有超级管理员能添加分组 */
this.props.curUserRole === 'admin' ? <Tooltip title="添加分组"><a className="editSet"><Icon className="btn" type="folder-add" onClick={this.showModal} /></a></Tooltip> : ''
}
</div>
<div className="curr-group-desc">简介: {currGroup.group_desc}</div>
</div>
@ -370,27 +277,6 @@ export default class GroupList extends Component {
</Row>
</Modal> : ''
}
<Modal
title="编辑分组"
visible={this.state.editGroupModalVisible}
onOk={this.editGroup}
onCancel={() => this.hideModal(TYPE_EDIT)}
className="add-group-modal"
>
<Row gutter={6} className="modal-input">
<Col span="5"><div className="label">分组名</div></Col>
<Col span="15">
<Input placeholder="请输入分组名称" value={this.state.currGroupName} onChange={(e) => this.inputNewGroupName(e, TYPE_EDIT)}></Input>
</Col>
</Row>
<Row gutter={6} className="modal-input">
<Col span="5"><div className="label">简介</div></Col>
<Col span="15">
<TextArea rows={3} placeholder="请输入分组描述" value={this.state.currGroupDesc} onChange={(e) => this.inputNewGroupDesc(e, TYPE_EDIT)}></TextArea>
</Col>
</Row>
</Modal>
</div>
)
}

View File

@ -0,0 +1,198 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { autobind } from 'core-decorators';
import { Row, Col, Input, Button, message, Icon, Card, Alert, Modal } from 'antd';
import { fetchNewsData } from '../../../reducer/modules/news.js';
import { changeGroupMsg, fetchGroupList, setCurrGroup, fetchGroupMsg, updateGroupList, deleteGroup } from '../../../reducer/modules/group.js';
const { TextArea } = Input;
import _ from 'underscore';
const confirm = Modal.confirm;
@connect(
state => {
return {
groupList: state.group.groupList,
currGroup: state.group.currGroup,
curUserRole: state.user.role
}
},
{
changeGroupMsg,
fetchGroupList,
setCurrGroup,
fetchGroupMsg,
fetchNewsData,
updateGroupList,
deleteGroup
}
)
class GroupLog extends Component {
constructor(props) {
super(props);
this.state = {
currGroupDesc: '',
currGroupName: '',
showDangerOptions: false
}
}
static propTypes = {
currGroup: PropTypes.object,
curUserRole: PropTypes.string,
changeGroupMsg: PropTypes.func,
fetchGroupList: PropTypes.func,
setCurrGroup: PropTypes.func,
fetchGroupMsg: PropTypes.func,
fetchNewsData: PropTypes.func,
updateGroupList: PropTypes.func,
deleteGroup: PropTypes.func,
groupList: PropTypes.array
}
// 修改分组名称
changeName = (e) => {
this.setState({
currGroupName: e.target.value
})
}
// 修改分组描述
changeDesc = (e) => {
this.setState({
currGroupDesc: e.target.value
})
}
componentDidMount() {
this.setState({
currGroupName: this.props.currGroup.group_name,
currGroupDesc: this.props.currGroup.group_desc
})
}
// 点击“查看危险操作”按钮
toggleDangerOptions = () => {
// console.log(this.state.showDangerOptions);
this.setState({
showDangerOptions: !this.state.showDangerOptions
});
}
// 编辑分组信息
@autobind
async editGroup() {
const id = this.props.currGroup._id;
const res = await this.props.changeGroupMsg({
group_name: this.state.currGroupName,
group_desc: this.state.currGroupDesc,
id: this.props.currGroup._id
});
if (!res.payload.data.errcode) {
message.success('修改成功!');
await this.props.fetchGroupList(this.props.groupList);
this.props.updateGroupList(this.props.groupList)
const currGroup = _.find(this.props.groupList, (group) => { return + group._id === + id });
this.props.setCurrGroup(currGroup);
this.props.fetchGroupMsg(this.props.currGroup._id);
this.props.fetchNewsData(this.props.currGroup._id, "group", 1, 10)
}
}
// 删除分组
@autobind
async deleteGroup() {
const that = this;
const { currGroup } = that.props;
const res = await this.props.deleteGroup({ id: currGroup._id });
if (!res.payload.data.errcode) {
message.success('删除成功')
await that.props.fetchGroupList();
const currGroup = that.props.groupList[0] || { group_name: '', group_desc: '' };
that.setState({ groupList: that.props.groupList });
that.props.setCurrGroup(currGroup)
}
}
// 删除分组的二次确认
showConfirm = () => {
const that = this;
confirm({
title: "确认删除 " + that.props.currGroup.group_name + " 分组吗?",
content: <div style={{ marginTop: '10px', fontSize: '13px', lineHeight: '25px' }}>
<Alert message="警告:此操作非常危险,会删除该分组下面所有项目和接口,并且无法恢复!" type="warning" />
<div style={{ marginTop: '16px' }}>
<p><b>请输入分组名称确认此操作:</b></p>
<Input id="group_name" />
</div>
</div>,
onOk() {
const groupName = document.getElementById('group_name').value;
if (that.props.currGroup.group_name !== groupName) {
message.error('分组名称有误')
return new Promise((resolve, reject) => {
reject('error')
})
} else {
that.deleteGroup()
}
},
iconType: 'delete',
onCancel() { }
});
}
componentWillReceiveProps(nextProps) {
// 切换分组时,更新分组信息并关闭删除分组操作
if (this.props.currGroup._id !== nextProps.currGroup._id) {
this.setState({
showDangerOptions: false,
currGroupName: nextProps.currGroup.group_name,
currGroupDesc: nextProps.currGroup.group_desc
})
}
}
render () {
return (
<div className="m-panel card-panel-s">
<div>
<Row gutter={6} className="modal-input">
<Col span="4"><div className="label">分组名</div></Col>
<Col span="15">
<Input placeholder="请输入分组名称" value={this.state.currGroupName} onChange={this.changeName}></Input>
</Col>
</Row>
<Row gutter={6} className="modal-input">
<Col span="4"><div className="label">简介</div></Col>
<Col span="15">
<TextArea rows={3} placeholder="请输入分组描述" value={this.state.currGroupDesc} onChange={this.changeDesc}></TextArea>
</Col>
</Row>
<Row gutter={6} className="modal-input">
<Col span="15" offset="4"><Button type="primary" onClick={this.editGroup}>保存</Button></Col>
</Row>
</div>
{/* 只有超级管理员能删除分组 */}
{this.props.curUserRole === "admin" ?
<div className="danger-container">
<div className="title">
<h2 className="content"><Icon type="exclamation-circle-o" /> 危险操作</h2>
<Button onClick={this.toggleDangerOptions}> <Icon type={this.state.showDangerOptions ? 'up' : 'down'} /></Button>
</div>
{this.state.showDangerOptions ? <Card noHovering={true} className="card-danger">
<div className="card-danger-content">
<h3>删除分组</h3>
<p>分组一旦删除将无法恢复数据请慎重操作</p>
<p>只有超级管理员有权限删除分组</p>
</div>
<Button type="danger" ghost className="card-danger-btn" onClick={this.showConfirm}>删除</Button>
</Card> : null}
</div> : null}
</div>
)
}
}
export default GroupLog;

View File

@ -8,11 +8,17 @@ const FETCH_GROUP_MSG = 'yapi/group/FETCH_GROUP_MSG';
const ADD_GROUP_MEMBER = 'yapi/group/ADD_GROUP_MEMBER';
const DEL_GROUP_MEMBER = 'yapi/group/DEL_GROUP_MEMBER';
const CHANGE_GROUP_MEMBER = 'yapi/group/CHANGE_GROUP_MEMBER';
const CHANGE_GROUP_MESSAGE = 'yapi/group/CHANGE_GROUP_MESSAGE';
const UPDATE_GROUP_LIST = 'yapi/group/UPDATE_GROUP_LIST';
const DEL_GROUP = 'yapi/group/DEL_GROUP';
// Reducer
const initialState = {
groupList: [],
currGroup: { group_name: '' },
currGroup: {
group_name: '',
group_desc: ''
},
member: [],
role: ''
};
@ -25,6 +31,12 @@ export default (state = initialState, action) => {
groupList: action.payload.data.data
};
}
case UPDATE_GROUP_LIST: {
return {
...state,
groupList: action.payload
}
}
case SET_CURR_GROUP: {
return {
...state,
@ -83,6 +95,30 @@ export function changeMemberRole(param) {
}
}
// 修改分组信息
export function changeGroupMsg(param) {
return {
type: CHANGE_GROUP_MESSAGE,
payload: axios.post('/api/group/up', param)
}
}
// 更新左侧的分组列表
export function updateGroupList(param) {
return {
type: UPDATE_GROUP_LIST,
payload: param
}
}
// 删除分组
export function deleteGroup(param) {
return {
type: DEL_GROUP,
payload: axios.post('/api/group/del', param)
}
}
// 获取分组成员列表
export function fetchGroupMemberList(id) {
return {