mirror of
https://github.com/YMFE/yapi.git
synced 2024-12-21 05:19:42 +08:00
Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev
This commit is contained in:
commit
1f6e5b31e3
48
client/components/GuideBtns/GuideBtns.js
Normal file
48
client/components/GuideBtns/GuideBtns.js
Normal 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;
|
@ -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>
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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>
|
||||
{
|
||||
|
@ -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>}
|
||||
|
@ -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')
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user