2020-09-28 14:51:24 +08:00
|
|
|
import React, { useState, useEffect , useImperativeHandle ,forwardRef } from "react";
|
2021-01-11 17:18:12 +08:00
|
|
|
import { FlexAJ, AlignCenter , Banner } from "../Component/layout";
|
2020-07-31 20:15:28 +08:00
|
|
|
import { Table, Pagination, Popconfirm } from "antd";
|
|
|
|
|
import { truncateCommitId } from "../common/util";
|
2020-08-26 16:09:27 +08:00
|
|
|
import {getUrl} from 'educoder';
|
2020-07-31 20:15:28 +08:00
|
|
|
import axios from "axios";
|
2020-07-27 18:45:18 +08:00
|
|
|
|
2021-01-11 17:18:12 +08:00
|
|
|
import styled from 'styled-components';
|
|
|
|
|
|
|
|
|
|
const Div = styled.div`{
|
|
|
|
|
padding:24px 30px;
|
|
|
|
|
}`;
|
2020-07-10 15:42:57 +08:00
|
|
|
const STATUS = [
|
2020-08-26 16:09:27 +08:00
|
|
|
{ name: "所有"},
|
|
|
|
|
{ name: "运行中", value: "running" },
|
2020-09-11 17:35:05 +08:00
|
|
|
{ name: "已撤销", value: "killed" },
|
|
|
|
|
{ name: "构建失败", value: "failure" },
|
2020-08-26 16:09:27 +08:00
|
|
|
{ name: "已完成", value: "success" },
|
2020-07-31 20:15:28 +08:00
|
|
|
];
|
2020-07-10 15:42:57 +08:00
|
|
|
const LIMIT = 15;
|
2020-09-28 14:51:24 +08:00
|
|
|
function Structure(props,ref){
|
2020-08-26 16:09:27 +08:00
|
|
|
const [status, setStatus] = useState(undefined);
|
2020-07-31 20:15:28 +08:00
|
|
|
const [page, setPage] = useState(1);
|
2020-08-26 16:09:27 +08:00
|
|
|
const [total, setTotal] = useState(0);
|
2020-07-31 20:15:28 +08:00
|
|
|
const [data, setData] = useState(undefined);
|
|
|
|
|
const [tableLoading, setTableLoading] = useState(true);
|
2020-07-10 15:42:57 +08:00
|
|
|
|
2020-09-11 17:35:05 +08:00
|
|
|
let projectsId = props.match.params.projectsId;
|
|
|
|
|
let owner = props.match.params.owner;
|
2020-10-16 17:29:10 +08:00
|
|
|
const permission = props.projectDetail && props.projectDetail.permission;
|
2020-08-26 16:09:27 +08:00
|
|
|
|
2020-09-28 14:51:24 +08:00
|
|
|
useImperativeHandle(ref, () => ({
|
|
|
|
|
changeVal: () => {
|
|
|
|
|
setTableLoading(true);
|
|
|
|
|
Init();
|
|
|
|
|
}
|
|
|
|
|
}))
|
2020-10-16 17:29:10 +08:00
|
|
|
|
2020-07-31 20:15:28 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (projectsId) {
|
|
|
|
|
Init();
|
|
|
|
|
}
|
2020-11-27 16:29:08 +08:00
|
|
|
}, [page]);
|
2020-10-16 17:29:10 +08:00
|
|
|
|
2020-08-26 16:09:27 +08:00
|
|
|
let current_user = props.current_user;
|
|
|
|
|
function Init(status) {
|
|
|
|
|
const url = `/${owner}/${projectsId}/builds.json`;
|
|
|
|
|
axios.get(url,{
|
|
|
|
|
params:{
|
|
|
|
|
search:status,
|
|
|
|
|
page,limit:LIMIT
|
|
|
|
|
}
|
|
|
|
|
}).then((result) => {
|
|
|
|
|
if (result && result.data) {
|
|
|
|
|
let list = result.data.builds && result.data.builds.map((item, key) => {
|
|
|
|
|
return {
|
|
|
|
|
...item,
|
|
|
|
|
author:item.author && item.author.name,
|
|
|
|
|
message: {
|
|
|
|
|
branch: item.branch_target,
|
|
|
|
|
message: item.message,
|
|
|
|
|
sha: truncateCommitId(item.build_after_sha),
|
|
|
|
|
},
|
|
|
|
|
started: item.started || "--"
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
setTotal(result.data.total_count);
|
|
|
|
|
setData(list);
|
|
|
|
|
setTableLoading(false);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.log(error);
|
|
|
|
|
});
|
2020-07-31 20:15:28 +08:00
|
|
|
}
|
2020-07-10 15:42:57 +08:00
|
|
|
|
2020-07-31 20:15:28 +08:00
|
|
|
function ChangeStatus(value) {
|
|
|
|
|
setStatus(value);
|
2020-08-26 16:09:27 +08:00
|
|
|
Init(value);
|
2020-07-10 15:42:57 +08:00
|
|
|
}
|
|
|
|
|
// 切换分页
|
2020-07-31 20:15:28 +08:00
|
|
|
function ChangePage(page) {
|
|
|
|
|
setPage(page);
|
2020-07-10 15:42:57 +08:00
|
|
|
}
|
|
|
|
|
function renderStatus() {
|
2020-07-31 20:15:28 +08:00
|
|
|
return (
|
2020-07-10 15:42:57 +08:00
|
|
|
<ul className="listNav">
|
2020-07-31 20:15:28 +08:00
|
|
|
{STATUS.map((item, key) => {
|
|
|
|
|
return (
|
|
|
|
|
<li
|
|
|
|
|
onClick={() => ChangeStatus(item.value)}
|
|
|
|
|
className={status === item.value ? "active" : ""}
|
|
|
|
|
>
|
|
|
|
|
{item.name}
|
|
|
|
|
</li>
|
|
|
|
|
);
|
|
|
|
|
})}
|
2020-07-10 15:42:57 +08:00
|
|
|
</ul>
|
2020-07-31 20:15:28 +08:00
|
|
|
);
|
2020-07-10 15:42:57 +08:00
|
|
|
}
|
2020-07-31 20:15:28 +08:00
|
|
|
function renderStatusBtn(status, number) {
|
2020-09-11 17:35:05 +08:00
|
|
|
if (status === "error" || status === "success") {
|
2020-08-26 16:09:27 +08:00
|
|
|
return "";
|
2020-09-11 17:35:05 +08:00
|
|
|
}else if(status === "killed" || status === "failure"){
|
2020-08-26 16:09:27 +08:00
|
|
|
return(
|
2020-07-31 20:15:28 +08:00
|
|
|
<Popconfirm
|
|
|
|
|
title="确认重新构建?"
|
|
|
|
|
onConfirm={(e) => repeatSet(e,number)}
|
|
|
|
|
onCancel={(e)=>{e.stopPropagation()}}
|
|
|
|
|
cancelText="取消"
|
|
|
|
|
okText="确定"
|
|
|
|
|
>
|
|
|
|
|
<a className="color-blue" onClick={(e)=>{e.stopPropagation()}}>重新构建</a>
|
|
|
|
|
</Popconfirm>
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return (
|
|
|
|
|
<Popconfirm
|
|
|
|
|
title="确认撤销构建?"
|
|
|
|
|
onConfirm={(e) => cancelSet(e,number)}
|
|
|
|
|
onCancel={(e)=>{e.stopPropagation()}}
|
|
|
|
|
cancelText="取消"
|
|
|
|
|
okText="确定"
|
|
|
|
|
>
|
|
|
|
|
<a className="color-red" onClick={(e)=>{e.stopPropagation()}}>撤销构建</a>
|
|
|
|
|
</Popconfirm>
|
|
|
|
|
);
|
2020-07-10 15:42:57 +08:00
|
|
|
}
|
|
|
|
|
}
|
2020-07-31 20:15:28 +08:00
|
|
|
// 重新构建
|
|
|
|
|
function repeatSet(e,number) {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setTableLoading(true);
|
2020-08-26 16:09:27 +08:00
|
|
|
const url = `/${owner}/${projectsId}/builds/${number}/restart.json`;
|
|
|
|
|
axios.post(url).then((result) => {
|
|
|
|
|
if (result) {
|
|
|
|
|
props.showNotification("工作流正在重新构建!");
|
|
|
|
|
Init();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.log(error);
|
|
|
|
|
});
|
2020-07-31 20:15:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 撤销构建
|
|
|
|
|
function cancelSet(e,number) {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
setTableLoading(true);
|
2020-08-26 16:09:27 +08:00
|
|
|
const url = `/${owner}/${projectsId}/builds/${number}/stop.json`;
|
|
|
|
|
axios.delete(url).then((result) => {
|
|
|
|
|
if (result) {
|
|
|
|
|
props.showNotification("撤销构建成功!");
|
|
|
|
|
Init(projectsId);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.log(error);
|
|
|
|
|
});
|
2020-07-31 20:15:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderTableStatus(status) {
|
|
|
|
|
switch (status) {
|
2020-07-27 18:45:18 +08:00
|
|
|
case "running":
|
2020-07-31 20:15:28 +08:00
|
|
|
return (
|
|
|
|
|
<span className="statusTag running">
|
|
|
|
|
<i className="iconfont icon-yunhangzhong"></i>运行中
|
|
|
|
|
</span>
|
2020-07-10 15:42:57 +08:00
|
|
|
);
|
2020-08-26 16:09:27 +08:00
|
|
|
case "failure": case 'error':
|
2020-07-10 15:42:57 +08:00
|
|
|
return (
|
2020-07-31 20:15:28 +08:00
|
|
|
<span className="statusTag failed">
|
|
|
|
|
<i className="iconfont icon-weitongguo"></i>未通过
|
|
|
|
|
</span>
|
2020-07-10 15:42:57 +08:00
|
|
|
);
|
2020-07-27 18:45:18 +08:00
|
|
|
case "success":
|
2020-07-10 15:42:57 +08:00
|
|
|
return (
|
2020-07-31 20:15:28 +08:00
|
|
|
<span className="statusTag pass">
|
|
|
|
|
<i className="iconfont icon-yitongguo"></i>已通过
|
|
|
|
|
</span>
|
2020-07-10 15:42:57 +08:00
|
|
|
);
|
2020-08-26 16:09:27 +08:00
|
|
|
case 'killed':
|
|
|
|
|
return (
|
|
|
|
|
<span className="statusTag killed">
|
|
|
|
|
<i className="iconfont icon-weitongguo"></i>已撤销
|
|
|
|
|
</span>
|
|
|
|
|
);
|
|
|
|
|
case 'pending':
|
2020-07-10 15:42:57 +08:00
|
|
|
return (
|
2020-07-31 20:15:28 +08:00
|
|
|
<span className="statusTag Preparing">
|
|
|
|
|
<i className="iconfont icon-zhunbeizhong"></i>准备中
|
|
|
|
|
</span>
|
2020-07-10 15:42:57 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-31 20:15:28 +08:00
|
|
|
|
|
|
|
|
function clickRows(event,e){
|
2020-08-26 16:09:27 +08:00
|
|
|
props.history.push(`/projects/${owner}/${projectsId}/devops/${e.number}/detail`);
|
2020-07-31 20:15:28 +08:00
|
|
|
}
|
2020-07-10 15:42:57 +08:00
|
|
|
const column = [
|
|
|
|
|
{
|
2020-07-31 20:15:28 +08:00
|
|
|
title: "序号",
|
|
|
|
|
dataIndex: "number",
|
|
|
|
|
key: "number",
|
|
|
|
|
width: "8%",
|
|
|
|
|
render: ( value, item, key) => {
|
|
|
|
|
return <span>#{value}</span>;
|
|
|
|
|
},
|
2020-07-10 15:42:57 +08:00
|
|
|
},
|
|
|
|
|
{
|
2020-07-31 20:15:28 +08:00
|
|
|
title: "状态",
|
|
|
|
|
dataIndex: "status",
|
|
|
|
|
key: "status",
|
|
|
|
|
width: "12%",
|
|
|
|
|
render: (value, item, key) => {
|
|
|
|
|
return renderTableStatus(value);
|
|
|
|
|
},
|
2020-07-10 15:42:57 +08:00
|
|
|
},
|
|
|
|
|
{
|
2020-07-31 20:15:28 +08:00
|
|
|
title: "构建人",
|
|
|
|
|
dataIndex: "author",
|
|
|
|
|
key: "author",
|
|
|
|
|
width: "12%",
|
|
|
|
|
align: "center",
|
2020-07-10 15:42:57 +08:00
|
|
|
},
|
|
|
|
|
{
|
2020-07-31 20:15:28 +08:00
|
|
|
title: "提交信息",
|
|
|
|
|
dataIndex: "message",
|
|
|
|
|
key: "message",
|
|
|
|
|
width: "30%",
|
|
|
|
|
render: (value, item, key) => {
|
2020-07-10 15:42:57 +08:00
|
|
|
let meg = item.message;
|
2020-07-31 20:15:28 +08:00
|
|
|
return (
|
2020-07-10 15:42:57 +08:00
|
|
|
<React.Fragment>
|
|
|
|
|
<div>
|
2020-07-31 20:15:28 +08:00
|
|
|
{meg.branch && (
|
|
|
|
|
<span className="mr10 color-grey-8">
|
|
|
|
|
<i className="iconfont icon-fenzhi1 font-16 mr5"></i>分支
|
|
|
|
|
{meg.branch}
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
{meg.sha && <span className="color-orange">{meg.sha}</span>}
|
2020-07-10 15:42:57 +08:00
|
|
|
</div>
|
2020-07-27 18:45:18 +08:00
|
|
|
<AlignCenter>
|
2020-08-26 16:09:27 +08:00
|
|
|
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} src={`${current_user && getUrl(`/images/${current_user.image_url}`)}`} />
|
2020-07-31 20:15:28 +08:00
|
|
|
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
|
|
|
|
|
{meg.message}
|
|
|
|
|
</div>
|
2020-07-27 18:45:18 +08:00
|
|
|
</AlignCenter>
|
2020-07-10 15:42:57 +08:00
|
|
|
</React.Fragment>
|
2020-07-31 20:15:28 +08:00
|
|
|
);
|
|
|
|
|
},
|
2020-07-10 15:42:57 +08:00
|
|
|
},
|
|
|
|
|
{
|
2020-07-31 20:15:28 +08:00
|
|
|
title: "开始时间",
|
|
|
|
|
dataIndex: "started",
|
|
|
|
|
key: "started",
|
|
|
|
|
width: "15%",
|
|
|
|
|
render: (value, item, key) => {
|
|
|
|
|
return <span>{value || "--"}</span>;
|
|
|
|
|
},
|
2020-07-10 15:42:57 +08:00
|
|
|
},
|
|
|
|
|
{
|
2020-07-31 20:15:28 +08:00
|
|
|
title: "运行时间",
|
2020-08-26 16:09:27 +08:00
|
|
|
dataIndex: "duration_time",
|
|
|
|
|
key: "duration_time",
|
2020-07-31 20:15:28 +08:00
|
|
|
width: "15%",
|
|
|
|
|
render: (value, item, key) => {
|
2020-08-26 16:09:27 +08:00
|
|
|
return <span>{value || "--"}</span>;
|
2020-07-31 20:15:28 +08:00
|
|
|
},
|
2020-07-10 15:42:57 +08:00
|
|
|
},
|
|
|
|
|
{
|
2020-07-31 20:15:28 +08:00
|
|
|
title: "操作",
|
|
|
|
|
dataIndex: "operation",
|
|
|
|
|
key: "operation",
|
|
|
|
|
render: (value, item, key) => {
|
2020-10-16 17:29:10 +08:00
|
|
|
if(permission === "Admin" || permission === "Owner"){
|
|
|
|
|
return renderStatusBtn(item.status, item.number);
|
|
|
|
|
}else{
|
|
|
|
|
return "--";
|
|
|
|
|
}
|
2020-07-31 20:15:28 +08:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
return (
|
2021-01-11 17:18:12 +08:00
|
|
|
<div className="disposePanel">
|
|
|
|
|
<Banner>构建列表</Banner>
|
|
|
|
|
<Div>
|
|
|
|
|
<div className="listPart">
|
|
|
|
|
<FlexAJ>
|
|
|
|
|
{renderStatus()}
|
|
|
|
|
{/* <Blueback>手动创建</Blueback> */}
|
|
|
|
|
{/* <span className="mr30">
|
|
|
|
|
<i className="iconfont icon-fenzhi1 font-16 mr5 color-blue"></i>分支
|
|
|
|
|
</span>
|
|
|
|
|
<span>
|
|
|
|
|
<i className="iconfont icon-biaoqian3 font-16 mr5 color-blue"></i>
|
|
|
|
|
标签
|
|
|
|
|
</span> */}
|
|
|
|
|
</FlexAJ>
|
|
|
|
|
<Table
|
|
|
|
|
onRow={(record,index)=>{
|
|
|
|
|
return{
|
|
|
|
|
onClick:(event)=>clickRows(event,record)
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
columns={column}
|
|
|
|
|
className="normalTable"
|
|
|
|
|
dataSource={data}
|
|
|
|
|
pagination={false}
|
|
|
|
|
loading={tableLoading}
|
|
|
|
|
></Table>
|
|
|
|
|
{total > LIMIT ?
|
|
|
|
|
<div style={{ textAlign: "center", margin: "30px 50px" }}>
|
|
|
|
|
<Pagination
|
|
|
|
|
showQuickJumper
|
|
|
|
|
defaultCurrent={page}
|
|
|
|
|
total={total}
|
|
|
|
|
pageSize={LIMIT}
|
|
|
|
|
onChange={ChangePage}
|
|
|
|
|
></Pagination>
|
|
|
|
|
</div>
|
|
|
|
|
:
|
|
|
|
|
"" }
|
|
|
|
|
</div>
|
|
|
|
|
</Div>
|
2020-07-10 15:42:57 +08:00
|
|
|
</div>
|
2020-07-31 20:15:28 +08:00
|
|
|
);
|
|
|
|
|
};
|
2020-09-28 14:51:24 +08:00
|
|
|
export default forwardRef(Structure);
|