Compare commits

...

21 Commits

Author SHA1 Message Date
jasder 8b4d4dc893 Merge pull request 'sonar质量分析列表增加获取推荐按钮' (#274) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-11-19 17:22:41 +08:00
caishi 260239b5d2 sonar质量分析列表增加获取推荐按钮 2021-11-19 17:06:07 +08:00
jasder a58188c662 Merge pull request 'sona列表换行显示' (#269) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-11-19 10:57:52 +08:00
caishi e33443ba72 sonar-内容换行显示 2021-11-19 10:31:08 +08:00
jasder ec5e27e479 Merge pull request 'webhook新建页面增加两个提示弹框' (#268) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-11-18 11:33:14 +08:00
caishi 09b6fbed6b 弹框 2021-11-18 11:32:01 +08:00
jasder a8d387869d Merge pull request '代码库质量分析tab' (#265) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-11-18 09:08:20 +08:00
caishi e543987baa 增加代码质量分析页面 2021-11-17 16:46:59 +08:00
jasder 445ba03195 Merge pull request 'merge代码,且增加sonar质量分析块' (#221) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-10-22 17:15:50 +08:00
caishi ef3ee596f2 木兰-增加sonar质量分析的url显示 2021-10-22 17:11:46 +08:00
caishi 9d58b363df Merge branch 'mulanoss_git_server' of https://git.trustie.net/Gitlink/forgeplus-react into mulanoss_git_server 2021-10-22 16:56:06 +08:00
caishi ca3c935c56 footer 2021-10-22 16:55:46 +08:00
jasder f2085dc596 Merge pull request 'FIX 合并主干分支功能' (#218) from master into mulanoss_git_server 2021-10-22 16:55:36 +08:00
jasder 1871eb7a5a FIX 合并pre_develop分支代码并处理代码冲突 2021-10-18 16:33:39 +08:00
jasder 13376d82bd Merge pull request '木兰社区,merge forge代码,底部信息全由后台配置' (#154) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-10-13 11:41:45 +08:00
caishi 35de29c677 底部信息 2021-10-13 11:37:14 +08:00
caishi d768761afb Merge branch 'pre_develop_dev' into mulanoss_git_server 2021-10-13 09:59:33 +08:00
jasder 6ce9777095 Merge pull request '登录弹框-注册按钮根据接口返回字段隐藏、显示' (#95) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-09-30 11:43:09 +08:00
caishi 73e9de5cef 登录弹框-注册按钮根据接口返回字段隐藏、显示 2021-09-30 11:26:27 +08:00
jasder 4d02dff386 Merge pull request '木兰社区第三方登录logo' (#90) from caishi/forgeplus-react:mulanoss_git_server into mulanoss_git_server 2021-09-29 16:18:16 +08:00
caishi efda2132ae 木兰社区-和forge统一,不包含通知系统、资源库等、第三方登录改为木兰 2021-09-29 15:38:07 +08:00
17 changed files with 352 additions and 82 deletions

View File

@ -1,4 +1,4 @@
import React, { useState, useCallback, memo } from 'react';
import React, { useState, useCallback, memo, useEffect } from 'react';
import { Tooltip } from 'antd';
CopyTool.defaultProps = {
@ -10,16 +10,15 @@ CopyTool.defaultProps = {
};
function CopyTool({ beforeText, afterText, className , inputId , timeOut }) {
function CopyTool({ beforeText, afterText, className , inputId , timeOut , text }) {
const [title, setTitle] = useState(() => {
return beforeText;
});
//
const copyUrl = useCallback(() => {
const copyEle = document.querySelector(`#${inputId}`); //
if (!copyEle) {
console.error("您的CopyTool未设置正确的inputId");
console.error(`您的CopyTool未设置正确的inputId${inputId}`);
return;
}
copyEle.select(); //
@ -37,12 +36,17 @@ function CopyTool({ beforeText, afterText, className , inputId , timeOut }) {
}, []);
return (
<Tooltip
placement="top"
title={title}
onVisibleChange={() => { setTitle(beforeText) }}
>
<i className={`iconfont icon-fuzhiicon ${className}`} style={{ color: '#466aff' }} onClick={copyUrl}></i>
{text?
<a className="color-blue" onClick={copyUrl}>{text}</a>
:
<i className={`iconfont icon-fuzhiicon ${className}`} style={{ color: '#466aff' }} onClick={copyUrl}></i>
}
</Tooltip>
);
}

View File

@ -16,49 +16,11 @@ function Footer(){
var html = {__html:htmlString};
return <div dangerouslySetInnerHTML={html}></div> ;
}
return(
<div>
<div style={{height:"543px"}}></div>
<div className="newFooter edu-txt-center">
{value && showhtml(value)}
{/* <div className="footerInfos">
<ul>
<li>社区</li>
<li><a href={`/`} target="_blank">网站首页</a></li>
<li><a href={`https://www.trustie.net/agreement`} target="_blank">服务协议</a></li>
<li><a href={`https://forum.trustie.net/forums/1168/detail`} target="_blank">帮助中心</a></li>
<li><a href={`https://forum.trustie.net/`} target="_blank">问吧交流</a></li>
<li><a href={`https://www.trustie.net/cooperation`} target="_blank">合作伙伴</a></li>
</ul>
<ul>
<li>支持与服务</li>
<li><a href={`https://forgeplus.trustie.net/docs/api`} target="_blank">API文档</a></li>
<li><a href={`https://forum.trustie.net/forums/1168/detail`} target="_blank">帮助中心</a></li>
<li><a href={`https://git-scm.com`} target="_blank">Git常用命令</a></li>
<li><a href={`https://forum.trustie.net/forums/3080/detail`} target="_blank">DevOps使用文档</a></li>
<li><a href={`https://forgeplus.trustie.net/projects/jasder/forgeplus/tree/master/CHANGELOG.md`} target="_blank">日志更新</a></li>
</ul>
<ul>
<li>合作伙伴</li>
<li><a href={`http://www.sei.pku.edu.cn`} target="_blank">北京大学</a></li>
<li><a href={`http://scse.buaa.edu.cn`} target="_blank">北京航空航天大学</a></li>
<li><a href={`https://www.nju.edu.cn`} target="_blank">南京大学</a></li>
<li><a href={`https://www.xtu.edu.cn`} target="_blank">湘潭大学</a></li>
<li><a href={`http://www.iscas.ac.cn`} target="_blank">ISCAS</a></li>
<li><a href={`https://www.ucloud.cn`} target="_blank">UCloud优刻得</a></li>
<li><a href={`http://www.inforbus.com`} target="_blank">中创软件</a></li>
<li><a href={`https://www.inspur.com`} target="_blank">浪潮集团</a></li>
<li><a href={`http://www.copu.org.cn`} target="_blank">中国开源软件推进联盟</a></li>
<li><a href={`https://www.sjtu.edu.cn`} target="_blank">上海交通大学</a></li>
</ul>
<ul>
<li>合作伙伴</li>
<li><span>热线</span></li>
<li><span>QQ群1071514693</span></li>
</ul>
</div>
<p className="footerCopy">© Copyright 2007~2021 国防科技大学Trustie团队 & IntelliDE <a href="https://beian.miit.gov.cn">湘ICP备 17009477</a></p> */}
</div>
</div>
)

View File

@ -63,6 +63,7 @@ function CoderDepot(props){
const [ desc , setDesc ] = useState(undefined);
const [ website , setWebsite ] = useState(undefined);
const [ lesson_url , setLessonUrl ] = useState(undefined);
const [ sonar_url , setSonarUrl ] = useState(undefined);
const [ readme , setReadme ] = useState(undefined);
const [ defaultBranch , setDefaultBranch ] = useState(undefined);
const [ editReadme , setEditReadme ] = useState(false);
@ -100,6 +101,7 @@ function CoderDepot(props){
setDesc(details.description);
setWebsite(details.website);
setLessonUrl(details.lesson_url);
setSonarUrl(details.sonar_url);
setDefaultBranch(details.default_branch);
setInviteCode(details.invite_code);
}
@ -138,7 +140,7 @@ function CoderDepot(props){
if(result && result.data){
const release = {
"list":result.data.releases,
"total_count":result.data.releases.length
"total_count":result.data.releases ? result.data.releases.length :0
}
setReleaseVersions(release);
}
@ -334,6 +336,7 @@ function CoderDepot(props){
setDesc(result.data.description);
setWebsite(result.data.website);
setLessonUrl(result.data.lesson_url);
setSonarUrl(result.data.sonar_url);
}
})
}
@ -558,6 +561,26 @@ function CoderDepot(props){
<a href={lesson_url} target="_blank" className="color-grey-6" style={{textDecoration:"underline",wordBreak:"break-all"}}>{lesson_url}</a>
</div>
}
{/* {
<div>
<Divider />
<p className="font-16 color-ooo">质量分析</p>
{
sonar_url ?
<a href={sonar_url} target="_blank" className="color-grey-6" style={{textDecoration:"underline",wordBreak:"break-all"}}>{sonar_url}</a>
:
<span>
<span>暂时还没有检测结果</span>
{
projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter" ?
<Link to={`/${owner}/${projectsId}/settings/webhooks/new`} className="color-blue ml20">去检测</Link>
:""
}
</span>
}
</div>
} */}
{/* 发布 */}
{
releaseVersions &&

View File

@ -69,7 +69,11 @@ const MergeIndexDetail = Loadable({
loader: () => import('../Merge/merge'),
loading: Loading,
})
// 代码质量分析
const Sonar = Loadable({
loader: () => import('../Sonar/Index'),
loading: Loading,
})
const CreateMerge = Loadable({
loader: () => import('../Merge/CreateMerge'),
loading: Loading,
@ -167,6 +171,8 @@ function checkPathname(projectsId, owner, pathname) {
name = "source"
} else if (url.indexOf(`/wiki`) > -1) {
name = "wiki"
} else if (url.indexOf(`/sonar`) > -1) {
name = "sonar"
}
}
return name;
@ -772,6 +778,11 @@ class Detail extends Component {
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/sonar"
render={
(props) => (<Sonar {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/following"
render={
(props) => (<WatchUsers {...this.props} {...props} {...this.state} {...common} />)

View File

@ -228,7 +228,7 @@
li{
text-align: center;
padding:0px;
margin-right: 40px;
margin-right: 35px;
display: flex;
& > a{
position: relative;

View File

@ -128,6 +128,12 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
)
})
}
<li className={pathname==="sonar" ? "active" : ""}>
<Link to={{ pathname: `/${owner}/${projectsId}/sonar`, state }}>
<i className={"iconfont icon-banbenicon color-grey-3 mr5 font-14"}></i>
<span>代码质量分析</span>
</Link>
</li>
</ul>
:
<Skeleton paragraph={false} active={true}/>

View File

@ -11,6 +11,8 @@ function turnbar(str){
}
return str;
}
const port = window.location.port;
const hostname = window.location.hostname;
class MergeItem extends Component {
constructor(props) {
super(props);
@ -166,24 +168,17 @@ class MergeItem extends Component {
)}
</li>
<li>{item.version || "--"}</li>
<li>
<div
className="flex1 df"
style={{ justifyContent: "center" }}
>
{item.journals_count ? (
<div className="flex1 df" style={{ justifyContent: "center" }}>
{item.journals_count ?
<Link
className="mr5 color-grey-8"
to={`/${owner}/${projectsId}/pulls/${item.pull_request_id}`}
>
<i className="iconfont icon-huifu1 font-15 mr5 ver-middle"></i>
{item.journals_count}
</Link>
) : (
""
)}
{user_admin_or_developer && item.pull_request_status === 0 ? (
<i className="iconfont icon-huifu1 font-15 mr5 ver-middle"></i>{item.journals_count}
</Link>:""
}
{user_admin_or_developer && item.pull_request_status === 0 &&
<div
className="milepostleft"
style={{
@ -194,7 +189,7 @@ class MergeItem extends Component {
: "none",
}}
>
<div className="grid-item mr15 color-grey-9">
<div className="grid-item color-grey-9">
<Link
to={`/${owner}/${projectsId}/pulls/${item.pull_request_id}/edit`}
className="color-grey-9"
@ -203,11 +198,10 @@ class MergeItem extends Component {
</Link>
</div>
</div>
) : (
""
)}
}
</div>
</li>
<li style={{width:"50px",textAlign:"left"}}><a className="color-blue" target="_blank" href={`http://106.75.189.31:5000/result?SrcPR=${port ? `${hostname}:${port}`:`https://${hostname}`}/${owner}/${projectsId}/pulls/${item.pull_request_id}/Messagecount`}>查重</a></li>
</ul>
</div>
);

View File

@ -382,6 +382,7 @@ class merge extends Component {
</span>
</Dropdown>
</li>
<li style={{width:"50px"}}></li>
</ul>
</div>
<div style={{minHeight:"470px"}}>

View File

@ -45,19 +45,6 @@
}
}
button {
color: #333333;
background: #FAFBFC;
border: 1px solid #D0D0D0;
border-radius: 4px;
height: 32px;
}
button:hover {
background: #F3F4F6;
}
button:active {
background: #EBECF0;
}
.deleteBut{
color: #DF0002;

View File

@ -88,8 +88,7 @@
background: #FAFCFF;
border-radius: 4px 4px 0px 0px;
border: 1px solid rgba(42, 97, 255, 0.23);
height: 50px;
padding:0px 20px;
padding:5px 20px;
margin-top: 20px;
display: flex;
align-items: center;
@ -168,4 +167,19 @@
}
}
}
}
.checkModalStyle{
.ant-modal-header{
padding:8px 20px;
.ant-modal-title{
text-align: left;
}
}
.ant-modal-close{
top:0px!important;
}
input{
width: 222px;
border:none;
}
}

View File

@ -6,6 +6,7 @@ import axios from 'axios';
import PushHistory from './sub/PushHistory';
import DeleteBox from '../../Component/DeleteModal/Index';
import './Index.scss';
import CheckModal from './sub/CheckModal';
// ,"issue_assign","issue_label","issue_milestone","issue_comment","issue_only","fork",
//"pull_request_milestone","pull_request_sync","pull_request_comment","repository","pull_request_label"
@ -21,6 +22,10 @@ function New({ form , match , showNotification , history }) {
const [ data , setData ] = useState(undefined);
const [ eventFlag , setEventFlag ] = useState(false);
const [ checkVisible , setCheckVisible ] = useState(false);
const [ checkContent , setCheckContent ] = useState(1);
const { getFieldDecorator, validateFields , setFieldsValue } = form;
const { id , owner , projectsId } = match.params;
@ -169,8 +174,18 @@ function New({ form , match , showNotification , history }) {
lineHeight: '30px',
};
function OpenCheckModal(params) {
setCheckContent(params);
setCheckVisible(true);
}
return(
<div className="newPanel">
<CheckModal
visible={checkVisible}
content={checkContent}
onCancel={()=>setCheckVisible(false)}
/>
<DeleteBox
visible={visible}
onCancel={()=>setVisible(false)}
@ -185,7 +200,12 @@ function New({ form , match , showNotification , history }) {
<span>{id ? "更新" : "添加"}Webhook</span>
</Banner>
<div>
<p className="deschead mg"><span>当webhook被触发时我们将向以下URL发送通知包括已选择事件的详细信息更多信息可查阅<a className="color-blue hoverLine" target="_blank" href="https://forum.trustie.net/forums/3408/detail">webhooks指南</a></span></p>
<p className="deschead mg">
<span>当webhook被触发时我们将向以下URL发送通知包括已选择事件的详细信息更多信息可查阅
<a className="color-blue hoverLine" target="_blank" href="https://forum.trustie.net/forums/3408/detail">webhooks指南</a>
<br/><a className="color-blue" onClick={()=>OpenCheckModal(1)}>开源敏感词检测服务设置</a><a className="color-blue" onClick={()=>OpenCheckModal(2)}>PR审阅推荐服务设置</a>
</span>
</p>
<Form>
<input type="password" style={{display:"none"}} />
<Form.Item label="目标URL" colon={false}>

View File

@ -0,0 +1,53 @@
import React, { useEffect, useState } from 'react';
import { Modal } from 'antd';
import CopyTool from '../../../Component/CopyTool';
function CheckModal({visible,content,onCancel}) {
const [ type ,setType ] = useState(content);
useEffect(()=>{
setType(content);
},[content])
return(
<Modal
visible={visible}
footer={null}
title="提示"
width="480px"
onCancel={onCancel}
closable={true}
className="checkModalStyle"
>
<div>
{
type===1?
<div>
<p style={{fontWeight:"500"}}>如需使用开源敏感词检测云功能请复制以下内容至指定的输入框中</p>
<p>目标URL<input type="text" id="copy_input_check" value={"https://api.learnerhub.net/mulan"} />
<CopyTool afterText="复制成功" inputId="copy_input_check" timeOut={true} text={"复制"}/>
</p>
<p>webhook密钥默认无须密钥</p>
<p>触发webhook选中自定义事件勾选 推送创建合并请求</p>
<p>分支过滤 默认无须修改</p>
</div>
:
<div>
<p style={{fontWeight:"500"}}>如需使用PR审阅推荐云功能请复制以下内容至指定的输入框中</p>
<p>目标URL
<input type="text" id="copy_input_check" style={{width:"160px"}} value={"http://117.50.99.180:80"} />
<CopyTool afterText="复制成功" inputId="copy_input_check" timeOut={true} text={"复制"}/>
</p>
<p>webhook密钥默认无须密钥</p>
<p>触发webhook选中自定义事件勾选 合并请求</p>
<p>分支过滤 默认无须修改</p>
</div>
}
</div>
</Modal>
)
}
export default CheckModal;

149
src/forge/Sonar/Index.jsx Normal file
View File

@ -0,0 +1,149 @@
import React , { useEffect , useState } from 'react';
import { Table , Pagination } from 'antd';
import { Base64 } from 'js-base64';
import moment from 'moment'
import axios from 'axios';
import Nodata from '../Nodata';
import './Index.scss';
import RecommedModal from './sub/RecommedModal';
const limit = 15;
function Index(props) {
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
const [ data , setData ] = useState(undefined);
const [ visible , setVisible ] = useState(false);
const [ content ,setContent ] = useState(undefined);
const { owner , projectsId } = props.match.params;
useEffect(()=>{
getInit();
},[page])
function getInit() {
// MLh8klm46f_ceshi ${owner}_${projectsId}
const url = `https://sonar.learnerhub.net/api/issues/search?componentKeys=${owner}_${projectsId}&s=FILE_LINE&resolved=false&types=BUG&ps=${limit}&facets=owaspTop10%2CsansTop25%2Cseverities%2CsonarsourceSecurity%2Ctypes&additionalFields=_all&timeZone=Asia%2FShanghai&p=${page}`
axios.get(url,{
headers:{Authorization:`Basic ${Base64.encode('ecae161ce05add6121c6263f843c76d79fcd953c:')}`}
}).then(result=>{
if(result){
setData(result.data.issues);
setTotal(result.data.total);
}
}).catch(error=>{})
}
const columns = [
{
title: '文件',
dataIndex: 'component',
key: 'component',
width:"15%",
render:(v,l,i)=>{
const name = l.component && l.component.split(":")[1];
return(
<span>{name}</span>
)
}
},
{
title: '所在起始行',
dataIndex: 'startLine',
key: 'startLine',
align:"center",
width:"9%",
render:(v,l,i)=>{
return(
<span>{l.textRange && l.textRange.startLine}</span>
)
}
},
{
title: '所在结束行',
dataIndex: 'endLine',
key: 'endLine',
align:"center",
width:"9%",
render:(v,l,i)=>{
return(
<span>{l.textRange && l.textRange.endLine}</span>
)
}
},
// {
// title: '',
// dataIndex: 'type',
// align:"center",
// key: 'type',
// width:"8%",
// },
{
title: '问题信息',
dataIndex: 'message',
key: 'message',
width:"40%"
},
{
title: '创建时间',
dataIndex: 'creationDate',
key: 'creationDate',
align:"center",
render:(v,l,i)=>{
return(
<span>{l.creationDate && moment(l.creationDate).format('YYYY-MM-DD HH:mm:ss')}</span>
)
}
},
{
title: '问题修复推荐',
dataIndex: 'recommend',
key: 'recommend',
align:"center",
render:(v,l,i)=>{
return(
<a className="color-blue" onClick={()=>receiveRecommend(l)}>获取推荐</a>
)
}
},
];
function receiveRecommend(l){
// http://ng.learnerhub.net/mulan/repair
// 线 https://api.learnerhub.net/mulan/repair
const url = `https://api.learnerhub.net/mulan/repair`;
axios.get(url,{
params:{
data:l
}
}).then(result=>{
if(result){
setContent(result.data.data && result.data.data.content);
setVisible(true);
}
}).catch(error=>{})
}
return(
<div className="main" style={{padding:"0px"}}>
<RecommedModal visible={visible} content={content} onCancel={()=>setVisible(false)}/>
{
total > 0 ?
<div style={{minHeight:"300px"}}>
<p style={{padding:"12px 20px"}}>一共存在{total}个问题</p>
<Table className="sonarTable" dataSource={data} columns={columns} pagination={false}/>
</div>
:
<Nodata _html="代码质量非常优秀,没有检测到问题存在!" />
}
{
total > limit &&
<div style={{padding:"15px",textAlign:"center"}}>
<Pagination pageSize={limit} current={page} total={total} onChange={(p)=>setPage(p)}/>
</div>
}
</div>
)
}
export default Index

View File

@ -0,0 +1,16 @@
.sonarTable{
.ant-table-thead > tr > th, .ant-table-tbody > tr > td{
padding:10px 12px;
}
}
.recommendbox{
.ant-modal-body{
padding:0px;
padding-bottom: 20px;
div{
height: 620px;
overflow-y: auto;
padding:20px
}
}
}

View File

@ -0,0 +1,23 @@
import { Modal } from 'antd';
import React from 'react';
import '../Index.scss';
function RecommedModal({content,visible,onCancel}){
return(
<Modal
visible={visible}
footer={null}
width="1000px"
closable={true}
onCancel={onCancel}
title="推荐内容"
centered={true}
className="recommendbox"
>
<div>
<pre style={{whiteSpace: "pre-line"}}>{content}</pre>
</div>
</Modal>
)
}
export default RecommedModal;

View File

@ -5,6 +5,7 @@ import { notification } from 'antd';
import axios from 'axios';
import educoderLogo from './educoder.png';
import mulanLogo from './img/mulan.png';
import './LoginDialog.css';
import { broadcastChannelPostMessage } from 'educoder'
@ -561,8 +562,14 @@ class LoginDialog extends Component {
</span>
<span className="fr">
<a onClick={(url) => this.getloginurl(`${settings && settings.common && settings.common.lost_password}`)} className="mr3 color-grey-9">找回密码</a>
<em className="vertical-line"></em>
<a onClick={(url) => this.getloginurl(`${settings && settings.common && settings.common.register}`)} className="color-grey-9">注册</a>
{
settings && settings.common && settings.common.register ?
<React.Fragment>
<em className="vertical-line"></em>
<a onClick={(url) => this.getloginurl(`${settings && settings.common && settings.common.register}`)} className="color-grey-9">注册</a>
</React.Fragment>
:""
}
</span>
</p>
{
@ -573,7 +580,7 @@ class LoginDialog extends Component {
{settings.third_party.map((item,key)=>{
return(
<a href={`${item.url}`}>
<img src={item.name === "educoder" ? educoderLogo : ""} width="46px" alt={`${item.name}登录`} />
<img src={item.name === "mulan" ? mulanLogo : ""} width="46px" alt={`${item.name}登录`} />
</a>
)
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB