This commit is contained in:
caishi 2020-11-05 11:31:26 +08:00
parent 5e36abb259
commit e9fef026a6
7 changed files with 335 additions and 34 deletions

View File

@ -1,7 +1,7 @@
import React , { Component } from 'react';
import { Spin , Pagination } from 'antd';
import { getImageUrl } from 'educoder';
import { truncateCommitId } from '../common/util'
import { truncateCommitId } from '../common/util';
import SelectBranch from '../Branch/Select';
import Nodata from '../Nodata';

View File

@ -0,0 +1,51 @@
import React , { useEffect , useState } from 'react';
import axios from 'axios';
import { AlignCenter , FlexAJ } from '../Component/layout';
import User from '../Component/User';
import { truncateCommitId } from '../common/util';
import { getImageUrl } from 'educoder';
import {Link} from 'react-router-dom';
function Commits(props){
const [ commits , setCommits ] = useState(undefined);
const { projectsId , owner , mergeId } = props.match.params;
useEffect(()=>{
if(projectsId && owner && mergeId){
const url = `/${owner}/${projectsId}/pulls/${mergeId}/commits.json`;
axios.get(url).then(result=>{
if(result){
setCommits(result.data.commits);
}
}).catch(error=>{})
}
},[projectsId,owner,mergeId]);
return(
<div className="pb20">
{
commits && commits.length>0 && commits.map((item,key)=>{
return(
<div className="prCommits">
<p className="prCreate">{item.created_at}</p>
<div className="prInfo">
<FlexAJ>
<AlignCenter>
<span className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</span>
<p className="ml15 font-16 color-grey-3">{item.message}</p>
</AlignCenter>
{/* <Link to={""} className="color-blue">浏览代码</Link> */}
<AlignCenter>
<User url={getImageUrl(`images/${item.committer && item.committer.image_url}`)} name={`${item.committer && item.committer.name}`}></User><span>提交于{item.time_from_now}</span>
</AlignCenter>
</FlexAJ>
</div>
</div>
)
})
}
</div>
)
}
export default Commits;

71
src/forge/Merge/Files.jsx Normal file
View File

@ -0,0 +1,71 @@
import React ,{useEffect,useState} from 'react';
import { AlignCenter , FlexAJ } from '../Component/layout';
import axios from 'axios';
function Files(props){
const [ data , setData ] = useState(undefined);
const [ files , setFiles ] = useState(undefined);
const { projectsId , owner , mergeId } = props.match.params;
useEffect(()=>{
if(projectsId && owner && mergeId){
const url = `/${owner}/${projectsId}/pulls/${mergeId}/files.json`;
axios.get(url).then(result=>{
if(result){
setData(result.data);
setFiles(result.data.files);
}
}).catch(error=>{})
}
},[projectsId,owner,mergeId]);
return(
<div>
<AlignCenter className="color-grey-9 pb10" style={{borderBottom:"1px solid #eee"}}>
<i className="iconfont icon-sanjiaoxing-down mr5"></i>
<span>
共有<span className="color-grey-3"> {data && data.files_count} 个文件被更改</span>包括
{data && data.total_addition && <span className="color-green"> {data && data.total_addition} 次插入</span> }
{ data && data.total_deletion ? `${<span className="color-red"> {data && data.total_deletion} 次删除</span>}`:""}
</span>
</AlignCenter>
{
files && files.length>0 &&
<div>
{
files.map((item,key)=>{
return(
<div className="files">
<FlexAJ className="filesInfo">
<AlignCenter>
<i className="iconfont icon-wenjia font-16 mr8 color-grey-9"></i>
<span>{item.name}</span>
</AlignCenter>
<span>
<span className="color-green">+{item.addition}</span>
<span className="color-red ml20">-{item.deletion}</span>
</span>
</FlexAJ>
<div className="filesContent">
{
item.sections && item.sections.length >= 1 && item.sections[0].lines &&
item.sections[0].lines.map((item,key)=>{
return(
<div className={item.type === 1 ? "linesContent add" : (item.type === 3 ||item.type === 2) ? "linesContent reduce": item.type===4?"linesContent translate":"linesContent"}>
<span>{item.rightIdx && item.rightIdx !=="0" ? item.rightIdx :"" }</span>
<p>{item.content}</p>
</div>
)
})
}
</div>
</div>
)
})
}
</div>
}
</div>
)
}
export default Files;

View File

@ -1,6 +1,7 @@
import React, { Component } from "react";
import { Tabs } from 'antd';
import { Link } from "react-router-dom";
import { AlignCenter } from '../Component/layout';
import axios from "axios";
import { getImageUrl } from "educoder";
import {
@ -39,6 +40,8 @@ class MessageCount extends Component {
SpinMerge: false,
edit_spin: false,
pr_status: undefined,
copyVisible:false,
};
}
@ -47,7 +50,18 @@ class MessageCount extends Component {
SpinFlag: true,
});
this.getDetail();
// this.clickBody();
};
clickBody=()=>{
document.body.addEventListener('click', e => {
let name = e.target.className;
if(name.indexOf("notHide")>-1 || name.indexOf("ant-tabs-tab")>-1 || name==="ant-tabs-nav-scroll"){return;}
this.setState({
copyVisible:false
})
})
}
getDetail = () => {
const { projectsId, mergeId, owner } = this.props.match.params;
@ -198,6 +212,33 @@ class MessageCount extends Component {
return <RenderHtml className="break_word_comments imageLayerParent" value={v} />;
};
setCopyVisible=(e)=>{
e.stopPropagation();
this.setState({
copyVisible:true
})
}
copyItem =()=>{
return(
<div className="copyTab notHide">
<Tabs defaultActiveKey="1" className="notHide" animated={false} size={"small"}>
<Tabs.TabPane key="1" tab={<span className="notHide">HTTPS</span>}>{this.returnCopyUrl("https://gitee.com/44886/polhttp.git")}</Tabs.TabPane>
<Tabs.TabPane key="2" tab={<span className="notHide">SSH</span>}>{this.returnCopyUrl("https://gitee.com/44886/polssh.git")}</Tabs.TabPane>
</Tabs>
</div>
)
}
returnCopyUrl=(url)=>{
return(
<div className="df notHide">
<Input value={url} className="notHide" disabled={true}/>
<Button type="primary" ghost className="ml15 notHide">复制</Button>
</div>
)
}
render() {
const { projectsId, mergeId , owner } = this.props.match.params;
@ -208,6 +249,7 @@ class MessageCount extends Component {
isSpin,
ismesrge,
SpinFlag,
copyVisible
} = this.state;
const { current_user, projectDetail } = this.props;
const menu = (
@ -352,13 +394,20 @@ class MessageCount extends Component {
</div>
</div>
<div className="ml10">
<div className="mt15 text-right">
<div className="mt15 text-right" style={{display:"flex",justifyContent:"flex-end"}}>
{/* <span className="composeButton">
<Dropdown overlay={this.copyItem()} visible={copyVisible} onClick={(e)=>this.setCopyVisible(e)}>
<span>复制</span>
</Dropdown>
<span>下载为<i className="iconfont icon-sanjiaoxing-down color-blue"></i></span>
</span> */}
{current_user && projectDetail &&
pr_status !== 2 &&
projectDetail.permission !=="Reporter" && (
<Button
type="success"
type="green"
ghost
className="ml20"
onClick={()=>{this.props.history.push(`/projects/${owner}/${projectsId}/pulls/${mergeId}/UpdateMerge`);}}
>
编辑
@ -369,7 +418,7 @@ class MessageCount extends Component {
type="danger"
ghost
onClick={() => this.closedetail()}
className="ml15"
className="ml20"
loading={isSpin}
>
拒绝
@ -471,7 +520,7 @@ class MessageCount extends Component {
</div>
</div>
<div className=" main">
<div className="main" style={{padding:"15px 30px 20px 30px"}}>
<MergeFooter
footer_type="show"
order_id={data && data.issue.id}

View File

@ -1,5 +1,5 @@
import React, { Component } from "react";
import { Input, Select, Button, Spin, Alert } from "antd";
import { Input, Select , Spin, Alert } from "antd";
import axios from "axios";
import "../Order/order.css";
import "./merge.css";
@ -34,7 +34,7 @@ class NewMerge extends Component {
this.getmergelist(projectsId);
};
//获取新建分数据
//获取新建分数据
getmergelist = (projectsId) => {
this.setState({isSpin: true})
const { owner } = this.props.match.params;
@ -120,9 +120,7 @@ class NewMerge extends Component {
};
selectProjectName = (value) => {
console.log("value",value)
const { project_id, projects_names,id } = this.state;
const { owner } = this.props.match.params;
const { projects_names,id } = this.state;
let arr = projects_names && projects_names.filter(item=>item.id===value);
let identifier = arr && arr[0].project_id;
let login = arr && arr[0].project_user_login;
@ -138,7 +136,6 @@ class NewMerge extends Component {
})
this.props.history.push(`/projects/${login}/${identifier}/pulls/new`);
this.newMergelist(login,identifier);
};
//判断2分支是否可以合并
@ -146,7 +143,7 @@ class NewMerge extends Component {
ischeckmerge = () => {
this.setState({ isSpin: true });
const { projectsId , owner } = this.props.match.params;
const { pull, merge, project_id, merge_head, id } = this.state;
const { pull, merge , merge_head, id } = this.state;
const url = `/${owner}/${projectsId}/pulls/check_can_merge.json`;
axios.post(url, {
head: pull,
@ -196,7 +193,6 @@ class NewMerge extends Component {
merge_head,
projects_names,
} = this.state;
const { projectsId } = this.props.match.params;
const renderBrances = (list, type) => {
if (list && list.length > 0) {
return list.map((item, key) => {
@ -296,6 +292,14 @@ class NewMerge extends Component {
)}
</Spin>
</div>
<div className="main" style={{paddingTop:"0px"}}>
<MergeFooter
order_id={data && data.issue.id}
{...this.props}
{...this.state}
></MergeFooter>
</div>
</div>
);
}

View File

@ -58,4 +58,133 @@ form .ant-cascader-picker, form .ant-select {
}
.w240{
width: 240px;
}
.custom-commit-tabs .ant-tabs-nav .ant-tabs-tab{
padding:14px 0px!important;
}
.custom-commit-tabs .ant-tabs-bar{
border-bottom: none;
}
.custom-commit-tabs .ant-tabs-nav .ant-tabs-tab-active .tabNum{
background-color: #EBF4FE;
}
.custom-commit-tabs .ant-tabs-ink-bar{
width: 34px!important;
}
.tabNum{
display: inline-block;
margin-left:8px ;
border-radius: 10px;
height: 18px;
line-height: 18px;
background-color: #eee;
padding:0px 9px;
font-size: 12px;
}
/* 复制-下载为,组合按钮 */
.composeButton{
display: flex;
border:1px solid #5091FF;
border-radius: 5px;
height: 34px;
line-height: 34px;
}
.composeButton > span{
display: block;
padding:0px 18px;
color: #5091FF;
display: flex;
align-items: center;
border-radius: 5px;
cursor: pointer;
}
.composeButton > span:hover{
background-color: #F1F8FF;
}
.composeButton > span:first-child{
border-radius: 5px 0px 0px 5px;
border-right: 1px solid #5091FF;
}
.ant-btn{
border-radius: 5px;
}
/* 绿色按钮-type="green" */
.ant-btn.ant-btn-green{
border:1px solid #28BD6C;
color: #28BD6C;
}
.copyTab{
min-width: 370px;
padding:0px 18px 22px 18px;
box-shadow: 0px 2px 10px rgba(0,0,0,0.2);
background-color: #fff;
}
.copyTab .ant-tabs-tab{
padding:12px 0px!important;
}
/* pr--提交tab页面 */
.prCommits{
border:1px solid #ddd;
border-top: none;
}
.prCommits:first-child{
border-top: 1px solid #ddd;
}
.prCommits .prCreate{
height: 50px;
line-height: 50px;
padding:0px 25px;
background-color:#fafafa;
color:#333;
font-size: 16px;
border-bottom: 1px solid #ddd;
}
.prCommits .prInfo{
padding:20px 25px;
}
/* pr-文件修改信息页面 */
.files{
border:1px solid #ddd;
margin-top: 15px;
border-radius: 2px;
}
.filesInfo{
padding:10px 15px;
/* cursor: pointer; */
background-color: #fafafa;
}
.filesContent{
border-top: 1px solid #ddd;
}
.linesContent{
display: flex;
height: 30px;
line-height: 30px;
align-items: center;
color: #333;
}
.linesContent > span{
padding: 0px 8px 0px 15px;
min-width: 8%;
text-align: right;
display: block;
border-right: 1px solid #ddd;
margin-right: 8px;
color: #888;
}
.linesContent.translate{
background-color:#F1F8FF;
}
.linesContent.translate > span{
border-right: 1px solid transparent;
}
.linesContent.reduce{
background-color:rgba(247, 48, 48, 0.15);;
}
.linesContent.add{
background: rgba(48, 232, 132, 0.15);
}

View File

@ -2,16 +2,13 @@ import React, { Component } from "react";
import { Tabs, Empty } from "antd";
import "../Order/order.css";
import "./merge.css";
import CodesCommit from "../Main/CoderRootCommit";
import Commits from "./Commits";
import Comments from "../comments/comments";
import Files from "./Files";
const { TabPane } = Tabs;
class MergeFooter extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { footer_type, order_id } = this.props;
@ -20,25 +17,25 @@ class MergeFooter extends Component {
<Tabs
defaultActiveKey={footer_type === "show" ? "1" : "2"}
className="custom-commit-tabs"
animated={false}
>
{
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><span className="font-16">评论</span><span className="tabNum">1</span></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> */}
<TabPane tab={<span><span className="font-16">提交</span><span className="tabNum">111</span></span>} key="2">
<Commits {...this.props}></Commits>
</TabPane>
<TabPane tab={<span><span className="font-16">文件</span><span className="tabNum">11</span></span>} key="3">
<Files {...this.props} />
</TabPane>
</Tabs>
</div>
);