This commit is contained in:
caishi 2020-06-12 18:12:29 +08:00
commit a730072663
19 changed files with 1552 additions and 1626 deletions

View File

@ -1564,6 +1564,9 @@ a.edu-txt-w80,
.font-50 { .font-50 {
font-size: 50px !important; font-size: 50px !important;
} }
.font-80 {
font-size: 80px !important;
}
/*a标签的下划线*/ /*a标签的下划线*/
a.decoration { a.decoration {
@ -2658,7 +2661,18 @@ a.color-green:hover {
.width89 { .width89 {
width: 89%; width: 89%;
} }
.width50 {
width: 50%;
}
.width40 {
width: 40%;
}
.width45 {
width: 45%;
}
.width10 {
width: 10%;
}
.width20 { .width20 {
width: 20%; width: 20%;
} }

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
.CodeMirror-merge { /* .CodeMirror-merge {
position: relative; position: relative;
white-space: pre; white-space: pre;
} }
@ -163,4 +163,34 @@
} }
.color-grey { .color-grey {
color: #888 !important; color: #888 !important;
} */
.maxW50{max-width: 50%;}
.minW50{min-width: 50%;}
.width70{width: 70%;}
.width30{width: 30%;}
.custom-commit-tabs .ant-tabs-bar{border-bottom: none;}
.maxW200px{max-width: 200px;}
.pr_tags_open{
background: #28BD6C !important;
color: #fff !important;
border: none !important;
}
.pr_tags_closed{
background: #FA6400 !important;
color: #fff !important;
border: none !important;
}
.pr_tags_merged{
background: #4C9ED3 !important;
color: #fff !important;
border: none !important;
}
.ant-btn-success{
border: 1px solid #28BD6C !important;
color: #28BD6C !important;
}
.ant-btn-success:hover{
background: #28BD6C !important;
color:#fff !important;
} }

View File

@ -100,7 +100,7 @@ export function initAxiosInterceptors(props) {
// TODO 读取到package.json中的配置 // TODO 读取到package.json中的配置
var proxy = "http://localhost:3000" var proxy = "http://localhost:3000"
// proxy = "https://pre-newweb.educoder.net" // proxy = "https://pre-newweb.educoder.net"
proxy = "https://testforgeplus.trustie.net/" // proxy = "https://testforgeplus.trustie.net/"
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求 // 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求
// 如果需要支持重复的请求考虑config里面自定义一个allowRepeat参考来控制 // 如果需要支持重复的请求考虑config里面自定义一个allowRepeat参考来控制

View File

@ -76,7 +76,7 @@ class CoderRootCommit extends Component{
render(){ render(){
const { branch , data , dataCount , limit , page , isSpin } = this.state; const { branch , data , dataCount , limit , page , isSpin } = this.state;
const { branchs , projectDetail } = this.props; const { branchs , projectDetail, commit_class } = this.props;
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const title =()=>{ const title =()=>{
return( return(
@ -97,7 +97,7 @@ class CoderRootCommit extends Component{
} }
return( return(
<React.Fragment> <React.Fragment>
<div className="main"> <div className={commit_class}>
<div className="f-wrap-between"> <div className="f-wrap-between">
<SelectBranch <SelectBranch
repo_id={projectDetail && projectDetail.repo_id} repo_id={projectDetail && projectDetail.repo_id}

View File

@ -48,7 +48,7 @@ class CoderRootIndex extends Component{
<Switch {...this.props}> <Switch {...this.props}>
<Route path="/projects/:projectsId/coders/commit" <Route path="/projects/:projectsId/coders/commit"
render={ render={
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} />) (props) => (<CoderRootCommit {...this.props} {...props} {...this.state} commit_class="main" />)
} }
></Route> ></Route>
{/* diff */} {/* diff */}

View File

@ -94,6 +94,11 @@ const MessageCount = Loadable({
loading: Loading, loading: Loading,
}) })
const UpdateMerge = Loadable({
loader: () => import('../Merge/UpdateMerge'),
loading: Loading,
})
const MilepostDetail = Loadable({ const MilepostDetail = Loadable({
loader: () => import('../Order/MilepostDetail'), loader: () => import('../Order/MilepostDetail'),
loading: Loading, loading: Loading,
@ -547,7 +552,7 @@ class Detail extends Component {
<Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge" <Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge"
render={ render={
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common}/>) (props) => (<UpdateMerge {...this.props} {...props} {...this.state} {...common}/>)
} }
></Route> ></Route>

View File

@ -1,6 +1,8 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { Popconfirm } from "antd"; import { Popconfirm, Tag } from "antd";
import { getImageUrl } from "educoder";
import "./merge.css"
class MergeItem extends Component { class MergeItem extends Component {
constructor(props) { constructor(props) {
@ -29,7 +31,7 @@ class MergeItem extends Component {
if (issue_tags && issue_tags.length > 0) { if (issue_tags && issue_tags.length > 0) {
return issue_tags.map((item, key) => { return issue_tags.map((item, key) => {
return ( return (
<span className="issue-tag-show" style={{ background: item.color }}> <span className="issue-tag-show" style={{ color: item.color }}>
{item.name} {item.name}
</span> </span>
); );
@ -40,7 +42,7 @@ class MergeItem extends Component {
}; };
render() { render() {
const { issues, search_count, page, limit } = this.props; const { issues, project_name } = this.props;
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const { current_user } = this.props; const { current_user } = this.props;
const renderList = () => { const renderList = () => {
@ -49,34 +51,66 @@ class MergeItem extends Component {
return ( return (
<div className="issueItem"> <div className="issueItem">
<div className="flex-1"> <div className="flex-1">
<p className="mb15 df"> <p className="mb15 df" style={{ alignItems: "center" }}>
<span
className={
item.issue_status === "关闭"
? "issueNo"
: "issueNo issueOpen"
}
>
# {search_count - (key + (page - 1) * limit)}
</span>
<Link <Link
to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`} to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}
className="flex-1 hide-1 font-16 color-grey-3 lineh-30" className="hide-1 font-15 color-grey-3 fwb lineh-30 mr10"
style={{ maxWidth: "300px" }}
> >
{item.name} {item.name}
</Link> </Link>
<Tag className={`pr_tags_${item.pull_request_staus}`}>
{item.pull_request_staus==="merged" ? "已合并" : (item.pull_request_staus === "closed"?"已拒绝" : "开启的") }
</Tag>
</p> </p>
<p className="color-grey-6 font-12"> <p className="grid-item font-13">
<span>{item.format_time}</span> <Link
<span className="ml5">发布</span> to={`/users/${item && item.author_login}`}
{item.updated_at === item.format_time ? ( className="show-user-link"
"" >
) : ( <img
<span className="ml20"> className="radius"
<span>{item.updated_at}</span> src={getImageUrl(`images/${item && item.avatar_url}`)}
<span className="ml5">更新</span> alt=""
width="24"
height="24"
/>
</Link>
<span>
<Link
to={`/users/${item && item.author_login}`}
className="show-user-link color-grey-8 ml5"
>
{item && item.author_name}
</Link>
<span className="ml15 color-grey-8">
{item.pull_request_staus === "open"
? "创建于"
: item.pull_request_staus === "merged"
? "合并于"
: "更新于"}
</span>
<span className="color-grey-8">{item.pr_time}</span>
<span className="ml15">
<Tag>
<Link
to={`projects/${projectsId}/coders?branch=${item.pull_request_head}`} className="maxW200px hide-1 ver-middle"
>
{project_name}:{item.pull_request_head}
</Link>
</Tag>
<span className="mr8 ver-middle">
<i className={"iconfont icon-youjiang color-grey-c font-16"}></i>
</span>
<Tag>
<Link
to={`projects/${projectsId}/coders?branch=${item.pull_request_base}`} className="maxW200px hide-1 ver-middle"
>
{project_name}:{item.pull_request_base}
</Link>
</Tag>
</span>
</span> </span>
)}
</p> </p>
</div> </div>
<ul <ul
@ -84,9 +118,8 @@ class MergeItem extends Component {
onMouseMove={() => this.onMouseMove(item.id)} onMouseMove={() => this.onMouseMove(item.id)}
onMouseOut={() => this.onMouseOut()} onMouseOut={() => this.onMouseOut()}
> >
<li>{item.priority}</li>
<li>{this.set_issue_tags(item.issue_tags)}</li> <li>{this.set_issue_tags(item.issue_tags)}</li>
{/*<li>{item.issue_type || "--"}</li>*/}
<li>{item.version || "--"}</li>
<li> <li>
{item.assign_user_name ? ( {item.assign_user_name ? (
<Link <Link
@ -99,14 +132,19 @@ class MergeItem extends Component {
"--" "--"
)} )}
</li> </li>
<li>{item.version || "--"}</li>
<li> <li>
<div className="flex1 df" style={{justifyContent:"center"}}> <div
className="flex1 df"
style={{ justifyContent: "center" }}
>
{item.journals_count ? ( {item.journals_count ? (
<Link <Link
className="mr5" className="mr5 color-grey-8"
to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`} to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}
> >
<i className="iconfont icon-pinglun1 mr3 font-16"></i> <i className="iconfont icon-huifu1 font-15 mr5 ver-middle"></i>
{item.journals_count} {item.journals_count}
</Link> </Link>
) : ( ) : (

File diff suppressed because it is too large Load Diff

View File

@ -1,431 +1,187 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import { Link } from 'react-router-dom'; import { Input, Select, Button, Spin, Alert } from "antd";
import { Radio, Form, Menu, Dropdown, Input, Select, Table, Spin } from 'antd'; import axios from "axios";
import axios from 'axios'; import "../Order/order.css";
import UploadComponent from '../Upload/Index'; import "./merge.css";
import { getImageUrl } from 'educoder'; import MergeForm from "./merge_form"
import '../Order/order.css'; import MergeFooter from "./merge_footer"
import MDEditor from '../../modules/tpm/challengesnew/tpm-md-editor';
const { Button } = Radio;
const Option = Select.Option; const Option = Select.Option;
const options = [
['bold', 'italic', 'underline'],
[{ header: [1, 2, 3, false] }],
['blockquote', 'code-block'],
['link', 'image'],
['formula']
];
class NewMerge extends Component { class NewMerge extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
data: undefined, data: undefined,
//合并 拉取 branches: undefined,
origin_branches: undefined,
merge: undefined, merge: undefined,
pull: undefined, pull: undefined,
//判断 是否显示创建合并请求的页面
desc: undefined,
iscreatemerge: 'none',
issue_tag_ids: "",
fixed_version_id: "",
assigned_to_id: "",
titledata: undefined,
dataCount: undefined,
limit: 50,
page: 1,
isSpin: false, isSpin: false,
mergedata: undefined, show_message: true,
} default_message: "必须选择不同的分支",
};
} }
componentDidMount = () => { componentDidMount = () => {
this.getmergelist(); this.getmergelist();
this.InitData(); };
}
InitData = () => {
this.props.form.setFieldsValue({
...this.state
});
}
onPanelChange = (time, mode) => {
this.setState({
value: time
});
}
onSelect = (time) => {
this.setState({
value: time,
selectedValue: time,
});
}
getOption = (name, id) => {
if (id === 'branches') {
this.ischeckmerge(name, this.state.pull)
this.setState({
merge: name
})
} else {
if (this.state.iscreatemerge === 'block') {
if (this.state.merge === name) {
} else {
const { page, limit } = this.state;
this.getCommitList(name, page, limit);
}
} else {
}
this.ischeckmerge(this.state.merge, name)
this.setState({
pull: name
})
}
}
ismerge = () => {
this.setState({
iscreatemerge: 'block'
})
const { page, limit } = this.state;
this.getCommitList(this.state.pull, page, limit);
}
//获取新建分枝数据 //获取新建分枝数据
getmergelist = () => { getmergelist = () => {
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const url = `/projects/${projectsId}/pull_requests/new.json`; const url = `/projects/${projectsId}/pull_requests/new.json`;
axios.get(url).then((result) => { axios
.get(url)
.then((result) => {
if (result) { if (result) {
this.setState({ this.setState({
data: result.data, data: result.data,
merge: result.data.branches[0], branches: result.data.branches,
pull: result.data.branches[0], origin_branches: result.data.branches,
}) });
} }
}).catch((error) => { })
.catch((error) => {
console.log(error); console.log(error);
}) });
} };
renderMenu = (array, id) => { selectBrach = (type, value) => {
return ( this.state[type] = value;
<Menu> this.ischeckmerge();
{ };
array && array.length > 0 && array.map((item, key) => {
return (
<Menu.Item key={item} onClick={() => this.getOption(item, id)}>{item}</Menu.Item>
)
})
}
</Menu>
)
}
renderSelect = (list) => {
if (list && list.length > 0) {
return (
list.map((item, key) => {
return (
<Option key={key + 1} value={item.id + ''}>{item.name}</Option>
)
})
)
}
}
//创建合并请求
submit = () => {
this.setState({
isSpin: true
})
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
const { projectsId } = this.props.match.params;
const url = `/projects/${projectsId}/pull_requests.json`;
if (values.issue_tag_ids.length > 0) {
values.issue_tag_ids = [parseInt(values.issue_tag_ids)]
} else {
values.issue_tag_ids = []
}
const { desc } = this.state;
axios.post(url, {
...values,
body: JSON.stringify(desc),
project_id: projectsId,
head: this.state.merge,
base: this.state.pull,
}).then(result => {
if (result) {
this.setState({
isSpin: false
})
this.props.history.push(`/projects/${projectsId}/merge`);
const { getDetail } = this.props;
getDetail && getDetail();
}
}).catch(error => {
this.setState({
isSpin: false
})
console.log(error);
})
} else {
this.setState({
isSpin: false
})
}
})
}
//获取提交列表
getCommitList = (branch, page, limit) => {
const { projectsId } = this.props.match.params;
const url = `/repositories/${projectsId}/commits.json`;
axios.get(url, {
params: {
sha: branch,
page,
limit
}
}).then((result) => {
if (result) {
const array = [];
result.data && result.data.commits.length > 0 && result.data.commits.map((item, key) => {
array.push({
name: item.author && item.author.name,
login: item.author && item.author.login,
image_url: item.author && item.author.image_url,
sha: item.sha,
time_from_now: item.time_from_now,
message: item.message
})
})
this.setState({
titledata: array,
dataCount: result.data.total_count,
isSpin: false
})
}
}).catch((error) => { console.log(error) })
}
//判断2分支是否可以合并 //判断2分支是否可以合并
ischeckmerge = (head, base) => { ischeckmerge = () => {
this.setState({ isSpin: true });
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const { pull, merge } = this.state;
const url = `/projects/${projectsId}/pull_requests/check_can_merge.json`; const url = `/projects/${projectsId}/pull_requests/check_can_merge.json`;
axios.post(url, { axios
.post(url, {
project_id: projectsId, project_id: projectsId,
head: head, head: merge ? merge : "master",
base: base, base: pull ? pull : "master",
})
}).then(result => { .then((result) => {
if (result) { if (result) {
if (result.data.status === 0) {
this.setState({ this.setState({
mergedata: result.data isSpin: false,
}) show_message: false,
});
} else {
this.setState({
isSpin: false,
show_message: true,
default_message: result.data.message,
});
} }
} else {
}).catch(error => { this.setState({
isSpin: false,
show_message: true,
default_message: "出现错误了",
});
}
})
.catch((error) => {
this.setState({ isSpin: false, show_message: true });
console.log(error); console.log(error);
}) });
};
}
onContentChange = (value) => {
this.setState({
desc: value
})
}
render() { render() {
const { getFieldDecorator } = this.props.form; const {
const { projectsId } = this.props.match.params; data,
const { current_user } = this.props; branches,
const { issue_tag_ids, fixed_version_id, assigned_to_id, data, titledata, desc, isSpin } = this.state; origin_branches,
pull,
merge,
isSpin,
show_message,
default_message,
} = this.state;
const renderBrances = (list) => {
const columns = [{ if (list && list.length > 0) {
title: "作者", return list.map((item, key) => {
dataIndex: 'name',
width: "10%",
render: (text, item) => (
<span className="f-wrap-alignCenter">
<Link to={`/users/${item.login}`} className="show-user-link">
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius" />
<label className="hide-1" style={{ maxWidth: "75px", 'vertical-align': 'middle' }}>{text}</label>
</Link>
</span>
),
}, {
title: "SHA",
dataIndex: 'sha',
render: (text) => (
<span className="commitKey">{text}</span>
)
}, {
title: "备注",
dataIndex: 'message',
render: (text) => (
<span>{text}</span>
)
}, {
title: "提交时间",
className: "edu-txt-right",
dataIndex: 'time_from_now',
render: (text) => (
<span>{text}</span>
)
}]
const title = () => {
return ( return (
<div className="f-wrap-between" style={{ alignItems: "center" }}> <Option key={key + 1} value={item}>
<span className="font-16">提交列表</span> {item}
</div> </Option>
) );
});
} }
};
const withHtml = (html) => {
return <div dangerouslySetInnerHTML={{ __html: html }}></div>;
};
const pull = () => {
if (this.state.mergedata && this.state.mergedata.status === -2) {
return ( return (
<div > <div >
在这些分支直接合并请求已经存在<Link to={`/projects/${projectsId}/merge/${this.state.mergedata && this.state.mergedata.pull_request_id}/Messagecount`} style={{ color: 'blue' }}>{this.state.mergedata && this.state.mergedata.pull_request_name}</Link>
</div>
)
} else {
return (
<div>
{this.state.mergedata && this.state.mergedata.status === 0 ? <Button className="topWrapper_btn" onClick={() => this.ismerge()}>创建合并请求</Button> : ""}
</div>
)
}
}
return (
<div className="main"> <div className="main">
<h1 className="mb10">创建合并请求</h1>
<h5 className="mb10">选择合并的目标分支和源分支</h5>
<div style={{ display: 'flex' }}>
<div className="mergediv">
<div>
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(this.state.data && this.state.data.branches, 'branches')} trigger={['click']} placement="bottomCenter">
<Button>合并到{this.state.merge}</Button>
</Dropdown>
...
<Dropdown overlay={this.renderMenu(this.state.data && this.state.data.branches, 'pull')} trigger={['click']} placement="bottomCenter">
<Button>拉取从{this.state.pull}</Button>
</Dropdown>
</div>
</div>
</div>
<div style={{ display: this.state.iscreatemerge === 'none' ? 'block' : 'none' }}>
<div className="mergediv" style={{ marginTop: 15 }} >
{pull()}
</div>
</div>
<div style={{ display: this.state.iscreatemerge === 'none' ? 'none' : 'block' }}>
<Form>
<div className="f-wrap-between mt20" style={{ alignItems: "flex-start" }}>
<div className="list-right df" style={{ padding: "0px", paddingTop: "10px" }}>
<Link to={`/users/${current_user && current_user.login}`} className="show-user-link">
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt="" />
</Link>
<div className="new_context">
<Form.Item>
{getFieldDecorator('title', {
rules: [{
required: true, message: '请填写请求标题'
}],
})(
<Input placeholder="标题" />
)}
</Form.Item>
<MDEditor placeholder={'请输入合并请求的描述...'} height={350}
mdID={'merge-new-description'} initValue={desc} onChange={this.onContentChange} ></MDEditor>
<UploadComponent load={this.UploadFunc} isComplete={true} ></UploadComponent>
<p className="clearfix mt15">
<Spin spinning={isSpin}> <Spin spinning={isSpin}>
<a className="topWrapper_btn fr" type="submit" onClick={this.submit}>创建合并请求</a> <div className="merge-header width100 inline-block">
</Spin> <div className="width45 pull-left">
</p> <div className="color-grey-3 mb10 fwb">源分支:</div>
</div> <Input.Group compact>
</div> <Button className="merge-header-button maxW50 hide-1 task-hide">
<div className="list-left" style={{ paddingRight: "0px", paddingLeft: "15px", paddingTop: "10px" }}> {data && data.project_author} / {data && data.project_name}
<div className="list-l-panel"> </Button>
<Form.Item <Select
label="标签" defaultValue={pull ? pull : "master"}
onSelect={(e) => this.selectBrach("pull", e)}
showSearch
className="minW50"
> >
{getFieldDecorator('issue_tag_ids', { {renderBrances(branches)}
rules: [],
})(
<Select value={issue_tag_ids}>
<Option value="">{data && data.issue_tags.length > 0 ? '未选择标签' : '请在仓库设置里添加标签'}</Option>
{this.renderSelect(data && data.issue_tags)}
</Select> </Select>
)} </Input.Group>
</Form.Item> </div>
<Form.Item <div className="width10 pull-left text-center mt25">
label="里程碑" <i className={"iconfont icon-youjiang color-grey-c font-32"}></i>
</div>
<div className="width45 pull-left">
<div>
<div className="color-grey-3 mb10 fwb">目标分支:</div>
<Input.Group compact>
<Button className="merge-header-button maxW50 hide-1 task-hide">
{data && data.project_author} / {data && data.project_name}
</Button>
<Select
defaultValue={merge ? merge : "master"}
onSelect={(e) => this.selectBrach("merge", e)}
showSearch
className="minW50"
> >
{getFieldDecorator('fixed_version_id', { {renderBrances(branches)}
rules: [],
})(
<Select value={fixed_version_id}>
<Option value="">{data && data.issue_versions.length > 0 ? '未选择里程碑' : '请添加里程碑'}</Option>
{this.renderSelect(data && data.issue_versions)}
</Select> </Select>
)} </Input.Group>
</Form.Item>
<Form.Item
label="指派成员"
>
{getFieldDecorator('assigned_to_id', {
})(
<Select value={assigned_to_id}>
<Option value="">未指派成员</Option>
{this.renderSelect(data && data.members)}
</Select>
)}
</Form.Item>
</div> </div>
</div> </div>
</div> </div>
</Form> {show_message ? (
</div> <div className="mb50 mt50">
<div style={{ display: this.state.iscreatemerge === 'none' ? 'none' : 'block' }}> <Alert
<Table description={withHtml(default_message)}
className="mt20 wrap-commit-table" type="error"
columns={columns}
dataSource={titledata}
showHeader={false}
size="small"
pagination={false}
title={() => title()}
/> />
</div> </div>
</div>
) )
:
<MergeForm {...this.props} merge_type="new" data={data} merge={merge?merge:"master"} pull={pull?pull:"master"}></MergeForm>
}
</Spin>
</div>
<div className=" main">
<MergeFooter footer_type="new" {...this.props}></MergeFooter>
</div>
</div>
);
} }
} }
const WrappedNewMerge = Form.create({ name: 'NewMergeFrom' })(NewMerge);
export default WrappedNewMerge; export default NewMerge;

View File

@ -1,275 +1,116 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import { Link } from 'react-router-dom'; import { Input, Select, Button, Spin, Empty } from "antd";
import axios from 'axios'; import axios from "axios";
import UploadComponent from '../Upload/Index'; import "../Order/order.css";
import { getImageUrl } from 'educoder'; import "./merge.css";
import { Modal, Form, Input, Select, Spin } from 'antd' import MergeForm from "./merge_form";
import MDEditor from '../../modules/tpm/challengesnew/tpm-md-editor'; import MergeFooter from "./merge_footer";
import Attachments from '../Upload/attachment'
const Option = Select.Option; const Option = Select.Option;
class UpdateMerge extends Component { class UpdateMerge extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
data: undefined, data: undefined,
isShow: false, merge: undefined,
imgsrc: '', pull: undefined,
journalsdata: undefined, isSpin: false,
//图片区域是否显示 none 隐藏 block 显示 };
display: 'none',
titledisplay: 'none',
subject: '',
branch_name: "",
issue_tag_ids: "",
fixed_version_id: "",
tracker_id: 0,
issue_type: 0,
status_id: 0,
assigned_to_id: "",
priority_id: 0,
done_ratio: 0,
textcount: "",
fileList: undefined,
get_attachments: undefined,
desc: undefined,
isSpin: false
}
} }
componentDidMount = () => { componentDidMount = () => {
this.getDetail(); this.getmergelist();
} };
getDetail = () => { //获取新建分枝数据
getmergelist = () => {
this.setState({ isSpin: true });
const { projectsId, mergeId } = this.props.match.params; const { projectsId, mergeId } = this.props.match.params;
const url = `/projects/${projectsId}/pull_requests/${mergeId}/edit.json`; const url = `/projects/${projectsId}/pull_requests/${mergeId}/edit.json`;
axios.get(url).then((result) => { axios
.get(url)
.then((result) => {
if (result) { if (result) {
this.setState({ this.setState({
isSpin: false,
data: result.data, data: result.data,
subject: result.data.issue.subject, pull: result.data.head,
issue_chosen: result.data.issue.issue_chosen, merge: result.data.base,
branches: result.data.issue.branches, });
tracker_id: result.data.issue.tracker_id, } else {
issue_type: result.data.issue.issue_type, this.setState({ isSpin: false });
status_id: result.data.issue.status_id,
priority_id: result.data.issue.priority_id,
done_ratio: result.data.issue.done_ratio,
textcount: result.data.issue.description,
branch_name: result.data.issue.branch_name,
get_attachments: result.data.issue.attachments,
fileList: undefined,
issue_tag_ids: result.data.issue.issue_tags && result.data.issue.issue_tags[0].id,
fixed_version_id: result.data.issue.fixed_version_id,
assigned_to_id: result.data.issue.assigned_to_id
})
// this.getjournalslist();
} }
}).catch((error) => { })
.catch((error) => {
this.setState({ isSpin: false });
console.log(error); console.log(error);
})
}
handleok = () => {
this.setState({
isShow: false
}); });
}; };
handleCancel = () => {
this.setState({
isShow: false
});
}
imgshow = () => {
this.setState({
isShow: true
});
};
onContentChange = (value) => {
this.setState({
textcount: value
})
}
changmodelname = (e) => {
this.setState({
subject: e.target.value
})
}
stringJson = (value) => {
let _value = null;
try {
_value = JSON.parse(value);
} catch (e) {
_value = value;
}
return _value
}
renderSelect = (list) => {
if (list && list.length > 0) {
return (
list.map((item, key) => {
return (
<Option key={key + 1} value={item.id}>{item.name}</Option>
)
})
)
}
}
// 获取上传后的文件id数组
UploadFunc = (fileList) => {
this.setState({
fileList
})
}
handleSubmit = () => {
const { fileList } = this.state;
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
const { projectsId, mergeId } = this.props.match.params;
const { data, textcount } = this.state;
const url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
if (values.issue_tag_ids === '') {
values.issue_tag_ids = []
}
if (values.assigned_to_id === 0) {
values.assigned_to_id = ""
}
axios.put(url, {
project_id: projectsId,
id: data.issue.id,
attachment_ids: fileList,
body: textcount,
...values
}).then(result => {
if (result) {
this.props.history.push(`/projects/${projectsId}/merge`);
this.setState({
textcount: ''
})
}
}).catch(error => {
console.log(error);
})
}
})
}
render() { render() {
const { projectsId, mergeId } = this.props.match.params; const { data, isSpin, pull, merge } = this.state;
const { getFieldDecorator } = this.props.form;
const { current_user } = this.props;
const { issue_tag_ids, fixed_version_id, assigned_to_id, issue_chosen, subject, textcount, get_attachments, isSpin } = this.state;
return ( return (
<div className="main">
<div> <div>
<Form> <div className="main">
<div className="f-wrap-between mt20" style={{ alignItems: "flex-start" }}>
<div className="list-right df" >
<Link to={`/users/${current_user && current_user.login}`} className="show-user-link">
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt="" />
</Link>
<div className="new_context">
<Form.Item>
{getFieldDecorator('title', {
rules: [{
required: true, message: '请填写任务标题'
}],
initialValue: subject
})(
<Input placeholder="标题" onChange={this.changmodelname} />
)}
</Form.Item>
<MDEditor placeholder={'请输入合并请求的描述...'} height={350}
mdID={`orderdetail-add-description`} initValue={textcount} onChange={this.onContentChange} ></MDEditor>
<UploadComponent load={this.UploadFunc} showNotification={this.props.showNotification} isComplete={true} ></UploadComponent>
{
get_attachments ?
<Attachments attachments={get_attachments} showNotification={this.props.showNotification} canDelete={true} />
:
""
}
<p className="clearfix mt15 text-right">
<Spin spinning={isSpin}> <Spin spinning={isSpin}>
<a className="topWrapper_btn fr" type="submit" style={{ marginLeft: 5 }} onClick={this.handleSubmit}>保存</a> {data ? (
<Link to={`/projects/${projectsId}/merge/${mergeId}/Messagecount`} className="a_btn cancel_btn fr">取消</Link> <div>
<div className="merge-header width100 inline-block">
<div className="width45 pull-left">
<div className="color-grey-3 mb10 fwb">源分支:</div>
<Input.Group compact>
<Button className="merge-header-button maxW50 hide-1 task-hide">
{data && data.project_author} /{" "}
{data && data.project_name}
</Button>
<Select
defaultValue={pull ? pull : "master"}
className="minW50"
disabled
></Select>
</Input.Group>
</div>
<div className="width10 pull-left text-center mt25">
<i
className={"iconfont icon-youjiang color-grey-c font-32"}
></i>
</div>
<div className="width45 pull-left">
<div>
<div className="color-grey-3 mb10 fwb">目标分支:</div>
<Input.Group compact>
<Button className="merge-header-button maxW50 hide-1 task-hide">
{data && data.project_author} /{" "}
{data && data.project_name}
</Button>
<Select
defaultValue={merge ? merge : "master"}
className="minW50"
disabled
></Select>
</Input.Group>
</div>
</div>
</div>
<MergeForm
{...this.props}
merge_type="edit"
data={data}
merge={merge}
pull={pull}
></MergeForm>
</div>
) : (
""
)}
</Spin> </Spin>
</p> </div>
<div className=" main">
<MergeFooter footer_type="new" {...this.props}></MergeFooter>
</div> </div>
</div> </div>
<div className="list-left" style={{ paddingRight: "0px", paddingLeft: "15px", paddingTop: "10px" }}> );
<div className="list-l-panel">
<Form.Item
label="标签"
>
{getFieldDecorator('issue_tag_ids', {
initialValue: issue_tag_ids ? [issue_tag_ids] : '',
rules: [],
})(
<Select>
<Option value={''}>{issue_chosen && issue_chosen.issue_tag.length > 0 ? '未选择标签' : '请在仓库设置里添加标签'}</Option>
{this.renderSelect(issue_chosen && issue_chosen.issue_tag)}
</Select>
)}
</Form.Item>
<Form.Item
label="里程碑"
>
{getFieldDecorator('fixed_version_id', {
initialValue: fixed_version_id ? fixed_version_id : "",
rules: [],
})(
<Select>
<Option value={''}>{issue_chosen && issue_chosen.issue_version.length > 0 ? '未选择里程碑' : '请添加里程碑'}</Option>
{this.renderSelect(issue_chosen && issue_chosen.issue_version)}
</Select>
)}
</Form.Item>
<Form.Item
label="指派成员"
>
{getFieldDecorator('assigned_to_id', {
initialValue: assigned_to_id ? assigned_to_id : "",
})(
<Select>
<Option value={''}>未指派成员</Option>
{this.renderSelect(issue_chosen && issue_chosen.assign_user)}
</Select>
)}
</Form.Item>
</div>
</div>
</div>
</Form>
</div>
<Modal
onCancel={this.handleCancel}
visible={this.state.isShow}
width="400px"
footer={
[]
}
bodyStyle={{ textAlign: 'center' }}
>
<img class="list_img" src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt="" />
</Modal>
</div>
)
} }
} }
const UpdateMergeForm = Form.create({ name: 'UpdateMergeForm' })(UpdateMerge); export default UpdateMerge;
export default UpdateMergeForm;

View File

@ -38,3 +38,6 @@
form .ant-cascader-picker, form .ant-select { form .ant-cascader-picker, form .ant-select {
width: 100%; width: 100%;
} }
.merge-header-button{
background:rgba(241,248,255,1);
}

View File

@ -1,12 +1,12 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { Input, Dropdown, Menu, Icon, Pagination, Spin } from 'antd'; import { Input, Dropdown, Menu, Icon, Pagination, Spin } from "antd";
import './merge.css'; import "./merge.css";
import '../Order/order.css'; import "../Order/order.css";
import NoneData from '../Nodata'; import "../Order/index.scss";
import OrderItem from './MergeItem'; import NoneData from "./no_data";
import OrderItem from "./MergeItem";
import axios from "axios";
import axios from 'axios';
const Search = Input.Search; const Search = Input.Search;
/** /**
@ -37,68 +37,75 @@ class merge extends Component {
// page: 1, // page: 1,
search_count: undefined, search_count: undefined,
issue_type: undefined, issue_type: undefined,
status_type: '1', status_type: undefined,
//设置选择高亮 //设置选择高亮
openselect: 1, openselect: 1,
closeselect: undefined, closeselect: undefined,
issue_tag_ids: '标签', issue_tag_ids: "标签",
fixed_version_ids: '里程碑', fixed_version_ids: "里程碑",
assigned_to_ids: '指派人', assigned_to_ids: "审查人员",
paix: '排序', paix: "排序",
priority_ids: "优先级",
select_params: { select_params: {
status_type: "1", //开启中和关闭中,默认为开启中的 status_type: undefined, //开启中和关闭中,默认为开启中的
assigned_to_id: undefined, // 指派人 assigned_to_id: undefined, // 指派人
fixed_version_id: undefined, fixed_version_id: undefined,
priority_id: undefined,
order_name: undefined, order_name: undefined,
order_type: undefined, order_type: undefined,
search: undefined, search: undefined,
page: 1, page: 1,
limit: 15, limit: 15,
}, },
};
}
} }
componentDidMount = () => { componentDidMount = () => {
this.getSelectList(); this.getSelectList();
this.getIssueList(); this.getIssueList();
} };
getSelectList = () => { getSelectList = () => {
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const url = `/projects/${projectsId}/issues/index_chosen.json`; const url = `/projects/${projectsId}/issues/index_chosen.json`;
axios.get(url).then((result) => { axios
.get(url)
.then((result) => {
if (result) { if (result) {
this.setState({ this.setState({
issue_chosen: result.data.issue_chosen issue_chosen: result.data.issue_chosen,
}) });
} }
}).catch((error) => { })
.catch((error) => {
console.log(error); console.log(error);
}) });
} };
// 获取列表数据 // 获取列表数据
getIssueList = () => { getIssueList = () => {
const { select_params } = this.state; const { select_params } = this.state;
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const url = `/projects/${projectsId}/pull_requests.json`; const url = `/projects/${projectsId}/pull_requests.json`;
axios.get(url, { axios
.get(url, {
params: select_params, params: select_params,
}).then((result) => { })
.then((result) => {
if (result) { if (result) {
this.setState({ this.setState({
data: result.data, data: result.data,
issues: result.data.issues, issues: result.data.issues,
search_count: result.data.search_count, search_count: result.data.search_count,
isSpin: false isSpin: false,
}) });
} }
}).catch((error) => { })
.catch((error) => {
console.log(error); console.log(error);
}) });
} };
getMenu = (e, id, name) => { getMenu = (e, id, name) => {
this.setState({ this.setState({
@ -145,22 +152,29 @@ class merge extends Component {
this.state.select_params.page = 1; this.state.select_params.page = 1;
this.state[`${id}s`] = name; this.state[`${id}s`] = name;
this.getIssueList(); this.getIssueList();
} };
renderMenu = (array, name, id) => { renderMenu = (array, name, id) => {
return ( return (
<Menu> <Menu>
<Menu.Item key={"all"} onClick={(e) => this.getOption(e, id, name)}>{name}</Menu.Item> <Menu.Item key={"all"} onClick={(e) => this.getOption(e, id, name)}>
{ {name}
array && array.length > 0 && array.map((item, key) => { </Menu.Item>
{array &&
array.length > 0 &&
array.map((item, key) => {
return ( return (
<Menu.Item key={item.id} onClick={(e) => this.getOption(e, id, item.name)}>{item.name}</Menu.Item> <Menu.Item
) key={item.id}
}) onClick={(e) => this.getOption(e, id, item.name)}
} >
{item.name}
</Menu.Item>
);
})}
</Menu> </Menu>
) );
} };
// 翻页 // 翻页
ChangePage = (page) => { ChangePage = (page) => {
@ -169,7 +183,7 @@ class merge extends Component {
}); });
this.state.select_params.page = page; this.state.select_params.page = page;
this.getIssueList(); this.getIssueList();
} };
// 搜索 // 搜索
searchFunc = (value) => { searchFunc = (value) => {
@ -180,47 +194,19 @@ class merge extends Component {
this.state.select_params.search = value; this.state.select_params.search = value;
this.state.select_params.page = 1; this.state.select_params.page = 1;
this.getIssueList(); this.getIssueList();
} };
openorder = (type) => { openorder = (type) => {
// if (type) {
// if (type === 1) {
// this.setState({
// status_type: '1',
// closeselect: undefined,
// openselect: '123',
// issue_tag_ids: '标签',
// fixed_version_ids: '里程碑',
// assigned_to_ids: '指派人',
// paix: '排序'
// })
// this.getIssueList("", "", "", "", "", 1, "");
// } else {
// this.setState({
// status_type: '2',
// openselect: undefined,
// closeselect: '123',
// issue_tag_ids: '标签',
// fixed_version_ids: '里程碑',
// assigned_to_ids: '指派人',
// paix: '排序'
// })
// this.getIssueList("", "", "", "", "", 2, "");
// }
// }
this.setState({ this.setState({
isSpin: true, isSpin: true,
}); });
if (type) {
this.setState({ this.setState({
status_type: type, status_type: type,
issue_tag_ids: '标签', issue_tag_ids: "标签",
fixed_version_ids: '里程碑', fixed_version_ids: "里程碑",
assigned_to_ids: '指派人', assigned_to_ids: "审查人员",
paix: '排序' paix: "排序",
priority_ids: "优先级",
}); });
this.state.select_params = { this.state.select_params = {
status_type: type, status_type: type,
@ -229,20 +215,30 @@ class merge extends Component {
limit: 15, limit: 15,
}; };
this.getIssueList(); this.getIssueList();
}} };
islogin() { islogin() {
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
if (this.props.checkIfLogin() === false) { if (this.props.checkIfLogin() === false) {
this.props.showLoginDialog() this.props.showLoginDialog();
return return;
} else { } else {
this.props.history.push(`/projects/${projectsId}/merge/new`); this.props.history.push(`/projects/${projectsId}/merge/new`);
} }
} }
render() { render() {
const { issue_chosen, issues, limit, page, search_count, data, isSpin, status_type, select_params } = this.state; const { projectsId } = this.props.match.params;
const {
issue_chosen,
issues,
limit,
page,
search_count,
data,
isSpin,
status_type,
select_params,
} = this.state;
const menu = ( const menu = (
<Menu onClick={(e) => this.getMenu(e)}> <Menu onClick={(e) => this.getMenu(e)}>
<Menu.Item key={"created_on-desc"} value="desc"> <Menu.Item key={"created_on-desc"} value="desc">
@ -262,17 +258,175 @@ class merge extends Component {
const Paginations = ( const Paginations = (
<React.Fragment> <React.Fragment>
{ {search_count > limit ? (
search_count > limit ?
<div className="mt30 mb50 edu-txt-center"> <div className="mt30 mb50 edu-txt-center">
<Pagination simple defaultCurrent={page} total={search_count} pageSize={limit} onChange={this.ChangePage}></Pagination> <Pagination
</div> : "" simple
} defaultCurrent={page}
total={search_count}
pageSize={limit}
onChange={this.ChangePage}
></Pagination>
</div>
) : (
""
)}
</React.Fragment> </React.Fragment>
) );
return ( return (
<div className="main"> <div className="main">
<div className="topWrapper" style={{ borderBottom: "none" }}> <div className="topWrapper">
<div className="target-detail-search">
<Search
placeholder="输入关键字搜索合并请求"
enterButton
onSearch={this.searchFunc}
style={{ width: 300 }}
/>
</div>
<a className="topWrapper_btn ml10" onClick={() => this.islogin()}>
+&nbsp;新建合并请求
</a>
</div>
<div className="f-wrap-between screenWrap">
<div className="df">
<ul className="searchBanner">
<li
className={!status_type ? "active" : ""}
onClick={() => this.openorder(undefined)}
>
<label>搜索结果</label>
<span>{data && data.search_count}</span>
</li>
<li
className={status_type === "1" ? "active" : ""}
onClick={() => this.openorder("1")}
>
<label>开启的</label>
<span>{data && data.open_count}</span>
</li>
<li
className={status_type === "11" ? "active" : ""}
onClick={() => this.openorder("11")}
>
<label>已合并</label>
<span>{data && data.merged_issues_size}</span>
</li>
<li
className={status_type === "2" ? "active" : ""}
onClick={() => this.openorder("2")}
>
<label>已关闭</label>
<span>{data && data.close_count}</span>
</li>
</ul>
</div>
<ul className="topWrapper_select">
<li>
<Dropdown
className="topWrapperSelect"
overlay={this.renderMenu(
issue_chosen && issue_chosen.priority,
"优先级",
"priority_id"
)}
trigger={["click"]}
placement="bottomCenter"
>
<span>
{this.state.priority_ids}
<Icon type="caret-down" className="ml5" />
</span>
</Dropdown>
</li>
<li>
<Dropdown
className="topWrapperSelect"
overlay={this.renderMenu(
issue_chosen && issue_chosen.issue_tag,
"标签",
"issue_tag_id"
)}
trigger={["click"]}
placement="bottomCenter"
>
<span>
{this.state.issue_tag_ids}
<Icon type="caret-down" className="ml5" />
</span>
</Dropdown>
</li>
<li>
<Dropdown
className="topWrapperSelect"
overlay={this.renderMenu(
issue_chosen && issue_chosen.assign_user,
"审查人员",
"assigned_to_id"
)}
trigger={["click"]}
placement="bottomCenter"
>
<span>
{this.state.assigned_to_ids}
<Icon type="caret-down" className="ml5" />
</span>
</Dropdown>
</li>
<li>
<Dropdown
className="topWrapperSelect"
overlay={this.renderMenu(
issue_chosen && issue_chosen.issue_version,
"里程碑",
"fixed_version_id"
)}
trigger={["click"]}
placement="bottomCenter"
>
<span>
{this.state.fixed_version_ids}
<Icon type="caret-down" className="ml5" />
</span>
</Dropdown>
</li>
<li>
<Dropdown
className="topWrapperSelect"
overlay={menu}
trigger={["click"]}
placement="bottomCenter"
>
<span>
{this.state.paix}
<Icon type="caret-down" className="ml5" />
</span>
</Dropdown>
</li>
</ul>
</div>
{data && data.search_count && data.search_count > 0 ? (
<div>
<Spin spinning={isSpin}>
<OrderItem
issues={issues}
search_count={search_count}
page={select_params.page}
limit={select_params.limit}
project_name={data.project_name}
{...this.props}
{...this.state}
></OrderItem>
{Paginations}
</Spin>
</div>
) : (
<NoneData _html="暂时还没有相关数据哦!" projectsId={projectsId} />
)}
{/* <div className="topWrapper" style={{ borderBottom: "none" }}>
<p className="topWrapper_type_infos"> <p className="topWrapper_type_infos">
<li className={status_type === "1" ? "active" : ""} onClick={() => this.openorder("1")}>{data && data.open_count ? data.open_count : 0}个开启中</li> <li className={status_type === "1" ? "active" : ""} onClick={() => this.openorder("1")}>{data && data.open_count ? data.open_count : 0}个开启中</li>
<li className={status_type === "2" ? "active" : ""} onClick={() => this.openorder("2")}>{data && data.close_count ? data.close_count : 0}个已关闭</li> <li className={status_type === "2" ? "active" : ""} onClick={() => this.openorder("2")}>{data && data.close_count ? data.close_count : 0}个已关闭</li>
@ -326,11 +480,9 @@ class merge extends Component {
</div> </div>
: :
<NoneData _html="暂时还没有相关数据哦!" /> <NoneData _html="暂时还没有相关数据哦!" />
} } */}
</div> </div>
) );
} }
} }
export default merge; export default merge;

View File

@ -0,0 +1,47 @@
import React, { Component } from "react";
import { Tabs, Empty } from "antd";
import "../Order/order.css";
import "./merge.css";
import CodesCommit from "../Main/CoderRootCommit";
import Comments from "../comments/comments";
const { TabPane } = Tabs;
class MergeFooter extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { footer_type, order_id } = this.props;
return (
<div>
<Tabs
defaultActiveKey={footer_type === "show" ? "1" : "2"}
className="custom-commit-tabs"
>
{
footer_type === "show" &&
<TabPane tab={<span className="ml-3 font-16">评论</span>} key="1">
<Comments
order_id={order_id}
showNotification={this.props.showNotification}
only_show_content={true}
{...this.props}
/>
</TabPane>
}
<TabPane tab={<span className="ml-3 font-16">提交</span>} key="2">
<CodesCommit {...this.props} main_class="pd10"></CodesCommit>
</TabPane>
<TabPane tab={<span className="ml-3 font-16">文件</span>} key="3">
<Empty />
</TabPane>
</Tabs>
</div>
);
}
}
export default MergeFooter;

View File

@ -0,0 +1,404 @@
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Button, Form, Menu, Input, Select, Tag, Checkbox } from "antd";
import axios from "axios";
import "../Order/order.css";
import "./merge.css";
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
const Option = Select.Option;
class MergeForm extends Component {
constructor(props) {
super(props);
this.state = {
desc: undefined,
issue_tag_ids: undefined,
fixed_version_id: undefined,
assigned_to_id: undefined,
titledata: undefined,
isSpin: false,
mergedata: undefined,
priority_id: undefined,
title: undefined,
};
}
componentDidMount = () => {
this.set_defatul();
};
set_defatul = () => {
const { data, merge_type } = this.props;
if (data && merge_type === "edit") {
this.setState({
desc: data.body,
issue_tag_ids: data.issue_tag_ids[0],
fixed_version_id: String(data.fixed_version_id),
assigned_to_id: String(data.assigned_to_id),
priority_id: String(data.priority_id),
title: data.title,
});
}
this.InitData();
};
InitData = () => {
setTimeout(() => {
this.props.form.setFieldsValue({
...this.state,
});
}, 100);
};
onPanelChange = (time, mode) => {
this.setState({
value: time,
});
};
onSelect = (time) => {
this.setState({
value: time,
selectedValue: time,
});
};
renderMenu = (array, id) => {
return (
<Menu>
{array &&
array.length > 0 &&
array.map((item, key) => {
return (
<Menu.Item key={item} onClick={() => this.getOption(item, id)}>
{item}
</Menu.Item>
);
})}
</Menu>
);
};
renderSelect = (list) => {
if (list && list.length > 0) {
return list.map((item, key) => {
return (
<Option key={key + 1} value={item.id + ""}>
{item.name}
</Option>
);
});
}
};
//创建合并请求
handleSubmit = () => {
this.setState({
isSpin: true,
});
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
const { projectsId, mergeId } = this.props.match.params;
const { merge, pull, merge_type } = this.props;
if (values.issue_tag_ids && values.issue_tag_ids.length > 0) {
values.issue_tag_ids = [parseInt(values.issue_tag_ids)];
} else {
values.issue_tag_ids = [];
}
const { desc } = this.state;
if (merge_type === "new") {
let url = `/projects/${projectsId}/pull_requests.json`;
axios
.post(url, {
...values,
body: desc,
head: pull,
base: merge,
})
.then((result) => {
if (result) {
this.setState({
isSpin: false,
});
this.props.history.push(`/projects/${projectsId}/merge`);
// const { getDetail } = this.props;
// getDetail && getDetail();
} else {
this.setState({
isSpin: false,
});
}
})
.catch((error) => {
this.setState({
isSpin: false,
});
console.log(error);
});
} else {
let url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
axios
.put(url, {
...values,
body: desc,
head: pull,
base: head,
})
.then((result) => {
if (result) {
this.setState({
isSpin: false,
});
this.props.history.push(`/projects/${projectsId}/merge/${mergeId}/Messagecount`);
} else {
this.setState({
isSpin: false,
});
}
})
.catch((error) => {
this.setState({
isSpin: false,
});
console.log(error);
});
}
} else {
this.setState({
isSpin: false,
});
}
});
};
onContentChange = (value) => {
this.setState({
desc: value,
});
};
render() {
const { merge_type, data } = this.props;
const { getFieldDecorator } = this.props.form;
const { projectsId, mergeId } = this.props.match.params;
const {
issue_tag_ids,
fixed_version_id,
assigned_to_id,
priority_id,
desc,
isSpin,
title,
} = this.state;
return (
<div>
<div className="mt20 mb20">
<span className="font-16 fwb mr10 ver-middle">
{merge_type === "new" ? "新建" : "编辑"}合并请求:
</span>
<Tag color="#28BD6C" className="ver-middle">
可合并的
</Tag>
</div>
<Form>
<div className="width100 inline-block">
<div className="width70 pull-left">
<Form.Item>
{getFieldDecorator("title", {
rules: [
{
required: true,
message: "请填写请求标题",
},
],
initialValue: title,
})(<Input placeholder="标题" />)}
</Form.Item>
<MDEditor
placeholder={"请输入合并请求的描述..."}
height={350}
mdID={"merge-new-description"}
initValue={desc}
onChange={this.onContentChange}
></MDEditor>
<p className="clearfix mt20">
<Button
type="primary"
loading={isSpin}
onClick={this.handleSubmit}
>
<span className="plr10">
{merge_type === "new" ? "创建" : "提交"}
</span>
</Button>
<Button
type="default"
className="ml30"
href={
merge_type === "new"
? `/projects/${projectsId}/merge`
: `/projects/${projectsId}/merge/${mergeId}/detail`
}
>
<span className="plr10">取消</span>
</Button>
</p>
</div>
<div className="width30 pull-left">
<div className="pl30">
<Form.Item>
{getFieldDecorator("assigned_to_id", {
initialValue: assigned_to_id,
})(
<Select placeholder="审查人员" showSearch>
{this.renderSelect(data && data.members)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("fixed_version_id", {
initialValue: fixed_version_id,
})(
<Select
placeholder={
data && data.issue_versions.length > 0
? "未选择里程碑"
: "请添加里程碑"
}
showSearch
>
{this.renderSelect(data && data.issue_versions)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("issue_tag_ids", {
initialValue: issue_tag_ids,
})(
<Select
placeholder={
data && data.issue_tags.length > 0
? "未选择标签"
: "请在仓库设置里添加标签"
}
showSearch
>
{this.renderSelect(data && data.issue_tags)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("priority_id", {
initialValue: priority_id,
})(
<Select placeholder="优先级" showSearch>
{this.renderSelect(data && data.issue_priories)}
</Select>
)}
</Form.Item>
<Form.Item name="checkbox-group" label="其他">
<Checkbox.Group>
<div>
<Checkbox value="A">必须审查代码</Checkbox>
</div>
<div>
<Checkbox value="B">合并后删除提交分支</Checkbox>
</div>
<div>
<Checkbox value="C">合并后关闭提到的任务</Checkbox>
</div>
</Checkbox.Group>
</Form.Item>
</div>
</div>
</div>
</Form>
</div>
// <div className="main">
// <h1 className="mb10">创建合并请求</h1>
// <div style={{ display: this.state.iscreatemerge === 'none' ? 'block' : 'none' }}>
// <div className="mergediv" style={{ marginTop: 15 }} >
// {pull()}
// </div>
// </div>
// <div style={{ display: this.state.iscreatemerge === 'none' ? 'none' : 'block' }}>
// <Form>
// <div className="f-wrap-between mt20" style={{ alignItems: "flex-start" }}>
// <div className="list-right df" style={{ padding: "0px", paddingTop: "10px" }}>
// <Link to={`/users/${current_user && current_user.login}`} className="show-user-link">
// <img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt="" />
// </Link>
// <div className="new_context">
// <Form.Item>
// {getFieldDecorator('title', {
// rules: [{
// required: true, message: '请填写请求标题'
// }],
// })(
// <Input placeholder="标题" />
// )}
// </Form.Item>
// <MDEditor placeholder={'请输入合并请求的描述...'} height={350}
// mdID={'merge-new-description'} initValue={desc} onChange={this.onContentChange} ></MDEditor>
// <UploadComponent load={this.UploadFunc} isComplete={true} ></UploadComponent>
// <p className="clearfix mt15">
// <Spin spinning={isSpin}>
// <a className="topWrapper_btn fr" type="submit" onClick={this.submit}>创建合并请求</a>
// </Spin>
// </p>
// </div>
// </div>
// <div className="list-left" style={{ paddingRight: "0px", paddingLeft: "15px", paddingTop: "10px" }}>
// <div className="list-l-panel">
// <Form.Item
// label="标签"
// >
// {getFieldDecorator('issue_tag_ids', {
// rules: [],
// })(
// <Select value={issue_tag_ids}>
// <Option value="">{data && data.issue_tags.length > 0 ? '未选择标签' : '请在仓库设置里添加标签'}</Option>
// {this.renderSelect(data && data.issue_tags)}
// </Select>
// )}
// </Form.Item>
// <Form.Item
// label="里程碑"
// >
// {getFieldDecorator('fixed_version_id', {
// rules: [],
// })(
// <Select value={fixed_version_id}>
// <Option value="">{data && data.issue_versions.length > 0 ? '未选择里程碑' : '请添加里程碑'}</Option>
// {this.renderSelect(data && data.issue_versions)}
// </Select>
// )}
// </Form.Item>
// <Form.Item
// label="指派成员"
// >
// {getFieldDecorator('assigned_to_id', {
// })(
// <Select value={assigned_to_id}>
// <Option value="">未指派成员</Option>
// {this.renderSelect(data && data.members)}
// </Select>
// )}
// </Form.Item>
// </div>
// </div>
// </div>
// </Form>
// </div>
// </div>
);
}
}
const WrappedNewMerge = Form.create({ name: "NewMergeForm" })(MergeForm);
export default WrappedNewMerge;

View File

@ -0,0 +1,22 @@
import React , { Component } from 'react';
import { Link } from "react-router-dom";
class Nodata extends Component{
render(){
const { _html, projectsId } = this.props;
return(
<div className="none_panels">
<div>
<div className="mb15">
<i className="iconfont icon-hebingqingqiu font-80 ver-middle color-grey-8"></i>
</div>
<h3>欢迎使用合并请求</h3>
<div className="color-grey-8">
合并请求可以帮助您与他人协作编写代码在使用之前请先创建一个 <Link className="color-blue" to={`/projects/${projectsId}/merge/new`}>合并请求</Link>
</div>
</div>
</div>
)
}
}
export default Nodata;

View File

@ -225,7 +225,7 @@
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-content: center; align-content: center;
border-bottom: 1px dashed #cecdcd; border-bottom: 1px solid #eee;
padding: 16px 0px 16px 20px; padding: 16px 0px 16px 20px;
} }
.issueNo { .issueNo {
@ -726,3 +726,5 @@ a.issue-type-button.active:hover {
} }
.boder-4{border-radius: 4px;} .boder-4{border-radius: 4px;}
.pbt20{padding: 20px 0;} .pbt20{padding: 20px 0;}
.inline-block{display: inline-block;}
.pd10{padding: 10px;}

View File

@ -15,10 +15,10 @@
.plr-20 { .plr-20 {
padding: 0 20px; padding: 0 20px;
} }
.font-18 { /* .font-18 {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
} } */
.font-12 { .font-12 {
font-size: 12px; font-size: 12px;
} }

View File

@ -283,7 +283,7 @@ class comments extends Component {
orderId, orderId,
new_journal_id, new_journal_id,
} = this.state; } = this.state;
const { current_user } = this.props; const { current_user, only_show_content } = this.props;
const Paginations = ( const Paginations = (
<React.Fragment> <React.Fragment>
@ -303,10 +303,6 @@ class comments extends Component {
</React.Fragment> </React.Fragment>
); );
// const comment_meditor = (
// )
const new_comment = (is_reply, item_id) => { const new_comment = (is_reply, item_id) => {
return ( return (
<div className="grid-item-top pb10"> <div className="grid-item-top pb10">
@ -466,6 +462,48 @@ class comments extends Component {
}; };
return ( return (
<div>
{only_show_content ? (
<div>
<div className="mb10">
{is_reply && !reply_id ? (
<div className="pd20">{new_comment(is_reply, undefined)}</div>
) : (
<div className="children-comment-bg pd20 grid-item">
<img
className="radius"
src={
current_user && current_user.image_url
? getImageUrl(`images/${current_user.image_url}`)
: "images/avatars/User/b"
}
alt=""
width="30"
height="30"
/>
<span className="reply-comment-input mr20">
<Button
className="add_reply_button ml10"
onClick={() => this.add_reply(undefined)}
>
<span>添加评论...</span>
</Button>
</span>
</div>
)}
</div>
{journalsdata && journalsdata.journals_total_count > 0 && (
<List
size="large"
loading={isSpin}
header=""
dataSource={journalsdata.issue_journals}
renderItem={(item) => <List.Item>{renderList(item)}</List.Item>}
/>
)}
{Paginations}
</div>
) : (
<div className="mt20"> <div className="mt20">
<div className="comment-background pd10 mb10"> <div className="comment-background pd10 mb10">
<Tabs defaultActiveKey="1" className="custom-comment-tabs"> <Tabs defaultActiveKey="1" className="custom-comment-tabs">
@ -474,7 +512,9 @@ class comments extends Component {
<span className="ml-3 font-16"> <span className="ml-3 font-16">
评论 评论
{search_count > 0 && ( {search_count > 0 && (
<span className="search-count-button">{search_count}</span> <span className="search-count-button">
{search_count}
</span>
)} )}
</span> </span>
} }
@ -482,7 +522,9 @@ class comments extends Component {
> >
<div className="mb10"> <div className="mb10">
{is_reply && !reply_id ? ( {is_reply && !reply_id ? (
<div className="pd20">{new_comment(is_reply, undefined)}</div> <div className="pd20">
{new_comment(is_reply, undefined)}
</div>
) : ( ) : (
<div className="children-comment-bg pd20 grid-item"> <div className="children-comment-bg pd20 grid-item">
<img <img
@ -523,6 +565,8 @@ class comments extends Component {
{Paginations} {Paginations}
</div> </div>
</div> </div>
)}
</div>
); );
} }
} }