forked from Gitlink/forgeplus-react
个人中心-工作流CI
This commit is contained in:
parent
3169867415
commit
6795e61870
|
|
@ -100,6 +100,7 @@ li.ant-menu-item{
|
|||
right:240px;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1800px){
|
||||
.handleBox{
|
||||
right:190px;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import { Modal , Button } from 'antd';
|
||||
import './Component.scss';
|
||||
|
||||
function Modals({visible,title,content,onOk,onCancel}){
|
||||
return(
|
||||
<Modal
|
||||
className="modalsStyle"
|
||||
visible={visible}
|
||||
title={title}
|
||||
onCancel={onCancel}
|
||||
closable={true}
|
||||
footer={
|
||||
<div>
|
||||
<Button onClick={onCancel}>取消</Button>
|
||||
<Button type={"primary"} style={{marginLeft:"20px"}} onClick={onOk}>确定</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{content}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Modals;
|
||||
|
|
@ -156,9 +156,12 @@ function About(props, ref) {
|
|||
<Blueback onClick={goStep}>下一步</Blueback>
|
||||
</React.Fragment>
|
||||
:""}
|
||||
{step === 1 &&(
|
||||
{step >= 1 &&(
|
||||
<div style={{textAlign:'center',marginTop:"20px"}}>
|
||||
<p style={{ maxWidth: "300px",textAlign:"left",color:"#999" }}>初始化配置已完成,请前往:<br/><a target="_blank" href={redirectUrl} className="color-blue">{redirectUrl}</a> 进入认证</p>
|
||||
{
|
||||
step === 1 &&
|
||||
<p style={{ maxWidth: "300px",textAlign:"left",color:"#999" }}>初始化配置已完成,请前往:<br/><a target="_blank" href={redirectUrl} className="color-blue">{redirectUrl}</a> 进入认证</p>
|
||||
}
|
||||
<Blueback onClick={startActive} className="mt20">开始激活</Blueback>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,24 @@ form{
|
|||
vertical-align: middle;
|
||||
}
|
||||
.pd510{padding: 5px 10px;}
|
||||
|
||||
.modalsStyle{
|
||||
.ant-modal-content{
|
||||
&>.ant-modal-header{
|
||||
text-align: left!important;
|
||||
}
|
||||
}
|
||||
.ant-modal-body{
|
||||
max-width: 400px;
|
||||
margin:0px auto;
|
||||
text-align: left;
|
||||
min-height: 140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.ant-modal-close-x{
|
||||
margin-top:8px;
|
||||
}
|
||||
}
|
||||
.list-l-Menu{
|
||||
margin-bottom: 12px;
|
||||
border-radius:2px;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Button ,Spin , Pagination } from 'antd';
|
||||
import Nodata from '../Nodata';
|
||||
import axios from 'axios';
|
||||
|
||||
const limit = 10;
|
||||
function CIList(props){
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ isSpining , setIsSpining] = useState(true);
|
||||
const [ list , setList ] = useState(undefined);
|
||||
let user = props.current_user;
|
||||
|
||||
useEffect(()=>{
|
||||
setIsSpining(true);
|
||||
if(user && user.login){
|
||||
const url = `/users/${user.login}/projects.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
limit , page
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
setList(result.data.projects);
|
||||
setTotal(result.data.count);
|
||||
setIsSpining(false);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
},[user,page])
|
||||
|
||||
function changePage(page){
|
||||
setPage(page);
|
||||
}
|
||||
return(
|
||||
<div style={{minHeight:"400px"}}>
|
||||
<Spin spinning={isSpining}>
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<ul className="CIList">
|
||||
{list.map((item,key)=>{
|
||||
return(
|
||||
<li>
|
||||
<span>
|
||||
<span>{item.author && item.author.name}/{item.name}</span>
|
||||
{ item.open_devops ?
|
||||
<span className="authTag green ml20">已激活</span>
|
||||
:
|
||||
<span className="authTag red ml20">未激活</span>
|
||||
}
|
||||
</span>
|
||||
{ !item.open_devops && <Button type={"primary"} onClick={()=>{props.history.push(`/projects/${item.author && item.author.login}/${item.identifier}/devops`)}}>马上激活</Button> }
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
:<Nodata _html="暂无数据"/>
|
||||
}
|
||||
{
|
||||
total > limit &&
|
||||
<div className="mt20 mb30" style={{textAlign:"center"}}>
|
||||
<Pagination simple onChange={changePage} pageSize={limit} current={page} total={total}></Pagination>
|
||||
</div>
|
||||
}
|
||||
</Spin>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default CIList;
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
import React , { useEffect , useState , forwardRef , useCallback } from 'react';
|
||||
import { Button , Modal , Form , Input } from 'antd';
|
||||
import { AlignCenter } from '../Component/layout';
|
||||
import axios from 'axios';
|
||||
import Modals from '../Component/Modal';
|
||||
|
||||
const TIPS = "解除CI服务器绑定后,您所有的项目构建数据将被清空。确定解除绑定?";
|
||||
function CIdispose(props){
|
||||
const [ CIData , setCIData ] = useState(undefined);
|
||||
const [ step , setStep ] = useState(0);
|
||||
const [ visible, setVisible ] = useState(false);
|
||||
const [ bindVisible, setBindVisible ] = useState(false);
|
||||
const [ btnLoading , setBtnLoading ] = useState(false);
|
||||
|
||||
|
||||
const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props;
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget, isRequired) => (
|
||||
<React.Fragment>
|
||||
<span className={isRequired ? "required" : ""}>{label}</span>
|
||||
<Form.Item>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(()=>{
|
||||
getInit();
|
||||
},[])
|
||||
|
||||
function getInit(){
|
||||
const url = `/users/ci/cloud_account.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setCIData(result.data.cloud_account);
|
||||
setStep(result.data.step);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
// 解除绑定
|
||||
function cancelBind(){
|
||||
const url = `/users/ci/cloud_account/unbind.json`;
|
||||
axios.delete(url).then(result=>{
|
||||
if(result && result.data){
|
||||
props.showNotification("成功解除绑定!");
|
||||
setVisible(false);
|
||||
getInit();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
function onCancel(){
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
// 确定绑定服务器信息
|
||||
function sureBindInfo(){
|
||||
validateFields((error, values) => {
|
||||
if (!error) {
|
||||
setBtnLoading(true);
|
||||
const url = `/users/ci/cloud_account/bind.json`;
|
||||
axios.post(url,{
|
||||
...values
|
||||
}).then(result=>{
|
||||
setBtnLoading(false);
|
||||
if(result && result.data){
|
||||
setBindVisible(false);
|
||||
setCIData(result.data.cloud_account);
|
||||
setStep(result.data.step);
|
||||
props.showNotification("服务器绑定成功!");
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 取消绑定服务器信息
|
||||
function cancelBindInfo(){
|
||||
setBindVisible(false);
|
||||
setFieldsValue({
|
||||
ip_num:undefined,
|
||||
secret:undefined,
|
||||
account:undefined
|
||||
})
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="disposeInfo">
|
||||
<Modal
|
||||
className="modalsStyle"
|
||||
visible={bindVisible}
|
||||
title={"绑定CI服务器地址"}
|
||||
onCancel={cancelBindInfo}
|
||||
closable={true}
|
||||
footer={
|
||||
<div>
|
||||
<Button onClick={cancelBindInfo}>取消</Button>
|
||||
<Button loading={btnLoading} type={"primary"} style={{marginLeft:"20px"}} onClick={sureBindInfo}>确定</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Form style={{marginTop:"20px"}}>
|
||||
{helper(
|
||||
"服务器IP地址:",
|
||||
"ip_num",
|
||||
[{ required: true, message: "请输入服务器IP地址" }],
|
||||
<Input
|
||||
placeholder="请输入服务器IP地址"
|
||||
style={{ width: "368px" }}
|
||||
size="large"
|
||||
/>,
|
||||
true
|
||||
)}
|
||||
{helper(
|
||||
"服务器用户名:",
|
||||
"account",
|
||||
[{ required: true, message: "请输入服务器用户名" }],
|
||||
<Input placeholder="请输入服务器用户名" size="large" />,
|
||||
true
|
||||
)}
|
||||
{helper(
|
||||
"服务器密码:",
|
||||
"secret",
|
||||
[{ required: true, message: "请输入服务器密码" }],
|
||||
<Input.Password placeholder="请输入服务器密码" size="large" />,
|
||||
true
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
<Modals visible={visible} title={"解除绑定"} content={TIPS} onOk={cancelBind} onCancel={onCancel}/>
|
||||
<div className="disposeItem">
|
||||
<AlignCenter>
|
||||
<span>CI服务器地址</span>
|
||||
{CIData && step >= 1 && <span className="ml10">{CIData.ip}</span>}
|
||||
{ step === 0 && <span className="ml10 authTag red">未绑定</span> }
|
||||
{ step === 1 && <span className="ml10 authTag red">未认证</span> }
|
||||
{ step === 2 && <span className="ml10 authTag green">已认证</span> }
|
||||
</AlignCenter>
|
||||
<AlignCenter>
|
||||
{ step === 0 && <Button type={'primary'} onClick={()=>setBindVisible(true)} >马上绑定</Button> }
|
||||
{ step === 1 && <Button type={'primary'} style={{color:"#fff"}} href={CIData && CIData.redirect_url} target="_blank">马上认证</Button> }
|
||||
{ step >= 1 && <Button type={'danger'} className="ml20" onClick={()=>setVisible(true)}>解除绑定</Button> }
|
||||
</AlignCenter>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(forwardRef(CIdispose));;
|
||||
|
|
@ -70,4 +70,52 @@ $flex:flex;
|
|||
margin: 8px 0 0 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.ant-menu.menuStyle{
|
||||
padding:0px 30px;
|
||||
font-size: 16px;
|
||||
li{
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
padding:0px;
|
||||
margin-right: 30px!important;
|
||||
}
|
||||
}
|
||||
.disposeInfo{
|
||||
padding:0px 30px;
|
||||
min-height: 400px;
|
||||
.disposeItem{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding:30px 0px;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
}
|
||||
}
|
||||
.authTag{
|
||||
display: inline-block;
|
||||
padding:0px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
&.red{
|
||||
border:1px solid #F73030;
|
||||
color: #F73030;
|
||||
}
|
||||
&.green{
|
||||
border:1px solid #28BD6C;
|
||||
color: #28BD6C;
|
||||
}
|
||||
}
|
||||
.CIList{
|
||||
padding:0px 30px;
|
||||
min-height: 400px;
|
||||
li{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding:28px 0px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
|
|
@ -252,10 +252,10 @@ class Infos extends Component {
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
{/* <div className="bgcF">
|
||||
<div className="bgcF">
|
||||
<ul className="list-l-Menu">
|
||||
<li className="MenuTitle">
|
||||
<i className="iconfont icon-xiangmuleixing font-15 mr5"></i>
|
||||
<i className="iconfont icon-gongzuoliu font-15 mr5"></i>
|
||||
DevOps工作流
|
||||
<i className="iconfont icon-youjiantou font-15 mr20 color-grey-9 pull-right"></i>
|
||||
</li>
|
||||
|
|
@ -267,16 +267,16 @@ class Infos extends Component {
|
|||
</span>
|
||||
</p>
|
||||
</li>
|
||||
<li className={project_type && project_type === "CDService" ? "active" : ""} onClick={() => this.change_devops_type("CDService")}>
|
||||
{/* <li className={project_type && project_type === "CDService" ? "active" : ""} onClick={() => this.change_devops_type("CDService")}>
|
||||
<p>
|
||||
<span className="font-16">CD服务</span>
|
||||
<span className="color-blue">
|
||||
{user && user.common_projects_count}
|
||||
</span>
|
||||
</p>
|
||||
</li>
|
||||
</li> */}
|
||||
</ul>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
{/* <div className="bgcF">
|
||||
<div className="list-l-Menu">
|
||||
|
|
|
|||
|
|
@ -1,8 +1,30 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Menu } from 'antd';
|
||||
import './Index.scss';
|
||||
import CIdispose from './CIdispose';
|
||||
import CIList from './CIList';
|
||||
|
||||
function DevOpsCI(){
|
||||
|
||||
function DevOpsCI(props){
|
||||
const [ selectKey , setSelectKey ] = useState("dispose");
|
||||
|
||||
function changeKeys(e){
|
||||
setSelectKey(e.key);
|
||||
}
|
||||
|
||||
return(
|
||||
<div>111</div>
|
||||
<div>
|
||||
<Menu mode="horizontal" className="menuStyle" onClick={changeKeys} selectedKeys={[selectKey]}>
|
||||
<Menu.Item key="dispose">服务器配置</Menu.Item>
|
||||
<Menu.Item key="list">项目列表</Menu.Item>
|
||||
</Menu>
|
||||
{
|
||||
selectKey === "dispose" ?
|
||||
<CIdispose {...props}/>
|
||||
:
|
||||
<CIList {...props}/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default DevOpsCI;
|
||||
Loading…
Reference in New Issue