diff --git a/src/forge/Component/Component.scss b/src/forge/Component/Component.scss
index 57d23cee..bd9df436 100644
--- a/src/forge/Component/Component.scss
+++ b/src/forge/Component/Component.scss
@@ -100,6 +100,7 @@ li.ant-menu-item{
right:240px;
z-index: 10000;
}
+
@media screen and (max-width: 1800px){
.handleBox{
right:190px;
diff --git a/src/forge/Component/Modal.jsx b/src/forge/Component/Modal.jsx
new file mode 100644
index 00000000..5f1f664e
--- /dev/null
+++ b/src/forge/Component/Modal.jsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import { Modal , Button } from 'antd';
+import './Component.scss';
+
+function Modals({visible,title,content,onOk,onCancel}){
+ return(
+
+
+
+
+ }
+ >
+ {content}
+
+ )
+}
+export default Modals;
diff --git a/src/forge/DevOps/About.jsx b/src/forge/DevOps/About.jsx
index 2f1cfc97..9dfada31 100644
--- a/src/forge/DevOps/About.jsx
+++ b/src/forge/DevOps/About.jsx
@@ -156,9 +156,12 @@ function About(props, ref) {
下一步
:""}
- {step === 1 &&(
+ {step >= 1 &&(
)}
diff --git a/src/forge/css/index.scss b/src/forge/css/index.scss
index e86c2e66..b9ddc529 100644
--- a/src/forge/css/index.scss
+++ b/src/forge/css/index.scss
@@ -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;
diff --git a/src/forge/users/CIList.jsx b/src/forge/users/CIList.jsx
new file mode 100644
index 00000000..5c219c88
--- /dev/null
+++ b/src/forge/users/CIList.jsx
@@ -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(
+
+
+ {
+ list && list.length > 0 ?
+
+ {list.map((item,key)=>{
+ return(
+ -
+
+ {item.author && item.author.name}/{item.name}
+ { item.open_devops ?
+ 已激活
+ :
+ 未激活
+ }
+
+ { !item.open_devops && }
+
+ )
+ })}
+
+ :
+ }
+ {
+ total > limit &&
+
+ }
+
+
+ )
+}
+export default CIList;
diff --git a/src/forge/users/CIdispose.jsx b/src/forge/users/CIdispose.jsx
new file mode 100644
index 00000000..68d3d34b
--- /dev/null
+++ b/src/forge/users/CIdispose.jsx
@@ -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) => (
+
+ {label}
+
+ {getFieldDecorator(name, { rules, validateFirst: true })(widget)}
+
+
+ ),
+ []
+ );
+
+ 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(
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ CI服务器地址
+ {CIData && step >= 1 && {CIData.ip}}
+ { step === 0 && 未绑定 }
+ { step === 1 && 未认证 }
+ { step === 2 && 已认证 }
+
+
+ { step === 0 && }
+ { step === 1 && }
+ { step >= 1 && }
+
+
+
+ )
+}
+export default Form.create()(forwardRef(CIdispose));;
diff --git a/src/forge/users/Index.scss b/src/forge/users/Index.scss
index b67abf15..d65b2c50 100644
--- a/src/forge/users/Index.scss
+++ b/src/forge/users/Index.scss
@@ -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;
+ }
}
\ No newline at end of file
diff --git a/src/forge/users/Infos.js b/src/forge/users/Infos.js
index ae06f4a8..1c530672 100644
--- a/src/forge/users/Infos.js
+++ b/src/forge/users/Infos.js
@@ -252,10 +252,10 @@ class Infos extends Component {
- {/*
{/*
diff --git a/src/forge/users/devOpsCI.jsx b/src/forge/users/devOpsCI.jsx
index 6e9a6544..563120a6 100644
--- a/src/forge/users/devOpsCI.jsx
+++ b/src/forge/users/devOpsCI.jsx
@@ -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(
-
111
+
+
+ {
+ selectKey === "dispose" ?
+
+ :
+
+ }
+
)
}
export default DevOpsCI;
\ No newline at end of file