- {/*
版本库地址已变更,请基于新地址提交代码
*/}
- {
- http_url &&
HTTP
- }
-
-
- this.jsCopy()}>
-
- {
- downloadUrl &&
-
-
-
-
-
-
-
- }
+function CloneAddress({http_url , ssh_url , zip_url , tar_url}) {
+ const [ key , setKey ] = useState("HTTP");
+ return (
+
+
+
+
+
+
+
- )
- }
+
+
+ )
}
export default CloneAddress;
\ No newline at end of file
diff --git a/src/forge/Branch/Select.jsx b/src/forge/Branch/Select.jsx
index f33a716f..a39f9556 100644
--- a/src/forge/Branch/Select.jsx
+++ b/src/forge/Branch/Select.jsx
@@ -1,116 +1,67 @@
-import React , { useState , useEffect } from 'react';
-import { Popover , Input , Spin } from 'antd';
-import './branch.css';
-import { getBranch , getTag } from '../GetData/getData';
-
+import React , { useState , useEffect , useRef } from 'react';
+import { Dropdown} from 'antd';
+import './branch.scss';
+import SelectOverlay from './SelectOverlay';
+import { findDOMNode } from 'react-dom';
+import { turnbar } from 'educoder';
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true })=>{
const [ showValue , setShowValue ] = useState(branch);
- const [ inputValue , setInputValue] = useState(undefined);
- const [ nav , setNav ] = useState(0);
- const [ isSpin , setIsSpin ] = useState(true);
- const [ flag , setFlag ] = useState(false);
+ const [ visible , setVisible ] = useState(false);
- const [ data , setData ] = useState(undefined);
- const [ datas , setDatas ] = useState(undefined);
+ const refFa = useRef(null);
+ const refBox = useRef(null);
+
+ useEffect(() => {
+ document.addEventListener('click', clickMe , false);
+ }, [])
+
+ const clickMe = ({ target }) => {
+ // 查找父组件
+ const faComponent = findDOMNode(refFa.current);
+ const boxComponent = findDOMNode(refBox.current);
+
+ if (faComponent && boxComponent) {
+ const isChild = faComponent.contains(target);
+ const isBox = boxComponent.contains(target);
+ if(!isChild && !isBox){
+ setVisible(false);
+ }
+ }
+ }
useEffect(()=>{
setShowValue(branch);
},[branch])
- useEffect(()=>{
- document.body.addEventListener('click', e => {
- let name = e.target.className;
- let turn = name === "ant-input OptionsInput" || name === "navli active"|| name === "navli" || name === "padding10 bor-bottom-greyE";
- if(turn){
- return;
- }else{
- setFlag(false);
- }
- })
- })
-
- useEffect(()=>{
- if(branchList){
- setData(branchList);
- setDatas(branchList);
- setIsSpin(false);
- }
- },[branchList])
-
-
- async function getBranchs(id,owner){
- let result = await getBranch(id,owner);
- setData(result);
- setDatas(result);
- setIsSpin(false);
+ function ChangeB(params) {
+ setVisible(false);
+ let en = turnbar(params);
+ changeBranch(en);
}
- async function getTags(id,owner){
- let result = await getTag(id,owner);
- setData(result);
- setDatas(result);
- setIsSpin(false);
- }
-
- function changeInputValue(e){
- setInputValue(e.target.value);
- let filter = e.target.value ? data && data.length>0 && data.filter(item=>item.name.indexOf(e.target.value)>-1) : data;
- setDatas(filter);
- }
-
- function changeNav(nav){
- setNav(nav);
- setIsSpin(true);
- if(nav === 0){
- getBranchs(projectsId,owner);
- }else{
- getTags(projectsId,owner);
- }
- }
- function chooseitem(value){
- // setShowValue(value);
- changeBranch(value);
- }
-
const menu = (
-
-
-
-
- - changeNav(0)}>分支列表
- { tagflag && - changeNav(1)}>标签列表
}
-
-
-
-
-
+
+
);
return(
-
setFlag(!flag)} overlayClassName="branch-tagBox-list">
-
+
+ setVisible(visible ? false : true)}>
{/* {nav === 0 ?"分支":"标签"} */}
-
+
{showValue}
-
-
+
+
-
+
)
})
\ No newline at end of file
diff --git a/src/forge/Branch/SelectOverlay.jsx b/src/forge/Branch/SelectOverlay.jsx
new file mode 100644
index 00000000..0be56732
--- /dev/null
+++ b/src/forge/Branch/SelectOverlay.jsx
@@ -0,0 +1,90 @@
+import React , { useState , useEffect } from 'react';
+import { Input , Spin , Menu } from 'antd';
+import { getBranch , getTag } from '../GetData/getData';
+
+function SelectOverlay({ changeBranch , tagflag , projectsId , owner , visible }) {
+ const [ inputValue , setInputValue] = useState(undefined);
+ const [ nav , setNav ] = useState(0);
+ const [ isSpin , setIsSpin ] = useState(true);
+
+ const [ data , setData ] = useState(undefined);
+ const [ datas , setDatas ] = useState(undefined);
+ const [ keys ,setKeys] = useState("branch");
+
+ useEffect(()=>{
+ if(visible){
+ setKeys("branch");
+ getBranchs(projectsId,owner);
+ setIsSpin(true);
+ }
+ },[visible])
+
+ async function getBranchs(id,owner){
+ let result = await getBranch(id,owner);
+ setData(result);
+ setDatas(result);
+ setIsSpin(false);
+ }
+ async function getTags(id,owner){
+ let result = await getTag(id,owner);
+ setData(result);
+ setDatas(result);
+ setIsSpin(false);
+ }
+ function chooseitem(value){
+ changeBranch(value);
+ }
+ function changeInputValue(e){
+ setInputValue(e.target.value);
+ let filter = e.target.value ? data && data.length>0 && data.filter(item=>item.name.indexOf(e.target.value)>-1) : data;
+ setDatas(filter);
+ }
+
+ function changeNav(e){
+ setKeys(e.key);
+ setIsSpin(true);
+ if(e.key === "branch"){
+ getBranchs(projectsId,owner);
+ setNav(0);
+ }else{
+ getTags(projectsId,owner);
+ setNav(1);
+ }
+ }
+
+ return(
+
+
+ }
+ placeholder={`请输入分支${tagflag ? "或标签" :""}名称搜索`}
+ autocomplete="off" className="OptionsInput"
+ value={inputValue}
+ onChange={changeInputValue}
+ />
+
+
+
+
+
+
+ )
+}
+export default SelectOverlay;
\ No newline at end of file
diff --git a/src/forge/Branch/branch.css b/src/forge/Branch/branch.css
deleted file mode 100644
index 962b0197..00000000
--- a/src/forge/Branch/branch.css
+++ /dev/null
@@ -1,84 +0,0 @@
-.branchDropdown{
- border:1px solid #eee;
- border-radius: 4px;
- display: flex;
- justify-content: center;
- height: 40px;
- line-height: 40px;
- min-width: 220px;
-}
-.branchDropdown .ant-dropdown-trigger{
- width: 100%;
- padding:0px 15px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- cursor: pointer;
-}
-.branchOptions{
- width: 220px;
- box-shadow: 0px 0px 3px 1px rgba(134, 134, 134, 0.4);
- border-radius: 3px;
- background: #fff;
- max-height: 300px;
-}
-.OptionsUl{
- max-height: 220px;
- overflow-y: auto;
-}
-.OptionsUl li{
- height: 35px;
- line-height: 35px;
- cursor: pointer;
- padding:0px 10px;
-}
-.OptionsUl li:hover{
- background-color: #F0F0F0;
-}
-.OptionsUl li a{
- display: block;
-}
-.OptionsInput{
- height: 32px;
- padding-left: 4px;
- line-height: 32px;
- width: 100%;
-}
-.branch-tagBox{
- border:1px solid #eee;
- border-radius: 3px;
- height: 40px;
- display: flex;
- align-items: center;
- cursor: pointer;
- min-width: 140px;
-}
-.branch-tagBox-list .ant-popover-arrow{
- display: none;
-}
-.branch-tagBox-list.ant-popover.ant-popover-placement-bottom{
- padding-top:0px;
-}
-.branch-tagBox .ant-dropdown-link{
- display: block;
- flex:1;
-}
-.branch-tagBox-list .ant-popover-inner-content{
- padding:0px;
-}
-.navUl{
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-top: 5px;
-}
-.navUl li{
- cursor: pointer;
-}
-.navUl li.active{
- color:#5091FF;
-}
-.listTips{
- padding:20px 0px;
- text-align: center;
-}
\ No newline at end of file
diff --git a/src/forge/Branch/branch.scss b/src/forge/Branch/branch.scss
new file mode 100644
index 00000000..030b05cd
--- /dev/null
+++ b/src/forge/Branch/branch.scss
@@ -0,0 +1,129 @@
+.branchDropdown{
+ border:1px solid #eee;
+ border-radius: 4px;
+ display: flex;
+ justify-content: center;
+ height: 40px;
+ line-height: 40px;
+ min-width: 220px;
+}
+.branchDropdown .ant-dropdown-trigger{
+ width: 100%;
+ padding:0px 15px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+}
+.branchOptions{
+ width: 220px;
+ box-shadow: 0px 0px 3px 1px rgba(134, 134, 134, 0.4);
+ border-radius: 3px;
+ background: #fff;
+ max-height: 300px;
+}
+.OptionsUl{
+ min-height: 50px;
+ max-height: 220px;
+ overflow-y: auto;
+}
+.OptionsUl li{
+ height: 30px;
+ line-height: 30px;
+ cursor: pointer;
+ padding:0px 20px;
+ margin:5px 0px;
+}
+.OptionsUl li:hover{
+ background-color: #F0F0F0;
+}
+.OptionsUl li a{
+ display: block;
+}
+.OptionsInput{
+ height: 32px;
+ padding-left: 4px;
+ line-height: 32px;
+ width: 100%;
+}
+.branch-tagBox{
+ border:1px solid #D0D0D0;
+ border-radius: 3px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ min-width: 104px;
+}
+.branch-tagBox:hover{
+ background-color: #F3F4F6;
+}
+.branch-tagBox-list{
+ background: #FFFFFF;
+ box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5);
+ border-radius: 4px;
+ .ant-popover-arrow{
+ display: none;
+ }
+ &.ant-popover.ant-popover-placement-bottom{
+ padding-top:0px;
+ }
+ .branch-tagBox .ant-dropdown-link{
+ display: block;
+ flex:1;
+ max-width: 105px;
+ }
+ .ant-popover-inner-content{
+ padding:0px;
+ }
+}
+.overlayBranch{
+ width: 325px;
+ .navUl{
+ margin-top: 8px;
+ height: 30px;
+ line-height: 30px;
+ li{
+ height: 30px;
+ line-height: 30px;
+ padding:0px 5px;
+ margin-left: 20px!important;
+ &.ant-menu-item-selected{
+ border-color:#466aff!important;
+ color:#466aff!important;
+ }
+ &.ant-menu-item-active{
+ border-color:transparent ;
+ }
+ }
+ }
+}
+.listTips{
+ padding:20px 0px;
+ text-align: center;
+}
+
+.urlMenu{
+ line-height: 30px;
+ margin-bottom: 10px;
+ padding:15px 20px 0px 20px;
+ border-bottom: none;
+ li.ant-menu-item{
+ height: 30px;
+ line-height: 30px;
+ padding:0px 5px;
+ margin-right: 20px!important;
+ &.ant-menu-item-selected,&.ant-menu-item-active{
+ color: #333;
+ }
+ &.ant-menu-item-selected{
+ border-color:#466aff!important;
+ }
+ &.ant-menu-item-active{
+ border-color:transparent ;
+ }
+ }
+}
+.copytool{
+ margin:0px 10px;
+}
\ No newline at end of file
diff --git a/src/forge/Component/AddGroup.jsx b/src/forge/Component/AddGroup.jsx
index 656175d5..feff6f37 100644
--- a/src/forge/Component/AddGroup.jsx
+++ b/src/forge/Component/AddGroup.jsx
@@ -55,6 +55,7 @@ function AddGroup({organizeId,getGroupID}){
function addCollaborator(){
getGroupID && getGroupID(id);
+ setID(undefined);
}
return(
diff --git a/src/forge/Component/AddMember.jsx b/src/forge/Component/AddMember.jsx
index 0548e52d..f453be05 100644
--- a/src/forge/Component/AddMember.jsx
+++ b/src/forge/Component/AddMember.jsx
@@ -4,7 +4,7 @@ import axios from 'axios';
import { getImageUrl } from 'educoder';
const { Option } = AutoComplete;
-function AddMember({getID,login}){
+function AddMember({getID,login,showNotification}){
const [ id , setID ] = useState(undefined);
const [ source , setSource ] = useState(undefined);
const [ searchKey , setSearchKey ] = useState(undefined);
@@ -45,7 +45,7 @@ function AddMember({getID,login}){
src={getImageUrl(`/${item && item.image_url}`)}
alt=""
/>
-
+
{item.username}
({item.login})
@@ -66,7 +66,13 @@ function AddMember({getID,login}){
};
function addCollaborator(){
- getID && getID(id);
+ if(source && source.length>0&&searchKey){
+ getID && getID(id);
+ setSearchKey(undefined);
+ setID(undefined)
+ }else{
+ showNotification("请选择存在的用户!");
+ }
}
return(
diff --git a/src/forge/Component/Component.scss b/src/forge/Component/Component.scss
index 12a899d8..3e9b01cf 100644
--- a/src/forge/Component/Component.scss
+++ b/src/forge/Component/Component.scss
@@ -113,7 +113,14 @@ li.ant-menu-item{
z-index: 10000;
}
.laterest{
- color: #05690d;
+ background-color: #EF3131;
+ color: #fff;
+ font-size: 12px;
+ margin-left: 10px;
+ padding:0px 5px;
+ border-radius: 2px;
+ height: 18px;
+ line-height: 18px;
}
@media screen and (max-width: 1800px){
@@ -155,41 +162,301 @@ li.ant-menu-item{
margin:0px 20px!important;
}
}
-
+.hoverA{
+ display:flex;
+ align-items: center;
+ max-width: 78px;
+ &:hover a{
+ color:#2A61FF !important ;
+ }
+}
.menuPanels{
- width: 240px;
- height: 180px;
+ width: 295px;
+ .leftline{
+ position: relative;
+ color: #666;
+ height: 16px;
+ margin-left: 14px;
+ font-size: 12px;
+ &::before{
+ position: absolute;
+ left: -7px;
+ top:3px;
+ height: 12px;
+ width: 1px;
+ background-color: #999;
+ content: "";
+ }
+ }
+ .ant-btn{
+ height: 36px;
+ line-height: 34px;
+ width: 83px;
+ text-align: center;
+ padding:0px ;
+ font-weight: 500;
+ font-size: 14px;
+ &.currentBtn{
+ cursor: default;
+ color: #333;
+ &:hover{
+ color: #333;
+ border-color: #d0d0d0;
+ }
+ }
+ }
+ .ant-btn-default{
+ color: #333;
+ border-color: #d0d0d0;
+ &:hover{
+ background: #F3F4F6;
+ }
+ }
+ .ant-btn{
+ width: 102px;
+ height: 32px;
+ line-height: 30px;
+ }
+ .ant-btn-primary{
+ color: #fff;
+ background-color: #466AFF;
+ border:none;
+ &:hover{
+ background-color: rgba(70,106,255,0.85);
+ }
+ }
+ .focusPanelHeadInfo{
+ padding:14px 16px;
+ border-bottom: 1px solid #eee;
+ }
.ant-popover-content,.ant-popover-inner{
height: 100%;
width: 100%;
}
+ .ant-popover-inner-content{
+ padding:0px;
+ }
}
.halfs{
margin-top: 24px;
padding:24px 0px 0px 0px;
border-top: 1px solid #e8e8e8;
- .attrPerson{
- padding-bottom: 24px;
- }
+}
+.aboutSubTitle{
+ display: flex;
+ align-items: center;
+}
+.menuMaininfos{
+ padding:10px 16px 14px;
+ border-bottom: 1px solid #eee;
}
.menuinfos{
- padding:15px 0px;
+ padding:10px 20px 16px;
&>a{
display: flex;
flex-direction: column;
align-items: center;
- border-right: 1px solid #eee;
flex: 1;
& >span:first-child{
- font-size: 18px;
- font-weight: 400;
+ font-size: 16px;
+ font-weight: 500;
color: #333;
+ line-height: 22px;
}
& >span:last-child{
color: #666;
- }
- &:last-child{
- border-right: none;
+ font-weight: 400;
+ line-height: 20px;
+ margin-top: 6px;
}
}
-}
\ No newline at end of file
+}
+
+/*-------------------个人主页:右侧提示区域--------------------------*/
+.-task-sidebar {
+ position: fixed;
+ width: 40px;
+ right: 10px;
+ bottom: 80px;
+ z-index: 10;
+}
+
+@media screen and (max-width: 1920px){
+ .-task-sidebar{
+ right:220px;
+ }
+}
+@media screen and (max-width: 1750px){
+ .-task-sidebar{
+ right:160px;
+ }
+}
+@media screen and (max-width: 1650px){
+ .-task-sidebar{
+ right:115px;
+ }
+}
+@media screen and (max-width: 1550px){
+ .-task-sidebar{
+ right:90px;
+ }
+}
+@media screen and (max-width: 1450px){
+ .-task-sidebar{
+ right:45px;
+ }
+}
+@media screen and (max-width: 1200px){
+ .-task-sidebar{
+ right:0px;
+ display: none;
+ }
+}
+.-task-sidebar>div {
+ height: 48px;
+ line-height: 48px;
+ box-sizing: border-box;
+ width: 48px;
+ color: #999;
+ font-size: 20px;
+ text-align: center;
+ margin-bottom: 20px;
+ border-radius: 50%;
+ background: #FFFFFF;
+ box-shadow: 0px 0px 12px 5px rgba(208, 208, 208, 0.2);
+}
+
+.-task-sidebar>div i {
+ color: #999;
+}
+
+.-task-sidebar>div:hover i {
+ color: #fff !important;
+}
+.-task-sidebar>div:hover{
+ background: #466AFF;
+ box-shadow: 0px 0px 10px 2px #B6D0FC;
+}
+.helpBox{
+ width: 260px;
+ z-index: 103;
+ &.shareContent{
+ width: 160px;
+ }
+ .ant-popover-title{
+ font-size: 16px;
+ }
+ .ant-popover-inner-content{
+ padding:0px;
+ }
+ p.titlecontent{
+ font-size: 16px;
+ color: #333;
+ line-height: 20px;
+ padding:15px 20px;
+ }
+ .faqUl{
+ padding:10px 15px;
+ max-height: 230px;
+ overflow-y: auto;
+ font-size: 13px;
+ li{
+ background: #F5F5F5;
+ border-radius: 20px;
+ padding:0px 15px;
+ color: #333;
+ height: 30px;
+ line-height: 30px;
+ margin-bottom: 3px !important;
+ a{
+ display: block;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ &:hover{
+ background-color: #D1E9FF;
+ a{
+ color: #333!important;
+ }
+ }
+ }
+ }
+ .shareUl{
+ display: flex;
+ align-items: center;
+ li > i{
+ font-size: 32px!important;
+ }
+ }
+}
+// tooltip样式
+.tooltipBox .ant-tooltip-inner{
+ padding: 8px 12px;
+ font-size: 15px;
+}
+
+.-task-desc {
+ background: #494949;
+ width: 90px;
+ line-height: 36px;
+ text-align: center;
+ position: absolute;
+ color: #fff;
+ font-size: 13px;
+ z-index: 999999;
+ opacity: 0;
+}
+
+.-task-desc div {
+ position: absolute;
+ top: 10px;
+ right: -7px;
+ height: 13px;
+}
+
+.-task-desc div img {
+ float: left
+}
+
+.-task-sidebar .scan_ewm {
+ position: absolute !important;
+ right: 45px !important;
+ bottom: 0px !important;
+ background-color: #494949 !important;
+ -webkit-box-sizing: border-box !important;
+ box-sizing: border-box !important;
+ font-size: 14px !important;
+ line-height: 16px !important;
+ display: none;
+ height: 213px !important;
+}
+
+.trangle_right {
+ position: absolute;
+ right: -5px;
+ bottom: 15px;
+ width: 0;
+ height: 0px;
+ border-top: 6px solid transparent;
+ border-left: 5px solid #494949;
+ border-bottom: 6px solid transparent
+}
+//头部输入框样式
+.headSerach{
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 4px;
+ padding-left: 20px;
+ //修改antd输入框默认样式
+ .ant-input,.ant-input:focus{
+ border: none !important;
+ background-color: rgba(255, 255, 255, 0) !important;
+ }
+ &:hover{
+ padding: 2px 20px 2px 20px;
+ background: #FFF;
+ & i{
+ color: #333;
+ }
+ }
+}
diff --git a/src/forge/Component/Contributors.jsx b/src/forge/Component/Contributors.jsx
index 1e26354a..f6dade6a 100644
--- a/src/forge/Component/Contributors.jsx
+++ b/src/forge/Component/Contributors.jsx
@@ -1,13 +1,13 @@
import React, { useEffect, useState } from 'react';
import { AlignCenter , FlexAJ } from '../Component/layout';
import { Link } from 'react-router-dom';
-import { Popover , Spin } from 'antd';
+import { Popover , Spin , Button } from 'antd';
import { getImageUrl } from 'educoder';
import './Component.scss';
import { getUser } from '../GetData/getData';
import axios from 'axios';
-function Contributors({contributors,owner,projectsId}){
+function Contributors({owner,projectsId,currentLogin}){
const [ menuList ,setMenuList ]= useState([]);
const [ list , setList ]= useState(undefined);
const [ total , setTotal ]= useState(0);
@@ -16,11 +16,18 @@ function Contributors({contributors,owner,projectsId}){
const [ isSpin , setIsSpin ] = useState(false);
useEffect(()=>{
- if(contributors && contributors.total_count>0){
- setTotal(contributors.total_count);
- setList(contributors.list);
- }
- },[contributors])
+ getData();
+ },[])
+
+ function getData(){
+ const url = `/${owner}/${projectsId}/contributors.json`;
+ axios.get(url).then(result=>{
+ if(result){
+ setTotal(result.data.total_count);
+ setList(result.data.list);
+ }
+ }).catch(error=>{})
+ }
useEffect(()=>{
if(login){
@@ -46,46 +53,60 @@ function Contributors({contributors,owner,projectsId}){
}
}
+ function renderOrganize(list) {
+ let str = "";
+ list.map(i=>{
+ str = str+i.name + "、";
+ })
+ return str && str.substr(0,str.length - 1);
+ }
+
function setMenusFunc(data){
if(data){
let ele = (
-
+
-
- {data.name}
-
- {
- data.is_watch ? FocusFunc(false,data.login)}>取消关注:FocusFunc(true,data.login)}>关注
- }
-
-
-
- {data.projects_count}
- 项目数
-
-
- {data.followers_count}
- 粉丝数
-
-
- {data.following_count}
- 关注数
-
-
- {
- data.organizations && data.organizations.length > 0 ?
-
- 所属组织:
-
- {renderArray(data.organizations)}
+
})
+
+
+
{data.name}
+ { data.location &&
{data.location} }
+ {
+ data.organizations && data.organizations.length>0&&
+
+ 所属组织:{renderOrganize(data.organizations)}
+
+ }
- :""
- }
- {
- data.location &&
所在地址:{data.location}
- }
+
+
+
+ {data.projects_count}
+ 项目数
+
+
+ {data.followers_count}
+ 粉丝数
+
+
+ {data.following_count}
+ 关注数
+
+
+
+ {
+ currentLogin && (currentLogin === data.login)
+ ?
+
+ :
+ data.is_watch ?
+
+ :
+
+ }
+
)
setMenu(ele);
@@ -134,27 +155,26 @@ function Contributors({contributors,owner,projectsId}){
}
return(
+ total > 0 ?
-
- 贡献者{ contributors && contributors.total_count > 0 && {contributors.total_count}}
- 全部
-
+
+
贡献者
+ { total > 0 &&
{total}}
+
setVisibleFunc(false)}>
{
- total > 0 ?
- list.map((item,key)=>{
+ list && list.length>0 && list.map((item,key)=>{
return(
-
+
setVisibleFunc(true,item.login,key)}/>
)
})
- :""
}
-
+
:""
)
}
export default Contributors;
\ No newline at end of file
diff --git a/src/forge/Component/CopyTool.jsx b/src/forge/Component/CopyTool.jsx
new file mode 100644
index 00000000..36ed1d8c
--- /dev/null
+++ b/src/forge/Component/CopyTool.jsx
@@ -0,0 +1,51 @@
+import React, { useState, useCallback, memo } from 'react';
+import { Tooltip } from 'antd';
+
+CopyTool.defaultProps = {
+ beforeText: '复制链接', //浮动过去显示的文字
+ afterText: '复制成功', //点击后显示的文字
+ className: '', //传给svg的class
+ inputId: 'copyText', //要复制的文本的ID
+ timeOut:true, //复制后将浮动的文字改为beforeText
+};
+
+
+function CopyTool({ beforeText, afterText, className , inputId , timeOut }) {
+ const [title, setTitle] = useState(() => {
+ return beforeText;
+ });
+
+ // 复制链接
+ const copyUrl = useCallback(() => {
+ const copyEle = document.querySelector(`#${inputId}`); // 获取要复制的节点
+ if (!copyEle) {
+ console.error("您的CopyTool未设置正确的inputId");
+ return;
+ }
+ copyEle.select(); // 执行选中元素
+ if (document.execCommand('copy')) {
+ document.execCommand('copy');
+ }
+ document.getSelection().removeAllRanges();
+
+ setTitle(afterText);
+ if(timeOut){
+ setTimeout(function(){
+ setTitle(beforeText);
+ },1500)
+ }
+ }, []);
+
+ return (
+ { setTitle(beforeText) }}
+ >
+
+
+ );
+}
+
+
+export default memo(CopyTool);
\ No newline at end of file
diff --git a/src/forge/Component/DeleteModal/Index.jsx b/src/forge/Component/DeleteModal/Index.jsx
new file mode 100644
index 00000000..f12b8ea8
--- /dev/null
+++ b/src/forge/Component/DeleteModal/Index.jsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import { AlignCenter } from '../layout';
+import { Button } from 'antd';
+import Modals from '../PublicModal/Index';
+
+function DeleteBox({
+ visible ,
+ onCancel ,
+ onSuccess ,
+ title ,
+ subTitle,
+ content
+}) {
+ return(
+
+
+
+
+ }
+ onCancel={onCancel}
+ visible={visible}
+ >
+
+
{content}
+
删除后未来事件将不会推送至此Webhook地址:{subTitle}
+
+
+ )
+}
+export default DeleteBox;
\ No newline at end of file
diff --git a/src/forge/Component/DrawerPanel.jsx b/src/forge/Component/DrawerPanel.jsx
index 8070f3fa..28847fda 100644
--- a/src/forge/Component/DrawerPanel.jsx
+++ b/src/forge/Component/DrawerPanel.jsx
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Drawer , Tree , Spin } from 'antd';
+import { turnbar} from 'educoder';
import './Component.scss';
import axios from 'axios';
const { TreeNode , DirectoryTree } = Tree;
@@ -71,7 +72,8 @@ function DrawerPanel({visible,onClose,branch,owner,projectsId,history, name , li
let dataref = event.node.props.dataRef;
if(dataref.type==="file"){
onClose();
- history.push(`/projects/${owner}/${projectsId}/tree/${branch}/${dataref.path}`);
+ let value = turnbar(branch);
+ history.push(`/${owner}/${projectsId}/tree/${value}/${dataref.path}`);
}
}
diff --git a/src/forge/Component/EAccount.scss b/src/forge/Component/EAccount.scss
index 4bcd6b91..6fe44ab3 100644
--- a/src/forge/Component/EAccount.scss
+++ b/src/forge/Component/EAccount.scss
@@ -1,9 +1,6 @@
.ant-modal-mask{
- z-index: 1001;
+ z-index: 1031;
}
.ant-modal-wrap{
- z-index: 1002;
- .ant-form-explain{
- position: absolute;
- }
+ z-index: 1032;
}
\ No newline at end of file
diff --git a/src/forge/Component/HeadSearch.jsx b/src/forge/Component/HeadSearch.jsx
new file mode 100644
index 00000000..0e44a2cd
--- /dev/null
+++ b/src/forge/Component/HeadSearch.jsx
@@ -0,0 +1,41 @@
+import React, { useState } from "react";
+import { Input ,notification} from "antd";
+
+const { Search } = Input;
+export default ({history}) => {
+ const [openSearch, setOpenSearch] = useState(false);
+
+ function onGlobalSearch(value) {
+ history.push('/search?value=' + value);
+ // window.location.href = `search?value=` + value;
+ // history.push({
+ // pathname:'/search',
+ // state:value
+ // })
+ }
+ return (
+
+ {
+ openSearch ?
+ {
+ setTimeout(() => {
+ setOpenSearch(false)
+ }, 500)
+ }}
+ >
+
+
+ :
+ {
+ setOpenSearch(true)
+ }} />
+ }
+
+ )
+};
diff --git a/src/forge/Component/LanguagePower.jsx b/src/forge/Component/LanguagePower.jsx
index 3197309c..b2fb174b 100644
--- a/src/forge/Component/LanguagePower.jsx
+++ b/src/forge/Component/LanguagePower.jsx
@@ -1,18 +1,41 @@
import React, { useEffect, useState } from 'react';
import { FlexAJ } from '../Component/layout';
+import { Divider } from 'antd';
+import axios from 'axios';
-function LanguagePower({languages}){
+function LanguagePower({owner,projectsId}){
const [ array , setArray ] = useState(undefined);
+
useEffect(()=>{
- if(languages){
- let arr = [];
- Object.keys(languages).map((item,key)=>{
- arr.push({name:item,percent:languages[item],color:getColor()});
- })
- setArray(arr);
- }
- },[languages])
+ getData();
+ },[])
+
+ function getData(){
+ const url = `/${owner}/${projectsId}/languages.json`;
+ axios.get(url).then(result=>{
+ if(result){
+ let languages = result.data;
+ if(languages){
+ let arr = [];
+ Object.keys(languages).map((item,key)=>{
+ arr.push({name:item,percent:languages[item],color:getColor()});
+ })
+ setArray(arr);
+ }
+ }
+ }).catch(error=>{})
+ }
+
+ // useEffect(()=>{
+ // if(languages){
+ // let arr = [];
+ // Object.keys(languages).map((item,key)=>{
+ // arr.push({name:item,percent:languages[item],color:getColor()});
+ // })
+ // setArray(arr);
+ // }
+ // },[languages])
function getColor(){
let str = "#";
@@ -24,8 +47,10 @@ function LanguagePower({languages}){
return str;
}
return(
+ (array && array.length > 0) ?
-
开发语言
+
+
开发语言
{
array && array.map((item,key)=>{
@@ -47,8 +72,7 @@ function LanguagePower({languages}){
}
}
-
-
+
:""
)
}
export default LanguagePower;
\ No newline at end of file
diff --git a/src/forge/Component/MemberCards.jsx b/src/forge/Component/MemberCards.jsx
index 393ddbb1..48d90e13 100644
--- a/src/forge/Component/MemberCards.jsx
+++ b/src/forge/Component/MemberCards.jsx
@@ -45,15 +45,15 @@ const Div = styled.div`{
export default (({ user , img, name, time, focusStatus, is_current_user, login , successFunc }) => {
return (
-
})
+
- {name}
+ {name}
{
is_current_user ?
:
-
+
}
diff --git a/src/forge/Component/ModalFun/index.jsx b/src/forge/Component/ModalFun/index.jsx
new file mode 100644
index 00000000..8fee2c73
--- /dev/null
+++ b/src/forge/Component/ModalFun/index.jsx
@@ -0,0 +1,125 @@
+/* eslint-disable react/jsx-no-duplicate-props */
+import React, { useState } from 'react';
+import * as ReactDOM from 'react-dom';
+import { Modal, Button } from 'antd';
+import './index.scss';
+
+// 函数式调用删除、通知等模态框
+
+InitModal.defaultProps = {
+ okText: '确认', //确定按钮的文字
+ cancelText: '取消', //取消按钮的文字
+ className: '', //传入的模态框类名
+ inputId: 'copyText', //要复制的文本的ID
+ onCancel:()=>{}, //取消的回调
+ onOk:()=>{}, //确认的回调
+ title:'提示', //模态框名字
+ contentTitle:'', //内容标题
+ content:'', //详细内容
+ afterClose:()=>{}, //关闭模态框以后的回调
+};
+
+// 使用函数调用删除组件
+export default function DelModal(props) {
+ renderModal({ ...props, type: 'delete' })
+}
+
+// 使用函数调用选择模态框组件
+export function Confirm(props) {
+ renderModal({ ...props, type: 'confirm' })
+}
+
+function renderModal(props) {
+ const { type, afterClose } = props;
+ const div = document.createElement('div');
+ document.body.appendChild(div);
+
+ function destroy() {
+ afterClose && afterClose();
+ const unmountResult = ReactDOM.unmountComponentAtNode(div);
+ if (unmountResult && div.parentNode) {
+ div.parentNode.removeChild(div);
+ }
+ }
+
+ function modalType(type) {
+ if (type === 'delete') {
+ return
+
+ {props.contentTitle}
+ }
+ />
+ } else if (type === 'confirm') {
+ return
+ } else {
+ return
+ }
+ }
+
+ function render() {
+ setTimeout(() => {
+ ReactDOM.render(
+ modalType(type),
+ div,
+ );
+ });
+ }
+ render();
+}
+
+// 选择模态框组件
+function InitModal({
+ onCancel,
+ onOk,
+ title,
+ contentTitle,
+ content,
+ okText,
+ cancelText,
+ afterClose,
+ className,
+}) {
+
+ const [visible, setVisible] = useState(true);
+
+ function onCancelModal() {
+ setVisible(false);
+ onCancel && onCancel()
+ }
+
+ function onSuccess() {
+ setVisible(false);
+ onOk && onOk();
+ }
+
+ return (
+
+ {cancelText}
+ ,
+ ,
+ ]}
+ >
+
+ {contentTitle &&
{contentTitle}
}
+
{content}
+
+
+ )
+}
diff --git a/src/forge/Component/ModalFun/index.scss b/src/forge/Component/ModalFun/index.scss
new file mode 100644
index 00000000..24f7b021
--- /dev/null
+++ b/src/forge/Component/ModalFun/index.scss
@@ -0,0 +1,63 @@
+.myself-modal {
+ .ant-modal-header {
+ padding: 9px 24px;
+ background: #f8f8f8;
+ border-bottom: 1px solid #eee;
+ }
+ .ant-modal-title {
+ text-align: left;
+ }
+ .ant-modal-close {
+ top: 0px !important;
+ }
+ .ant-modal-close-x {
+ font-size: 24px;
+ }
+ .ant-modal-body {
+ text-align: center;
+ }
+ .content-title {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin: 2rem 0 1rem !important;
+ font-size: 16px;
+ color: #333;
+ letter-spacing: 0;
+ line-height: 29px;
+ font-weight: 400;
+ }
+ .red-circle {
+ align-self: flex-start;
+ color: #ca0002;
+ font-size: 1.5rem !important;
+ }
+ .content-descibe {
+ font-size: 14px;
+ color: #666;
+ line-height: 33px;
+ font-weight: 400;
+ }
+ .ant-modal-footer {
+ padding: 2rem 0;
+ text-align: center;
+ border: 0;
+ .ant-btn {
+ width: 6rem;
+ }
+ }
+ .foot-submit {
+ margin-left: 3rem;
+ color: #df0002;
+ &:hover {
+ border-color: #df0002;
+ }
+ }
+ .ant-btn-default:hover,
+ .ant-btn-default:active,
+ .ant-btn-default:focus {
+ background: #f3f4f6;
+ color: #333;
+ border-color: #d0d0d0;
+ }
+}
\ No newline at end of file
diff --git a/src/forge/Component/Monaco.jsx b/src/forge/Component/Monaco.jsx
new file mode 100644
index 00000000..aa70d803
--- /dev/null
+++ b/src/forge/Component/Monaco.jsx
@@ -0,0 +1,62 @@
+import React, {useEffect, useRef, useState} from 'react';
+import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
+import './Component.scss';
+
+function Monaco(props) {
+ const {
+ style = { // dom节点样式
+ height: '400px',
+ },
+ value = '', // 代码文本
+ onChange = () => { // 改变的事件
+ },
+ fontSize = 14, // 代码字体大小
+ monacoOptions = {
+ scrollBeyondLastLine: false,
+ lineNumbers: "off",
+ wordWrap: true,
+ overviewRulerBorder: true,
+ lineHeight: 24,
+ readOnly:true
+ }, // monaco 自定义属性
+ language = 'html', // 语言 支持 js ts sql css json html等
+ } = props;
+ const editOrRef = useRef();
+ const ThisEditor = useRef();
+ useEffect(() => {
+ ThisEditor.current = monaco.editor.create(editOrRef.current, {
+ value: value || '',
+ language,
+ theme: "vs-grey",
+ fontSize: fontSize + 'px',
+ minimap: { // 关闭代码缩略图
+ enabled: false,
+ },
+ ...monacoOptions,
+ });
+
+ ThisEditor.current.onDidChangeModelContent((e) => {
+ let newValue = ThisEditor.current.getValue();
+ onChange(newValue);
+ });
+ return () => {
+ ThisEditor.current.dispose();
+ ThisEditor.current = undefined; // 清除编辑器对象
+ }
+ }, []);
+ useEffect(() => {
+ if (ThisEditor.current) {
+ ThisEditor.current.updateOptions({
+ fontSize: fontSize + 'px',
+ })
+ }
+ }, [fontSize]);
+
+ return (
+
+
+
+ );
+}
+
+export default Monaco;
\ No newline at end of file
diff --git a/src/forge/Component/NoticeModal/Index.scss b/src/forge/Component/NoticeModal/Index.scss
new file mode 100644
index 00000000..ab83ea14
--- /dev/null
+++ b/src/forge/Component/NoticeModal/Index.scss
@@ -0,0 +1,90 @@
+.systemBox{
+ .ant-modal-body{
+ padding:1px 0px 0px 0px;
+ .sysBox{
+ background-image: url('./bg.png');
+ background-repeat: no-repeat;
+ background-size: 100% 334px;
+ margin-top: -55px;
+ }
+ .sysnoticeBox{
+ width: 100%;
+ padding:80px 0px 34px;
+ display: flex;
+ flex-direction: column;
+ width: 780px;
+ margin: 0px auto;
+ p.ntitle{
+ height: 33px;
+ font-size: 24px;
+ font-weight: 500;
+ color: #31FFF7;
+ line-height: 33px;
+ text-align: center;
+ }
+ p.nSubtitle{
+ height: 25px;
+ line-height: 25px;
+ font-size: 18px;
+ font-weight: 500;
+ color: #FFFFFF;
+ margin-top: 60px;
+ }
+ .markdown-body{
+ box-shadow: 0px 0px 17px rgba(0,0,0,0.2);
+ border-radius: 4px;
+ margin-top: 17px!important;
+ color: white;
+ }
+ .nContent{
+ padding:20px 34px;
+ background-color: #fff;
+ line-height: 30px;
+ font-size: 15px;
+ font-weight: 400;
+ color: #333;
+ .realmName{
+ margin-top: 20px;
+ display: flex;
+ ul{
+ width: 50%;
+ padding-left: 0px!important;
+ li{
+ font-size: 15px;
+ font-weight: 500;
+ line-height: 32px;
+ text-align: left;
+ color: #000;
+ list-style-type: none!important;
+ &:first-child{
+ color: #E65714;
+ }
+ }
+ }
+ }
+ .nSubdesc{
+ font-size: 15px;
+ font-weight: 400;
+ color: #000000;
+ line-height: 31px;
+ margin-top: 20px;
+ }
+ .nInfo{
+ font-size: 14px;
+ font-weight: 400;
+ color: #333333;
+ text-align: right;
+ margin-top: 25px;
+ p{
+ height: 20px;
+ line-height: 20px;
+ }
+ }
+ }
+ .nBtn{
+ text-align: center;
+ margin-top: 33px;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/forge/Component/NoticeModal/SystemNotice.jsx b/src/forge/Component/NoticeModal/SystemNotice.jsx
new file mode 100644
index 00000000..c95a8030
--- /dev/null
+++ b/src/forge/Component/NoticeModal/SystemNotice.jsx
@@ -0,0 +1,92 @@
+import React , { useEffect , useState } from 'react';
+import { Modal , Button } from 'antd';
+import './Index.scss';
+import '../../css/index.scss';
+import RenderHtml from '../../../components/render-html';
+// import cookie from 'react-cookies';
+import axios from 'axios';
+
+function SystemNotice({showNotice,system_notification,history,login,hideSystemNotice}){
+ const [ visible , setVisible ] = useState(false);
+
+ useEffect(()=>{
+
+ if(system_notification && !system_notification.is_read && showNotice && login){
+ setVisible(true);
+ }
+ },[system_notification,login])
+
+ function sureContinue() {
+ if(login && ( system_notification && system_notification.id )){
+ const url = `/users/${login}/system_notification_histories.json`;
+ axios.post(url,{
+ system_notification_id:system_notification.id
+ }).then(result=>{
+ if(result){
+ setVisible(false);
+ hideSystemNotice();
+ }
+ }).catch(error=>{})
+ }else{
+ setVisible(false);
+ hideSystemNotice();
+ }
+ // cookie.remove('notice_stage');
+
+ // let inFifteenMinutes = new Date(new Date().getTime() + 24 * 3600 * 1000);//一天
+ // // let inFifteenMinutes = new Date(new Date().getTime() + 60 * 1000);//一分钟
+ // cookie.save('notice_stage', true,{ expires: inFifteenMinutes,path:"/" });
+
+ // setVisible(false);
+ }
+
+ return (
+
+
+
+
{system_notification && system_notification.subject}
+
{system_notification && system_notification.sub_subject}
+ {/*
+
+ 为了给用户提供更加稳定、优质的服务,我们即将对平台门户首页、平台名称、平台域名进行一次全面升级与变更。原平台名称:Trustie(中文名:确实)将于2021年10月xx日统一更改为Gitlink(中文名:确实开源)。届时平台域名将统一进行更换,更换规则如下
+
+
+
+ - 原域名:
+ - 官网顶级域名https://www.trustie.net
+ - 版本库子域名https://forgeplus.trustie.net
+ - 论坛子域名https://forum.trustie.net/forums
+
+
+ - 更换后域名:
+ - 官网顶级域名https://www.gitlink.org.cn
+ - 版本库子域名https://www.git.gitlink.org.cn
+ - 论坛子域名https://forum.gitlink.org.cn
+
+
+
+ 自2021年10月xx日起,旧域名将停止访问。因平台名称与域名变更给您带来的不便,我们深表歉意!非常感谢您一直以来对本平台的信任与支持,我们将一如既往地为您提供优质的服务。 特此通知!
+
+
+
Gitlink运营团队
+
2021年10月xx日
+
+
*/}
+
+
+
+
+
+
+
+ )
+}
+export default SystemNotice;
\ No newline at end of file
diff --git a/src/forge/Component/NoticeModal/bg.png b/src/forge/Component/NoticeModal/bg.png
new file mode 100644
index 00000000..625b3c31
Binary files /dev/null and b/src/forge/Component/NoticeModal/bg.png differ
diff --git a/src/forge/Component/ProfileModal/Index.jsx b/src/forge/Component/ProfileModal/Index.jsx
new file mode 100644
index 00000000..7cead761
--- /dev/null
+++ b/src/forge/Component/ProfileModal/Index.jsx
@@ -0,0 +1,72 @@
+import React , { useEffect , useState } from 'react';
+import Modals from '../PublicModal/Index';
+import { Button } from 'antd';
+import axios from 'axios';
+
+import ProfileImg from './images/profile.png';
+import './Index.scss';
+
+function ProfileModal({visible,onCancel,history}) {
+ const [ modalVis , setModalVis ] = useState(visible);
+ const [ addMemberCheck , setAddMemberCheck ] = useState(false);
+
+ useEffect(()=>{
+ axios.interceptors.response.use((response) => {
+ if (response && (response.data.status === 411 || response.data.status === 412)) {
+ setModalVis(true);
+ if(response.data.status === 412){
+ setAddMemberCheck(true);
+ }
+ }
+ return response;
+ }, (error) => {
+ });
+ },[])
+
+ useEffect(()=>{
+ setModalVis(visible);
+ },[visible])
+
+ function onOk(){
+ onCancel();
+ setModalVis(false);
+ setTimeout(function(){
+ window.open(`/settings/profile`,"_blank");
+ },200)
+ }
+
+ function onNo() {
+ onCancel();
+ setModalVis(false);
+ }
+
+ return(
+
+
+
+ :
+
+
+
+
+ }
+ >
+
+

+ {
+ addMemberCheck ?
+
目标用户个人资料不完整,需提醒目标用户补充资料后以进行后续操作
+ :
+
您目前的个人资料不完整,需要补充资料以进行后续操作。是否前往补充个人信息?
+ }
+
+
+ )
+}
+export default ProfileModal;
\ No newline at end of file
diff --git a/src/forge/Component/ProfileModal/Index.scss b/src/forge/Component/ProfileModal/Index.scss
new file mode 100644
index 00000000..cf13121e
--- /dev/null
+++ b/src/forge/Component/ProfileModal/Index.scss
@@ -0,0 +1,18 @@
+.contents{
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin:10px auto 0px;
+ img{
+ margin-right: 13px;
+ width: 44px;
+ }
+ p{
+ line-height: 29px;
+ max-width: 327px;
+ font-size: 16px!important;
+ }
+}
+.font-44{
+ font-size: 44px!important;
+}
\ No newline at end of file
diff --git a/src/forge/Component/ProfileModal/Profile.jsx b/src/forge/Component/ProfileModal/Profile.jsx
new file mode 100644
index 00000000..e63c1286
--- /dev/null
+++ b/src/forge/Component/ProfileModal/Profile.jsx
@@ -0,0 +1,17 @@
+import React from 'react';
+
+function Profile({children,sureFunc,showCompeleteDialog , completeProfile, className}) {
+
+ function checkProfile() {
+ if(!completeProfile){
+ showCompeleteDialog && showCompeleteDialog();
+ }else{
+ sureFunc();
+ }
+ }
+
+ return(
+
{children}
+ )
+}
+export default Profile;
\ No newline at end of file
diff --git a/src/forge/Component/ProfileModal/images/profile.png b/src/forge/Component/ProfileModal/images/profile.png
new file mode 100644
index 00000000..6dbed21f
Binary files /dev/null and b/src/forge/Component/ProfileModal/images/profile.png differ
diff --git a/src/forge/Component/PublicModal/Index.jsx b/src/forge/Component/PublicModal/Index.jsx
new file mode 100644
index 00000000..c12e12b1
--- /dev/null
+++ b/src/forge/Component/PublicModal/Index.jsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import { Modal } from 'antd';
+import './Index.scss';
+
+function Modals({title,children,btn,onCancel,visible}) {
+ return(
+
+ {children}
+
+ )
+}
+export default Modals;
\ No newline at end of file
diff --git a/src/forge/Component/PublicModal/Index.scss b/src/forge/Component/PublicModal/Index.scss
new file mode 100644
index 00000000..1a0fbf31
--- /dev/null
+++ b/src/forge/Component/PublicModal/Index.scss
@@ -0,0 +1,75 @@
+.deleteBox{
+ z-index: 1033;
+ .ant-modal-close-x{
+ font-size: 17px!important;
+ }
+ .ant-modal-header{
+ background-color: #f8f8f8;
+ padding:10px 30px;
+ .ant-modal-title{
+ text-align: left;
+ font-size: 16px;
+ font-weight: bold;
+ }
+ }
+ .ant-modal-close{
+ top:0px !important;
+ font-size: 24px !important;
+ }
+ .ant-modal-body{
+ padding:30px 50px;
+ p{
+ font-size: 14px;
+ line-height: 26px;
+ color:#666;
+ word-break: break-all;
+ }
+ .desc{
+ .descMain{
+ align-items: center;
+ justify-content: center;
+ font-size: 20px;
+ margin-bottom: 10px;
+ i.red{
+ color:#DF0002;
+ }
+ }
+ }
+ }
+ .ant-modal-footer{
+ border-top: none;
+ text-align: center;
+ padding-bottom: 40px;
+ button,a{
+ width: 96px;
+ height: 32px;
+ margin:0px 20px;
+ font-weight: 400;
+ font-size: 14px;
+ &.ant-btn{
+ border-color: #D0D0D0;
+ color: #666;
+ &:hover,&:active,&:focus{
+ background: #f3f4f6;
+ }
+ }
+ &.ant-btn-danger{
+ background-color: #fff;
+ color: #DF0002;
+ border-color: #D0D0D0;
+ &:hover,&:active,&:focus{
+ border-color: #DF0002;
+ background-color: #fff;
+ }
+ }
+ &.ant-btn.ant-btn-primary{
+ background-color: #466AFF;
+ color: #fff;
+ border-color: #466AFF;
+ &:hover,&:focus,&:active{
+ background-color: rgba(70,106,255,0.85);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/forge/Component/Releases.jsx b/src/forge/Component/Releases.jsx
index 501c6b63..260e6bd2 100644
--- a/src/forge/Component/Releases.jsx
+++ b/src/forge/Component/Releases.jsx
@@ -1,38 +1,35 @@
import React from 'react';
-import { AlignCenter , AlignTop , FlexAJ } from '../Component/layout';
+import { AlignTop } from '../Component/layout';
import { Link } from 'react-router-dom';
-function Releases({owner,projectsId,releaseVersions}){
-
+function Releases({ owner, projectsId, releaseVersions, distribution }) {
return(
-
- 发行版
- { releaseVersions && releaseVersions.total_count > 0 && {releaseVersions.total_count}}
-
- { releaseVersions && releaseVersions.total_count > 0 ?
- 全部
- :
- 新建
- }
-
+
+
发行版
+ { releaseVersions && releaseVersions.total_count > 0 &&
{releaseVersions.total_count}}
+
{
releaseVersions && releaseVersions.total_count>0 ?
releaseVersions.list.map((item,key)=>{
return(
key === 0 &&
-
-
- {item.name}
+
+ {/* 如果是点击最新则发行版列表页只展示最新的一个 */}
+ {item.name}
最新
-
{item.created_at}
+
{item.created_at}
)
})
- :""
+ :
+
+ 您暂未发布任何版本
+ {distribution && 创建新版本}
+
}
diff --git a/src/forge/Component/SiderBar.js b/src/forge/Component/SiderBar.js
new file mode 100644
index 00000000..a5c4836d
--- /dev/null
+++ b/src/forge/Component/SiderBar.js
@@ -0,0 +1,120 @@
+import React, { useEffect, useState } from 'react';
+import { Popover , Tooltip } from 'antd';
+import './Component.scss';
+import axios from 'axios';
+import ShareModal from './SiderBarShareModal';
+
+const $ = window.$;
+
+$(window).scroll(function () {
+ if ($(".gotop").length > 0) {
+ if ($(document).scrollTop() > 0) {
+ $(".-task-sidebar .gotop").show();
+ $(".gotop").click(function () {
+ $("html,body").scrollTop(0);
+ });
+ }
+ if ($(document).scrollTop() === 0) {
+ $(".-task-sidebar .gotop").hide();
+ }
+ }
+});
+
+function SiderBar() {
+ const [ data , setData ] = useState([]);
+ const [ visible , setVisible ] = useState(false);
+ const [ login , setLogin ]= useState(false);
+
+ useEffect(()=>{
+ getFAQ();
+ getCurrentUser();
+ //页面加载完成之后隐藏回到顶点
+ $(".-task-sidebar .gotop").hide();
+ },[])
+
+ function getFAQ(){
+ const url = `/faqs.json`;
+ axios.get(url).then(result=>{
+ if(result && result.data){
+ setData(result.data);
+ }
+ }).catch(error=>{})
+ }
+
+ //获取当前登录账号信息->用于建议反馈
+ function getCurrentUser(){
+ let url = `/users/get_user_info.json`;
+ axios.get(url).then((response) => {
+ if (response && response.data && response.data.login) {
+ setLogin(response.data.login);
+ }
+ }).catch(error=>{})
+ }
+
+ function content(list){
+ return
+
+ {
+ list && list.map((i,k)=>{
+ return(
+ - {i.question}
+ )
+ })
+ }
+
+
+ }
+
+ function shareContent(){
+ return
+
+ 分享到
+ - setVisible(true)}>
+
+
+ }
+
+ return (
+
+ {/* 平台反馈 */}
+
+
+
+
+ {/* 帮助 */}
+ {
+ data && data.length > 0 && (data[0] && data[0].question) ?
+
+
+
+
+
+ :""
+ }
+
+ {/* 分享 */}
+ {/*
+
+
*/}
+
setVisible(false)}/>
+
+
+
+
+
+
+ {/* 返回顶部 */}
+
+
+
+
+ )
+}
+
+export default SiderBar;
diff --git a/src/forge/Component/SiderBarShareModal.jsx b/src/forge/Component/SiderBarShareModal.jsx
new file mode 100644
index 00000000..cf911503
--- /dev/null
+++ b/src/forge/Component/SiderBarShareModal.jsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import { Modal } from 'antd';
+import QRCode from 'qrcode.react';
+
+function SiderBarShareModal({visible,urlValue,onCancel}) {
+ return(
+
+
+ {urlValue &&
}
+
打开微信“扫一扫”,点击右上角菜单,即可将网页分享至朋友圈
+
+
+ )
+}
+export default SiderBarShareModal;
\ No newline at end of file
diff --git a/src/forge/Component/Sort.jsx b/src/forge/Component/Sort.jsx
index 58f8a5d2..a15f04da 100644
--- a/src/forge/Component/Sort.jsx
+++ b/src/forge/Component/Sort.jsx
@@ -2,9 +2,9 @@ import React from 'react';
import {Popover} from 'antd';
import './Component.scss';
-export default (({menu , children})=>{
+export default (({menu , children, overlayClassName})=>{
return(
-
+
{children}
)
diff --git a/src/forge/Component/Title.jsx b/src/forge/Component/Title.jsx
index 9b3f8bf3..8ab6d7e4 100644
--- a/src/forge/Component/Title.jsx
+++ b/src/forge/Component/Title.jsx
@@ -5,7 +5,7 @@ const Nav = styled.div`{
background-color:#fff;
padding:20px 30px;
border-bottom:1px solid #eee;
- font-size:16px;
+ font-size:18px;
color:#333;
display:flex;
justify-content: space-between;
diff --git a/src/forge/Component/User.jsx b/src/forge/Component/User.jsx
index 4d22c77b..0d970173 100644
--- a/src/forge/Component/User.jsx
+++ b/src/forge/Component/User.jsx
@@ -5,6 +5,7 @@ import { Link } from 'react-router-dom';
export default ({ url , name , column , id , login })=>{
const Img = styled.span`
display:flex;
+ font-weight: bold;
${column && "flex-direction: column;text-align:center;"}
align-items: center;
& img{
@@ -20,7 +21,7 @@ export default ({ url , name , column , id , login })=>{
`;
return(
id?
-
+
{ url &&
}
{name}
diff --git a/src/forge/Component/layout.jsx b/src/forge/Component/layout.jsx
index 57b20c1e..dcc133e8 100644
--- a/src/forge/Component/layout.jsx
+++ b/src/forge/Component/layout.jsx
@@ -7,6 +7,8 @@ export const Banner = styled.div`{
border-bottom:1px solid #eee;
background-color:#fff;
border-radius:5px 5px 0px 0px;
+ justify-content: space-between;
+ display: flex;
}`
export const AlignCenterBetween = styled.div`{
display:flex;
@@ -28,6 +30,11 @@ export const AlignTop = styled.div`{
display:flex;
align-items: flex-start;
}`
+export const AlignAJBottom = styled.div`{
+ display:flex;
+ justify-content: space-between;
+ align-items: flex-end;
+}`
// 左右结构
export const Box = styled.div`{
display:flex;
diff --git a/src/forge/DevOps/About.jsx b/src/forge/DevOps/About.jsx
index b9524d54..4831f73b 100644
--- a/src/forge/DevOps/About.jsx
+++ b/src/forge/DevOps/About.jsx
@@ -36,15 +36,15 @@ function About(props, ref) {
const [ disabled, setDisabled ] = useState(false);
const [ typeFlag, setTypeFlag] = useState(false);
- const AuthorLogin = props.projectDetail && props.projectDetail.author && props.projectDetail.author.login;
+ const isPermission = props.projectDetail && props.projectDetail.permission && props.projectDetail.permission!=="Reporter";
const CurrentLogin = props.current_user && props.current_user.login;
useEffect(()=>{
- if(CurrentLogin === AuthorLogin){
+ if(isPermission){
auth('get');
}else{
setIsSpining(false);
}
- },[AuthorLogin,CurrentLogin])
+ },[isPermission,CurrentLogin])
function auth(type){
const url = `/${owner}/${projectsId}/ci_authorize.json`;
@@ -149,7 +149,7 @@ function About(props, ref) {
axios.post(url).then(result=>{
setIsSpining(false);
if(result && result.data.status === 0){
- props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
+ props.history.push(`/${owner}/${projectsId}/devops`);
// 需要将顶部的open_devops修改
let { changeOpenDevops } = props;
changeOpenDevops && changeOpenDevops(true);
@@ -167,17 +167,17 @@ function About(props, ref) {
定义DevOps工作流,帮助您检测bug、发布代码…
{
- CurrentLogin !== AuthorLogin ?
+ !isPermission ?
DevOps开启功能暂未对项目创建者以外的角色开放,可以联系项目创建者进行开启,开启后便可查看构建信息。
:""
}
了解什么是DevOps?
- 如何使用DevOps?
+ 如何使用引擎(Engine)功能?
{
- AuthorLogin === CurrentLogin ?
+ isPermission ?
{
step === 0 && !typeFlag ?
diff --git a/src/forge/DevOps/Dispose.jsx b/src/forge/DevOps/Dispose.jsx
index 2211dbb5..1e08cdab 100644
--- a/src/forge/DevOps/Dispose.jsx
+++ b/src/forge/DevOps/Dispose.jsx
@@ -96,7 +96,7 @@ function Dispose(props){
setVisible(false);
if(result && result.data){
props.showNotification("流水线新增成功,请进行工作流配置!");
- props.history.push(`/projects/${owner}/${projectsId}/devops/dispose/${result.data.id}`);
+ props.history.push(`/${owner}/${projectsId}/devops/${result.data.id}`);
}else{
props.showNotification("流水线新增失败,请稍后再试!");
}
@@ -134,12 +134,12 @@ function Dispose(props){
// 模板管理
function toModalManage(){
- props.history.push(`/projects/${owner}/${projectsId}/devops/mould`);
+ props.history.push(`/${owner}/${projectsId}/devops/mould`);
}
// 参数管理
function toparameter(){
- props.history.push(`/projects/${owner}/${projectsId}/devops/params`);
+ props.history.push(`/${owner}/${projectsId}/devops/params`);
}
const operate = current_user && (permission && permission !== "Reporter");
diff --git a/src/forge/DevOps/Dispose/List.jsx b/src/forge/DevOps/Dispose/List.jsx
index 72a26785..80a53372 100644
--- a/src/forge/DevOps/Dispose/List.jsx
+++ b/src/forge/DevOps/Dispose/List.jsx
@@ -1,6 +1,7 @@
import React from 'react';
import { Table , Popconfirm } from 'antd';
import { Link } from 'react-router-dom';
+import { turnbar } from "educoder";
// const STATUS = {
// running:"运行中",
@@ -65,8 +66,9 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
width:"15%",
ellipsis:true,
render:(value,item)=>{
+ let v = turnbar(item.branch);
return(
- {value}
+ {value}
)
}
},
@@ -110,7 +112,7 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
return(
{ operate ?
-
+
编辑 :""
}
{ operate ?
@@ -118,7 +120,7 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
删除
:""
}
- 查看运行记录
+ 查看运行记录
)
}
diff --git a/src/forge/DevOps/Dispose/PipelineName.jsx b/src/forge/DevOps/Dispose/PipelineName.jsx
index 3cf7f96a..63ee5437 100644
--- a/src/forge/DevOps/Dispose/PipelineName.jsx
+++ b/src/forge/DevOps/Dispose/PipelineName.jsx
@@ -42,7 +42,7 @@ function PipelineName({visible,onCancel,onOk,value ,branchList}){