流水线卡片,关联id124514

This commit is contained in:
谢思 2025-02-19 11:12:49 +08:00
parent 03463ce3c4
commit caee38a169
15 changed files with 1608 additions and 1155 deletions

2283
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2340181 */
src: url('iconfont.woff2?t=1686823554834') format('woff2'),
url('iconfont.woff?t=1686823554834') format('woff'),
url('iconfont.ttf?t=1686823554834') format('truetype');
src: url('iconfont.woff2?t=1737515905908') format('woff2'),
url('iconfont.woff?t=1737515905908') format('woff'),
url('iconfont.ttf?t=1737515905908') format('truetype');
}
.iconfont {
@ -13,6 +13,82 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-a-fenzhi1:before {
content: "\e980";
}
.icon-yunxiazai:before {
content: "\e97b";
}
.icon-lunwen1:before {
content: "\e97c";
}
.icon-zhuanli2:before {
content: "\e97d";
}
.icon-jiantou2:before {
content: "\e97e";
}
.icon-jiantou-you-cuxiantiao:before {
content: "\e97f";
}
.icon-gongxianquequan:before {
content: "\e979";
}
.icon-xuanzhong5:before {
content: "\e97a";
}
.icon-big-circle:before {
content: "\e978";
}
.icon-gitee:before {
content: "\e974";
}
.icon-gitea:before {
content: "\e975";
}
.icon-coding:before {
content: "\e976";
}
.icon-github1:before {
content: "\e977";
}
.icon-gitlab:before {
content: "\e973";
}
.icon-a-lianhe6:before {
content: "\e972";
}
.icon-a-22ziliaoshouce-xianxing:before {
content: "\e971";
}
.icon-changjiantou:before {
content: "\e970";
}
.icon-bangzhuzhongxinicon2:before {
content: "\e96f";
}
.icon-liulan1:before {
content: "\e96e";
}
.icon-a-zu2044:before {
content: "\e96d";
}
@ -397,6 +473,10 @@
content: "\e90e";
}
.icon-shanchu_important:before {
content: "\f1d8";
}
.icon-shanchu_tc_icon1:before {
content: "\e90c";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,139 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "39410543",
"name": "分支 (1)",
"font_class": "a-fenzhi1",
"unicode": "e980",
"unicode_decimal": 59776
},
{
"icon_id": "42234576",
"name": "云下载",
"font_class": "yunxiazai",
"unicode": "e97b",
"unicode_decimal": 59771
},
{
"icon_id": "42234575",
"name": "论文",
"font_class": "lunwen1",
"unicode": "e97c",
"unicode_decimal": 59772
},
{
"icon_id": "42234574",
"name": "专利",
"font_class": "zhuanli2",
"unicode": "e97d",
"unicode_decimal": 59773
},
{
"icon_id": "42234573",
"name": "箭头",
"font_class": "jiantou2",
"unicode": "e97e",
"unicode_decimal": 59774
},
{
"icon_id": "42234572",
"name": "箭头-右-粗线条",
"font_class": "jiantou-you-cuxiantiao",
"unicode": "e97f",
"unicode_decimal": 59775
},
{
"icon_id": "41876673",
"name": "贡献确权",
"font_class": "gongxianquequan",
"unicode": "e979",
"unicode_decimal": 59769
},
{
"icon_id": "657556",
"name": "分期-选中",
"font_class": "xuanzhong5",
"unicode": "e97a",
"unicode_decimal": 59770
},
{
"icon_id": "157771",
"name": "细圆",
"font_class": "big-circle",
"unicode": "e978",
"unicode_decimal": 59768
},
{
"icon_id": "41539674",
"name": "gitee",
"font_class": "gitee",
"unicode": "e974",
"unicode_decimal": 59764
},
{
"icon_id": "41539676",
"name": "gitea",
"font_class": "gitea",
"unicode": "e975",
"unicode_decimal": 59765
},
{
"icon_id": "41539677",
"name": "coding",
"font_class": "coding",
"unicode": "e976",
"unicode_decimal": 59766
},
{
"icon_id": "41539675",
"name": "github",
"font_class": "github1",
"unicode": "e977",
"unicode_decimal": 59767
},
{
"icon_id": "41539679",
"name": "gitlab",
"font_class": "gitlab",
"unicode": "e973",
"unicode_decimal": 59763
},
{
"icon_id": "41195024",
"name": "联合 6",
"font_class": "a-lianhe6",
"unicode": "e972",
"unicode_decimal": 59762
},
{
"icon_id": "40333433",
"name": "使用手册",
"font_class": "a-22ziliaoshouce-xianxing",
"unicode": "e971",
"unicode_decimal": 59761
},
{
"icon_id": "40172194",
"name": "长箭头",
"font_class": "changjiantou",
"unicode": "e970",
"unicode_decimal": 59760
},
{
"icon_id": "37836900",
"name": "帮助中心icon",
"font_class": "bangzhuzhongxinicon2",
"unicode": "e96f",
"unicode_decimal": 59759
},
{
"icon_id": "36898536",
"name": "浏览",
"font_class": "liulan1",
"unicode": "e96e",
"unicode_decimal": 59758
},
{
"icon_id": "36020261",
"name": "组 2044",
@ -677,6 +810,13 @@
"unicode": "e90e",
"unicode_decimal": 59662
},
{
"icon_id": "41976790",
"name": "shanchu_tc_icon-copy",
"font_class": "shanchu_important",
"unicode": "f1d8",
"unicode_decimal": 61912
},
{
"icon_id": "26470602",
"name": "shanchu_tc_icon",

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -32,7 +32,7 @@ export function initAxiosInterceptors(props) {
// 判断网络是否连接
initOnlineOfflineListener();
var proxy = "https://testforgeplus.trustie.net";
var proxy = "http://172.20.32.201:4000";
//响应前的设置
axios.interceptors.request.use(

View File

@ -135,4 +135,25 @@ export function timeAgo(backDate) {
// return seconds + "秒前";
// }
return "刚刚";
}
// seconds: 秒数,返回格式为 xxhxxmxxs 的字符串
export function secondsToTimeFormat(seconds) {
const hours = Math.floor(seconds / 3600); // 计算小时数
const minutes = Math.floor((seconds % 3600) / 60); // 计算分钟数
const remainingSeconds = seconds % 60; // 计算剩余秒数
let result = "";
if (hours > 0) {
result += `${hours}h`;
}
if (minutes > 0) {
result += `${minutes}m`;
}
if (remainingSeconds > 0 || result === "") {
result += `${remainingSeconds}s`;
}
return result;
}

View File

@ -0,0 +1,80 @@
import { message, Popover } from "antd";
import React, { useEffect, useState } from "react";
import './index.scss';
import axios from "axios";
import { secondsToTimeFormat, timeAgo } from "../../../common/DateUtil";
import { getPipelineIdByFileName } from "../../Information/api";
import Nodata from "../../Nodata";
function CardDevops(props) {
const { project, history, match, mygetHelmetapi } = props || {};
const {owner, projectsId} = match.params;
const [list, setList] = useState([])
useEffect(() => {
const { author, name } = project || {}
document.title = `流水线-${author && author.name}/${name}`;
}, [])
useEffect(()=>{
getList();
const intervalId = setInterval(() => {
getList();
}, 10000);
return () => clearInterval(intervalId);
}, [])
function getList(){
axios.get(`/v1/${owner}/${projectsId}/actions/new_index.json`).then(res=>{
if(res && res.data){
setList(res.data.data);
}
})
}
const listType = {
1: '声明式',
2: '图形化',
}
const statusEnum = {
1: '成功',
2: '失败',
5: '等待',
6: '运行中'
}
return <div className="cardList">
{list && list.map(e=>{
return <div className={`card developStatus${e.status}`} onClick={()=>{
getPipelineIdByFileName(owner, owner, projectsId, e.filename).then(res=>{
if(res.data && res.data.code === 200){
window.location.href = `${mygetHelmetapi && mygetHelmetapi.common.zone}/${owner}/pipeline/${res.data.data.pipelineId}`
}else{
message.error("发生错误,请联系平台管理员")
}
})
}}>
<div className="statusBar"></div>
<div className="cardContent">
<div className="cartHead">
<div className={e.pipeline_type === 1 ? "f36" : ''}>{listType[e.pipeline_type]}</div>
<Popover content={e.name} ><span className="task-hide weight">{e.name}</span></Popover>
</div>
<div className="cardBody">
<p>
<div className={`statusIcon developStatus${e.status}`}></div>
{statusEnum[e.status] || e.filename ? "待启动" : "待设计"}
{!!e.index && <span>#{e.index} &nbsp;&nbsp;&nbsp;{timeAgo(e.stopped)}&nbsp;执行时长{secondsToTimeFormat(e.length)}</span>}
</p>
<p className="mt5"><i className="iconfont icon-a-fenzhi1 font-12 mr4 mb3"></i> 分支{e.branch}</p>
<div className="mt5">{e.schedule && <span className="scheduleBox mr10">定时</span>}历史共执行{e.total || 0}成功{e.success || 0}失败{e.failure || 0}</div>
</div>
</div>
</div>
})}
{list && !list.length && <div style={{margin: '100px auto'}}><Nodata _html="暂无数据"/></div>}
</div>
}
export default CardDevops

View File

@ -0,0 +1,123 @@
.cardList {
display: flex;
flex-wrap: wrap;
margin: 30px 20px;
.card {
width: 333px;
border-radius: 6px;
margin-right: 31px;
margin-bottom: 25px;
padding: 0 1px 1px 1px;
display: flex;
flex-direction: column;
cursor: pointer;
&:hover{
box-shadow: 0px 0px 15px 1px rgba(109,130,170,0.44);
}
.statusBar{
height: 6px;
margin: 0 4px;
}
.cardContent {
flex-grow: 2;
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
padding: 15px 17px 20px;
box-sizing: border-box;
.cartHead {
display: flex;
align-items: center;
div {
width: 57px;
height: 21px;
border-radius: 4px 4px 4px 4px;
border: 1px solid $primary-color;
font-size: 13px;
color: $primary-color;
line-height: 21px;
text-align: center;
margin-right: 11px;
}
.f36{
color: #F3651C;
border-color: #F3651C;
}
span {
font-family: 'alibaba-medium';
font-size: 16px;
color: #1E1E1E;
}
}
.cardBody {
margin-top: 12px;
background: rgba(212,223,241,0.24);
border-radius: 6px 6px 6px 6px;
padding: 15px;
font-size: 14px;
color: #082340;
box-sizing: border-box;
height: 75%;
p {
display: flex;
align-items: baseline;
}
.statusIcon {
width: 4px;
height: 12px;
border-radius: 6px 6px 6px 6px;
margin-right: 12px;
}
}
.cartBottom {
display: flex;
align-items: center;
.leftButton {
img {
width: 26px;
margin-right: 20px;
cursor: pointer;
}
}
.rightButton {
margin-left: auto;
font-size: 14px;
color: $primary-color;
}
}
}
.scheduleBox{
border-radius: 4px;
border: 1px solid #F3651C;
color: #F3651C;
padding: 3px 4px;
}
}
.statusIcon, .card, .statusBar{
background: #979797;
}
.developStatus2.statusIcon, .card.developStatus2, .developStatus2 .statusBar{
background: #EC6E66;
}
.developStatus1.statusIcon, .card.developStatus1, .developStatus1 .statusBar{
background: #07A35A;
}
.developStatus5.statusIcon, .card.developStatus5, .developStatus5 .statusBar{
background: #979797;
}
.developStatus6.statusIcon, .card.developStatus6, .developStatus6 .statusBar{
background: #2D74FB;
}
.card.developStatus6 .statusBar {
background-image: repeating-linear-gradient(115deg, #ffffff63 0, #2D74FB 1px, #2D74FB 10px, #ffffff63 11px, #ffffff63 20px);
animation: 3s linear 0s infinite normal none running workflow-running;
}
}
@keyframes workflow-running{
0% {
background-position-x: -53.5px;
}
100% {
background-position-x: 0;
}
}

View File

@ -292,4 +292,12 @@ export function getUserList(orgId){
url:`/pms/pmsEnterprise/gitlinkUserList/${orgId}`,
method: 'get',
})
}
// 根据流水线filename查询流水线java端id
export function getPipelineIdByFileName(enterpriseIdentifier, repoOwner, repoIdentifier, fileName){
return fetch({
url:`/pms/${enterpriseIdentifier}/pipelines/${repoOwner}/${repoIdentifier}/getPipelineId/${fileName}`,
method: 'get',
})
}

View File

@ -116,6 +116,10 @@ const DevIndex = Loadable({
loader: () => import('../DevOps/Index'),
loading: Loading,
});
const DevopsCard = Loadable({
loader: () => import('../DevOps/cardList'),
loading: Loading,
});
const Wiki = Loadable({
loader: () => import('../Wiki/Index'),
loading: Loading,
@ -750,10 +754,10 @@ class Detail extends Component {
() => (<Wiki {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 工作流 */}
{/* 水线: 仅对组织仓库开放 */}
<Route path="/:owner/:projectsId/devops"
render={
() => (<DevIndex {...this.props} {...this.state} {...common} />)
() => (<DevopsCard {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 标签列表 */}

View File

@ -92,17 +92,17 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
</Link>
</li>:""
}
{/* 引擎仅对当前仓库管理员可见 */}
{/* {
item.menu_name === "devops" ?
{/* 流水线: 仅对组织仓库开放<div className='newBtnImg'></div> */}
{
item.menu_name === "devops" && projectDetail.author.type === "Organization" ?
<li className={pathname==="devops" ? "active" : ""}>
<Link className='newTab' to={{ pathname: `/${owner}/${projectsId}/devops`, state:{...state,open_devops} }}>
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>引擎(Engine)<div className='newBtnImg'></div>
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>流水线(Devops)
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
</Link>
</li>
:""
} */}
}
{/* {
item.menu_name === "resources" &&
<li className={pathname==="source" ? "active" : ""}>