工作流
This commit is contained in:
parent
dfbcc09e5b
commit
940c9c0253
|
|
@ -24,15 +24,15 @@ export const Tags = (status)=>{
|
|||
|
||||
export const TagsLine = (status)=>{
|
||||
switch(status){
|
||||
case 1:
|
||||
case "running":
|
||||
return(
|
||||
<span className="statuslineColor running">运行中</span>
|
||||
);
|
||||
case 2:
|
||||
case "failure":
|
||||
return (
|
||||
<span className="statuslineColor failed">未通过</span>
|
||||
);
|
||||
case 3:
|
||||
case "success":
|
||||
return (
|
||||
<span className="statuslineColor pass">已通过</span>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import React, { useEffect ,useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { FlexAJ, Blueline, AlignCenter } from "../Component/layout";
|
||||
import styled from "styled-components";
|
||||
import { Menu , Popconfirm } from "antd";
|
||||
import { Menu, Popconfirm } from "antd";
|
||||
import { TagsLine } from "../Component/OpsStatus";
|
||||
import { Time } from "../Utils/Time";
|
||||
import { truncateCommitId } from "../common/util";
|
||||
|
||||
|
||||
const SubMenu = Menu.SubMenu;
|
||||
const Img = styled.img`
|
||||
{
|
||||
|
|
@ -16,37 +15,83 @@ const Img = styled.img`
|
|||
margin-right: 10px;
|
||||
}
|
||||
`;
|
||||
export default ({ data , repeatSet }) => {
|
||||
const [ tamp , setTamp ] = useState(undefined);
|
||||
const [ sha , setSha ] = useState(undefined);
|
||||
useEffect(()=>{
|
||||
if(data && data.started){
|
||||
export default ({ data, repeatSet }) => {
|
||||
const [tamp, setTamp] = useState(undefined);
|
||||
const [sha, setSha] = useState(undefined);
|
||||
useEffect(() => {
|
||||
if (data && data.started) {
|
||||
let t = parseInt(data.started) * 1000;
|
||||
let time = Time(t);
|
||||
setTamp(time);
|
||||
}
|
||||
if(data && data.after){
|
||||
if (data && data.after) {
|
||||
setSha(truncateCommitId(data.after));
|
||||
}
|
||||
},[data])
|
||||
}, [data]);
|
||||
|
||||
function renderMenu() {
|
||||
if (data.stages && data.stages.length > 0) {
|
||||
data.stages.map((item, key) => {
|
||||
return item.steps && item.steps.length > 0 ? (
|
||||
<SubMenu
|
||||
title={
|
||||
<div>
|
||||
<i className="iconfont icon-gongzuoliu font-14 mr4"></i>
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{item.steps.map((i, k) => {
|
||||
return (
|
||||
<Menu.Item>
|
||||
<FlexAJ>
|
||||
<span>
|
||||
{i.name} {i.status ? TagsLine(i.status) : ""}
|
||||
</span>
|
||||
<span>
|
||||
{i.stopped
|
||||
? parseInt(parseInt(i.stopped) - parseInt(i.started))
|
||||
: "0"}
|
||||
s
|
||||
</span>
|
||||
</FlexAJ>
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
</SubMenu>
|
||||
) : (
|
||||
""
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function titleClick(e,index){
|
||||
console.log(index);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FlexAJ className="leftheader">
|
||||
<AlignCenter>
|
||||
<Img src={data && data.author_avatar} />
|
||||
{data && data.started && (
|
||||
{data && data.started ? (
|
||||
<span className="nest">
|
||||
开始时间:<span> {tamp}</span>
|
||||
</span>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
{data && data.timestamp && (
|
||||
<span className="nest">
|
||||
运行时间:<span>{data && data.timestamp}s</span>
|
||||
</span>
|
||||
)}
|
||||
<span className="nest">
|
||||
运行时间:<span>{data && data.timestamp}s</span>
|
||||
</span>
|
||||
</AlignCenter>
|
||||
<Popconfirm title="是否重新创建?" okText="确定" cancelText="取消" onConfirm={repeatSet}>
|
||||
<Popconfirm
|
||||
title="是否重新创建?"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onConfirm={repeatSet}
|
||||
>
|
||||
<Blueline>重新创建</Blueline>
|
||||
</Popconfirm>
|
||||
</FlexAJ>
|
||||
|
|
@ -59,21 +104,38 @@ export default ({ data , repeatSet }) => {
|
|||
</AlignCenter>
|
||||
</div>
|
||||
<Menu mode="inline" className="leftMenu">
|
||||
<SubMenu
|
||||
title={
|
||||
<div>
|
||||
<i className="iconfont icon-gongzuoliu font-14 mr4"></i>
|
||||
<span>CI</span>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Menu.Item>
|
||||
<FlexAJ>
|
||||
<span>Build setup 01 {TagsLine(1)}</span>
|
||||
<span>20s</span>
|
||||
</FlexAJ>
|
||||
</Menu.Item>
|
||||
</SubMenu>
|
||||
{data && data.stages
|
||||
? data.stages.map((item, key) => {
|
||||
return item.steps && item.steps.length > 0 ? (
|
||||
<SubMenu
|
||||
title={
|
||||
<div>
|
||||
<i className="iconfont icon-gongzuoliu font-14 mr4"></i>
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
}
|
||||
onTitleClick={(e)=>titleClick(e,key)}
|
||||
>
|
||||
{item.steps.map((i, k) => {
|
||||
return (
|
||||
<Menu.Item>
|
||||
<FlexAJ>
|
||||
<span>
|
||||
{i.name} {i.status ? TagsLine(i.status) : ""}
|
||||
</span>
|
||||
<span>
|
||||
{i.stopped ? (parseInt(i.stopped) - parseInt(i.started)): "0"}s
|
||||
</span>
|
||||
</FlexAJ>
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
</SubMenu>
|
||||
) : (
|
||||
""
|
||||
);
|
||||
})
|
||||
: ""}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,21 +1,31 @@
|
|||
import React from 'react';
|
||||
import { FlexAJ , AlignCenter } from '../Component/layout';
|
||||
import React, {useState,useEffect} from "react";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
|
||||
export default (()=>{
|
||||
return(
|
||||
export default ({ stages }) => {
|
||||
const [ list , setList ] = useState(undefined);
|
||||
useEffect(()=>{
|
||||
if(stages){
|
||||
console.log(stages.steps);
|
||||
setList(stages.steps);
|
||||
}
|
||||
},[stages])
|
||||
|
||||
return (
|
||||
<div className="rightMainContent">
|
||||
<div>
|
||||
<FlexAJ className="items">
|
||||
<span>Build setup 01</span>
|
||||
<AlignCenter>20<i className="iconfont icon-triangle"></i></AlignCenter>
|
||||
</FlexAJ>
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="items"></FlexAJ>
|
||||
</div>
|
||||
<div>
|
||||
<FlexAJ className="items"></FlexAJ>
|
||||
</div>
|
||||
{list && list.length>0 ? list.map((item, key) => {
|
||||
return (
|
||||
<div>
|
||||
<FlexAJ className="items">
|
||||
<span>{item.name}</span>
|
||||
<AlignCenter>
|
||||
{ item.stopped ? (parseInt(item.stopped) - parseInt(item.started)) : "0" }
|
||||
<i className="iconfont icon-triangle"></i>
|
||||
</AlignCenter>
|
||||
</FlexAJ>
|
||||
</div>
|
||||
);
|
||||
}):"1111"
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState , useRef , useContext } from "react";
|
||||
import React, { useEffect, useState, useRef, useContext } from "react";
|
||||
import "./ops.scss";
|
||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||
import { Tags } from "../Component/OpsStatus";
|
||||
|
|
@ -7,7 +7,7 @@ import LeftPanel from "./OpsDetailLeftpanel";
|
|||
import RightPanel from "./OpsDetailRightpanel";
|
||||
import axios from "axios";
|
||||
import { Spin } from "antd";
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export default (props) => {
|
||||
const [data, setData] = useState(undefined);
|
||||
|
|
@ -23,37 +23,41 @@ export default (props) => {
|
|||
}
|
||||
}, [opsId]);
|
||||
|
||||
function Init(){
|
||||
function Init() {
|
||||
const url = `/dev_ops/builds/${opsId}.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
project_id: projectId,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result && result.data) {
|
||||
setSpinning(false);
|
||||
setData(result.data);
|
||||
setStages(result.data.stages);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
project_id: projectId,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result && result.data) {
|
||||
setSpinning(false);
|
||||
setData(result.data);
|
||||
setStages(
|
||||
result.data.stages && result.data.stages.length > 0 ? result.data.stages[0] : undefined
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 重新构建
|
||||
function repeatSet() {
|
||||
const url = `/dev_ops/builds/${data && data.number}.json`;
|
||||
axios.post(url, { project_id: projectId })
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
Init();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
axios
|
||||
.post(url, { project_id: projectId })
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
Init();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
return (
|
||||
<Spin spinning={spinning}>
|
||||
|
|
@ -64,7 +68,10 @@ export default (props) => {
|
|||
<span className="ml10">{data && data.message}</span>
|
||||
{Tags(`${data && data.status}`)}
|
||||
</AlignCenter>
|
||||
<Link style={{ color: "#ddd" }} to={`/projects/${projectId}/ops/list`}>
|
||||
<Link
|
||||
style={{ color: "#ddd" }}
|
||||
to={`/projects/${projectId}/ops/list`}
|
||||
>
|
||||
<i className="iconfont icon-yiguanbi font-15 mr5"></i>退出
|
||||
</Link>
|
||||
</FlexAJ>
|
||||
|
|
@ -77,10 +84,10 @@ export default (props) => {
|
|||
defaultSize="40%"
|
||||
>
|
||||
<section className="leftSection">
|
||||
<LeftPanel data={data} repeatSet={repeatSet}/>
|
||||
<LeftPanel data={data} repeatSet={repeatSet} />
|
||||
</section>
|
||||
<section className="rightSection">
|
||||
<RightPanel data={data} />
|
||||
<RightPanel stages={stages} />
|
||||
</section>
|
||||
</SplitPane>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue