forked from Gitlink/forgeplus-react
Merge branch 'develop' into dev_orgnize
This commit is contained in:
commit
7b7b206741
|
@ -27,7 +27,7 @@ if (isDev) {
|
||||||
}
|
}
|
||||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'student'
|
||||||
}
|
}
|
||||||
function clearAllCookie() {
|
function clearAllCookie() {
|
||||||
cookie.remove('_educoder_session', { path: '/' });
|
cookie.remove('_educoder_session', { path: '/' });
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React , { useState , useEffect } from 'react';
|
import React , { useState , useEffect } from 'react';
|
||||||
import { Spin } from 'antd';
|
import { Spin , Pagination } from 'antd';
|
||||||
import { Blueback } from '../Component/layout';
|
import { Blueback } from '../Component/layout';
|
||||||
import List from './Dispose/List';
|
import List from './Dispose/List';
|
||||||
import Head from './Dispose/head';
|
import Head from './Dispose/head';
|
||||||
|
@ -11,13 +11,16 @@ import styled from 'styled-components';
|
||||||
const Div = styled.div`{
|
const Div = styled.div`{
|
||||||
padding:24px 30px;
|
padding:24px 30px;
|
||||||
}`;
|
}`;
|
||||||
|
const limit = 15;
|
||||||
function Dispose(props){
|
function Dispose(props){
|
||||||
const [ spining , setSpining ] = useState(true);
|
const [ spining , setSpining ] = useState(true);
|
||||||
const [ updateInfo , setUpdateInfo ] = useState(undefined);
|
const [ updateInfo , setUpdateInfo ] = useState(undefined);
|
||||||
const [ list , setList ] = useState(undefined);
|
const [ list , setList ] = useState(undefined);
|
||||||
const [ permission , setPermission ] = useState(undefined);
|
const [ permission , setPermission ] = useState(undefined);
|
||||||
const [ visible , setVisible ] = useState(false);
|
const [ visible , setVisible ] = useState(false);
|
||||||
|
const [ page , setPage ] = useState(1);
|
||||||
|
const [ totalCount , setTotalCount ] = useState(0);
|
||||||
|
const [ branchList , setBranchList ] =useState(undefined);
|
||||||
|
|
||||||
|
|
||||||
const projectDetail = props.projectDetail;
|
const projectDetail = props.projectDetail;
|
||||||
|
@ -36,7 +39,8 @@ function Dispose(props){
|
||||||
const url = `/ci/pipelines/list.json`;
|
const url = `/ci/pipelines/list.json`;
|
||||||
axios.get(url,{
|
axios.get(url,{
|
||||||
params:{
|
params:{
|
||||||
identifier:projectsId
|
identifier:projectsId,
|
||||||
|
page,limit
|
||||||
}
|
}
|
||||||
}).then(result=>{
|
}).then(result=>{
|
||||||
if(result && result.data){
|
if(result && result.data){
|
||||||
|
@ -48,20 +52,30 @@ function Dispose(props){
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
Init();
|
Init();
|
||||||
},[])
|
},[page])
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(owner && projectsId){
|
||||||
|
const url = `/${owner}/${projectsId}/branches.json`;
|
||||||
|
axios.get(url).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setBranchList(result.data);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
},[owner,projectsId])
|
||||||
|
|
||||||
// 新增流水线
|
// 新增流水线
|
||||||
function addNew(pipeline_name,id){
|
function addNew(pipeline_name,id,branch,event){
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
setUpdateInfo(undefined);
|
setUpdateInfo(undefined);
|
||||||
if(pipeline_name){
|
if(pipeline_name){
|
||||||
let l = {pipeline_name,id}
|
let l = {pipeline_name,id,branch,event}
|
||||||
setUpdateInfo(l);
|
setUpdateInfo(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onOk(pipeline_name,updateId){
|
function onOk(pipeline_name,updateId,branch,event){
|
||||||
if(pipeline_name){
|
if(pipeline_name){
|
||||||
if(!updateId){
|
if(!updateId){
|
||||||
// 新增
|
// 新增
|
||||||
|
@ -69,7 +83,7 @@ function Dispose(props){
|
||||||
axios.post(url,{
|
axios.post(url,{
|
||||||
pipeline_name,
|
pipeline_name,
|
||||||
file_name:".trustie-pipeline.yml",
|
file_name:".trustie-pipeline.yml",
|
||||||
identifier:projectsId
|
repo:projectsId,branch,event,owner
|
||||||
}).then(result=>{
|
}).then(result=>{
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
if(result && result.data){
|
if(result && result.data){
|
||||||
|
@ -83,7 +97,7 @@ function Dispose(props){
|
||||||
// 修改
|
// 修改
|
||||||
const url = `/ci/pipelines/${updateId}.json`;
|
const url = `/ci/pipelines/${updateId}.json`;
|
||||||
axios.put(url,{
|
axios.put(url,{
|
||||||
pipeline_name
|
pipeline_name,repo:projectsId,branch,event,owner
|
||||||
}).then(result=>{
|
}).then(result=>{
|
||||||
if(result && result.data){
|
if(result && result.data){
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
@ -110,17 +124,28 @@ function Dispose(props){
|
||||||
}).catch(error=>{})
|
}).catch(error=>{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 模板管理
|
||||||
|
function toModalManage(){
|
||||||
|
props.history.push(`/projects/cxt/DevOps-mo/devops/mould`);
|
||||||
|
}
|
||||||
|
|
||||||
const operate = current_user && (permission && permission !== "Reporter");
|
const operate = current_user && (permission && permission !== "Reporter");
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<Spin spinning={spining}>
|
<Spin spinning={spining}>
|
||||||
<PipelineName visible={visible} value={updateInfo} onCancel={()=>{setVisible(false);}} onOk={onOk}/>
|
<PipelineName branchList={branchList} visible={visible} value={updateInfo} onCancel={()=>setVisible(false)} onOk={onOk}/>
|
||||||
<div className="disposePanel">
|
<div className="disposePanel">
|
||||||
<Head />
|
<Head manager={ operate ? toModalManage : undefined} />
|
||||||
<Div>
|
<Div>
|
||||||
{ operate && (!list ||(list && list.length === 0)) && <Blueback onClick={()=>addNew(undefined,undefined)}>新增流水线</Blueback> }
|
{ operate && <Blueback onClick={()=>addNew(undefined,undefined)}>新增流水线</Blueback> }
|
||||||
<div className="mt20 disposeList">
|
<div className="mt20 disposeList">
|
||||||
<List list={list} operate={operate} projectsId={projectsId} owner={owner} showModal={addNew} deleteFunc={deleteFunc}/>
|
<List list={list} operate={operate} projectsId={projectsId} owner={owner} showModal={addNew} deleteFunc={deleteFunc}/>
|
||||||
|
{
|
||||||
|
totalCount > limit &&
|
||||||
|
<div className="mt20 pb20" style={{textAlign:'center'}}>
|
||||||
|
<Pagination simple current={page} pageSize={limit} total={totalCount} onChange={(page)=>setPage(page)}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</Div>
|
</Div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Editor from 'react-monaco-editor';
|
import Editor from 'react-monaco-editor';
|
||||||
|
|
||||||
function Editors({value,onChange,theme,height,visible}){
|
function Editors({value,onChange,theme,height,visible,width="100%",Numbers="on"}){
|
||||||
const editor_options = {
|
const editor_options = {
|
||||||
lineNumbers: "on",
|
lineNumbers: Numbers,
|
||||||
wordWrap: true, //强制换行
|
wordWrap: true, //强制换行
|
||||||
selectOnLineNumbers: true,
|
selectOnLineNumbers: true,
|
||||||
lineHeight: 24,
|
lineHeight: 24,
|
||||||
|
@ -23,6 +23,7 @@ function Editors({value,onChange,theme,height,visible}){
|
||||||
return(
|
return(
|
||||||
<Editor
|
<Editor
|
||||||
height={height}
|
height={height}
|
||||||
|
width={width}
|
||||||
language={"yaml"}
|
language={"yaml"}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
placeholder="请输入内容"
|
placeholder="请输入内容"
|
||||||
|
|
|
@ -2,6 +2,14 @@ import React from 'react';
|
||||||
import { Table , Popconfirm } from 'antd';
|
import { Table , Popconfirm } from 'antd';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
const STATUS = {
|
||||||
|
running:"运行中",
|
||||||
|
failure:"未通过",
|
||||||
|
error:"未通过",
|
||||||
|
success:"已通过",
|
||||||
|
killed:"已撤销",
|
||||||
|
pending:"准备中"
|
||||||
|
}
|
||||||
function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
|
@ -9,11 +17,11 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
title:"流水线名称",
|
title:"流水线名称",
|
||||||
dataIndex:"pipeline_name",
|
dataIndex:"pipeline_name",
|
||||||
key:1,
|
key:1,
|
||||||
width:"20%",
|
width:"19%",
|
||||||
ellipsis:true,
|
ellipsis:true,
|
||||||
render:(txt,item)=>{
|
render:(txt,item)=>{
|
||||||
return(
|
return(
|
||||||
<span onDoubleClick={()=>showModal(txt,item.id)} style={{display:"block",cursor:"pointer"}}>{txt}</span>
|
<span onDoubleClick={()=>showModal(txt,item.id,item.branch,item.event)} style={{display:"block",cursor:"pointer"}}>{txt}</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -21,7 +29,7 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
title:"文件名称",
|
title:"文件名称",
|
||||||
dataIndex:"file_name",
|
dataIndex:"file_name",
|
||||||
key:1,
|
key:1,
|
||||||
width:"17%",
|
width:"15%",
|
||||||
className:"color-blue",
|
className:"color-blue",
|
||||||
ellipsis:true
|
ellipsis:true
|
||||||
},
|
},
|
||||||
|
@ -29,14 +37,31 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
title:"创建时间",
|
title:"创建时间",
|
||||||
dataIndex:"created_at",
|
dataIndex:"created_at",
|
||||||
key:1,
|
key:1,
|
||||||
width:"18%",
|
width:"15%",
|
||||||
ellipsis:true
|
ellipsis:true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title:"最近构建时间",
|
||||||
|
dataIndex:"last_build_time",
|
||||||
|
key:1,
|
||||||
|
width:"15%",
|
||||||
|
ellipsis:true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title:"最近构建状态",
|
||||||
|
dataIndex:"pipeline_status",
|
||||||
|
key:1,
|
||||||
|
width:"15%",
|
||||||
|
ellipsis:true,
|
||||||
|
render:(txt)=>{
|
||||||
|
return(STATUS[txt])
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title:"操作",
|
title:"操作",
|
||||||
dataIndex:"operation",
|
dataIndex:"operation",
|
||||||
key:1,
|
key:1,
|
||||||
width:"30%",
|
width:"21%",
|
||||||
render:(txt,item)=>{
|
render:(txt,item)=>{
|
||||||
return(
|
return(
|
||||||
<span>
|
<span>
|
||||||
|
@ -49,7 +74,7 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
<a className="mr10 color-grey-6"><i className="iconfont icon-lajitong font-13 mr3"></i>删除</a>
|
<a className="mr10 color-grey-6"><i className="iconfont icon-lajitong font-13 mr3"></i>删除</a>
|
||||||
</Popconfirm>:""
|
</Popconfirm>:""
|
||||||
}
|
}
|
||||||
<Link to={`/projects/${owner}/${projectsId}/devops/list`} className="color-grey-6"><i className="iconfont icon-yunhang font-13 mr3"></i>查看运行记录</Link>
|
<Link to={`/projects/${owner}/${projectsId}/devops/list/${item.branch}`} className="color-grey-6"><i className="iconfont icon-yunhang font-13 mr3"></i>查看运行记录</Link>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
import React , { useEffect , useState } from 'react';
|
import React , { useEffect , useState } from 'react';
|
||||||
import { Modal , Input } from 'antd';
|
import { Modal , Input , Select } from 'antd';
|
||||||
|
const { Option }= Select;
|
||||||
|
|
||||||
function PipelineName({visible,onCancel,onOk,value}){
|
const EVENT = ["push","pull_request","tag","cron","custom","promote","rollback"]
|
||||||
|
function PipelineName({visible,onCancel,onOk,value ,branchList}){
|
||||||
const [ name , setName ] = useState(undefined);
|
const [ name , setName ] = useState(undefined);
|
||||||
|
const [ branchValue , setBranchValue ] = useState(undefined);
|
||||||
|
const [ eventValue , setEventValue ] = useState(EVENT[0]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(branchList && branchList.length>0){
|
||||||
|
setBranchValue(branchList[0].name);
|
||||||
|
}
|
||||||
|
},[branchList])
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(value){
|
if(value){
|
||||||
setName(value.pipeline_name);
|
setName(value.pipeline_name);
|
||||||
|
setBranchValue(value.branch);
|
||||||
|
setEventValue(value.event);
|
||||||
}
|
}
|
||||||
},[value])
|
},[value])
|
||||||
|
|
||||||
function onSure(){
|
function onSure(){
|
||||||
onOk(name,value && value.id);
|
onOk(name,value && value.id,branchValue,eventValue);
|
||||||
}
|
}
|
||||||
return(
|
return(
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -26,6 +38,27 @@ function PipelineName({visible,onCancel,onOk,value}){
|
||||||
<span>流水线名称:</span>
|
<span>流水线名称:</span>
|
||||||
<Input value={name} onChange={(e)=>setName(e.target.value)} placeholder="请输入名称" style={{width:"340px",margin:"6px 0px"}}/>
|
<Input value={name} onChange={(e)=>setName(e.target.value)} placeholder="请输入名称" style={{width:"340px",margin:"6px 0px"}}/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="choosenList mt20">
|
||||||
|
<span>触发条件:</span>
|
||||||
|
<Select value={branchValue} style={{width:"160px"}} onChange={(e)=>setBranchValue(e)}>
|
||||||
|
{
|
||||||
|
branchList && branchList.length>0 && branchList.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<Option value={item.name} key={key}>{item.name}</Option>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Select>
|
||||||
|
<Select value={eventValue} style={{width:"160px",marginLeft:"20px"}} onChange={(e)=>setEventValue(e)}>
|
||||||
|
{
|
||||||
|
EVENT.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<Option value={item} key={key}>{item}</Option>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AlignCenterBetween } from '../../Component/layout';
|
import { AlignCenterBetween , Blueline , FlexAJ } from '../../Component/layout';
|
||||||
|
|
||||||
|
|
||||||
function head(){
|
function head({manager}){
|
||||||
return(
|
return(
|
||||||
<AlignCenterBetween>
|
<AlignCenterBetween>
|
||||||
<span className="font-20">工作流配置</span>
|
<span className="font-20">工作流配置</span>
|
||||||
<a href={`https://forum.trustie.net/forums/3111/detail`} target="_blank" className="color-grey-6"><i className="iconfont icon-tishi1 font-14 mr3"></i>模板使用说明</a>
|
<FlexAJ>
|
||||||
|
<a href={`https://forum.trustie.net/forums/3111/detail`} target="_blank" className="color-grey-6"><i className="iconfont icon-tishi1 font-14 mr3"></i>模板使用说明</a>
|
||||||
|
{
|
||||||
|
manager && <Blueline style={{marginLeft:"20px"}} onClick={manager}>模板管理</Blueline>
|
||||||
|
}
|
||||||
|
</FlexAJ>
|
||||||
</AlignCenterBetween>
|
</AlignCenterBetween>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,20 +22,11 @@ const Stucture = Loadable({
|
||||||
loader: () => import('./Structure'),
|
loader: () => import('./Structure'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
const Mould = Loadable({
|
||||||
|
loader: () => import('./Mould'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
export default ((props)=>{
|
export default ((props)=>{
|
||||||
const { projectsId , owner } = props.match.params;
|
|
||||||
const open_devops = props.projectDetail && props.projectDetail.open_devops;
|
|
||||||
|
|
||||||
// 工作流:两种状态进入的链接不同
|
|
||||||
// useEffect(()=>{
|
|
||||||
// if(open_devops !== undefined){
|
|
||||||
// if(open_devops){
|
|
||||||
// props.history.replace(`/projects/${owner}/${projectsId}/devops/dispose`);
|
|
||||||
// }else{
|
|
||||||
// props.history.replace(`/projects/${owner}/${projectsId}/devops`);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },[open_devops])
|
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<WhiteBack className="opsPanel">
|
<WhiteBack className="opsPanel">
|
||||||
|
@ -45,6 +36,11 @@ export default ((props)=>{
|
||||||
(p) => (<New {...props} {...p}/>)
|
(p) => (<New {...props} {...p}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
<Route path="/projects/:owner/:projectsId/devops/mould"
|
||||||
|
render={
|
||||||
|
(p) => (<Mould {...props} {...p}/>)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
<Route path="/projects/:owner/:projectsId/devops/dispose/new"
|
<Route path="/projects/:owner/:projectsId/devops/dispose/new"
|
||||||
render={
|
render={
|
||||||
(p) => (<New {...props} {...p}/>)
|
(p) => (<New {...props} {...p}/>)
|
||||||
|
@ -55,7 +51,7 @@ export default ((props)=>{
|
||||||
(p) => (<Dispose {...props} {...p}/>)
|
(p) => (<Dispose {...props} {...p}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/projects/:owner/:projectsId/devops/list"
|
<Route path="/projects/:owner/:projectsId/devops/list/:branch"
|
||||||
render={
|
render={
|
||||||
(p) => (<Stucture {...props} {...p}/>)
|
(p) => (<Stucture {...props} {...p}/>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
import React , { useEffect , useState , useRef } from 'react';
|
||||||
|
import { Banner , Blueback , FlexAJ , Spin } from '../Component/layout';
|
||||||
|
import { Input , Table ,Pagination , Select , Popconfirm } from 'antd';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import axios from 'axios';
|
||||||
|
import New from './MouldNew';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
|
const Div = styled.div`{
|
||||||
|
padding:24px 30px;
|
||||||
|
min-height:420px;
|
||||||
|
}`;
|
||||||
|
const STAGE = [
|
||||||
|
{stage_name:"所有",stage_type:"all"},
|
||||||
|
{stage_name:"初始化",stage_type:"init"},
|
||||||
|
{stage_name:"编译构建",stage_type:"build"},
|
||||||
|
{stage_name:"部署",stage_type:"deploy"},
|
||||||
|
{stage_name:"其他",stage_type:"customize"}
|
||||||
|
]
|
||||||
|
const limit = 15;
|
||||||
|
function Mould(props){
|
||||||
|
const [ visible ,setVisible ] = useState(false);
|
||||||
|
const [ list ,setList ] = useState(undefined);
|
||||||
|
const [ page ,setPage ] = useState(1);
|
||||||
|
const [ totalCount ,setTotalCount ] = useState(0);
|
||||||
|
const [ stageType ,setStageType ] = useState("all");
|
||||||
|
const [ search ,setSearch ] = useState(undefined);
|
||||||
|
const childRef = useRef();
|
||||||
|
useEffect(()=>{
|
||||||
|
Init(page,stageType);
|
||||||
|
},[page,stageType])
|
||||||
|
|
||||||
|
function Init(page,stageType,searchvalue){
|
||||||
|
const url = `/ci/templates/list.json`;
|
||||||
|
axios.get(url,{
|
||||||
|
params:{
|
||||||
|
page,limit,stage_type:stageType,name:searchvalue
|
||||||
|
}
|
||||||
|
}).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setList(result.data.templates);
|
||||||
|
setTotalCount(result.data.total_count);
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns=[
|
||||||
|
{
|
||||||
|
title:"名称",
|
||||||
|
dataIndex:"template_name",
|
||||||
|
key:1,
|
||||||
|
ellipsis:true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title:"所属阶段",
|
||||||
|
dataIndex:"stage_type",
|
||||||
|
key:2,
|
||||||
|
ellipsis:true,
|
||||||
|
render:(txt,item)=>{
|
||||||
|
let i = STAGE.filter(item=>item.stage_type === txt);
|
||||||
|
return i && i.length>0 && i[0].stage_name
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title:"模板类型",
|
||||||
|
dataIndex:"category",
|
||||||
|
key:3,
|
||||||
|
ellipsis:true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title:"操作",
|
||||||
|
dataIndex:"operation",
|
||||||
|
key:4,
|
||||||
|
ellipsis:true,
|
||||||
|
render:(txt,item)=>{
|
||||||
|
return(
|
||||||
|
<span>
|
||||||
|
<a className="mr10 color-grey-6" onClick={()=>editMouldFunc(item)}><i className="iconfont icon-zaibianji font-13 mr3"></i>编辑</a>
|
||||||
|
<Popconfirm title={"确定要删除此模板?"} onConfirm={()=>deleteMouldFunc(item.id)} okText="确定" cancelText={"取消"}>
|
||||||
|
<a className="mr10 color-grey-6"><i className="iconfont icon-lajitong font-13 mr3"></i>删除</a>
|
||||||
|
</Popconfirm>
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// 编辑模板
|
||||||
|
function editMouldFunc(item){
|
||||||
|
if (childRef.current) {
|
||||||
|
childRef.current.setEditInfo(item);
|
||||||
|
}
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除模板
|
||||||
|
function deleteMouldFunc(id){
|
||||||
|
const url = `/ci/templates/${id}.json`;
|
||||||
|
axios.delete(url).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
props.showNotification("模板删除成功!");
|
||||||
|
Init(page,stageType,search);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchValue(){
|
||||||
|
Init(page,stageType,search);
|
||||||
|
}
|
||||||
|
|
||||||
|
function newMouldFunc(){
|
||||||
|
if (childRef.current) {
|
||||||
|
childRef.current.setEditInfo(undefined);
|
||||||
|
}
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOk(){
|
||||||
|
Init(page,"all");
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<div>
|
||||||
|
<New wrappedComponentRef={(f) => childRef.current = f} ref={childRef} visible={visible} onCancel={()=>setVisible(false)} onOk={onOk}></New>
|
||||||
|
<Banner>工作流 - 模板管理</Banner>
|
||||||
|
<Div className="disposeList">
|
||||||
|
<FlexAJ>
|
||||||
|
<Blueback onClick={newMouldFunc}>新建模板</Blueback>
|
||||||
|
<FlexAJ>
|
||||||
|
<span className="mr10">阶段:</span>
|
||||||
|
<Select onChange={e=>setStageType(e)} value={stageType} style={{width:"180px"}}>
|
||||||
|
{
|
||||||
|
STAGE.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<Option value={item.stage_type}>{item.stage_name}</Option>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Select>
|
||||||
|
<Input placeholder="请输入模板名称" value={search} onChange={(e)=>setSearch(e.target.value)} allowClear style={{width:"160px",marginLeft:"15px"}}/>
|
||||||
|
<Blueback className="ml15" onClick={searchValue}>搜索</Blueback>
|
||||||
|
</FlexAJ>
|
||||||
|
</FlexAJ>
|
||||||
|
<Table className="mt20" size="small" columns={columns} dataSource={list} rowKey={(row)=>row.id} pagination={false}></Table>
|
||||||
|
{
|
||||||
|
totalCount > limit &&
|
||||||
|
<div className="mt20 pb20" style={{textAlign:'center'}}>
|
||||||
|
<Pagination simple current={page} pageSize={limit} total={totalCount} onChange={(page)=>setPage(page)}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</Div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Mould;
|
|
@ -0,0 +1,139 @@
|
||||||
|
import React , { useImperativeHandle , useState , forwardRef , useCallback } from 'react';
|
||||||
|
import { Form , Modal , Input , Select , Spin } from 'antd';
|
||||||
|
import Editor from './Dispose/Editors';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
const TYPE = ["Java","C","C++","Python","Go","Ruby","R","PHP",
|
||||||
|
"Perl","Node","Docker","Rust","Swift","Erlang","Other"]
|
||||||
|
|
||||||
|
function MouldNew({ form , visible , onCancel , onOk }, ref){
|
||||||
|
const [value , setValue ] = useState(undefined);
|
||||||
|
const [isSpin , setIsSpin ] = useState(false);
|
||||||
|
const [valueFlag , setValueFlag ] = useState(false);
|
||||||
|
const [ id , setId ] = useState(false);
|
||||||
|
|
||||||
|
const { getFieldDecorator, validateFields , setFieldsValue , getFieldsValue } = form;
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
setEditInfo: (info) => {
|
||||||
|
if(info){
|
||||||
|
setFieldsValue({
|
||||||
|
...info
|
||||||
|
})
|
||||||
|
setValue(info.content);
|
||||||
|
setId(info.id);
|
||||||
|
}else{
|
||||||
|
clear();
|
||||||
|
setId(undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
const helper = useCallback(
|
||||||
|
(label, name, rules, widget, className, isRequired,flag) => (
|
||||||
|
<Form.Item label={label} >
|
||||||
|
{getFieldDecorator(name, { rules, validateFirst: true , valuePropName:flag ? "checked":"value" })(widget)}
|
||||||
|
</Form.Item>
|
||||||
|
),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
function changeContent(v){
|
||||||
|
if(v){
|
||||||
|
setValue(v);
|
||||||
|
setValueFlag(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function cancel(){
|
||||||
|
clear();
|
||||||
|
onCancel();
|
||||||
|
}
|
||||||
|
function sure(){
|
||||||
|
if(!value){
|
||||||
|
setValueFlag(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
validateFields((error,values)=>{
|
||||||
|
if(!error){
|
||||||
|
setIsSpin(true);
|
||||||
|
const url = `/ci/templates.json`;
|
||||||
|
axios.post(url,{
|
||||||
|
...values,id,content:value
|
||||||
|
}).then(result=>{
|
||||||
|
if(result && result.data){
|
||||||
|
setIsSpin(false);
|
||||||
|
cancel();
|
||||||
|
onOk();
|
||||||
|
}
|
||||||
|
}).catch(error=>{})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function clear(){
|
||||||
|
setFieldsValue({
|
||||||
|
stage_type:"all",
|
||||||
|
template_name:undefined,
|
||||||
|
category:"Java",
|
||||||
|
})
|
||||||
|
setValue("");
|
||||||
|
setValueFlag(false);
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<Modal
|
||||||
|
visible={visible}
|
||||||
|
width="500px"
|
||||||
|
title={"新建/编辑模板"}
|
||||||
|
onCancel={cancel}
|
||||||
|
onOk={sure}
|
||||||
|
centered={true}
|
||||||
|
>
|
||||||
|
<Spin spinning={isSpin}>
|
||||||
|
<Form layout={"inline"}>
|
||||||
|
{helper(
|
||||||
|
"所属阶段",
|
||||||
|
"stage_type",
|
||||||
|
[{required:true,message:"请选择所属阶段"}],
|
||||||
|
<Select placeholder="请选择所属阶段" style={{width:"350px"}}>
|
||||||
|
<Option value="all">所有</Option>
|
||||||
|
<Option value="init">初始化</Option>
|
||||||
|
<Option value="build">编译构建</Option>
|
||||||
|
<Option value="deploy">部署</Option>
|
||||||
|
<Option value="customize">其他</Option>
|
||||||
|
</Select>,true
|
||||||
|
)}
|
||||||
|
{helper(
|
||||||
|
"模板名称",
|
||||||
|
"template_name",
|
||||||
|
[{required:true,message:"请输入模板名称"}],
|
||||||
|
<Input placeholder="请输入模板名称" style={{width:"350px"}}/>,true
|
||||||
|
)}
|
||||||
|
{helper(
|
||||||
|
"模板分类",
|
||||||
|
"category",
|
||||||
|
[{required:true,message:"请选择模板分类"}],
|
||||||
|
<Select placeholder="请选择模板分类" style={{width:"350px"}}>
|
||||||
|
{
|
||||||
|
TYPE.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<Option value={item}>{item}</Option>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Select>,true
|
||||||
|
)}
|
||||||
|
<div style={{display:'flex',justifyContent:"flex-start"}}>
|
||||||
|
<span><span className="color-red">* </span>模板内容:</span>
|
||||||
|
<div>
|
||||||
|
<div className="editorPanel">
|
||||||
|
<Editor Numbers={"off"} width={"350px"} value={value} height="200px" theme="vs-grey" onChange={changeContent}/>
|
||||||
|
</div>
|
||||||
|
{ valueFlag && <span className="color-red">请输入模板内容</span>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</Spin>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Form.create()(forwardRef(MouldNew));
|
||||||
|
|
|
@ -28,6 +28,7 @@ function Structure(props,ref){
|
||||||
|
|
||||||
let projectsId = props.match.params.projectsId;
|
let projectsId = props.match.params.projectsId;
|
||||||
let owner = props.match.params.owner;
|
let owner = props.match.params.owner;
|
||||||
|
let branch = props.match.params.branch;
|
||||||
const permission = props.projectDetail && props.projectDetail.permission;
|
const permission = props.projectDetail && props.projectDetail.permission;
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
|
@ -49,7 +50,7 @@ function Structure(props,ref){
|
||||||
axios.get(url,{
|
axios.get(url,{
|
||||||
params:{
|
params:{
|
||||||
search:status,
|
search:status,
|
||||||
page,limit:LIMIT
|
page,limit:LIMIT,branch
|
||||||
}
|
}
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result && result.data) {
|
if (result && result.data) {
|
||||||
|
|
|
@ -261,8 +261,6 @@ function disposePipeline(props){
|
||||||
// 确认提交
|
// 确认提交
|
||||||
function sureSubmit(){
|
function sureSubmit(){
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
let sync = datas.sync || 0;
|
|
||||||
let url = '';
|
|
||||||
const { defaultBranch } = props;
|
const { defaultBranch } = props;
|
||||||
let params = {
|
let params = {
|
||||||
branch: defaultBranch,
|
branch: defaultBranch,
|
||||||
|
@ -273,32 +271,18 @@ function disposePipeline(props){
|
||||||
owner:owner,
|
owner:owner,
|
||||||
repo:projectsId
|
repo:projectsId
|
||||||
}
|
}
|
||||||
if(sync === 1){
|
let url = `/${owner}/${projectsId}/update_trustie_pipeline.json`;
|
||||||
// 为true,则是编辑否则是新建
|
axios.put(url,{
|
||||||
url = `/${owner}/${projectsId}/update_trustie_pipeline.json`;
|
...params
|
||||||
axios.put(url,{
|
}).then(result=>{
|
||||||
...params
|
if(result){
|
||||||
}).then(result=>{
|
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
|
||||||
if(result){
|
}
|
||||||
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
|
setLoading(false);
|
||||||
}
|
}).catch(error=>{
|
||||||
setLoading(false);
|
console.log(error);
|
||||||
}).catch(error=>{
|
setLoading(false);
|
||||||
console.log(error);
|
})
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
url = `/ci/pipelines/${disposeId}/create_trustie_pipeline.json`;
|
|
||||||
axios.post(url,params).then(result=>{
|
|
||||||
if(result){
|
|
||||||
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
|
|
||||||
}
|
|
||||||
setLoading(false);
|
|
||||||
}).catch(error=>{
|
|
||||||
console.log(error);
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
|
|
|
@ -487,4 +487,17 @@
|
||||||
.stepsBody.active{
|
.stepsBody.active{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.editorPanel{
|
||||||
|
border:1px solid #eee;
|
||||||
|
.margin{
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
.monaco-scrollable-element.editor-scrollable{
|
||||||
|
left: 0px!important;
|
||||||
|
width: 100%!important;
|
||||||
|
.view-lines{
|
||||||
|
width: 336px!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue