forked from Gitlink/forgeplus-react
修改代码库二级页面(一部分)
This commit is contained in:
parent
5c81abb253
commit
0b2a5a910b
|
@ -1520,7 +1520,15 @@ a.edu-txt-w80,
|
|||
.font-16 {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
.weight400{
|
||||
font-weight: 400;
|
||||
}
|
||||
.weight500{
|
||||
font-weight: 500;
|
||||
}
|
||||
.weight{
|
||||
font-weight: bold;
|
||||
}
|
||||
.font-17 {
|
||||
font-size: 17px !important;
|
||||
}
|
||||
|
@ -1540,6 +1548,9 @@ a.edu-txt-w80,
|
|||
.font-25 {
|
||||
font-size: 25px !important;
|
||||
}
|
||||
.font-26 {
|
||||
font-size: 26px !important;
|
||||
}
|
||||
|
||||
.font-24 {
|
||||
font-size: 24px !important;
|
||||
|
@ -1561,6 +1572,9 @@ a.edu-txt-w80,
|
|||
font-size: 36px !important;
|
||||
}
|
||||
|
||||
.font-40 {
|
||||
font-size: 40px !important;
|
||||
}
|
||||
.font-50 {
|
||||
font-size: 50px !important;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1630632852475') format('woff2'),
|
||||
url('iconfont.woff?t=1630632852475') format('woff'),
|
||||
url('iconfont.ttf?t=1630632852475') format('truetype');
|
||||
src: url('iconfont.woff2?t=1631692103587') format('woff2'),
|
||||
url('iconfont.woff?t=1631692103587') format('woff'),
|
||||
url('iconfont.ttf?t=1631692103587') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,54 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-icon:before {
|
||||
content: "\e8ce";
|
||||
}
|
||||
|
||||
.icon-tar:before {
|
||||
content: "\e8cf";
|
||||
}
|
||||
|
||||
.icon-a-fuzhi2:before {
|
||||
content: "\e8d0";
|
||||
}
|
||||
|
||||
.icon-fujian1:before {
|
||||
content: "\e8d1";
|
||||
}
|
||||
|
||||
.icon-a-bianji1:before {
|
||||
content: "\e8d2";
|
||||
}
|
||||
|
||||
.icon-banbenicon:before {
|
||||
content: "\e8d3";
|
||||
}
|
||||
|
||||
.icon-shanchuicon2:before {
|
||||
content: "\e8d4";
|
||||
}
|
||||
|
||||
.icon-a-lajitong_icon3x:before {
|
||||
content: "\e8d5";
|
||||
}
|
||||
|
||||
.icon-xialaanniu2:before {
|
||||
content: "\e8d6";
|
||||
}
|
||||
|
||||
.icon-xiazai-icon:before {
|
||||
content: "\e8d7";
|
||||
}
|
||||
|
||||
.icon-master_icon1:before {
|
||||
content: "\e8d8";
|
||||
}
|
||||
|
||||
.icon-shangchuanicon:before {
|
||||
content: "\e8d9";
|
||||
}
|
||||
|
||||
.icon-gerenziliao1:before {
|
||||
content: "\e8c7";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,90 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "24368060",
|
||||
"name": "icon",
|
||||
"font_class": "icon",
|
||||
"unicode": "e8ce",
|
||||
"unicode_decimal": 59598
|
||||
},
|
||||
{
|
||||
"icon_id": "24368061",
|
||||
"name": "tar",
|
||||
"font_class": "tar",
|
||||
"unicode": "e8cf",
|
||||
"unicode_decimal": 59599
|
||||
},
|
||||
{
|
||||
"icon_id": "24289113",
|
||||
"name": "复制 (2)",
|
||||
"font_class": "a-fuzhi2",
|
||||
"unicode": "e8d0",
|
||||
"unicode_decimal": 59600
|
||||
},
|
||||
{
|
||||
"icon_id": "24289114",
|
||||
"name": "附件",
|
||||
"font_class": "fujian1",
|
||||
"unicode": "e8d1",
|
||||
"unicode_decimal": 59601
|
||||
},
|
||||
{
|
||||
"icon_id": "24289115",
|
||||
"name": "编 辑",
|
||||
"font_class": "a-bianji1",
|
||||
"unicode": "e8d2",
|
||||
"unicode_decimal": 59602
|
||||
},
|
||||
{
|
||||
"icon_id": "24289116",
|
||||
"name": "版本icon",
|
||||
"font_class": "banbenicon",
|
||||
"unicode": "e8d3",
|
||||
"unicode_decimal": 59603
|
||||
},
|
||||
{
|
||||
"icon_id": "24289117",
|
||||
"name": "删除icon",
|
||||
"font_class": "shanchuicon2",
|
||||
"unicode": "e8d4",
|
||||
"unicode_decimal": 59604
|
||||
},
|
||||
{
|
||||
"icon_id": "24289118",
|
||||
"name": "垃圾桶_icon@3x",
|
||||
"font_class": "a-lajitong_icon3x",
|
||||
"unicode": "e8d5",
|
||||
"unicode_decimal": 59605
|
||||
},
|
||||
{
|
||||
"icon_id": "24289119",
|
||||
"name": "下拉按钮",
|
||||
"font_class": "xialaanniu2",
|
||||
"unicode": "e8d6",
|
||||
"unicode_decimal": 59606
|
||||
},
|
||||
{
|
||||
"icon_id": "24289120",
|
||||
"name": "下载-icon",
|
||||
"font_class": "xiazai-icon",
|
||||
"unicode": "e8d7",
|
||||
"unicode_decimal": 59607
|
||||
},
|
||||
{
|
||||
"icon_id": "24289121",
|
||||
"name": "master_icon",
|
||||
"font_class": "master_icon1",
|
||||
"unicode": "e8d8",
|
||||
"unicode_decimal": 59608
|
||||
},
|
||||
{
|
||||
"icon_id": "24289122",
|
||||
"name": "上传icon",
|
||||
"font_class": "shangchuanicon",
|
||||
"unicode": "e8d9",
|
||||
"unicode_decimal": 59609
|
||||
},
|
||||
{
|
||||
"icon_id": "24059956",
|
||||
"name": "个人资料",
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -69,7 +69,7 @@ export function appendFileSizeToUploadFile(item) {
|
|||
}
|
||||
export function appendFileSizeToUploadFileAll(fileList) {
|
||||
return fileList.map(item => {
|
||||
if (item.name.indexOf(uploadNameSizeSeperator) == -1) {
|
||||
if (item.name.indexOf(uploadNameSizeSeperator) === -1) {
|
||||
return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` })
|
||||
}
|
||||
return item
|
||||
|
|
|
@ -26,7 +26,7 @@ export default (({ projectsId , branch , owner , changeBranch , branchList , tag
|
|||
<div className="branch-tagBox">
|
||||
{/* {nav === 0 ?"分支":"标签"} */}
|
||||
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
|
||||
<span className="ant-dropdown-link task-hide" style={{fontWeight:"500"}}>
|
||||
<span className="ant-dropdown-link task-hide" style={{fontWeight:"500",minWidth:"45px"}}>
|
||||
{showValue}
|
||||
</span>
|
||||
<i className="showtag iconfont icon-sanjiaoxing-down font-15 color-grey-9 mr5 ml5 mt1" />
|
||||
|
|
|
@ -55,7 +55,7 @@ function SelectOverlay({ changeBranch , tagflag , branchList , projectsId , owne
|
|||
<div className="padding15" style={{paddingBottom:"0px"}}>
|
||||
<Input
|
||||
prefix={<i className="iconfont icon-sousuo_icon1 font-14"></i>}
|
||||
placeholder="请输入分支或标签名称搜索"
|
||||
placeholder={`请输入分支${tagflag ? "或标签" :""}名称搜索`}
|
||||
autocomplete="off" className="OptionsInput"
|
||||
value={inputValue}
|
||||
onChange={changeInputValue}
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
import React , { useState, useEffect } from 'react';
|
||||
import { Link } from "react-router-dom";
|
||||
import { Dropdown , Menu , Icon , Tooltip , Spin } from 'antd';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import { getBranch } from '../GetData/getData';
|
||||
import Nodata from '../Nodata';
|
||||
import './list.scss';
|
||||
|
||||
function turnbar(str){
|
||||
if(str && str.length>0 && str.indexOf("/")>-1){
|
||||
return str.replaceAll('/','%2F');
|
||||
}
|
||||
return str;
|
||||
}
|
||||
export default ((props)=>{
|
||||
const [ data , setData ] =useState(undefined);
|
||||
const [ isSpin , setIsSpin ] =useState(true);
|
||||
|
||||
const { projectsId , owner } = props.match.params;
|
||||
const { isManager , isDeveloper , projectDetail } = props;
|
||||
useEffect(()=>{
|
||||
getBranchs(projectsId, owner);
|
||||
},[projectsId])
|
||||
|
||||
async function getBranchs(id,owner){
|
||||
let result = await getBranch(id,owner);
|
||||
setData(result);
|
||||
setIsSpin(false);
|
||||
}
|
||||
|
||||
const list =()=>{
|
||||
if(data && data.length>0){
|
||||
return(
|
||||
<React.Fragment>
|
||||
<ul className="branchUl">
|
||||
{
|
||||
data.map((item,key)=>{
|
||||
return(
|
||||
<li key={key}>
|
||||
<div>
|
||||
<Link to={`/${owner}/${projectsId}/tree/${turnbar(item.name)}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||
<p className="f-wrap-alignCenter mt15">
|
||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.last_commit.sha}`)}`} className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</Link>
|
||||
<span className="color-grey-3 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
||||
<span className="color-grey-8 ml30">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
||||
</p>
|
||||
</div>
|
||||
<span>
|
||||
{
|
||||
(isManager || isDeveloper) && (projectDetail && projectDetail.type!==2) &&
|
||||
<Link to={`/${owner}/${projectsId}/pulls/new/${item.name}`} className="mr20 color-blue mr30">创建合并请求</Link>
|
||||
}
|
||||
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="color-green-file">
|
||||
<a className="ant-dropdown-link">
|
||||
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
|
||||
</a>
|
||||
</Dropdown>
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</React.Fragment>
|
||||
)
|
||||
}else if(data && data.length === 0){
|
||||
return ( <Nodata _html="暂无数据"/>)
|
||||
}
|
||||
}
|
||||
const menu =(zip_url,tar_url)=> (
|
||||
<Menu>
|
||||
<Menu.Item key={'0'}><a href={zip_url}>ZIP</a></Menu.Item>
|
||||
<Menu.Item key={'1'}><a href={tar_url}>TAR.GZ</a></Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
<div className="main">
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="branchTable">
|
||||
<p className="branchTitle bor-bottom-greyE">分支列表</p>
|
||||
<div style={{minHeight:"400px"}}>{list()}</div>
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Route , Switch } from 'react-router-dom';
|
||||
import Top from './DetailTop';
|
||||
// import Top from './DetailTop';
|
||||
import Loadable from 'react-loadable';
|
||||
import Loading from '../../Loading';
|
||||
import axios from 'axios';
|
||||
import './Index.scss';
|
||||
|
||||
const FileNew = Loadable({
|
||||
loader: () => import('../Newfile/Index'),
|
||||
|
@ -18,25 +19,25 @@ const CoderRootCommit = Loadable({
|
|||
loading: Loading,
|
||||
})
|
||||
const CoderRootBranch = Loadable({
|
||||
loader: () => import('./CoderRootBranch'),
|
||||
loader: () => import('./tree/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const CoderRootTag = Loadable({
|
||||
loader: () => import('./CoderRootTag'),
|
||||
loader: () => import('./tag/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const CoderRootVersion = Loadable({
|
||||
loader: () => import('../Version/version'),
|
||||
loading: Loading,
|
||||
})
|
||||
const CoderRootVersionNew = Loadable({
|
||||
loader: () => import('../Version/New'),
|
||||
loading: Loading,
|
||||
})
|
||||
const CoderRootVersionUpdate = Loadable({
|
||||
loader: () => import('../Version/New'),
|
||||
loader: () => import('./version/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
// const CoderRootVersionNew = Loadable({
|
||||
// loader: () => import('./version/New'),
|
||||
// loading: Loading,
|
||||
// })
|
||||
// const CoderRootVersionUpdate = Loadable({
|
||||
// loader: () => import('./version/New'),
|
||||
// loading: Loading,
|
||||
// })
|
||||
const Diff = Loadable({
|
||||
loader: () => import('./Diff'),
|
||||
loading: Loading,
|
||||
|
@ -83,8 +84,8 @@ class CoderRootIndex extends Component{
|
|||
}
|
||||
render(){
|
||||
return(
|
||||
<div>
|
||||
<Top {...this.props} {...this.state}/>
|
||||
<div className="coderSubPage">
|
||||
{/* <Top {...this.props} {...this.state}/> */}
|
||||
<Switch {...this.props}>
|
||||
{/* 新建文件 */}
|
||||
<Route path="/:owner/:projectsId/:branch/newfile/:path"
|
||||
|
@ -117,7 +118,7 @@ class CoderRootIndex extends Component{
|
|||
() => (<CoderRootCommit {...this.props} {...this.state} commit_class="main" getTopCount={this.getTopCount} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/:owner/:projectsId/releases/:versionId/update"
|
||||
{/* <Route path="/:owner/:projectsId/releases/:versionId/update"
|
||||
render={
|
||||
(props) => (<CoderRootVersionUpdate {...this.props} {...this.state} {...props} />)
|
||||
}
|
||||
|
@ -126,7 +127,7 @@ class CoderRootIndex extends Component{
|
|||
render={
|
||||
() => (<CoderRootVersionNew {...this.props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
></Route> */}
|
||||
<Route path="/:owner/:projectsId/releases"
|
||||
render={
|
||||
() => (<CoderRootVersion {...this.props} {...this.state} />)
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import { Spin } from 'antd';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
import Nodata from '../Nodata';
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
export default (( props, { projectDetail }) => {
|
||||
const [isSpin, setSpin] = useState(true);
|
||||
const [data, setData] = useState(undefined);
|
||||
|
||||
const { projectsId , owner } = props.match.params;
|
||||
|
||||
useEffect(() => {
|
||||
if (projectsId) {
|
||||
const url = `/${owner}/${projectsId}/tags.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setSpin(false);
|
||||
setData(result.data);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
}, [owner, projectsId]);
|
||||
|
||||
return (
|
||||
<div className="main" style={{padding:"0px",border:"none"}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<div style={{minHeight:"400px"}}>
|
||||
{
|
||||
data && data.length > 0 &&
|
||||
<div className="div_table">
|
||||
<ul className="ul_thead">
|
||||
<li>
|
||||
<span className="flex1">标签名</span>
|
||||
<span>提交信息</span>
|
||||
<span className="ul_tbody_forth">下载</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="ul_tbody">
|
||||
{
|
||||
data.map((item, key) => {
|
||||
return (
|
||||
<li>
|
||||
<span className="flex1">
|
||||
<i className="iconfont icon-biaoqian3 font-16 mr5 color-grey-8"></i>
|
||||
<span className="font-16">{item.name}</span>
|
||||
</span>
|
||||
<span className="ul_tbody_third">
|
||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.id}`)}`} className="commitKey" style={{ "marginLeft": 0 }}>{truncateCommitId(`${item.id}`)}</Link>
|
||||
</span>
|
||||
<span className="ul_tbody_forth">
|
||||
<a href={item.tarball_url} style={{ color: "#4CC1DA" }} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
||||
<a href={item.zipball_url} style={{ color: "#28BD6C" }}><i className="iconfont icon-ZIP font-18 mr5"></i>ZIP</a>
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
{ data && data.length === 0 && <Nodata _html={`暂无标签!`}/> }
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
)
|
||||
})
|
|
@ -447,4 +447,8 @@
|
|||
.ant-anchor-ink::before{
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
.coderSubPage{
|
||||
width: 1200px;
|
||||
margin:0px auto;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 590 B |
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import'./sub.scss'
|
||||
|
||||
function SubMenu({tab,owner,projectsId}) {
|
||||
return(
|
||||
<ul className="subMenu">
|
||||
<Link to={`/${owner}/${projectsId}/tags`} className={tab==="tags"?"active":""}>标签</Link>
|
||||
<Link to={`/${owner}/${projectsId}/releases`} className={tab==="releases"?"active":""}>发行版</Link>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
export default SubMenu;
|
|
@ -64,4 +64,28 @@
|
|||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.subMenu{
|
||||
display: flex;
|
||||
padding-top: 30px;
|
||||
a{
|
||||
width: 83px;
|
||||
font-weight: 500;
|
||||
line-height: 30px;
|
||||
height: 32px;
|
||||
color: #333333!important;
|
||||
text-align: center;
|
||||
border: 1px solid #D0D0D0;
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
background: rgba(250, 251, 252, 0);
|
||||
&:first-child{
|
||||
border-right: none;
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
}
|
||||
&.active{
|
||||
background-color: #466AFF;
|
||||
color: #fff!important;
|
||||
border-color: #466AFF;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
import React,{ useEffect , useState } from 'react';
|
||||
import SubMenu from '../sub/SubMenu';
|
||||
import { Table , Tooltip } from 'antd';
|
||||
import axios from 'axios';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { truncateCommitId } from '../../common/util';
|
||||
import './Index.scss';
|
||||
import Tree from '../img/tree.png'
|
||||
|
||||
|
||||
function Tags(props) {
|
||||
|
||||
const [ source , setSource ] = useState([]);
|
||||
|
||||
const { projectsId , owner } = props.match.params;
|
||||
|
||||
useEffect(() => {
|
||||
if (projectsId) {
|
||||
const url = `/${owner}/${projectsId}/tags.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setSource(result.data);
|
||||
}
|
||||
}).catch(error => {})
|
||||
}
|
||||
}, [owner, projectsId]);
|
||||
|
||||
const columns=[
|
||||
{
|
||||
title:"标签名",
|
||||
dataIndex:"name",
|
||||
key:1,
|
||||
ellipsis:true,
|
||||
render:(txt,item)=>{
|
||||
return <Link className="hover" to={`/${owner}/${projectsId}/tree/${item.name}`} >{item.name}</Link>
|
||||
}
|
||||
},
|
||||
{
|
||||
title:"创建时间",
|
||||
dataIndex:"time",
|
||||
key:2,
|
||||
ellipsis:true,
|
||||
render:(txt,item)=>{
|
||||
return (
|
||||
<span className="color-grey-3">
|
||||
<Link className="mr3" style={{fontWeight:"500"}} to={`/${item.commit && item.commit.login}`} >{item.commit && item.commit.name}</Link>
|
||||
<span>创建于{item.commit && item.commit.time}</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title:"提交ID",
|
||||
dataIndex:"id",
|
||||
key:3,
|
||||
ellipsis:true,
|
||||
render:(txt,item)=>{
|
||||
return (
|
||||
<Tooltip placement="top" title={`最后提交日期:${`dddddd`}`}>
|
||||
<img src={Tree} alt="提交ID" width="22px" className="mr4"/>
|
||||
<Link className="hover color-blue" to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.id}`)}`}>{truncateCommitId(item.id)}</Link>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title:"描述信息",
|
||||
dataIndex:"message",
|
||||
key:4,
|
||||
ellipsis:true,
|
||||
render:(txt,item)=>{
|
||||
return item.message || "--"
|
||||
}
|
||||
},
|
||||
{
|
||||
title:"下载",
|
||||
dataIndex:"stage_type",
|
||||
key:5,
|
||||
ellipsis:true,
|
||||
align:"center",
|
||||
width:"181px",
|
||||
render:(txt,item)=>{
|
||||
return (
|
||||
<div>
|
||||
<Link to={`/${owner}/${projectsId}/pulls/new/${item.name}`} className="btn-83">
|
||||
<i className="iconfont icon-xiazai-icon font-16 mr5"></i>TAR
|
||||
</Link>
|
||||
<Link to={`/${owner}/${projectsId}/pulls/new/${item.name}`} className="btn-83 ml15">
|
||||
<i className="iconfont icon-xiazai-icon font-16 mr5"></i>ZIP
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
return(
|
||||
<div>
|
||||
<SubMenu tab={"tags"} projectsId={projectsId} owner={owner}/>
|
||||
<Table className="tagTable" dataSource={source} columns={columns} pagination={false}></Table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Tags;
|
|
@ -0,0 +1,31 @@
|
|||
.tagTable{
|
||||
margin-top: 30px;
|
||||
thead{
|
||||
tr th{
|
||||
background-color: #fff;
|
||||
padding:5px 0px;
|
||||
.ant-table-column-title{
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
tbody{
|
||||
tr{
|
||||
&:hover td{
|
||||
background-color: #fff!important;
|
||||
}
|
||||
td{
|
||||
padding:0px;
|
||||
height: 69px;
|
||||
line-height: 69px;
|
||||
}
|
||||
&:last-child{
|
||||
td{
|
||||
border-bottom: none!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import CopyTool from '../../Component/CopyTool';
|
||||
import { truncateCommitId } from '../../common/util';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { Dropdown , Menu , Spin } from 'antd';
|
||||
import './Index.scss';
|
||||
|
||||
import Tree from '../img/tree.png';
|
||||
import Axios from 'axios';
|
||||
|
||||
function turnbar(str){
|
||||
if(str && str.length>0 && str.indexOf("/")>-1){
|
||||
return str.replaceAll('/','%2F');
|
||||
}
|
||||
return str;
|
||||
}
|
||||
function Index(props) {
|
||||
const [ list , setList ] = useState([]);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
|
||||
const { projectsId , owner } = props.match.params;
|
||||
const { isManager , isDeveloper , projectDetail } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
getList();
|
||||
},[])
|
||||
|
||||
|
||||
const menu =(zip_url,tar_url)=> (
|
||||
<Menu>
|
||||
<Menu.Item key={'0'}><a href={zip_url}>ZIP</a></Menu.Item>
|
||||
<Menu.Item key={'1'}><a href={tar_url}>TAR.GZ</a></Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
|
||||
function getList() {
|
||||
const url = `/${owner}/${projectsId}/branches_slice.json`;
|
||||
Axios.get(url).then(result=>{
|
||||
if(result){
|
||||
setList(result.data);
|
||||
}
|
||||
setIsSpin(false);
|
||||
}).catch(error=>{setIsSpin(false);})
|
||||
}
|
||||
|
||||
return(
|
||||
<Spin spinning={isSpin}>
|
||||
<div style={{paddingTop:"10px",minHeight:"400px"}}>
|
||||
{
|
||||
list && list.length>0 && list.map((item,key)=>{
|
||||
return(
|
||||
<React.Fragment>
|
||||
<p className="branchSort">{item.branch_type === "default" ? "默认分支" : item.branch_type==="protected"?"保护分支":"其它分支"}</p>
|
||||
{
|
||||
item.list && item.list.length>0 &&
|
||||
<ul className="treeUl">
|
||||
{
|
||||
item.list.map((i,k)=>{
|
||||
let last_commit = i.last_commit;
|
||||
return(
|
||||
<li>
|
||||
<div className="treeinfo">
|
||||
<Link to={`/${owner}/${projectsId}/tree/${turnbar(i.name)}`} className="task-hide">{i.name}</Link>
|
||||
<div>
|
||||
<img src={getImageUrl(`${last_commit && last_commit.committer && last_commit.image_url}`)} alt="" />
|
||||
<span className="mr3 color-grey-3" style={{fontWeight:"500"}}>{last_commit && last_commit.committer && last_commit.committer.name}</span>
|
||||
<span className="color-grey-3">更新于{last_commit && last_commit.time_from_now}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="treecopy">
|
||||
<div>
|
||||
<span>
|
||||
<img src={Tree} alt="sha" width={"16px"}/>
|
||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(last_commit && last_commit.sha)}`}>{truncateCommitId(last_commit && last_commit.sha)}</Link>
|
||||
<input type="text" id={`value${key}${k}`} value={`${truncateCommitId(last_commit && last_commit.sha)}`}/>
|
||||
</span>
|
||||
<CopyTool beforeText="复制commit id" afterText="复制成功" inputId={`value${key}${k}`}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="treeabout">
|
||||
{
|
||||
(isManager || isDeveloper) && (projectDetail && projectDetail.type!==2) &&
|
||||
<Link to={`/${owner}/${projectsId}/pulls/new/${item.name}`} className="btn-83">+ 合并请求</Link>
|
||||
}
|
||||
<Dropdown overlay={menu(i.zip_url,i.tar_url)} trigger={['click']} placement="bottomRight">
|
||||
<a className="btn-83 ml15">下载<i className="iconfont icon-sanjiaoxing-down font-14"></i></a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,81 @@
|
|||
.branchSort{
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
font-size: 15px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
padding-left: 10px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 6px!important;
|
||||
}
|
||||
.treeUl{
|
||||
background: #FAFCFF;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(42, 97, 255, 0.23);
|
||||
li{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 20px;
|
||||
border-bottom: 1px solid rgba(42, 97, 255, 0.23);
|
||||
&:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
.treeinfo{
|
||||
max-width: 399px;
|
||||
flex:1;
|
||||
flex-direction: column;
|
||||
a:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
img{
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.treecopy{
|
||||
flex:1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
&>div{
|
||||
height: 32px;
|
||||
background: #FAFBFC;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #D0D0D0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&>span{
|
||||
padding:0px 15px;
|
||||
border-right: 1px solid rgba(153, 153, 153, 0.4);
|
||||
height: 100%;
|
||||
img{
|
||||
margin-right: 4px;
|
||||
}
|
||||
a{
|
||||
color: #466AFF;
|
||||
&:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
&>i{
|
||||
margin:0px 12px;
|
||||
color: #333!important;
|
||||
}
|
||||
input{
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
opacity: 0;
|
||||
top: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.treeabout{
|
||||
flex:1;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
import './version.scss';
|
||||
|
||||
function Empty({operation,addFunc}) {
|
||||
return(
|
||||
<div className="emptyPanel color-grey-3">
|
||||
<i className="iconfont icon-banbenicon font-50 color-grey-6" style={{height:"50px",lineHeight:"50px",marginBottom:"13px"}}></i>
|
||||
<span className="weight500 font-26 mb15">这里暂未发布过任何版本</span>
|
||||
<span className="weight400" style={{textAlign:"center",lineHeight:"20px"}}>发行版功能基于仓库中的历史标记<br/>建议使用类似 V1.0 的版本标记作为发布点</span>
|
||||
<div className="operation">
|
||||
{
|
||||
operation ?
|
||||
<Button type={"primary"} onClick={addFunc} className="btnblue" style={{width:"118px",height:"36px"}}>发布新版本</Button>
|
||||
:
|
||||
<span className="color-grey-3 weight500 font-16">该项目暂时没有发布版本</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Empty;
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react';
|
||||
import { Switch , Route } from 'react-router';
|
||||
import Loadable from 'react-loadable';
|
||||
import Loading from '../../../Loading';
|
||||
import SubMenu from '../sub/SubMenu';
|
||||
import "./version.scss";
|
||||
|
||||
const CoderRootVersion = Loadable({
|
||||
loader: () => import('./version'),
|
||||
loading: Loading,
|
||||
})
|
||||
const CoderRootVersionNew = Loadable({
|
||||
loader: () => import('./New'),
|
||||
loading: Loading,
|
||||
})
|
||||
function Index(props) {
|
||||
const { projectsId , owner } = props.match.params;
|
||||
return(
|
||||
<div>
|
||||
<SubMenu tab={"releases"} projectsId={projectsId} owner={owner}/>
|
||||
<Switch>
|
||||
<Route path="/:owner/:projectsId/releases/:versionId/update"
|
||||
render={
|
||||
(p) => (<CoderRootVersionNew {...props} {...p} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/:owner/:projectsId/releases/new"
|
||||
render={
|
||||
(p) => (<CoderRootVersionNew {...props} {...p} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/:owner/:projectsId/releases"
|
||||
render={
|
||||
(p) => (<CoderRootVersion {...props} {...p} />)
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,253 @@
|
|||
import React, { useState, useEffect, forwardRef } from "react";
|
||||
import styled from "styled-components";
|
||||
import { AutoComplete , Input, Checkbox, Button, Form } from "antd";
|
||||
import SelectBranch from '../../Branch/Select';
|
||||
|
||||
import Editor from "../../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import Upload from "../../Upload/Index";
|
||||
import Attachments from "../../Upload/attachment";
|
||||
import axios from "axios";
|
||||
import "./version.scss";
|
||||
|
||||
const { Option } = AutoComplete;
|
||||
|
||||
const Span = styled.span`
|
||||
margin: 0px 15px;
|
||||
color: #bbb;
|
||||
line-height: 35px;
|
||||
font-size:16px;
|
||||
font-weight:400;
|
||||
color:#666;
|
||||
`;
|
||||
export default Form.create()(
|
||||
forwardRef(
|
||||
(
|
||||
{ form, projectDetail , match, showNotification, history },
|
||||
ref
|
||||
) => {
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
const [tagList, setTagList] = useState(undefined);
|
||||
const [desc, setDesc] = useState(null);
|
||||
const [branch, setBranch ] = useState(null);
|
||||
const [fileList, setFileList] = useState(undefined);
|
||||
const [attachment, setAttachment] = useState(undefined);
|
||||
const [options , setOptions] = useState(undefined);
|
||||
|
||||
const { projectsId, versionId , owner } = match.params;
|
||||
|
||||
useEffect(()=>{
|
||||
if(projectDetail && projectDetail.default_branch){
|
||||
setBranch(projectDetail.default_branch);
|
||||
}
|
||||
},[projectDetail])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (versionId) {
|
||||
const url = `/${owner}/${projectsId}/releases/${versionId}/edit.json`;
|
||||
axios.get(url).then(result => {
|
||||
if (result) {
|
||||
setFieldsValue(result.data);
|
||||
setDesc(result.data.body);
|
||||
setAttachment(result.data.attachments);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [versionId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (projectsId) {
|
||||
const url = `/${owner}/${projectsId}/tags.json`;
|
||||
axios
|
||||
.get(url,{params:{
|
||||
limit:1000
|
||||
}})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
setTagList(result.data);
|
||||
setOptions(renderTagList(result.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}, [projectsId]);
|
||||
|
||||
function renderTagList(list) {
|
||||
if (list) {
|
||||
let array = list.map((item, key) => {
|
||||
return (
|
||||
<Option key={key} value={item.name}>
|
||||
{item.name}
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
return array || undefined;
|
||||
}
|
||||
}
|
||||
function submit() {
|
||||
validateFields((err, value) => {
|
||||
if(err)return;
|
||||
if (versionId) {
|
||||
let url = `/${owner}/${projectsId}/releases/${versionId}.json`;
|
||||
axios
|
||||
.put(url, {
|
||||
...value,
|
||||
body: desc,
|
||||
attachment_ids: fileList,
|
||||
target_commitish:branch
|
||||
})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
showNotification("版本修改成功!");
|
||||
history.push(`/${owner}/${projectsId}/releases`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let url = `/${owner}/${projectsId}/releases.json`;
|
||||
axios.post(url, {
|
||||
...value,
|
||||
body: desc,
|
||||
attachment_ids: fileList
|
||||
})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
showNotification("版本发布成功!");
|
||||
history.push(`/${owner}/${projectsId}/releases`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// 输入标签名
|
||||
function changeAuto(value){
|
||||
let l = tagList.filter(item=>item.name.indexOf(value) > -1);
|
||||
setOptions(renderTagList(l));
|
||||
}
|
||||
|
||||
function changeBranch(params) {
|
||||
setBranch(params);
|
||||
}
|
||||
return (
|
||||
<div className="df pt20">
|
||||
<Form className="versionForm">
|
||||
<div className="itemInline">
|
||||
<Form.Item>
|
||||
{getFieldDecorator("tag_name",
|
||||
{ rules:[
|
||||
{ required: true, message: "请输入获取或选择一个标签" }
|
||||
],
|
||||
validateFirst: true
|
||||
})(
|
||||
<AutoComplete
|
||||
placeholder="标记一个版本"
|
||||
onChange={changeAuto}
|
||||
style={{ width: "200px" }}
|
||||
>
|
||||
{options}
|
||||
</AutoComplete>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Span>@</Span>
|
||||
<SelectBranch
|
||||
repo_id={projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
branch={branch}
|
||||
changeBranch={changeBranch}
|
||||
owner={owner}
|
||||
history={history}
|
||||
tagflag={false}
|
||||
branchList={projectDetail && projectDetail.branches && projectDetail.branches.list}
|
||||
></SelectBranch>
|
||||
<p className="font-12 color-grey-6 weight400">选择一个已经存在的标签,或者在发布时新建一个标签</p>
|
||||
</div>
|
||||
<Form.Item className="pt20">
|
||||
{getFieldDecorator("name",
|
||||
{ rules:[
|
||||
{ required: true, message: "请输入发行版的标题" }
|
||||
],
|
||||
validateFirst: true
|
||||
})(
|
||||
<Input placeholder="发行版的标题" />
|
||||
)}
|
||||
</Form.Item>
|
||||
<Editor
|
||||
placeholder={"描述此发行版"}
|
||||
height={200}
|
||||
mdID={`version-comments-description`}
|
||||
initValue={desc}
|
||||
onChange={setDesc}
|
||||
noStorage={true}
|
||||
/>
|
||||
|
||||
<div className="mt5 dragBox">
|
||||
<Upload
|
||||
className="versionStyle"
|
||||
isComplete={true}
|
||||
load={setFileList}
|
||||
icon={
|
||||
<i className="iconfont icon-shangchuanicon dragIcon" />
|
||||
}
|
||||
size={100}
|
||||
showNotification={showNotification}
|
||||
/>
|
||||
{versionId && attachment && attachment.length > 0 ? (
|
||||
<Attachments
|
||||
attachments={attachment}
|
||||
showNotification={showNotification}
|
||||
canDelete={true}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<Form.Item className="prerelease">
|
||||
{getFieldDecorator("prerelease",
|
||||
{ rules:[],
|
||||
validateFirst: true
|
||||
})(
|
||||
<Checkbox>这是一个预览版本</Checkbox>
|
||||
)}
|
||||
</Form.Item>
|
||||
<p className="pt20" style={{borderTop:"1px solid #eee"}}>
|
||||
<Button onClick={submit} type="primary" className="mr30">
|
||||
{versionId ? "保存" : "创建"}发行版
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>history.push(`/${owner}/${projectsId}/releases`)}
|
||||
style={{backgroundColor: "rgba(187,187,187,1)",color: "#fff"}}
|
||||
>取消</Button>
|
||||
</p>
|
||||
</Form>
|
||||
<div className="versionTips">
|
||||
<div className="infosTip">
|
||||
<p className="font-16 mb15 weight500">标签命名建议</p>
|
||||
<p className="mb15">
|
||||
通常的做法是在版本名称前加上字母 v 前缀, v1.0 或者 v2.3.4。
|
||||
</p>
|
||||
<p>
|
||||
如果标签不适合在生产环境下使用,请在版本名称后添加预发行版本。例如:v0.2-alpha
|
||||
或者 v5.9-beta.3。
|
||||
</p>
|
||||
</div>
|
||||
<div className="infosTip">
|
||||
<p className="font-16 mb15 weight500">语义化版本</p>
|
||||
<p>
|
||||
如果你是第一次发布版本,我们强烈建议你阅读<a className="color-blue">语义化版本</a>。
|
||||
</p>
|
||||
</div>
|
||||
<div className="infosTip">
|
||||
<p className="font-16 mb15 weight500">附件大小说明</p>
|
||||
<p>
|
||||
单个附件不能超过 100M(GVP 项目200M),每个仓库总附件不可超过
|
||||
1G(推荐项目不可超过 5G;GVP 项目不可超过
|
||||
20G)。附件总容量统计包括仓库附件和发行版附件。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
|
@ -0,0 +1,122 @@
|
|||
import React, { useEffect , useState } from "react";
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Spin , Button } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import Empty from './Empty';
|
||||
import './version.scss';
|
||||
import axios from 'axios';
|
||||
import RenderHtml from '../../../components/render-html';
|
||||
|
||||
function version(props) {
|
||||
const [ data , setData ] = useState(undefined);
|
||||
const [ releases , setReleases ] = useState(undefined);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
const { projectsId ,owner } = props.match.params;
|
||||
const { isManager , isDeveloper } = props;
|
||||
const type = props.projectDetail && props.projectDetail.type;
|
||||
|
||||
useEffect(()=>{
|
||||
getIssueList();
|
||||
},[])
|
||||
// 获取列表数据
|
||||
function getIssueList(){
|
||||
const url = `/${owner}/${projectsId}/releases.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setData(result.data);
|
||||
setReleases(result.data.releases);
|
||||
setIsSpin(false);
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
// 显示版本描述
|
||||
function showBody(key,flag){
|
||||
var lists = releases.concat();
|
||||
lists[key].bodyshow = !flag ? true : false;
|
||||
lists.splice();
|
||||
setReleases(lists);
|
||||
}
|
||||
|
||||
function renderList(releases){
|
||||
if (releases && releases.length > 0) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{
|
||||
data && data.user_permission && type !== 2 &&
|
||||
<div className="addReleaseBtn">
|
||||
<Button type={"primary"} onClick={addFunc} className="btnblue" style={{height:"36px"}}>发布新版本</Button>
|
||||
</div>
|
||||
}
|
||||
<div>
|
||||
{
|
||||
releases.map((item, key) => {
|
||||
return (
|
||||
<div className="versionInfo" key={key}>
|
||||
<span className="versionInfo_left">
|
||||
<span className={`${item.draft === "稳定" ?"versionTag green":"versionTag orange"}`}>{item.draft}</span>
|
||||
<span className="color-grey-3 mt15">
|
||||
<i className="iconfont icon-biaoqianicon mr3 font-14"></i>
|
||||
{item.tag_name}{item.draft === "预发行" ?"(standalone)":""}
|
||||
</span>
|
||||
</span>
|
||||
<div className="versionInfo_right">
|
||||
<div className="versionName">
|
||||
<Link to={`/${owner}/${projectsId}/tree/${item.tag_name}`} className="task-hide color-blue hover font-18">发布{item.name}{item.draft === "预发行" ?"(standalone)版本":""}</Link>
|
||||
{
|
||||
(isManager || isDeveloper) && type !==2 &&
|
||||
<Link to={`/${owner}/${projectsId}/releases/${item.version_id}/update`} className="ml15"><i className="iconfont icon-a-bianji1 font-16 color-grey-6"></i></Link>
|
||||
}
|
||||
</div>
|
||||
<span className="color-grey-3 mb15">
|
||||
<i className={`${item.bodyshow ? "iconfont icon-sanjiaoxing-down color-grey-8 mr3 font-14":"iconfont icon-triangle color-grey-8 mr3 font-14"}`} onClick={()=>showBody(key,item.bodyshow)}></i>
|
||||
<img src={getImageUrl(item.image_url)} alt="" className="sendAuthorImg"/>
|
||||
<span className="weight500">{item.user_name}</span>
|
||||
<span className="ml5">发布于{item.created_at}</span>
|
||||
</span>
|
||||
{
|
||||
item.bodyshow &&
|
||||
<div className="padding10">
|
||||
<RenderHtml className="break_word_comments imageLayerParent" value={item.body} url={props.history.location}/>
|
||||
</div>
|
||||
}
|
||||
<RenderHtml />
|
||||
<p className="versionFile">
|
||||
<a href={item.tarball_url}><i className="iconfont icon-tar font-14 mr10 color-grey-3"></i>{item.tag_name}.TAR.gz</a>
|
||||
<a href={item.zipball_url}><i className="iconfont icon-icon font-14 mr10 color-grey-3"></i>{item.tag_name}.ZIP</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
} else if (releases && releases.length === 0) {
|
||||
return (
|
||||
<Empty
|
||||
operation={data && data.user_permission && type !== 2}
|
||||
addFunc={addFunc}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function addFunc(){
|
||||
props.history.push(`/${owner}/${projectsId}/releases/new`);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="releaseIndex">
|
||||
<div className="releasesVersion">
|
||||
<Spin spinning={isSpin}>
|
||||
{renderList(releases)}
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default version;
|
|
@ -0,0 +1,338 @@
|
|||
.topWrapper {
|
||||
padding: 20px 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #EEEEEE;
|
||||
align-items: center;
|
||||
}
|
||||
.topWrapper_btn_new {
|
||||
background: #fff;
|
||||
color: #5091FF!important;
|
||||
padding:0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
border:1px solid #5091FF;
|
||||
}
|
||||
.versionInfo{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.versionInfo_left{
|
||||
display: flex;
|
||||
width: 182px;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
padding-right: 15px;
|
||||
}
|
||||
.versionInfo_right{
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
border-left: 1px solid #eee;
|
||||
position: relative;
|
||||
padding: 0px 30px 60px 24px;
|
||||
&::before{
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top:0px;
|
||||
content: '';
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #5091FF;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.sendAuthorImg{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.versionTag{
|
||||
display: inline;
|
||||
padding:0px 9px;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
margin-top: -8px;
|
||||
height: 22px;
|
||||
line-height: 20px;
|
||||
border-radius: 4px;
|
||||
&::before{
|
||||
position: absolute;
|
||||
content: "";
|
||||
width: 0;
|
||||
height: 0px;
|
||||
border-left: 4px solid #cccccc;
|
||||
border-top: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
z-index: 9;
|
||||
top: 6px;
|
||||
right: -9px;
|
||||
}
|
||||
&:after{
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
top:6px;
|
||||
right: -7px;
|
||||
position: absolute;
|
||||
border-left:4px solid #fff;
|
||||
border-top:4px solid transparent;
|
||||
border-bottom:4px solid transparent;
|
||||
border-right:4px solid transparent;
|
||||
content:'';
|
||||
z-index:10;
|
||||
}
|
||||
}
|
||||
.versionFile{
|
||||
margin-top: 5px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #eee;
|
||||
width: 100%;
|
||||
a{
|
||||
display: block;
|
||||
color: #333;
|
||||
font-weight: 400;
|
||||
height: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.versionTag.yellow{
|
||||
border: 1px solid #FBBC06;
|
||||
color: #FBBC06;
|
||||
&::before{
|
||||
border-left-color: #FBBC06;
|
||||
}
|
||||
}
|
||||
.versionTag.green{
|
||||
border: 1px solid #2DB44D;
|
||||
color: #2DB44D;
|
||||
&::before{
|
||||
border-left-color: #2DB44D;
|
||||
}
|
||||
}
|
||||
.versionTag.orange{
|
||||
border: 1px solid #FF6E23;
|
||||
color: #FF6E23;
|
||||
&::before{
|
||||
border-left-color: #FF6E23;
|
||||
}
|
||||
}
|
||||
.addReleaseBtn{
|
||||
text-align: right;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.versionName{
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
|
||||
.versionmilepostleft{
|
||||
padding: 15px;
|
||||
margin-right: 50px;
|
||||
width: 80%;
|
||||
}
|
||||
.topWrapper_btn_close {
|
||||
background: #504b4b;
|
||||
color: #FFFFFF!important;
|
||||
padding:0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.topWrapper_btn_delete {
|
||||
background: #da1010;
|
||||
color: #FFFFFF!important;
|
||||
padding:0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.versionrighe{
|
||||
flex: 2;
|
||||
}
|
||||
.versionleft{
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
/* .version_line{
|
||||
display: flex;
|
||||
height: 30px;
|
||||
margin: auto;
|
||||
border-left:1px solid #eee;
|
||||
} */
|
||||
.version_line_one{
|
||||
display: flex;
|
||||
height: 45px;
|
||||
margin: auto;
|
||||
border-left:1px solid #eee;
|
||||
}
|
||||
|
||||
.version_line_tpw{
|
||||
display: flex;
|
||||
height: 80px;
|
||||
margin: auto;
|
||||
border-left:1px solid #eee;
|
||||
}
|
||||
|
||||
.versiondiv{
|
||||
display: flex;
|
||||
}
|
||||
.verwinth{
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
/*开启中 关闭中*/
|
||||
.opendversionetail{
|
||||
display: inline-block;
|
||||
background: #21ba45;
|
||||
color: #ffffff!important;
|
||||
padding:0px 5px;
|
||||
text-align: center;
|
||||
height: 25px;
|
||||
/*width: 110px;*/
|
||||
border-radius: 4px;
|
||||
line-height: 25px;
|
||||
}
|
||||
.closedversionetail{
|
||||
display: inline-block;
|
||||
background: #e60b0b;
|
||||
color: #ffffff!important;
|
||||
padding:0px 5px;
|
||||
text-align: center;
|
||||
height: 25px;
|
||||
/*width: 110px;*/
|
||||
border-radius: 4px;
|
||||
line-height: 25px;
|
||||
}
|
||||
.versionrectangle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 100%;
|
||||
margin-top: 15px;
|
||||
margin-left: -4px;
|
||||
margin-bottom: 10px;
|
||||
background: rgb(83, 81, 81);
|
||||
}
|
||||
.ver-middle{
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* new */
|
||||
.versionForm{
|
||||
flex:1;
|
||||
padding-right: 40px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.versionTips{
|
||||
width:268px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.infosTip{
|
||||
border-bottom: 1px solid #EEEEEE;
|
||||
color: #333;
|
||||
padding-bottom: 26px;
|
||||
margin-bottom: 26px;
|
||||
font-weight: 400;
|
||||
text-align: justify;
|
||||
&:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
.dragBox{
|
||||
background: rgba(153, 153, 153, 0.04);
|
||||
border-radius: 4px;
|
||||
border: 1px dashed #d9d9d9;
|
||||
padding:20px;
|
||||
.versionStyle{
|
||||
border: none!important;
|
||||
padding-bottom:20px;
|
||||
.dragIcon{
|
||||
font-size: 40px!important;
|
||||
color: #666!important;
|
||||
line-height: 40px;
|
||||
height: 40px;
|
||||
margin-bottom: 14px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.ant-upload-list-item:hover .ant-upload-list-item-info {
|
||||
background-color: rgba(239, 244, 255, 1);
|
||||
}
|
||||
.ant-upload-list-item-info{
|
||||
padding:0px 20px 0px 8px;
|
||||
&>span{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.set-ant-row .ant-row{
|
||||
display: flex;
|
||||
height: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
.itemInline{
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
&>p{
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
}
|
||||
}
|
||||
.itemInline .ant-row{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.prerelease{
|
||||
padding-top: 20px;
|
||||
.ant-form-item-control{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
.releaseIndex{
|
||||
margin: 30px auto;
|
||||
width: 1200px;
|
||||
}
|
||||
.emptyPanel{
|
||||
width: 100%;
|
||||
background: #FAFCFF;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(42, 97, 255, 0.23);
|
||||
min-height: 418px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.operation{
|
||||
width: 400px;
|
||||
border-top: 1px solid #eee;
|
||||
padding-top: 34px;
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
.ant-form-item-control{
|
||||
line-height: initial;
|
||||
}
|
|
@ -39,7 +39,7 @@
|
|||
z-index: 1;
|
||||
}
|
||||
.ant-input-group .ant-input:focus{
|
||||
border-right: 1px solid #d9d9d9!important;
|
||||
border-right: 1px solid rgba(70, 106, 255, 1)!important;
|
||||
}
|
||||
.ant-btn-primary.grey{
|
||||
border:1px solid #BBBBBB;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { Component } from "react";
|
||||
import { Upload, Icon , Button } from 'antd';
|
||||
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
||||
import { AlignCenter } from '../Component/layout';
|
||||
|
||||
import axios from 'axios';
|
||||
const { Dragger } = Upload;
|
||||
|
@ -64,7 +63,6 @@ class Index extends Component {
|
|||
changeIsComplete && changeIsComplete(true);
|
||||
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||
let fileList = info.fileList;
|
||||
|
||||
this.setState({ fileList: appendFileSizeToUploadFileAll(fileList) });
|
||||
this.fileIdList(fileList);
|
||||
}
|
||||
|
@ -111,7 +109,7 @@ class Index extends Component {
|
|||
:
|
||||
<Dragger {...upload} className={className}>
|
||||
{icon || <Icon type="inbox" />}
|
||||
<p className="ant-upload-text font-14">拖动文件或<span className="color-blue">点击此处上传</span></p>
|
||||
<p className="ant-upload-text font-14">拖动文件或点击此处上传</p>
|
||||
</Dragger>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
|
||||
1.请求URL: https://code.ihub.org.cn/api/v1/mirrors/create.json
|
||||
|
||||
2.请求方式: POST
|
||||
|
||||
3.参数:
|
||||
|
||||
{
|
||||
"image_url": "xxx.git", #必填,且后缀必为.git,
|
||||
"language": "Ruby", #必填,如数据库不存在,则会创建新的记录
|
||||
}
|
||||
|
||||
|
||||
4. 返回值: {
|
||||
"status": 1,
|
||||
"message": "同步成功,项目ID===1806"
|
||||
}
|
||||
|
||||
5. 返回值说明: 仅有当有返回值,且返回值的status 的值为1, 才是创建成功,其余均为创建失败
|
||||
|
||||
|
|
@ -1,278 +0,0 @@
|
|||
import React, { useState, useEffect, useCallback, forwardRef } from "react";
|
||||
import styled from "styled-components";
|
||||
import { AutoComplete, Select, Input, Checkbox, Button, Form } from "antd";
|
||||
|
||||
import Editor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import Upload from "../Upload/Index";
|
||||
import Attachments from "../Upload/attachment";
|
||||
import axios from "axios";
|
||||
import "./version.css";
|
||||
import UploadImg from "../Images/upload.png";
|
||||
import { getBranch } from '../GetData/getData';
|
||||
|
||||
const { Option } = AutoComplete;
|
||||
|
||||
export default Form.create()(
|
||||
forwardRef(
|
||||
(
|
||||
{ form, projectDetail , match, showNotification, history },
|
||||
ref
|
||||
) => {
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
const [tagList, setTagList] = useState(undefined);
|
||||
const [branchList, setBranchList] = useState(undefined);
|
||||
const [desc, setDesc] = useState(null);
|
||||
const [fileList, setFileList] = useState(undefined);
|
||||
const [attachment, setAttachment] = useState(undefined);
|
||||
const [options , setOptions] = useState(undefined);
|
||||
|
||||
|
||||
const repo_id = projectDetail && projectDetail.repo_id;
|
||||
const { projectsId, versionId , owner } = match.params;
|
||||
useEffect(()=>{
|
||||
getBranchs(projectsId,owner);
|
||||
},[projectsId])
|
||||
|
||||
async function getBranchs(id,owner){
|
||||
let result = await getBranch(id,owner);
|
||||
setBranchList(result);
|
||||
}
|
||||
|
||||
const Span = styled.span`
|
||||
margin: 0px 15px;
|
||||
color: #bbb;
|
||||
line-height: 35px;
|
||||
`;
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (versionId) {
|
||||
const url = `/${owner}/${projectsId}/releases/${versionId}/edit.json`;
|
||||
axios.get(url).then(result => {
|
||||
if (result) {
|
||||
setFieldsValue(result.data);
|
||||
setDesc(result.data.body);
|
||||
setAttachment(result.data.attachments);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [versionId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (projectsId) {
|
||||
const url = `/${owner}/${projectsId}/tags.json`;
|
||||
axios
|
||||
.get(url,{params:{
|
||||
limit:1000
|
||||
}})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
setTagList(result.data);
|
||||
setOptions(renderTagList(result.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}, [projectsId]);
|
||||
|
||||
function renderTagList(list) {
|
||||
if (list) {
|
||||
let array = list.map((item, key) => {
|
||||
return (
|
||||
<Option key={key} value={item.name}>
|
||||
{item.name}
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
return array || undefined;
|
||||
}
|
||||
}
|
||||
function submit() {
|
||||
validateFields((err, value) => {
|
||||
if(err)return;
|
||||
if (versionId) {
|
||||
let url = `/${owner}/${projectsId}/releases/${versionId}.json`;
|
||||
axios
|
||||
.put(url, {
|
||||
...value,
|
||||
body: desc,
|
||||
attachment_ids: fileList
|
||||
})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
showNotification("版本修改成功!");
|
||||
history.push(`/${owner}/${projectsId}/releases`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let url = `/${owner}/${projectsId}/releases.json`;
|
||||
axios.post(url, {
|
||||
...value,
|
||||
body: desc,
|
||||
attachment_ids: fileList
|
||||
})
|
||||
.then(result => {
|
||||
if (result) {
|
||||
showNotification("版本发布成功!");
|
||||
history.push(`/${owner}/${projectsId}/releases`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, isRequired = true) => (
|
||||
<React.Fragment>
|
||||
<span required={isRequired}>{label}</span>
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
),
|
||||
[]
|
||||
);
|
||||
// 输入标签名
|
||||
function changeAuto(value){
|
||||
let l = tagList.filter(item=>item.name.indexOf(value) > -1);
|
||||
setOptions(renderTagList(l));
|
||||
}
|
||||
return (
|
||||
<div className="main df">
|
||||
<Form className="versionForm">
|
||||
<div>
|
||||
<p className="font-16 color-grey-3 mb15">{versionId?"编辑":"创建"}发行版</p>
|
||||
<div>
|
||||
<div className="itemInline">
|
||||
{helper(
|
||||
"",
|
||||
"tag_name",
|
||||
[{ required: true, message: "请输入获取或选择一个标签" }],
|
||||
<AutoComplete
|
||||
placeholder="标记一个版本"
|
||||
onChange={changeAuto}
|
||||
style={{ width: "200px" }}
|
||||
>
|
||||
{options}
|
||||
</AutoComplete>
|
||||
)}
|
||||
<Span>@</Span>
|
||||
{helper(
|
||||
"",
|
||||
"target_commitish",
|
||||
[{ required: true, message: "请选择一个分支" }],
|
||||
<Select
|
||||
placeholder="请选择一个分支"
|
||||
style={{ width: "200px" }}
|
||||
showArrow={false}
|
||||
>
|
||||
{renderTagList(branchList)}
|
||||
</Select>
|
||||
)}
|
||||
</div>
|
||||
<p className="font-13 color-grey-8">
|
||||
选择一个已经存在的标签,或者在发布时新建一个标签
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt20">
|
||||
{helper(
|
||||
"",
|
||||
"name",
|
||||
[{ required: true, message: "请输入发行版的标题" }],
|
||||
<Input placeholder="发行版的标题" />
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Editor
|
||||
placeholder={"描述此发行版"}
|
||||
height={200}
|
||||
mdID={`version-comments-description`}
|
||||
initValue={desc}
|
||||
onChange={setDesc}
|
||||
/>
|
||||
</div>
|
||||
<div className="set-ant-row">
|
||||
{helper(
|
||||
"",
|
||||
"prerelease",
|
||||
[],
|
||||
<Checkbox>这是一个预览版本</Checkbox>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Upload
|
||||
className="versionStyle"
|
||||
isComplete={true}
|
||||
load={setFileList}
|
||||
icon={
|
||||
<img
|
||||
src={UploadImg}
|
||||
width="58"
|
||||
alt=""
|
||||
style={{ marginBottom: 15 }}
|
||||
/>
|
||||
}
|
||||
size={100}
|
||||
showNotification={showNotification}
|
||||
/>
|
||||
{versionId && attachment && attachment.length > 0 ? (
|
||||
<Attachments
|
||||
attachments={attachment}
|
||||
showNotification={showNotification}
|
||||
canDelete={true}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<p className="pt20">
|
||||
<Button onClick={submit} type="primary" className="mr30">
|
||||
{versionId ? "保存" : "创建"}发行版
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
history.push(`/${owner}/${projectsId}/releases`)
|
||||
}
|
||||
style={{
|
||||
backgroundColor: "rgba(187,187,187,1)",
|
||||
color: "#fff"
|
||||
}}
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
</Form>
|
||||
<div className="versionTips">
|
||||
<div className="infosTip">
|
||||
<p className="font-16 mb15">标签命名建议</p>
|
||||
<p className="mb15">
|
||||
通常的做法是在版本名称前加上字母 v 前缀, v1.0 或者 v2.3.4。
|
||||
</p>
|
||||
<p>
|
||||
如果标签不适合在生产环境下使用,请在版本名称后添加预发行版本。例如:v0.2-alpha
|
||||
或者 v5.9-beta.3。
|
||||
</p>
|
||||
</div>
|
||||
<div className="infosTip">
|
||||
<p className="font-16 mb15">语义化版本</p>
|
||||
<p className="mb15">
|
||||
如果你是第一次发布版本,我们强烈建议你阅读语义化版本。
|
||||
</p>
|
||||
</div>
|
||||
<div className="infosTip">
|
||||
<p className="font-16 mb15">附件大小说明</p>
|
||||
<p className="mb15">
|
||||
单个附件不能超过 100M(GVP 项目200M),每个仓库总附件不可超过
|
||||
1G(推荐项目不可超过 5G;GVP 项目不可超过
|
||||
20G)。附件总容量统计包括仓库附件和发行版附件。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
|
@ -1,205 +0,0 @@
|
|||
.topWrapper {
|
||||
padding: 20px 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #EEEEEE;
|
||||
align-items: center;
|
||||
}
|
||||
.topWrapper_btn_new {
|
||||
background: #fff;
|
||||
color: #5091FF!important;
|
||||
padding:0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
border:1px solid #5091FF;
|
||||
}
|
||||
.versionInfo{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.versionInfo_left{
|
||||
display: flex;
|
||||
width: 30%;
|
||||
padding-top: 20px;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
padding-right: 15px;
|
||||
}
|
||||
.versionInfo_right{
|
||||
flex: 1;
|
||||
padding: 20px 0px 20px 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
.versionTag{
|
||||
display: inline;
|
||||
border-radius: 2px;
|
||||
padding:2px 12px;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
.versionTag.yellow{
|
||||
background-color: #FBBC06;
|
||||
}
|
||||
.versionTag.green{
|
||||
background-color: #20BA45;
|
||||
}
|
||||
.versionTag.orange{
|
||||
background-color: #F2711D;
|
||||
}
|
||||
.versionName{
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
position: relative;
|
||||
}
|
||||
.versionName::before{
|
||||
position: absolute;
|
||||
left: -19px;
|
||||
top:8px;
|
||||
content: '';
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #5091FF;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
|
||||
.versionmilepostleft{
|
||||
padding: 15px;
|
||||
margin-right: 50px;
|
||||
width: 80%;
|
||||
}
|
||||
.topWrapper_btn_close {
|
||||
background: #504b4b;
|
||||
color: #FFFFFF!important;
|
||||
padding:0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.topWrapper_btn_delete {
|
||||
background: #da1010;
|
||||
color: #FFFFFF!important;
|
||||
padding:0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.versionrighe{
|
||||
flex: 2;
|
||||
}
|
||||
.versionleft{
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
/* .version_line{
|
||||
display: flex;
|
||||
height: 30px;
|
||||
margin: auto;
|
||||
border-left:1px solid #eee;
|
||||
} */
|
||||
.version_line_one{
|
||||
display: flex;
|
||||
height: 45px;
|
||||
margin: auto;
|
||||
border-left:1px solid #eee;
|
||||
}
|
||||
|
||||
.version_line_tpw{
|
||||
display: flex;
|
||||
height: 80px;
|
||||
margin: auto;
|
||||
border-left:1px solid #eee;
|
||||
}
|
||||
|
||||
.versiondiv{
|
||||
display: flex;
|
||||
}
|
||||
.verwinth{
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
/*开启中 关闭中*/
|
||||
.opendversionetail{
|
||||
display: inline-block;
|
||||
background: #21ba45;
|
||||
color: #ffffff!important;
|
||||
padding:0px 5px;
|
||||
text-align: center;
|
||||
height: 25px;
|
||||
/*width: 110px;*/
|
||||
border-radius: 4px;
|
||||
line-height: 25px;
|
||||
}
|
||||
.closedversionetail{
|
||||
display: inline-block;
|
||||
background: #e60b0b;
|
||||
color: #ffffff!important;
|
||||
padding:0px 5px;
|
||||
text-align: center;
|
||||
height: 25px;
|
||||
/*width: 110px;*/
|
||||
border-radius: 4px;
|
||||
line-height: 25px;
|
||||
}
|
||||
.versionrectangle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 100%;
|
||||
margin-top: 15px;
|
||||
margin-left: -4px;
|
||||
margin-bottom: 10px;
|
||||
background: rgb(83, 81, 81);
|
||||
}
|
||||
.ver-middle{
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* new */
|
||||
.versionForm{
|
||||
flex:1;
|
||||
padding-right: 30px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.versionTips{
|
||||
width:30%;
|
||||
padding-left: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.infosTip{
|
||||
padding:20px;
|
||||
background-color: #F1F8FF;
|
||||
margin-bottom: 22px;
|
||||
color: #333;
|
||||
}
|
||||
.versionStyle{
|
||||
height: 200px!important;
|
||||
border: 1px dashed rgba(80,145,255,1)!important;
|
||||
}
|
||||
.set-ant-row .ant-row{
|
||||
display: flex;
|
||||
height: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
.itemInline{
|
||||
display: flex;
|
||||
align-item: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.itemInline .ant-row{
|
||||
margin-bottom: 0px;
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Spin } from 'antd';
|
||||
import NoneData from '../Nodata';
|
||||
import './version.css';
|
||||
import axios from 'axios';
|
||||
import RenderHtml from '../../components/render-html';
|
||||
|
||||
/**
|
||||
* issue_chosen:下拉的筛选列表,
|
||||
* data:列表接口返回的所有数据,
|
||||
* issues:列表数组,
|
||||
* isSpin:加载中,
|
||||
*/
|
||||
class version extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
issue_chosen: undefined,
|
||||
data: undefined,
|
||||
releases:undefined,
|
||||
issues: undefined,
|
||||
isSpin: true,
|
||||
search: undefined,
|
||||
search_count: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.getIssueList();
|
||||
}
|
||||
// 获取列表数据
|
||||
getIssueList = () => {
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
const url = `/${owner}/${projectsId}/releases.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
releases:result.data.releases,
|
||||
issues: result.data.issues,
|
||||
isSpin: false
|
||||
})
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
// 显示版本描述
|
||||
showBody=(key,flag)=>{
|
||||
let { releases } = this.state;
|
||||
releases[key].bodyshow = !flag;
|
||||
this.setState({
|
||||
releases
|
||||
})
|
||||
}
|
||||
|
||||
renderList = (releases) => {
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { isManager , isDeveloper } = this.props;
|
||||
const type = this.props.projectDetail && this.props.projectDetail.type;
|
||||
|
||||
if (releases && releases.length > 0) {
|
||||
return (
|
||||
releases.map((item, key) => {
|
||||
return (
|
||||
<div className="versionInfo" key={key}>
|
||||
<span className="versionInfo_left">
|
||||
<span className={`${item.draft === "稳定" ?"versionTag green":"versionTag yellow"}`}>{item.draft}</span>
|
||||
<span className="mt10">{item.created_at}</span>
|
||||
<span className="color-grey-8">
|
||||
<i className="iconfont icon-biaoqian3 mr3 font-14"></i>
|
||||
{item.tag_name}
|
||||
</span>
|
||||
</span>
|
||||
<div className="versionInfo_right">
|
||||
<span className="versionName">
|
||||
<span className="task-hide">{item.name}</span>
|
||||
{
|
||||
(isManager || isDeveloper) && type !==2 &&
|
||||
<Link to={`/${owner}/${projectsId}/releases/${item.version_id}/update`} className="color-blue ml3 font-12">(编辑)</Link>
|
||||
}
|
||||
</span>
|
||||
<span className="color-grey-3">
|
||||
<i className={`${item.bodyshow ? "iconfont icon-sanjiaoxing-down color-grey-8 mr3 font-14":"iconfont icon-triangle color-grey-8 mr3 font-14"}`} onClick={()=>this.showBody(key,item.bodyshow)}></i>
|
||||
{item.user_name}:<span className="color-grey-8">发布了这个版本,并在发布后提交给{item.target_commitish}</span>
|
||||
</span>
|
||||
{
|
||||
item.bodyshow && <RenderHtml className="break_word_comments imageLayerParent" value={item.body} url={this.props.history.location}/>
|
||||
}
|
||||
<RenderHtml />
|
||||
<p className="mt10 pl3">
|
||||
<a href={item.tarball_url} style={{color:"#4CC1DA"}} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
||||
<a href={item.zipball_url} style={{color:"#28BD6C"}}><i className="iconfont icon-ZIP font-18 mr5"></i>ZIP</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
)
|
||||
} else if (releases && releases.length === 0) {
|
||||
return ( <NoneData _html="暂时还没有相关数据!" /> )
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { projectsId ,owner } = this.props.match.params;
|
||||
const { data , releases , isSpin } = this.state;
|
||||
const type = this.props.projectDetail && this.props.projectDetail.type;
|
||||
return (
|
||||
<div className="main" style={{padding:"0px"}}>
|
||||
<div className="topWrapper" style={{padding:"15px 20px"}}>
|
||||
<span className="font-18 color-grey-3">版本发布</span>
|
||||
{
|
||||
data && data.user_permission && type !== 2 ?
|
||||
<Link to={`/${owner}/${projectsId}/releases/new`} className="topWrapper_btn_new">+ 发布新版</Link>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
<div className="releasesVersion">
|
||||
<Spin spinning={isSpin}><div>{this.renderList(releases)}</div></Spin>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default version;
|
|
@ -143,7 +143,7 @@ form.ant-form{
|
|||
}
|
||||
form{
|
||||
.ant-row.ant-form-item{
|
||||
margin-bottom: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1000px){
|
||||
|
@ -285,4 +285,29 @@ form{
|
|||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn-83{
|
||||
width: 83px;
|
||||
height: 32px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
background: #FAFBFC;
|
||||
border: 1px solid #D0D0D0;
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
font-weight: 500;
|
||||
color: #333333!important;
|
||||
&:hover,&:active{
|
||||
background: #F3F4F6;
|
||||
color: #333333!important;
|
||||
}
|
||||
}
|
||||
a.hover:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
button.ant-btn-primary.btnblue{
|
||||
background-color:rgba(70, 106, 255, 1);
|
||||
&:hover{
|
||||
background-color:rgba(70, 106, 255, 0.85);
|
||||
}
|
||||
}
|
|
@ -30,11 +30,11 @@
|
|||
|
||||
.ant-upload-list-item-info .anticon-loading,
|
||||
.ant-upload-list-item-info .anticon-paper-clip {
|
||||
color: #29bd8b !important;
|
||||
color: rgba(102, 102, 102, 1) !important;
|
||||
}
|
||||
|
||||
.anticon anticon-paper-clip {
|
||||
color: #29bd8b !important;
|
||||
color: rgba(102, 102, 102, 1) !important;
|
||||
}
|
||||
|
||||
.MuiModal-root-15 {
|
||||
|
|
|
@ -938,7 +938,7 @@ body #root {
|
|||
}
|
||||
|
||||
.ant-input:focus {
|
||||
border: 1px solid #d9d9d9 !important;
|
||||
border: 1px solid rgba(70, 106, 255, 1) !important;
|
||||
}
|
||||
|
||||
/* 公用的文字按钮:蓝、白、灰 */
|
||||
|
@ -1423,7 +1423,7 @@ samp {
|
|||
}
|
||||
|
||||
.newcourses .ant-select-selection--single:hover {
|
||||
border: 1px solid #d9d9d9 !important;
|
||||
border: 1px solid rgba(70, 106, 255, 1) !important;
|
||||
}
|
||||
|
||||
.pd20 {
|
||||
|
@ -1528,9 +1528,6 @@ samp {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.exerciselist .ant-input {
|
||||
border: 1px solid #d9d9d9 !important;
|
||||
}
|
||||
|
||||
.exercisetime .ant-form-explain {
|
||||
margin-left: 107px;
|
||||
|
@ -1689,18 +1686,12 @@ samp {
|
|||
height: 40px;
|
||||
}
|
||||
|
||||
.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled) {
|
||||
border: 1px solid #d9d9d9 !important;
|
||||
}
|
||||
|
||||
.ant-input-affix-wrapper .ant-input-prefix,
|
||||
.ant-input-affix-wrapper .ant-input-suffix {
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
.ant-input:hover {
|
||||
border: 1px solid #d9d9d9 !important;
|
||||
}
|
||||
|
||||
.ant-input:focus {
|
||||
box-shadow: none !important;
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){
|
||||
border:1px solid #d9d9d9!important;
|
||||
}
|
||||
.ant-input:hover{
|
||||
border:1px solid #d9d9d9!important;
|
||||
}
|
||||
.ant-input:focus{
|
||||
box-shadow:none!important;
|
||||
background-color: #fff!important;
|
||||
|
|
|
@ -163,7 +163,6 @@ body>.-task-title {
|
|||
outline: 0;
|
||||
-webkit-box-shadow: 0 0 0 2px transparent;
|
||||
box-shadow: 0 0 0 2px transparent;
|
||||
border: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
.HeaderSearch .ant-input-search .ant-input::-webkit-input-placeholder {
|
||||
|
|
Loading…
Reference in New Issue