Merge branch 'develop'

This commit is contained in:
caishi 2021-01-06 16:04:09 +08:00
commit e5d9728807
9 changed files with 225 additions and 89 deletions

View File

@ -4,10 +4,10 @@ import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
import { notification } from 'antd';
import cookie from 'react-cookies';
import './index.css';
let message501 = false;
let message501 = false;
broadcastChannelOnmessage('refreshPage', () => {
window.location.reload()
window.location.reload();
})
function locationurl(list) {
@ -54,10 +54,8 @@ setpostcookie();
window._debugType = debugType;
export function initAxiosInterceptors(props) {
initOnlineOfflineListener()
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
var
proxy = "http://localhost:3000";
initOnlineOfflineListener();
var proxy = "http://localhost:3000";
proxy = "https://testforgeplus.trustie.net";
const requestMap = {};

View File

@ -5,7 +5,7 @@ import './Component.scss';
export default (()=>{
return(
<div className="handleBox">
<a href="https://www.trustie.net/forums/82/memos/3075" target="_blank" >
<a href="https://forum.trustie.net/forums/3075/detail" target="_blank" >
<img src={Handbook} alt=""/>
</a>
</div>

View File

@ -1,9 +1,10 @@
import React, { forwardRef, useCallback, useState , useEffect } from "react";
import activate from "../Images/activate.png";
import { Blueback , AlignCenter } from "../Component/layout";
import { AlignCenter, Blueback } from "../Component/layout";
import PasswordAuthority from "../Component/PasswordAuthority";
import styled from "styled-components";
import { Form, Input , Spin , Modal } from "antd";
import { Form, Input , Spin , Button } from "antd";
import ServiceModal from './ServiceModal';
import axios from "axios";
const P = styled.p`
@ -20,15 +21,20 @@ const P = styled.p`
function About(props, ref) {
const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props;
const [isSpining, setIsSpining] = useState(true);
const [ authorityValBox , setAuthorityValBox ] = useState(false);
//
const [ authorityVal , setAuthorityVal ] = useState(undefined);
const [ authorityValFlag , setAuthorityValFlag ] = useState(false);
//0: devops
//1:
const [step, setStep] = useState(undefined);
// step1true
const [step, setStep] = useState(0);
const owner = props.match.params.owner;
const { user } = props;
const projectsId = props.match.params.projectsId;
const [ disabled, setDisabled ] = useState(false);
const [ typeFlag, setTypeFlag] = useState(false);
const AuthorLogin = props.author && props.author.login;
@ -47,12 +53,17 @@ function About(props, ref) {
method:`${type}`,
url
}).then(result=>{
setIsSpining(false);
if(result && result.data ){
setIsSpining(false);
setStep(result.data.step);
setFieldsValue({...result.data.cloud_account});
// setStep(0);
// setFieldsValue({...result.data.cloud_account});
// if(result.data.cloud_account){
// setDisabled(true);
// }
}
}).catch(error=>{
setIsSpining(false);
console.log(error);
})
}
@ -72,8 +83,8 @@ function About(props, ref) {
function goStep() {
validateFields((error, values) => {
if (!error) {
if(step > 0){
setAuthorityValBox(true);
if(disabled){
setStep(1);
}else{
setIsSpining(true);
const url = `/${owner}/${projectsId}/cloud_accounts.json`;
@ -82,7 +93,6 @@ function About(props, ref) {
if (result && result.data.redirect_url) {
props.showNotification("服务器信息配置完成!");
setStep(1);
setAuthorityValBox(true);
}
})
.catch((error) => {
@ -94,6 +104,50 @@ function About(props, ref) {
});
}
// 12trustie
function sureModal(type){
if(type === 2){
setTypeFlag(false);
setIsSpining(true);
const url = `/users/ci/cloud_account/trustie_bind.json`;
axios.post(url,{
account:user && user.login
}).then(result=>{
setIsSpining(false);
if(result && result.data){
setStep(result.data.step);
}
}).catch(error=>{setIsSpining(false)})
}else{
setTypeFlag(true);
}
}
//
function goUpStep(step){
setTypeFlag(false);
setStep(step);
}
//
function authStep(){
if(!authorityVal){
setAuthorityValFlag(true);
return;
}
setAuthorityValFlag(false);
setIsSpining(true);
const url = `/users/ci/oauth_grant.json`;
axios.get(url,{
params:{password:authorityVal}
}).then(result=>{
setIsSpining(false);
if(result){
setStep(result.data.step);
}
}).catch(error=>{setIsSpining(false)});
}
//
function startActive(){
setIsSpining(true);
@ -111,18 +165,10 @@ function About(props, ref) {
setIsSpining(false);
})
}
// -
function cancelAuthority(){
setAuthorityValBox(false);
}
//
function okAuthority(step){
setAuthorityValBox(false);
setStep(step);
}
return (
<Spin spinning={isSpining}>
<PasswordAuthority authorityValBox={authorityValBox} successFunc={okAuthority} cancelFunc={cancelAuthority}></PasswordAuthority>
{/* <PasswordAuthority authorityValBox={authorityValBox} successFunc={okAuthority} cancelFunc={cancelAuthority}></PasswordAuthority> */}
<div className="activatePanel">
<img src={activate} alt="" width="250px" />
<P>定义DevOps工作流帮助您检测bug发布代码</P>
@ -139,45 +185,69 @@ function About(props, ref) {
{
AuthorLogin === CurrentLogin ?
<React.Fragment>
{ step <=1 ?
<React.Fragment>
<Input.Password style={{display:'none'}} size="large" />
<Form style={{marginTop:"20px"}}>
<p className="mb20" style={{width:"370px"}}>请仔细核对您的服务器信息一旦确认提交将无法修改</p>
{helper(
"服务器IP地址",
"ip",
[{ required: true, message: "请输入服务器IP地址" }],
<Input
placeholder="请输入服务器IP地址"
style={{ width: "368px" }}
size="large"
disabled={step > 0}
/>,
true
)}
{helper(
"服务器用户名:",
"account",
[{ required: true, message: "请输入服务器用户名" }],
<Input placeholder="请输入服务器用户名" size="large" disabled={step > 0}/>,
true
)}
{helper(
"服务器密码:",
"secret",
[{ required: true, message: "请输入服务器密码" }],
<Input.Password placeholder="请输入服务器密码" size="large" disabled={step > 0}/>,
true
)}
</Form>
<Blueback onClick={goStep}>下一步</Blueback>
</React.Fragment>
:""}
{step > 1 &&
{
step === 0 && !typeFlag ?
<ServiceModal sureModal={sureModal}></ServiceModal>
:""
}
{ typeFlag ?
<React.Fragment>
<Input.Password style={{display:'none'}} size="large" />
<Form style={{marginTop:"20px"}}>
<p className="mb20" style={{width:"370px"}}>请仔细核对您的服务器信息一旦确认提交将无法修改</p>
{helper(
"服务器IP地址",
"ip",
[{ required: true, message: "请输入服务器IP地址" }],
<Input
placeholder="请输入服务器IP地址"
style={{ width: "368px" }}
size="large"
disabled={disabled}
/>,
true
)}
{helper(
"服务器用户名:",
"account",
[{ required: true, message: "请输入服务器用户名" }],
<Input placeholder="请输入服务器用户名" size="large" disabled={disabled}/>,
true
)}
{helper(
"服务器密码:",
"secret",
[{ required: true, message: "请输入服务器密码" }],
<Input.Password placeholder="请输入服务器密码" size="large" disabled={disabled}/>,
true
)}
</Form>
<AlignCenter>
{ !disabled && <Button className="mr20" onClick={()=>goUpStep(0)}>上一步</Button>}
<Blueback onClick={goStep}>下一步</Blueback>
</AlignCenter>
</React.Fragment>
:""
}
{
step === 1 ?
<div>
<AlignCenter style={{justifyContent:"center",marginTop:"20px"}}>
<span style={{marginBottom:"42px"}}>密码</span>
<div>
<Input.Password value={authorityVal} className={authorityValFlag===true && "flags"} onChange={(e)=>setAuthorityVal(e.target.value)} style={{width:"220px"}}></Input.Password>
<p className="color-grey-9" style={{textAlign:"left",lineHeight:'21px'}}>您已保存相关服务器信息请输入密码<br/>确认授权DevOps应用</p>
</div>
</AlignCenter>
<AlignCenter style={{justifyContent:'center'}}>
<Blueback onClick={authStep} className="mt20">下一步</Blueback>
</AlignCenter>
</div>:""
}
{ step === 2 ?
<div style={{textAlign:'center',marginTop:"20px"}}>
<Blueback onClick={startActive} className="mt20">开始激活</Blueback>
</div>
</div>:""
}
</React.Fragment>
:""

View File

@ -1,4 +1,4 @@
import React from 'react';
import React , { useEffect } from 'react';
import { WhiteBack } from '../Component/layout';
import './ops.scss';
@ -15,6 +15,20 @@ const Infos = Loadable({
loading: Loading,
})
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/list`);
}else{
props.history.replace(`/projects/${owner}/${projectsId}/devops`);
}
}
},[open_devops])
return(
<WhiteBack className="opsPanel">
<Switch {...props}>

View File

@ -0,0 +1,21 @@
import React, { useState } from 'react';
import { Radio , Button } from 'antd';
function ServiceModal({sureModal}){
const [ type , setType ] = useState(1);
function changeType(e){
setType(e.target.value);
}
return(
<div className="mt30" style={{textAlign:"center"}}>
<Radio.Group value={type} onChange={changeType}>
<Radio value={1}>自有服务器</Radio>
<Radio value={2}>Trustie服务器</Radio>
</Radio.Group>
<p className="mt30"><Button type="primary" onClick={()=>sureModal(type)}>下一步</Button></p>
</div>
)
}
export default ServiceModal;

View File

@ -199,17 +199,6 @@ class Detail extends Component {
platform:result.data.platform && result.data.platform !== 'educoder'
})
// 工作流:两种状态进入的链接不同
const pathname = this.props.history.location.pathname;
let p = checkPathname(pathname);
if(p==="devops"){
if(result.data.open_devops && pathname === `/projects/${owner}/${projectsId}/devops`){
this.props.history.push(`/projects/${owner}/${projectsId}/devops/list`);
}else if(result.data.open_devops===false && pathname !== `/projects/${owner}/${projectsId}/devops`){
this.props.history.push(`/projects/${owner}/${projectsId}/devops`);
}
}
if (result.data.type !== 0 && result.data.mirror_status === 1) {
console.log("--------start channel --------");
// 是镜像项目,且未完成迁移
@ -459,14 +448,15 @@ class Detail extends Component {
<span>{watched ? '取消关注' : '关注'}</span>
</a>
{
watchers_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" style={{color:`${watched?"#2878FF":"#666"}`}} to={platform?{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }:""}>
{watchers_count}
</Link>
:
<span className="detail_tag_btn_count">{watchers_count}</span>
:""
}
</span>
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.pariseFunc(praised)}>
@ -474,11 +464,13 @@ class Detail extends Component {
<span>{praised ? '取消点赞' : '点赞'}</span>
</a>
{
praises_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" style={{color:`${praised?"#2878FF":"#666"}`}} to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
{praises_count}
</Link>:
<span className="detail_tag_btn_count">{praises_count}</span>
:""
}
</span>
<span className="detail_tag_btn">
@ -486,12 +478,14 @@ class Detail extends Component {
<i className="iconfont icon-fork color-grey-9 mr3"></i> (Fork)
</a>
{
forked_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
{forked_count}
</Link>
:
<span className="detail_tag_btn_count">{praises_count}</span>
<span className="detail_tag_btn_count">{forked_count}</span>
:""
}
</span>
</span>

View File

@ -43,8 +43,8 @@ class Index extends Component {
const flag = pathname === `/projects/${owner}/${projectsId}/setting`;
return (
<div className="ProjectListIndex">
<div style={{width:"28%",borderRadius:"5px",marginBottom:"30%"}}>
<Box className="ProjectListIndex">
<Short>
<ul className="list-l-Menu">
<li className={flag ? "active" : ""}>
<p>
@ -101,9 +101,9 @@ class Index extends Component {
</p>
</li> */}
</ul>
</div>
<div style={{width:"72%",borderRadius:"5px",marginBottom:"30px"}}>
<div style={{paddingLeft:"20px",boxSizing:"border-box"}}>
</Short>
<Long>
<Gap>
<Switch {...this.props}>
{/* 协作者 */}
<Route
@ -151,9 +151,9 @@ class Index extends Component {
)}
></Route>
</Switch>
</div>
</div>
</div>
</Gap>
</Long>
</Box>
);
}
}

View File

@ -4,17 +4,20 @@ import { AlignCenter } from '../Component/layout';
import axios from 'axios';
import Modals from '../Component/Modal';
import PasswordAuthority from '../Component/PasswordAuthority';
import Service from './Service';
const TIPS = "解除CI服务器绑定后您所有的项目构建数据将被清空。确定解除绑定";
function CIdispose(props){
const [ CIData , setCIData ] = useState(undefined);
const [ step , setStep ] = useState(0);
const [ visible, setVisible ] = useState(false);
const [ serviceVisible , setServiceVisible ] = useState(false);
const [ bindVisible, setBindVisible ] = useState(false);
const [ ci_certification, setCi_certification ] = useState(false);
const [ btnLoading , setBtnLoading ] = useState(false);
const [ authorityValBox , setAuthorityValBox] = useState(false);
const { user } = props;
const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props;
const helper = useCallback(
@ -105,8 +108,28 @@ function CIdispose(props){
setAuthorityValBox(false);
}
//
function SureBtn(type){
if(type === 1){
setServiceVisible(false);
setBindVisible(true);
}else{
const url = `/users/ci/cloud_account/trustie_bind.json`;
axios.post(url,{
account:user && user.login
}).then(result=>{
if(result && result.data){
setServiceVisible(false);
setAuthorityValBox(true);
getInit();
}
}).catch(error=>{setServiceVisible(false)})
}
}
return(
<div className="disposeInfo">
<Service visible={serviceVisible} SureBtn={SureBtn} CancelBtn={()=>{setServiceVisible(false)}}></Service>
<PasswordAuthority authorityValBox={authorityValBox} successFunc={okAuthority} cancelFunc={cancelAuthority}></PasswordAuthority>
<Modal
className="modalsStyle"
@ -114,6 +137,7 @@ function CIdispose(props){
title={"绑定CI服务器地址"}
onCancel={cancelBindInfo}
closable={true}
centered={true}
footer={
<div>
<Button onClick={cancelBindInfo}>取消</Button>
@ -155,12 +179,12 @@ function CIdispose(props){
<span>CI服务器地址</span>
{CIData && step >= 1 && <span className="ml10">{CIData.ip}</span>}
{ step === 0 && <span className="ml10 authTag red">未绑定</span> }
{ step > 0 && !ci_certification && <span className="ml10 authTag red">未认证</span> }
{ step === 1 && !ci_certification && <span className="ml10 authTag red">未认证</span> }
{ ci_certification && <span className="ml10 authTag green">已认证</span> }
</AlignCenter>
<AlignCenter>
{ step === 0 && <Button type={'primary'} onClick={()=>setBindVisible(true)} >马上绑定</Button> }
{ step > 0 && !ci_certification && <Button type={'primary'} style={{color:"#fff"}} onClick={()=>setAuthorityValBox(true)} target="_blank">马上认证</Button> }
{ step === 0 && <Button type={'primary'} onClick={()=>setServiceVisible(true)} >马上绑定</Button> }
{ step === 1 && !ci_certification && <Button type={'primary'} style={{color:"#fff"}} onClick={()=>setAuthorityValBox(true)} target="_blank">马上认证</Button> }
{ step >= 1 && <Button type={'danger'} className="ml20" onClick={()=>setVisible(true)}>解除绑定</Button> }
</AlignCenter>
</div>

View File

@ -0,0 +1,15 @@
import React from 'react';
import ServiceModal from '../DevOps/ServiceModal';
import { Modal } from 'antd';
function Service ({visible, SureBtn , CancelBtn }){
function SureModal(type){
SureBtn(type);
}
return(
<Modal title={"请选择服务器类型"} centered={true} visible={visible} footer={false} onCancel={CancelBtn}>
<ServiceModal sureModal={SureModal}></ServiceModal>
</Modal>
)
}
export default Service;