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

This commit is contained in:
suxiaoxin 2017-07-28 17:29:22 +08:00
commit b2bfafec90
20 changed files with 171 additions and 90 deletions

View File

@ -14,18 +14,19 @@ class Footer extends Component {
'background': 'url(./image/footer-bac.jpg)'
}
return (
<div className = 'footer' style = {style}>
<div className = 'footContent'>
{ this.props.footList.map(function(item,i){
return <FootItem key = { i } linkList = { item.linkList } title = { item.title } iconType = { item.iconType } ></FootItem>
}) }
<div className = 'copyRight'>
<h4>Copyright © 2017</h4>
YMFF出品 @ YMFF
<div className = 'footer-wrapper'>
<div className = 'footer' style = {style}>
<div className = 'footContent'>
{ this.props.footList.map(function(item,i){
return <FootItem key = { i } linkList = { item.linkList } title = { item.title } iconType = { item.iconType } ></FootItem>
}) }
<div className = 'copyRight'>
<h4>Copyright © 2017</h4>
YMFF出品 @ YMFF
</div>
</div>
<div className='footerMask'></div>
</div>
<div className='footerMask'></div>
</div>
)
}

View File

@ -1,9 +1,12 @@
@import '../../styles/common.scss';
@import '../../styles/mixin.scss';
.footer-wrapper{
width: 100%;
}
.footer{
@include wrap-width-limit;
margin: 0px auto;
margin: 0 auto;
clear: both;
font-size: 12px;
background: #000c15;
@ -25,7 +28,7 @@
.footerMask{
@include wrap-width-limit;
position: absolute;
top: 0px;
top: 0;
height: 100%;
width: 100%;
background-color: #404040;
@ -34,8 +37,8 @@
}
.footContent{
@include row-width-limit;
width:90%;
margin:0px auto;
//width:90%;
margin:0 auto;
overflow: hidden;
position: relative;
z-index: 2;
@ -45,7 +48,7 @@
width: 25%;
float: left;
div{
margin: 6px 0px;
margin: 6px 0;
}
a{
font-weight: 200;
@ -68,6 +71,6 @@
margin: 0 auto 12px;
font-weight: 500;
position: relative;
text-indent: 0em;
text-indent: 0;
}
}

View File

@ -5,12 +5,18 @@ import { Icon, Input, AutoComplete } from 'antd'
import './Search.scss'
import { withRouter } from 'react-router';
import axios from 'axios';
import { setCurrGroup } from '../../../actions/group'
import { changeMenuItem } from '../../../actions/menu'
const Option = AutoComplete.Option;
@connect(
state => ({
groupList: state.group.groupList,
projectList: state.project.projectList
})
}),{
setCurrGroup,
changeMenuItem
}
)
@withRouter
@ -27,14 +33,18 @@ export default class Srch extends Component{
projectList: PropTypes.array,
router: PropTypes.object,
history: PropTypes.object,
location: PropTypes.object
location: PropTypes.object,
setCurrGroup: PropTypes.func,
changeMenuItem : PropTypes.func
}
onSelect = (value) => {
if( value.split(":")[0] == "分组" ){
this.props.history.push('/group/'+value.split(":")[1].trim());
onSelect = (value,option) => {
if( option.props.tpye == "分组" ){
this.props.changeMenuItem('/group');
this.props.history.push('/group/'+value);
this.props.setCurrGroup({"group_name":value,"_id":option.props['id']});
} else {
this.props.history.push('/project/'+value.split("(")[1].slice(0,-1));
this.props.history.push('/project/'+option.props['id']);
}
}
@ -43,9 +53,27 @@ export default class Srch extends Component{
.then((res) => {
if(res.data && res.data.errcode === 0){
const dataSource = [];
for(let title in res.data.data){
for(let title in res.data.data) {
res.data.data[title].map(item => {
title == "group" ? dataSource.push( "分组"+": "+item.groupName ): dataSource.push( "项目"+": "+item.name+"("+item._id+")" );
dataSource.push(
title == "group" ?
( <Option
key={`${item._id}`}
tpye="分组"
value={`${item.groupName}`}
id={`${item._id}`}
>
{`分组: ${item.groupName}`}
</Option>) :
(<Option
key={`${item._id}`}
tpye="项目"
value={`${item._id}`}
id={`${item._id}`}
>
{`项目: ${item.name}`}
</Option>)
)
})
}
this.setState({
@ -70,6 +98,7 @@ export default class Srch extends Component{
render(){
const { dataSource } = this.state;
return(
<div className="search-wrapper">
<AutoComplete
@ -85,11 +114,7 @@ export default class Srch extends Component{
<Input
prefix={<Icon type="search" className="srch-icon" />}
size="large"
style={{
// width: 200,
// borderColor:"#AAA",
// borderWidth:"1px",
}}
style={{}}
placeholder="搜索分组/项目"
className="search-input"
/>

View File

@ -3,7 +3,6 @@ $color-grey:#979DA7;
.search-wrapper{
.search-input{
width: 2rem;
//transition: width 2s;
}
.srch-icon{
}

View File

@ -5,7 +5,7 @@ import axios from 'axios'
import Mock from 'mockjs'
import { connect } from 'react-redux'
import { autobind } from 'core-decorators'
import { Button, Tabs, message } from 'antd'
import { Button, Tabs, message, Affix } from 'antd'
import ReqMethod from './ReqMethod/ReqMethod.js'
import ReqHeader from './ReqHeader/ReqHeader.js'
import ReqParams from './ReqParams/ReqParams.js'
@ -264,6 +264,7 @@ class AddInterface extends Component {
}
return (
<section className="add-interface-box">
<div className="content">
<Tabs type="card">
<TabPane tab={tagName} key="1">
@ -275,11 +276,13 @@ class AddInterface extends Component {
<h3 className="req-title">返回部分</h3>
<ResParams />
<Result isSave={isSave} mockJson={mockJson} />
<Button type="primary" className="save" onClick={this.saveForms}>保存</Button>
</TabPane>
{Pane}
</Tabs>
</div>
<Affix offsetBottom={0} className="save-button" onChange={affixed => console.log(affixed)}>
<Button type="primary" onClick={this.saveForms}>保存</Button>
</Affix>
<div className={`loading ${isLoading}`}></div>
</section>
)

View File

@ -14,7 +14,7 @@
border-radius: 4px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
background: #FFF;
padding: 10px 20px 50px 20px;
padding: 10px 20px 0 20px;
margin: 0 auto;
.ant-tabs {
@ -44,12 +44,6 @@
font-weight: normal;
}
.save {
position: absolute;
bottom: 0;
left: 550px;
}
.mock {
float: right;
margin: 0 15px 0 0;
@ -64,7 +58,7 @@
}
td {
padding: 10px 0;
padding: 11px 0;
}
.select {
@ -96,8 +90,7 @@
.req-header {
display: -webkit-box;
line-height: 32px;
margin: 10px 0 0 50px;
padding: 15px 0 0 0;
margin: 12px 0 0 58px;
.req-h3 {
line-height: 32px;
@ -110,7 +103,7 @@
li {
display: -webkit-box;
margin: 0 0 10px 0;
margin: 0 0 16px 0;
}
.title {
@ -125,18 +118,18 @@
}
.req-save, .res-save {
margin: 5px 0 0 159px;
margin: 0 0 0 167px;
}
/* .req-params.css */
.req-params {
display: -webkit-box;
padding: 20px 0 0 0;
margin: 20px 0 0 90px;
width: 650px;
margin: 22px 0 0 92px;
width: 562px;
height: 200px;
.req-h3 {
font-weight: normal;
margin: 0 0 0 8px;
}
}
@ -201,6 +194,10 @@
.ant-tabs {
-webkit-box-flex: 1;
}
.ant-card-head {
cursor: not-allowed;
}
}
.dynamic-delete-button {
@ -209,11 +206,20 @@
}
}
.ant-affix, .save-button {
padding: 20px 0;
background: #F6F6F6;
button {
margin: 0 auto;
display: block;
}
}
/* .mock-url-box.css */
.mock-url-box {
clear: both;
padding: 10px 0 0 0;
margin: 10px 0 0 90px;
margin: 14px 0 0 96px;
zoom: 1;
overflow: hidden;
display: none;
@ -222,7 +228,7 @@
line-height: 35px;
}
p {
width: 52.8%;
width: 47.3%;
height: 35px;
line-height: 35px;
border: 1px #DDD solid;
@ -230,6 +236,7 @@
margin: 0 10px 0 8px;
padding: 0 0 0 10px;
float: left;
border-radius: 4px;
}
.host {
margin: 10px 0 0 80px;
@ -258,6 +265,11 @@
.is-loading {
display: block;
}
.ant-tabs.ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active,
.ant-tabs.ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
font-size: .12rem;
margin-top: 3px;
}
}
#container {
@ -310,9 +322,9 @@ body {
#req-cover {
padding: 0 20px;
border: 1px #DDD solid;
// background-color: #FFF;
border-radius: 4px;
-webkit-box-flex: 1;
margin: 0 0 0 15px;
margin: 0 0 0 12px;
}
#res-cover {
background-color: #FFF;

View File

@ -24,9 +24,7 @@ const Option = Select.Option;
seqGroup: state.addInterface.seqGroup,
interfaceName: state.addInterface.interfaceName,
interfaceProject: state.addInterface.project
}),
{
}
})
)
@withRouter
export default class InterfaceTest extends Component {
@ -136,18 +134,16 @@ export default class InterfaceTest extends Component {
method,
headers,
data: params,
success: (res, header) => {
console.log(header)
success: (res) => {
try {
res = JSON.parse(res);
res = JSON.parse(res)
} catch (e) {
null;
null
}
this.setState({res})
this.setState({ loading: false })
},
error: (err, header) => {
console.log(header)
error: (err) => {
this.setState({res: err || '请求失败'})
this.setState({ loading: false })
}

View File

@ -120,7 +120,7 @@ class ReqList extends Component {
return (
<li>
<em className="title">头部标签 : </em>
<Select value={name} style={{ width: 220 }} onChange={this.handleChange} size="large">
<Select value={name} style={{ width: 180 }} onChange={this.handleChange} size="large">
<Option value="">选择请求头</Option>
{headersOptions}
</Select>

View File

@ -15,7 +15,8 @@ import QueueAnim from 'rc-queue-anim';
const oneAnim = { y: '+=30', opacity: 0, type: 'from', ease: 'easeOutQuad' };
const imgAnim = { y: '+=50', opacity: 0, type: 'from', ease: 'easeOutQuad', duration: '1500'};
const style = {
'height':'100%',
// 'height':'100%',
// 'height':'7rem',
'width':'100%',
'background': 'url(./image/bg-img.jpg) no-repeat',
'backgroundSize':'100% 100%'
@ -37,19 +38,17 @@ const HomeGuest = (props) => (
<Col span={8} className="main-one-left">
<Login/>
</Col>
<OverPack>
<TweenOne
key="feat-motion-one"
animation={imgAnim}
>
<Col span={16} className="main-one-right">
<div className="img-container">
<img src="./image/demo-img.png"/>
</div>
</Col>
</TweenOne>
</OverPack>
<Col span={16} className="main-one-right">
<OverPack>
<TweenOne
key="feat-motion-one"
animation={imgAnim}
className="img-container"
>
<img src="./image/demo-img.png"/>
</TweenOne>
</OverPack>
</Col>
</Row>
</div>
</div>

View File

@ -27,6 +27,8 @@ $color-black-lighter: #404040;
color: $color-white;
}
.img-container{
width: 100%;
//height: 5rem;
margin-bottom: -.3rem;
img{
width: 100%;

View File

@ -58,3 +58,8 @@
}
}
}
body .interface-mode-box .add-user .ant-input {
width: 100%;
}

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react'
import { Modal, Input, Button } from 'antd'
import { Modal, Button, AutoComplete } from 'antd'
import PropTypes from 'prop-types'
import axios from 'axios'
import { autobind } from 'core-decorators'
@ -9,7 +9,9 @@ class InterfaceMode extends Component {
static propTypes = {
modalVisible: PropTypes.bool,
closeProjectMember: PropTypes.func,
memberList: PropTypes.array
memberList: PropTypes.array,
dataSource: PropTypes.array,
inputValue: PropTypes.string
}
constructor(props) {
@ -31,7 +33,6 @@ class InterfaceMode extends Component {
}
axios.get('/project/get_member_list', { params })
.then(data => {
console.log(data)
this.setState({
'memberList': data.data.data
})
@ -41,13 +42,21 @@ class InterfaceMode extends Component {
})
}
@autobind
onSelect (userName) {
console.log(userName)
this.setState({
userName
})
}
@autobind
closeMember (id) {
const params = {
member_uid: id,
id: this.getInterfaceId()
}
axios.post('/project/del_member', params)
.then(() => {
this.getMemberList()
@ -79,10 +88,26 @@ class InterfaceMode extends Component {
}
@autobind
injectValue (e) {
handleSearch (value) {
this.setState({
userName: e.target.value
userName: value
})
const params = { q: value}
axios.get('/user/search', { params })
.then(data => {
const userList = []
data = data.data.data
if (data) {
data.forEach( v => userList.push(v.username) )
this.setState({
dataSource: userList
})
}
})
.catch (err => {
console.log(err)
})
}
handleOk (closeProjectMember) {
@ -104,7 +129,7 @@ class InterfaceMode extends Component {
const { modalVisible, closeProjectMember } = this.props
const handleOk = this.handleOk.bind(this, closeProjectMember)
const handleCancel = this.handleCancel.bind(this, closeProjectMember)
const { memberList } = this.state
const { memberList, dataSource } = this.state
return (
<Modal
@ -115,7 +140,13 @@ class InterfaceMode extends Component {
className="interface-mode-box"
>
<div className="add-user">
<Input placeholder="Basic usage" size="large" onBlur={this.injectValue} />
<AutoComplete
dataSource={dataSource}
style={{ width: 350 }}
onSelect={this.onSelect}
onSearch={this.handleSearch}
placeholder="input here"
/>
<Button onClick={this.addNewUser}> </Button>
</div>
<article className="users">

View File

@ -21,8 +21,8 @@ class ModeTags extends Component {
}
render() {
const { value: { username='', _id } } = this.props
console.log(this.props, _id, username)
const { value: { username='' } } = this.props
return (
<span onClick={this.closeTags}>
{username}

View File

@ -192,7 +192,7 @@ export default class GroupList extends Component {
const { currGroup } = this.props;
return (
<div>
<div className="m-group">
<div className="group-bar">
<div className="curr-group">
<div className="curr-group-name">

View File

@ -1,6 +1,8 @@
.group-bar {
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
border-radius: 4px;
background-color: #fff;
min-height: 5rem;
.curr-group {
background: #34495E;
border-radius: 4px 4px 0 0;
@ -54,6 +56,7 @@
border-bottom: 1px solid #e9e9e9;
padding-bottom: 24px;
border-radius: 0 0 4px 4px;
border: none;
.group-item {
// height: 48px;
// line-height: 48px;

View File

@ -2,6 +2,5 @@
.g-doc {
@include row-width-limit;
min-height: 5rem;
margin: .24rem auto;
}

View File

@ -3,6 +3,7 @@
padding: 24px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
border-radius: 4px;
min-height: 5rem;
}
.m-table {

View File

@ -2,7 +2,6 @@
.g-doc {
margin: .24rem auto;
min-height: 5rem;
}
/* .user-box.css */
@ -23,6 +22,7 @@
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
background: #FFF;
border-radius:4px;
min-height: 5rem;
margin-top: 15px;
.search{
padding: 5px;
@ -55,6 +55,7 @@
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
background: #FFF;
margin-top: 15px;
min-height: 5rem;
.ant-table-wrapper table {
// font-size: .14rem;
@ -72,6 +73,7 @@
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
background: #FFF;
border-radius: .04rem;
min-height: 5rem;
.user-item {
min-height:35px;
line-height:35px;

View File

@ -123,7 +123,7 @@ class projectModel extends baseModel {
checkMemberRepeat(id, uid) {
return this.model.count({
_id: id,
members: [uid]
members: {$in: [uid]}
});
}

View File

@ -170,7 +170,7 @@ var projectModel = function (_baseModel) {
value: function checkMemberRepeat(id, uid) {
return this.model.count({
_id: id,
members: [uid]
members: { $in: [uid] }
});
}
}, {