Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev

This commit is contained in:
suxiaoxin 2017-09-28 19:42:40 +08:00
commit 1f6e5b31e3
8 changed files with 194 additions and 34 deletions

View File

@ -0,0 +1,48 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types';
import { Button } from 'antd';
import { connect } from 'react-redux'
import { changeStudyTip, finishStudy } from '../../reducer/modules/user.js';
@connect(
null,
{
changeStudyTip,
finishStudy
}
)
class GuideBtns extends Component {
constructor(props) {
super(props)
}
static propTypes = {
changeStudyTip: PropTypes.func,
finishStudy: PropTypes.func,
isLast: PropTypes.bool
}
// 点击下一步
nextStep = () => {
this.props.changeStudyTip();
if (this.props.isLast) {
this.props.finishStudy();
}
}
// 点击退出指引
exitGuide = () => {
this.props.finishStudy();
}
render () {
console.log(this.props);
return (
<div className="btn-container">
<Button className="btn" type="primary" onClick={this.nextStep}>{this.props.isLast ? '完 成' : '下一步'}</Button>
<Button className="btn" type="dashed" onClick={this.exitGuide}>退出指引</Button>
</div>
)
}
}
export default GuideBtns;

View File

@ -3,7 +3,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { Icon, Layout, Menu, Dropdown, message, Tooltip, Avatar } from 'antd'
import { Icon, Layout, Menu, Dropdown, message, Tooltip, Avatar, Popover } from 'antd'
import { checkLoginState, logoutActions, loginTypeAction} from '../../reducer/modules/user'
import { changeMenuItem } from '../../reducer/modules/menu'
import { withRouter } from 'react-router';
@ -11,6 +11,7 @@ import Srch from './Search/Search'
const { Header } = Layout;
import { logoSVG } from '../../common.js';
import Breadcrumb from '../Breadcrumb/Breadcrumb.js'
import GuideBtns from '../GuideBtns/GuideBtns.js';
const MenuUser = (props) => (
<Menu theme="dark" className="user-menu" >
@ -23,6 +24,15 @@ const MenuUser = (props) => (
</Menu>
);
const tip = (<div className="title-container">
<h3 className="title">工具栏</h3>
<p><Icon type="search" /> 搜索功能: 搜索分组与项目;</p>
<p><Icon type="heart" /> 关注功能: 属于自己的收藏夹;</p>
<p><Icon type="plus-circle" /> 新建项目: 在任何页面都可以快速新建项目;</p>
<p><Icon type="question-circle" /> 使用文档: 遇到问题的时候随时可以查看文档;</p>
<p>你还可以更换头像便于同事在 YApi 里找到你 ~</p>
</div>);
MenuUser.propTypes={
user: PropTypes.string,
msg: PropTypes.string,
@ -96,7 +106,9 @@ ToolUser.propTypes={
user: state.user.userName,
uid: state.user.uid,
msg: null,
login:state.user.isLogin
login:state.user.isLogin,
studyTip: state.user.studyTip,
study: state.user.study
}
},
{
@ -123,7 +135,9 @@ export default class HeaderCom extends Component {
loginTypeAction:PropTypes.func,
changeMenuItem:PropTypes.func,
history: PropTypes.object,
location: PropTypes.object
location: PropTypes.object,
study: PropTypes.bool,
studyTip: PropTypes.number
}
linkTo = (e) =>{
if(e.key != '/doc'){
@ -184,13 +198,21 @@ export default class HeaderCom extends Component {
<Breadcrumb />
<div className="user-toolbar">
{login?
<ToolUser
user = { user }
msg = { msg }
uid = { uid }
relieveLink = { this.relieveLink }
logout = { this.logout }
/>
<Popover
overlayClassName="popover-index"
content={<GuideBtns/>}
title={tip}
placement="bottomRight"
visible={(this.props.studyTip === 1 && !this.props.study) ? true : false}
>
<ToolUser
user = { user }
msg = { msg }
uid = { uid }
relieveLink = { this.relieveLink }
logout = { this.logout }
/>
</Popover>
:""}
</div>
</div>

View File

@ -93,14 +93,14 @@ class UsernameAutoComplete extends Component {
render () {
const { dataSource, fetching, value } = this.state;
const { dataSource, fetching } = this.state;
const children = dataSource.map((item, index) => (
<Option key={index} value={'' + item.id}>{item.username}</Option>
))
return (
<Select
mode="multiple"
mode="multiple"
style={{ width: '100%' }}
placeholder="请输入用户名"
filterOption={false}
@ -109,7 +109,7 @@ class UsernameAutoComplete extends Component {
onChange={this.handleChange}
size="large"
>
{children}
{children}
</Select>
)
}

View File

@ -1,7 +1,7 @@
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 } from 'antd'
import { Icon, Modal, Alert, Input, message, Menu, Row, Col, Dropdown, Popover } from 'antd'
import { autobind } from 'core-decorators';
import axios from 'axios';
import { withRouter } from 'react-router-dom';
@ -10,6 +10,7 @@ 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';
import {
fetchGroupList,
@ -17,13 +18,20 @@ import {
setGroupList
} from '../../../reducer/modules/group.js'
import './GroupList.scss'
import './GroupList.scss';
const tip = (<div className="title-container">
<h3 className="title">欢迎使用 YApi ~</h3>
<p>这里的 <b>个人空间</b> YApi </p>
</div>);
@connect(
state => ({
groupList: state.group.groupList,
currGroup: state.group.currGroup,
curUserRole: state.user.role
curUserRole: state.user.role,
studyTip: state.user.studyTip,
study: state.user.study
}),
{
fetchGroupList,
@ -44,6 +52,8 @@ export default class GroupList extends Component {
match: PropTypes.object,
history: PropTypes.object,
curUserRole: PropTypes.string,
studyTip: PropTypes.number,
study: PropTypes.bool,
fetchNewsData: PropTypes.func
}
@ -236,13 +246,14 @@ export default class GroupList extends Component {
}
render() {
console.log(this.props);
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>
</Menu.Item>
const addmark = <Menu.Item>
<span onClick={this.showModal}>添加分组</span>
</Menu.Item>
@ -291,16 +302,27 @@ export default class GroupList extends Component {
onClick={this.selectGroup}
selectedKeys={[`${currGroup._id}`]}
>
{
this.state.groupList.map((group) => (
<Menu.Item key={`${group._id}`} className="group-item">
{group.type === 'private' ?
<Icon type="user" /> :
<Icon type="folder-open" />
}{group.group_name}
{this.state.groupList.map((group) => {
if(group.type === 'private') {
return <Menu.Item key={`${group._id}`} className="group-item">
<Icon type="user" />
<Popover
overlayClassName="popover-index"
content={<GuideBtns/>}
title={tip}
placement="right"
visible={(this.props.studyTip === 0 && !this.props.study) ? true : false}
>
{group.group_name}
</Popover>
</Menu.Item>
))
}
} else {
return <Menu.Item key={`${group._id}`} className="group-item">
<Icon type="folder-open" />
{group.group_name}
</Menu.Item>
}
})}
</Menu>
</div>
{

View File

@ -1,15 +1,23 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Row, Col, Button, Tooltip } from 'antd';
import { Row, Col, Button, Tooltip, Popover } from 'antd';
import { Link } from 'react-router-dom';
import { addProject, fetchProjectList, delProject, changeUpdateModal } from '../../../reducer/modules/project';
import ProjectCard from '../../../components/ProjectCard/ProjectCard.js';
import ErrMsg from '../../../components/ErrMsg/ErrMsg.js';
import { autobind } from 'core-decorators';
import { setBreadcrumb } from '../../../reducer/modules/user';
import GuideBtns from '../../../components/GuideBtns/GuideBtns.js';
import './ProjectList.scss'
import './ProjectList.scss';
const tip = (<div className="title-container">
<h3 className="title">项目列表</h3>
<p>这里列出了分组下的所有项目</p>
<p>成为分组成员即可在该分组下添加项目</p>
<p>赶快创建属于你的第一个项目把 ~</p>
</div>);
@connect(
state => {
@ -18,7 +26,9 @@ import './ProjectList.scss'
userInfo: state.project.userInfo,
tableLoading: state.project.tableLoading,
currGroup: state.group.currGroup,
currPage: state.project.currPage
currPage: state.project.currPage,
studyTip: state.user.studyTip,
study: state.user.study
}
},
{
@ -49,7 +59,9 @@ class ProjectList extends Component {
tableLoading: PropTypes.bool,
currGroup: PropTypes.object,
setBreadcrumb: PropTypes.func,
currPage: PropTypes.number
currPage: PropTypes.number,
studyTip: PropTypes.number,
study: PropTypes.bool
}
// 取消修改
@ -113,7 +125,15 @@ class ProjectList extends Component {
{/(admin)|(owner)|(dev)/.test(this.props.currGroup.role) ?
<Button type="primary" ><Link to="/add-project">添加项目</Link></Button> :
<Popover
overlayClassName="popover-index"
content={<GuideBtns isLast={true}/>}
title={tip}
placement="right"
visible={(this.props.studyTip === 2 && !this.props.study) ? true : false}
>
<Button type="primary" ><Link to="/add-project">添加项目</Link></Button>
</Popover> :
<Tooltip title="您没有权限,请联系该分组组长或管理员">
<Button type="primary" disabled >添加项目</Button>
</Tooltip>}

View File

@ -7,6 +7,8 @@ const LOGIN_TYPE = 'yapi/user/LOGIN_TYPE';
const GET_LOGIN_STATE = 'yapi/user/GET_LOGIN_STATE';
const REGISTER = 'yapi/user/REGISTER';
const SET_BREADCRUMB = 'yapi/user/SET_BREADCRUMB';
const CHANGE_STUDY_TIP = 'yapi/user/CHANGE_STUDY_TIP';
const FINISH_STUDY = 'yapi/user/FINISH_STUDY';
// Reducer
const LOADING_STATUS = 0;
@ -28,7 +30,8 @@ const initialState = {
// }, {
// name: '当前页面'
// }]
breadcrumb: []
breadcrumb: [],
studyTip: 0
};
export default (state = initialState, action) => {
@ -94,6 +97,18 @@ export default (state = initialState, action) => {
breadcrumb: action.data
};
}
case CHANGE_STUDY_TIP: {
return {
...state,
studyTip: state.studyTip + 1
}
}
case FINISH_STUDY: {
return {
...state,
study: true
};
}
default:
return state;
}
@ -151,3 +166,16 @@ export function setBreadcrumb(data) {
data
}
}
export function changeStudyTip() {
return {
type: CHANGE_STUDY_TIP
}
}
export function finishStudy() {
return {
type: FINISH_STUDY,
payload: axios.get('/api/user/up_study')
}
}

View File

@ -171,3 +171,22 @@ em {
.has-affix-footer {
padding-bottom: .92rem;
}
.popover-index {
max-width: 3.2rem;
.ant-popover-title {
height: auto;
}
.title-container {
padding: .16rem 0;
.title {
text-align: center;
}
}
.btn-container {
text-align: center;
.btn {
margin: 0 .04rem;
}
}
}

View File

@ -86,7 +86,7 @@ class userController extends baseController {
* @category user
* @foldnumber 10
* @returns {Object}
* @example
* @example
*/
async upStudy(ctx) {
@ -306,7 +306,8 @@ class userController extends baseController {
role: 'member',
add_time: yapi.commons.time(),
up_time: yapi.commons.time(),
type: "site"
type: "site",
study: false
};
if (!data.username) {