forked from Gitlink/forgeplus-react
Merge pull request '合并代码' (#602) from gitlink_server into pre_gitlink_server
This commit is contained in:
commit
61eb9ca07a
|
|
@ -172,7 +172,7 @@
|
|||
"dependencies": {
|
||||
"jsesc": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||
"resolved": "http://173.15.15.82:8081/repository/npm-all/jsesc/-/jsesc-2.5.2.tgz",
|
||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
|
||||
}
|
||||
}
|
||||
|
|
@ -245,7 +245,7 @@
|
|||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"resolved": "http://173.15.15.82:8081/repository/npm-all/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
|
|
@ -341,12 +341,12 @@
|
|||
},
|
||||
"globals": {
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
"resolved": "http://173.15.15.82:8081/repository/npm-all/globals/-/globals-11.12.0.tgz",
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"resolved": "http://173.15.15.82:8081/repository/npm-all/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
|
|
@ -7248,7 +7248,7 @@
|
|||
},
|
||||
"promise": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||
"resolved": "http://173.15.15.82:8081/repository/npm-all/promise/-/promise-7.3.1.tgz",
|
||||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||
"requires": {
|
||||
"asap": "~2.0.3"
|
||||
|
|
@ -8202,7 +8202,7 @@
|
|||
},
|
||||
"fsevents": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-1.2.13.tgz",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
|
@ -9677,7 +9677,7 @@
|
|||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"resolved": "http://173.15.15.82:8081/repository/npm-all/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
|
|
@ -19704,7 +19704,7 @@
|
|||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@
|
|||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"proxy": "http://localhost:3000",
|
||||
"proxy": "http://172.20.32.202:4000",
|
||||
"port": "3007",
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "7.0.0-beta.51",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" class="notranslate translated-ltr" translate="no">
|
||||
<html lang="zh-hans-CN" class="notranslate translated-ltr" translate="no">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<meta name="octolytics-dimension-repository_nwo" content="GitLink"></meta>
|
||||
<meta name="octolytics-dimension-repository_network_root_nwo" content="GitLink"></meta>
|
||||
<meta name="theme-color" content="#000000">
|
||||
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
|
||||
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" /> -->
|
||||
<meta content="IE=edge" http-equiv="X-UA-Compatible">
|
||||
<meta name="twitter:image:src" content="https://www.gitlink.org.cn/images/logo.png">
|
||||
<meta name="twitter:site" content="@gitlink">
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export function initAxiosInterceptors(props) {
|
|||
// 判断网络是否连接
|
||||
initOnlineOfflineListener();
|
||||
|
||||
var proxy = "https://testforgeplus.trustie.net";
|
||||
var proxy = "http://172.20.32.202:4000";
|
||||
|
||||
//响应前的设置
|
||||
axios.interceptors.request.use(
|
||||
|
|
@ -55,6 +55,7 @@ export function initAxiosInterceptors(props) {
|
|||
config.url = url;
|
||||
}
|
||||
}
|
||||
config.withCredentials = false;
|
||||
return config;
|
||||
},
|
||||
err => {
|
||||
|
|
|
|||
|
|
@ -140,10 +140,10 @@ export function setImagesUrl(path){
|
|||
}
|
||||
|
||||
export function getUrl(path, goTest) {
|
||||
const local = 'https://testforgeplus.trustie.net'
|
||||
if (isDev) {
|
||||
return `${local}${path?path:''}`
|
||||
}
|
||||
// const local = 'http://172.20.32.202:8080'
|
||||
// if (isDev) {
|
||||
// return `${local}${path?path:''}`
|
||||
// }
|
||||
return `${path ? path: ''}`;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ function AboutUs(){
|
|||
<img src={earth} className="earthImg"/>
|
||||
<div className="statistics_cont df">
|
||||
<div>
|
||||
<CountUp {...countUpProps} start={0} end={50000} />
|
||||
<CountUp {...countUpProps} start={0} end={85000} />
|
||||
<p>开发者</p>
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -275,7 +275,7 @@ function AboutUs(){
|
|||
</div>
|
||||
</div>
|
||||
</Carousel>
|
||||
<p className="delivery">简历投递邮箱:zengyt#csxjy.com.cn 曾先生 (用@符号替换#)</p>
|
||||
<p className="delivery">简历投递邮箱:48630328#qq.com 徐女士 (用@符号替换#)</p>
|
||||
</div>
|
||||
</div>
|
||||
{/* 精选组织 */}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function Releases({ owner, projectsId, releaseVersions, distribution }) {
|
|||
})
|
||||
:
|
||||
<div className="mt8">
|
||||
您暂未发布任何版本
|
||||
暂无发行版
|
||||
{distribution && <Link className="color-blue ml20" to={{pathname:`/${owner}/${projectsId}/releases/new`,state:{stable:true}}}>创建新版本</Link>}
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,167 @@
|
|||
import React from 'react';
|
||||
import { Button, message } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import MDEditor from "../../../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import Upload from "../../../../forge/Upload/Index";
|
||||
import Attachments from "../../../../forge/Upload/attachment";
|
||||
import UploadImg from "../../../../forge/Images/upload.png";
|
||||
import './list.scss';
|
||||
import '../../../../forge/Order/order.scss';
|
||||
import { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import { addComment, editComment } from '../../api'
|
||||
|
||||
function EditComment(props){
|
||||
const {owner, projectsId, index} = props.match.params;
|
||||
const {current_user, current_user:{login}, docId, showNotification, reloadComment, cancelMd, parentId, replyId, updateId, showUserImg=true} = props;
|
||||
const [content, setContent] = useState(props.content);
|
||||
const [quillFlag, setQuillFlag] = useState(false);
|
||||
// 确认评论按钮loading效果
|
||||
const [journalSpin, setJournalSpin] = useState(false);
|
||||
const [atWhoLoginList, setAtWhoLoginList] = useState(undefined);
|
||||
const [fileList, setFileList] = useState(undefined);
|
||||
const [attachmentClean, setAttachmentClean] = useState(true);
|
||||
const [ save , setSave ] = useState(undefined);
|
||||
|
||||
useState(()=>{
|
||||
setSave(props.defaultFileList);
|
||||
},[props.defaultFileList])
|
||||
|
||||
// 评论点击函数
|
||||
function addJournals(){
|
||||
if(!content){
|
||||
setQuillFlag(true);
|
||||
return
|
||||
}
|
||||
setJournalSpin(true);
|
||||
console.log(updateId)
|
||||
if(updateId){
|
||||
// 修改评论
|
||||
const params = {
|
||||
id: updateId,
|
||||
notes: content,
|
||||
attachmentIds: fileList,
|
||||
receivers_login:atWhoLoginList
|
||||
}
|
||||
editComment(docId, params).then(res=>{
|
||||
if(res && res.data && res.data.data){
|
||||
// 刷新评论列表
|
||||
reloadComment();
|
||||
message.success('评论成功');
|
||||
cancelMd();
|
||||
setContent(undefined);
|
||||
}
|
||||
setJournalSpin(false);
|
||||
})
|
||||
}else{
|
||||
// 新建评论
|
||||
const params = {
|
||||
parentId: parentId,
|
||||
replyId: replyId,
|
||||
notes: content,
|
||||
attachmentIds: fileList,
|
||||
}
|
||||
|
||||
addComment(docId, params).then(res=>{
|
||||
if(res && res.data && res.data.data){
|
||||
// 刷新评论列表
|
||||
reloadComment();
|
||||
message.success('评论成功');
|
||||
cancelMd();
|
||||
setContent(undefined);
|
||||
}
|
||||
setJournalSpin(false);
|
||||
})
|
||||
}
|
||||
};
|
||||
function deleteLoad(id){
|
||||
let arr = [];
|
||||
let list = save;
|
||||
if(list && list.length>0 ){
|
||||
arr = list.filter(i=>i.id !== id);
|
||||
}
|
||||
setFileList(arr.map(i=>{return i.id}));
|
||||
setSave(arr);
|
||||
}
|
||||
function UploadFunc(f){
|
||||
let list = [];
|
||||
let arr = [];
|
||||
if(save && save.length>0 ){
|
||||
arr = save.map(i=>{return i.id});
|
||||
}
|
||||
list = arr && arr.length>0 ? f.concat(arr) : f ;
|
||||
setFileList(list);
|
||||
};
|
||||
|
||||
return(
|
||||
<div className="grid-item-top pb10">
|
||||
<Link
|
||||
to={`/${current_user && current_user.login}`}
|
||||
className="show-user-link mr10"
|
||||
>
|
||||
<img
|
||||
className="radius"
|
||||
src={getImageUrl(
|
||||
`/${current_user && current_user.image_url}`
|
||||
)}
|
||||
alt=""
|
||||
width="30"
|
||||
height="30"
|
||||
style={{display: showUserImg ? '' : 'none'}}
|
||||
/>
|
||||
</Link>
|
||||
<div style={{position:"relative"}}>
|
||||
<MDEditor
|
||||
placeholder={"添加评论..."}
|
||||
height={300}
|
||||
mdID={"orderdetail-add-descriptions" + replyId}
|
||||
initValue={content}
|
||||
onChange={(value)=>{setQuillFlag(false);setContent(value);}}
|
||||
changeAtWhoLoginList = {(loginList)=>{setAtWhoLoginList(loginList); setAttachmentClean(true)}}
|
||||
owner = {owner}
|
||||
projectsId = {projectsId}
|
||||
></MDEditor>
|
||||
<p className="quillFlagBox">
|
||||
{quillFlag && <span>请输入评论内容</span>}
|
||||
</p>
|
||||
<Upload
|
||||
className="commentStyle"
|
||||
isComplete={attachmentClean}
|
||||
load={UploadFunc}
|
||||
icon={
|
||||
<img
|
||||
src={UploadImg}
|
||||
width="58"
|
||||
alt=""
|
||||
style={{ marginBottom: 15 }}
|
||||
/>
|
||||
}
|
||||
size={100}
|
||||
showNotification={showNotification}
|
||||
// defaultFileList={props.defaultFileList}
|
||||
/>
|
||||
{props.defaultFileList && props.defaultFileList.length > 0 &&
|
||||
<Attachments
|
||||
attachments={props.defaultFileList}
|
||||
showNotification={props.showNotification}
|
||||
canDelete={true}
|
||||
deleteLoad={deleteLoad}
|
||||
></Attachments>
|
||||
}
|
||||
<p className="clearfix mt20">
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={addJournals}
|
||||
loading={journalSpin}
|
||||
className="mr15 colorButton"
|
||||
>
|
||||
评论
|
||||
</Button>
|
||||
<Button className="colorButton2" onClick={()=>{cancelMd()}}>取消</Button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default EditComment;
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Popconfirm, Radio, Input, message, Tooltip, Spin, Pagination } from 'antd';
|
||||
import axios from 'axios';
|
||||
import { getImageUrl, timeAgo } from 'educoder';
|
||||
import RenderHtml from '../../../../components/render-html';
|
||||
import Attachment from '../../../Upload/attachment';
|
||||
import EditComment from './editComment';
|
||||
import Nodata from '../../../Nodata';
|
||||
import CheckProfile from '../../../Component/ProfileModal/Profile';
|
||||
import './list.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getCommentList, deleteComment } from '../../api'
|
||||
|
||||
function IssueCommentList(props){
|
||||
const{docId, history: {location}, reload, reloadComment, showNotification, current_user:{login, admin, image_url, username}, isManager, showLoginDialog, author} = props;
|
||||
const {owner, projectsId, index} = props.match.params;
|
||||
const [category, setCategory] = useState('comment');
|
||||
const [journals, setJournals] = useState(undefined);
|
||||
// 是否展示新建/编辑评论markdown部分新建评论1 编辑父级评论2 回复评论3 编辑回复内容4 回复子机评论5
|
||||
const [showEdit, setShowEdit] = useState(false);
|
||||
const [parentId, setParentId] = useState(undefined);
|
||||
const [replyId, setReplyId] = useState(undefined);
|
||||
// 修改评论id
|
||||
const [updateId, setUpdateId] = useState(undefined);
|
||||
// 操作日志展开效果
|
||||
const [open, setOpen] = useState(undefined);
|
||||
// 加载中效果(缓冲css 线条效果)
|
||||
const [spin, setSpin] = useState(false);
|
||||
// issue 评论总数
|
||||
const [journalsCount, setJournalsCount] = useState(undefined);
|
||||
// 分页
|
||||
const limit = 50;
|
||||
const [page, setPage] = useState(1);
|
||||
const [totalCount, setTotalCount] = useState(undefined);
|
||||
// 操作记录 icon
|
||||
const journalsIcon ={
|
||||
'issue': 'icon-chuangjianqianbao',
|
||||
'branch_name': 'icon-fenzhi3',
|
||||
'assigner': 'icon-chengyuan2',
|
||||
'status_id': 'icon-xiugaibaobiaomoban',
|
||||
'fixed_version_id': 'icon-lichengbeiicon2',
|
||||
'due_date': 'icon-riqi',
|
||||
'issue_tag': 'icon-biaoji2',
|
||||
'description': 'icon-xiugaibaobiaomoban',
|
||||
'subject': 'icon-xiugaibaobiaomoban',
|
||||
'start_date': 'icon-riqi',
|
||||
'priority_id': 'icon-youxian',
|
||||
'attachment': 'icon-xiugaibaobiaomoban'
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
setSpin(true);
|
||||
let params = {
|
||||
limit: limit,
|
||||
page: page
|
||||
}
|
||||
getCommentList(docId, params).then(res=>{
|
||||
if(res && res.data && res.data.data){
|
||||
const {journals, total_comment_journals_count, total_count} = res.data.data;
|
||||
if(category === 'all'){
|
||||
const array = [];
|
||||
let start = undefined;
|
||||
let isJournalCount = 0;
|
||||
journals.map((item, index)=>{
|
||||
!isJournalCount && (start = index)
|
||||
item.is_journal_detail && (isJournalCount++)
|
||||
if(!item.is_journal_detail && isJournalCount < 10){
|
||||
isJournalCount = 0;
|
||||
return
|
||||
}
|
||||
if(isJournalCount >= 10 && (!item.is_journal_detail || journals.length-1 === index)){
|
||||
array.push({start, count: isJournalCount});
|
||||
isJournalCount = 0;
|
||||
}
|
||||
})
|
||||
array.map((item, i)=>{
|
||||
journals[item.start].numCount = item.count-1;
|
||||
for (let index = 0; index < item.count; index++) {
|
||||
journals[item.start+index].start = journals[item.start].id;
|
||||
journals[item.start+index].closeAndSpan = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
setTotalCount(total_count);
|
||||
setJournalsCount(total_comment_journals_count);
|
||||
setJournals(journals);
|
||||
setSpin(false)
|
||||
}
|
||||
})
|
||||
}, [reload, category, page])
|
||||
|
||||
function commentCtx(v){
|
||||
return <RenderHtml owner={owner} projectsId={projectsId} className="break_word_comments imageLayerParent commentRenderHtml" value={v} url={location}/>;
|
||||
};
|
||||
|
||||
// 删除评论内容
|
||||
function deleteCommentFunc(id){
|
||||
deleteComment(docId, id).then(res=>{
|
||||
if(res && res.data && !res.data.data.status){
|
||||
reloadComment();
|
||||
message.success('删除成功');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// markdown 取消操作
|
||||
function cancelMd(){
|
||||
setShowEdit(false);
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="commentListBox">
|
||||
{/* 评论 */}
|
||||
<div className={`${!login && journalsCount > 0 && 'pb15'}`}>
|
||||
<div className='typeActionBox mb20'>
|
||||
<div className='line'></div>
|
||||
<div>评论{ journalsCount > 0 && `(共${ journalsCount }条评论)` }</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* 评论快速入口-仅有评论且登录时展示 */}
|
||||
{login && category !== 'operate' && journalsCount > 0 && <div className={`pb30 ${journalsCount > 0 && 'pt15'}`}><div className='gotoComment'>点击<a className='ml5' href='#addComments'>添加评论</a></div></div>}
|
||||
{/* 评论/操作日志 展示列表 */}
|
||||
<Spin spinning={spin}>
|
||||
<div className={`issueCommentsBox ${category === 'comment' && !spin && 'justComment'}`}>
|
||||
{journals && (journals.length > 0 && journals.map(item=>{return <div key={item.id} className='commentContentBox pb30'>
|
||||
{/* 评论 */}
|
||||
<div className='commentOperationBor'></div>
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr15'/></Link>
|
||||
<div className='commentContentRight'>
|
||||
{/* 判断是否是编辑状态 */}
|
||||
{(showEdit === 2 && updateId === item.id) ? <div className='mt15 mr20'><EditComment {...props} cancelMd={cancelMd} updateId={updateId} reloadComment={reloadComment} content={item.notes} defaultFileList={item.attachments} showUserImg={false}/></div> : <div>
|
||||
<div className='commentContent'>
|
||||
<div className='flexCenter font-14'>
|
||||
<div>
|
||||
<Link to={`/${item.user.login}`}>{item.user.name}</Link>
|
||||
<span className='ml15 timeAgo font-14'>{timeAgo(item.created_at)}</span>
|
||||
</div>
|
||||
{login && <div>
|
||||
{/* 平台管理员/仓库管理员/发布评论者/issue创建者 */}
|
||||
{(admin || isManager || login === item.user.login || username === author) && <Popconfirm
|
||||
placement="bottom"
|
||||
title={`确定要删除此条评论吗?${item.children_journals.length > 0 ? '子评论也将被一起删除。' : ''}`}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() => deleteCommentFunc(item.id)}
|
||||
>
|
||||
<Button type='link' className='color-grey-89'><i className='iconfont icon-fuzhi-shanchu font-14 mr8'></i>删除</Button>
|
||||
</Popconfirm>}
|
||||
{/* 仅评论者可修改 */}
|
||||
{login === item.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(item.id); setShowEdit(2)}}><i className='iconfont icon-a-bianji12 font-14 mr8'></i>修改</Button>}
|
||||
<CheckProfile {...props} sureFunc={()=>{setParentId(item.id); setReplyId(item.id); setShowEdit(3)}}><Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-14 mr8'></i>回复</Button></CheckProfile>
|
||||
</div>}
|
||||
</div>
|
||||
<div className='contentHtml mb5'>{commentCtx(item.notes)}</div>
|
||||
{item && item.attachments && item.attachments.length > 0 && <div className='attachmentBox mb5'><Attachment
|
||||
attachments={item.attachments}
|
||||
showNotification={showNotification}
|
||||
canDelete={false}
|
||||
/></div>}
|
||||
</div>
|
||||
</div>}
|
||||
{showEdit === 3 && replyId === item.id && <div className='contentHtml mr20'><EditComment {...props} cancelMd={cancelMd} parentId={parentId} replyId={replyId} reloadComment={reloadComment}/></div>}
|
||||
{/* 评论回复部分 */}
|
||||
{item.children_journals.map(i =>{
|
||||
return <div className='commentReply' key={i.id}>
|
||||
{(showEdit === 4 && updateId === i.id) ? <div className='mr20'><EditComment {...props} cancelMd={cancelMd} updateId={updateId} reloadComment={reloadComment} content={i.notes} defaultFileList={i.attachments}/></div> : <div>
|
||||
<div className='flexCenter'>
|
||||
<div>
|
||||
<Link to={`/${i.user.login}`}><img src={getImageUrl(i.user.image_url)} alt="" className='commentUserImg mr8'/></Link>
|
||||
<Link to={`/${i.user.login}`}>{i.user.name}</Link>
|
||||
{i.reply_user && <span className='ml5 timeAgo mr3'>回复</span>}
|
||||
<span>{i.reply_user && i.reply_user.name}</span>
|
||||
<span className='ml15 timeAgo font-14'>{timeAgo(i.created_at)}</span>
|
||||
</div>
|
||||
{login && <div>
|
||||
{/* 平台管理员/仓库管理员/发布评论者/回复评论者/issue创建者 */}
|
||||
{(admin || isManager || login === i.user.login || (i.reply_user && login === i.reply_user.login) || username === author) && <Popconfirm
|
||||
placement="bottom"
|
||||
title={"确定要删除当前回复吗?"}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() => deleteCommentFunc(i.id)}
|
||||
>
|
||||
<Button type='link' className='color-grey-89'><i className='iconfont icon-fuzhi-shanchu font-14 mr8'></i>删除</Button>
|
||||
</Popconfirm>}
|
||||
{/* 仅回复评论者可修改 */}
|
||||
{login === i.user.login && <Button type='link' className='color-grey-89' onClick={()=>{setUpdateId(i.id); setShowEdit(4)}}><i className='iconfont icon-a-bianji12 font-14 mr8'></i>修改</Button>}
|
||||
<CheckProfile {...props} sureFunc={()=>{setParentId(item.id);setReplyId(i.id); setShowEdit(5)}}>
|
||||
<Button type='link' className='color-grey-89'><i className='iconfont icon-a-xiaoxi1 font-14 mr8'></i>回复</Button>
|
||||
</CheckProfile>
|
||||
</div>}
|
||||
</div>
|
||||
<div className='contentHtml mt5 mb10'>{commentCtx(i.notes)}</div>
|
||||
{i && i.attachments && i.attachments.length > 0 && <div className='attachmentBox'><Attachment
|
||||
attachments={i.attachments}
|
||||
showNotification={showNotification}
|
||||
canDelete={false}
|
||||
/></div>}
|
||||
</div>}
|
||||
{showEdit === 5 && replyId === i.id && <div className='contentHtml mr20'><EditComment {...props} cancelMd={cancelMd} parentId={parentId} replyId={replyId} reloadComment={reloadComment}/></div>}
|
||||
</div>})}
|
||||
</div>
|
||||
</div>}))}
|
||||
</div>
|
||||
</Spin>
|
||||
{totalCount>limit && <div className='mt20 paginationIssueComment mb20'>
|
||||
<Pagination simple current={page} pageSize={limit} total={totalCount} onChange={(page)=>setPage(page)}/>
|
||||
</div>}
|
||||
{/* 添加评论 */}
|
||||
{category !== 'operate' && <div className="pb30" style={{marginTop: journalsCount ? '-5px' : '30px'}}>
|
||||
{login ? showEdit === 1 ? <EditComment {...props} cancelMd={cancelMd}/> : <div className="addComments" id='addComments'>
|
||||
<img src={getImageUrl(image_url)} alt="" />
|
||||
<div style={{flex:1}}>
|
||||
<CheckProfile {...props} sureFunc={()=>{setShowEdit(1)}}>
|
||||
<Input className='addCommentBox' placeholder="添加评论"/>
|
||||
</CheckProfile>
|
||||
</div>
|
||||
</div> : <div className='unLoginComment font-15 pl20'>
|
||||
{/* 未登录用户 */}
|
||||
<a className='mr5 loginBtn' onClick={()=>{showLoginDialog()}}>登录</a>并参与评论与回复
|
||||
</div>}
|
||||
</div>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default IssueCommentList;
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
.typeActionBox{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
.line {
|
||||
width: 3px;
|
||||
height: 14px;
|
||||
background: var(--primary-color);
|
||||
margin-right: 13px;
|
||||
}
|
||||
}
|
||||
.commentUserImg{
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.issueCommentsBox{
|
||||
.operationLog, .commentContentBox{
|
||||
position: relative;
|
||||
min-height: 62px;
|
||||
display: flex;
|
||||
>.flexCenter, >a{
|
||||
z-index: 2;
|
||||
}
|
||||
&::before, &::after{
|
||||
content: '';
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
position: absolute;
|
||||
background: #eee;
|
||||
left: 12px;
|
||||
z-index: 1;
|
||||
}
|
||||
&::after{
|
||||
background: #eee;
|
||||
top: 50%;
|
||||
}
|
||||
}
|
||||
.commentContentBox+.operationLog .operationCommentBor, .operationLog+.commentContentBox .commentOperationBor{
|
||||
border-top: 1px solid #eee;
|
||||
width: 98.5%;
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
}
|
||||
.operationLog+.commentContentBox{
|
||||
&>a, &>.commentContentRight{
|
||||
margin-top: 25px;
|
||||
}
|
||||
}
|
||||
.timeAgo{
|
||||
color:#acb0bf;
|
||||
}
|
||||
.operationLog:last-child::after, .operationLog:first-child::before, .commentContentBox:last-child::after, &.justComment .commentContentBox::before, &.justComment .commentContentBox::after{
|
||||
display: none;
|
||||
}
|
||||
.operationLog:first-child, .commentContentBox+.operationLog{
|
||||
margin-top: -15px;
|
||||
}
|
||||
.commentContentBox:last-child::before{
|
||||
height: 35%;
|
||||
}
|
||||
.flexCenter{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.commentRenderHtml.markdown-body p{
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.commentReply{
|
||||
padding: 15px 0 0 20px;
|
||||
background-color: hsla(225, 31%, 95%, 0.41);
|
||||
&>div{
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
&+.commentReply>div{
|
||||
margin-top: -15px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px dashed #eee;
|
||||
}
|
||||
}
|
||||
.opBox{
|
||||
justify-content: flex-start;
|
||||
// flex: 1;
|
||||
// width: 100%;
|
||||
}
|
||||
.commentContentBox{
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.commentContentRight{
|
||||
flex: 1;
|
||||
background-color:#fafafc;
|
||||
// border:1px solid var(--light-color-2);
|
||||
border:1px solid rgba(42, 97, 255, 0.23);
|
||||
border-radius:6px;
|
||||
position: relative;
|
||||
top: -6px;
|
||||
padding: 10px 15px 16px;
|
||||
width: 0;
|
||||
&::before{
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
left: -14px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border: 7px;
|
||||
border-style: solid;
|
||||
border-color: transparent rgba(42, 97, 255, 0.23) transparent transparent;
|
||||
}
|
||||
&::after{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border: 6px;
|
||||
border-style: solid;
|
||||
border-color: transparent #fafafc transparent transparent;
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: -11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.attachmentBox{
|
||||
margin-top: -8px;
|
||||
}
|
||||
.color-grey-89{
|
||||
color: #898d9d;
|
||||
// &:hover {
|
||||
// color: var(--primary-color);
|
||||
// }
|
||||
}
|
||||
// 添加评论样式
|
||||
.unLoginComment{
|
||||
height:58px;
|
||||
line-height: 58px;
|
||||
background-color:var(--more-light-color);
|
||||
border-radius:4px;
|
||||
color: rgba(84, 87, 103, 1);
|
||||
.loginBtn{
|
||||
color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
.quillFlagBox{
|
||||
color: red;
|
||||
margin-bottom: 5px !important;
|
||||
height: 28px;
|
||||
}
|
||||
.addComments{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color:var(--more-light-color);
|
||||
border-radius:4px;
|
||||
padding:7px 10px;
|
||||
&>img{
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 50%;
|
||||
margin-right: 13px;
|
||||
}
|
||||
}
|
||||
.addCommentBox{
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
border: none;
|
||||
&:focus {
|
||||
border-color: var(--primary-color) !important;
|
||||
}
|
||||
}
|
||||
.paginationIssueComment{
|
||||
text-align: center;
|
||||
}
|
||||
.gotoComment{
|
||||
// background-color:var(--more-light-color);
|
||||
background-color:rgba(241, 243, 252, 0.55);
|
||||
border-radius:4px;
|
||||
color: rgba(172, 176, 191, 1);
|
||||
padding: 8px 20px;
|
||||
margin-top: -10px;
|
||||
&>a{color: var(--primary-color);}
|
||||
}
|
||||
// .commentStyle {
|
||||
// &:hover {
|
||||
// border-color: var(--primary-color) !important;
|
||||
// }
|
||||
// }
|
||||
.colorButton {
|
||||
background-color: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
&:hover {
|
||||
background-color: var(--light-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
&:focus {
|
||||
background-color: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
.colorButton2 {
|
||||
&:hover {
|
||||
border-color: var(--primary-color);
|
||||
color: var(--light-color);
|
||||
}
|
||||
&:focus {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ function PublicBanner(props){
|
|||
const [ key , setKey ] = useState("1");
|
||||
const { deptId } = props.match.params;
|
||||
const { pathname } = props.history.location;
|
||||
const { data , adminUrl, temp } = props;
|
||||
const { data:{sectionHomepageShow, sectionHomepageTitle, sectionProjectShow, sectionProjectTitle, sectionResourceShow, sectionResourceTitle, sectionCmsShow, sectionCmsTitle, sectionMemberShow, sectionMemberTitle, sectionHelperShow, sectionHelperTitle}, data , adminUrl, temp } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(pathname){
|
||||
|
|
@ -53,13 +53,13 @@ function PublicBanner(props){
|
|||
}
|
||||
<div className="bannerMenus">
|
||||
<Menu mode={"horizontal"} selectedKeys={[key]}>
|
||||
<Menu.Item key={"1"}><Link to={`/zone/${deptId}`}><img src={require(`../img/${temp}Menu1.png`)} alt="" width="29px"/>首页</Link></Menu.Item>
|
||||
<Menu.Item key={"2"}><Link to={`/zone/${deptId}/projects`}><img src={require(`../img/${temp}Menu2.png`)} alt="" width="34px"/>开源项目</Link></Menu.Item>
|
||||
<Menu.Item key={"3"}><Link to={`/zone/${deptId}/source`}><img src={require(`../img/${temp}Menu3.png`)} alt="" width="33px"/>资源发布</Link></Menu.Item>
|
||||
<Menu.Item key={"4"}><Link to={`/zone/${deptId}/news`}><img src={require(`../img/${temp}Menu4.png`)} alt="" width="32px"/>{ tempConfig[temp].mainTitle }</Link></Menu.Item>
|
||||
{sectionHomepageShow && <Menu.Item key={"1"}><Link to={`/zone/${deptId}`}><img src={require(`../img/${temp}Menu1.png`)} alt="" width="29px"/>{sectionHomepageTitle}</Link></Menu.Item>}
|
||||
{sectionProjectShow && <Menu.Item key={"2"}><Link to={`/zone/${deptId}/projects`}><img src={require(`../img/${temp}Menu2.png`)} alt="" width="34px"/>{sectionProjectTitle}</Link></Menu.Item>}
|
||||
{sectionResourceShow && <Menu.Item key={"3"}><Link to={`/zone/${deptId}/source`}><img src={require(`../img/${temp}Menu3.png`)} alt="" width="33px"/>{sectionResourceTitle}</Link></Menu.Item>}
|
||||
{sectionCmsShow && <Menu.Item key={"4"}><Link to={`/zone/${deptId}/news`}><img src={require(`../img/${temp}Menu4.png`)} alt="" width="32px"/>{sectionCmsTitle}</Link></Menu.Item>}
|
||||
{/* <Menu.Item key={"5"}><img src={Menu5} alt="" width="27px"/>Sig小组</Menu.Item> */}
|
||||
<Menu.Item key={"6"}><Link to={`/zone/${deptId}/VIP`}><img src={require(`../img/${temp}Menu6.png`)} alt="" width="36px"/>{ tempConfig[temp].member }</Link></Menu.Item>
|
||||
{data && data.helperShow === 1 && <Menu.Item key={"8"}><Link to={`/zone/${deptId}/help`}><img src={require(`../img/${temp}Menu8.png`)} alt="" width="36px"/>{data.helperTitle}</Link></Menu.Item>}
|
||||
{sectionMemberShow && <Menu.Item key={"6"}><Link to={`/zone/${deptId}/VIP`}><img src={require(`../img/${temp}Menu6.png`)} alt="" width="36px"/>{ sectionMemberTitle }</Link></Menu.Item>}
|
||||
{sectionHelperShow && <Menu.Item key={"8"}><Link to={`/zone/${deptId}/help`}><img src={require(`../img/${temp}Menu8.png`)} alt="" width="36px"/>{data.sectionHelperTitle}</Link></Menu.Item>}
|
||||
{ adminUrl && <Menu.Item key={"7"}><a onClick={()=>{window.location.href=adminUrl}}><img src={require(`../img/${temp}Menu7.png`)} alt="" width="34px"/>后台管理</a></Menu.Item> }
|
||||
</Menu>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ function ProjectSource(props) {
|
|||
return (
|
||||
<div className="in_pro">
|
||||
<div className="boxmain" style={{ paddingTop: "56px" }}>
|
||||
<p className="in_title mb30">{data && data.helperTitle}</p>
|
||||
<p className="in_title mb30">{data && data.sectionHelperTitle}</p>
|
||||
<Spin spinning={loading}>
|
||||
{
|
||||
wikiList && (wikiList.length > 0 ? <Box className='zoneHelpBox'>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ function Main(props){
|
|||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
const [ newCateId , setNewCateId ] = useState(undefined);
|
||||
const { deptId , cateId } = props.match.params;
|
||||
const { id, temp, role, history } = props;
|
||||
const { id, temp, role, history, sectionCmsTitle } = props;
|
||||
|
||||
const menu = (
|
||||
<Menu>
|
||||
|
|
@ -121,7 +121,7 @@ function Main(props){
|
|||
<div className="main_content">
|
||||
<div className="boxmain">
|
||||
<div className='titleButBox'>
|
||||
<p className="in_title">{tempConfig[temp].mainTitle}</p>
|
||||
<p className="in_title">{sectionCmsTitle}</p>
|
||||
{role && role.role !== "None" && <div className='createButs mt10'>
|
||||
{role.role === "Member" && <Button type="primary" ghost className='mr20'>
|
||||
<Link to={`/zone/${deptId}/news/self`}>我的文章</Link>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React,{ useState , useEffect } from 'react';
|
||||
import React,{ useState , useEffect, useRef } from 'react';
|
||||
import { Badge, Breadcrumb , Divider, Spin } from 'antd';
|
||||
import liulan from '../img/liulan.png';
|
||||
import RenderHtml from '../../../components/render-html';
|
||||
|
|
@ -8,6 +8,7 @@ import { IsPC } from 'educoder';
|
|||
import { tempConfig } from '../tempInfo';
|
||||
import Acce from '../Component/mobile/accessory';
|
||||
import { addMeta, setSeoMeta } from 'educoder';
|
||||
import CommentList from '../Component/comments/list'
|
||||
|
||||
|
||||
function NewsDetail(props){
|
||||
|
|
@ -16,6 +17,7 @@ function NewsDetail(props){
|
|||
const [ cmsDir , setCmsDir ] = useState(undefined);
|
||||
const [ content , setContent]=useState(undefined);
|
||||
const [ isSpin , setIsSpin]=useState(false);
|
||||
const [ commentReload, setCommentReload] = useState(undefined);
|
||||
const temp = props.temp;
|
||||
const zonedetail = props.data;
|
||||
|
||||
|
|
@ -76,6 +78,7 @@ function NewsDetail(props){
|
|||
setIsSpin(false)
|
||||
})
|
||||
}
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
|
|
@ -120,6 +123,13 @@ function NewsDetail(props){
|
|||
<span>暂无详情~</span>
|
||||
}
|
||||
</div>
|
||||
{
|
||||
// 审核通过才有评论
|
||||
detail.auditStatus === '1' && <div className="info_text mt30">
|
||||
<CommentList {...props} docId={ id } reload={commentReload} author={ detail.createBy } reloadComment={()=>{setCommentReload(Math.random())}}/>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
}
|
||||
</Spin>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function ProjectSource(props){
|
|||
const [ searchName , setSearchName ] = useState(undefined);
|
||||
const [ value , setValue ] = useState(undefined);
|
||||
const [ loading , setLoading ] = useState(false);
|
||||
const { id, temp } = props;
|
||||
const { id, temp, sectionProjectTitle } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(id){
|
||||
|
|
@ -79,7 +79,7 @@ function ProjectSource(props){
|
|||
<div className="in_pro">
|
||||
{/* <Banner {...props}/> */}
|
||||
<div className="boxmain" style={{paddingTop:"56px"}}>
|
||||
<p className="in_title">开源项目</p>
|
||||
<p className="in_title">{sectionProjectTitle}</p>
|
||||
{ temp === tempEnum.zone1 && <p className="project_sub_title">聚合开源特色项目,搭建硬件开源服务桥梁</p> }
|
||||
<Box>
|
||||
<ul className="in_pro_menu">
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ function Source(props){
|
|||
const [ search , setSearch ] = useState(undefined);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
const limit = 20;
|
||||
const { id , temp, history, role } = props;
|
||||
const { id , temp, history, role, sectionResourceTitle } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
id && getLists();
|
||||
|
|
@ -80,7 +80,7 @@ function Source(props){
|
|||
return(
|
||||
<div className={`${temp}_source_box`}>
|
||||
<div className="source_h">
|
||||
<p className="in_title">资源发布</p>
|
||||
<p className="in_title">{sectionResourceTitle}</p>
|
||||
<div style={{marginTop:"30px",textAlign:"center"}} className='titleButBox'>
|
||||
<Search
|
||||
placeholder="请输入资源名称"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ function ZoneVIP(props){
|
|||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
const [ applyVisible , setApplyVisible ] = useState(false);
|
||||
const [ memberStatus , setMemberStatus] = useState(memberStatusEnum.notMember);
|
||||
const { id, showNotification, checkIfLogin, showLoginDialog, temp } = props;
|
||||
const { id, showNotification, checkIfLogin, showLoginDialog, temp, sectionMemberTitle } = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(id){
|
||||
|
|
@ -74,7 +74,7 @@ function ZoneVIP(props){
|
|||
|
||||
return(
|
||||
<div className={`boxmain ${temp}_VIP_box`}>
|
||||
<p className="in_title">{ tempConfig[temp].member }</p>
|
||||
<p className="in_title">{ sectionMemberTitle }</p>
|
||||
<p className="vip_sub_title">{ tempConfig[temp].vipDesc }</p>
|
||||
{ memberStatus === memberStatusEnum.notMember && <Button className="zone_apply_button" onClick={ apply }>申请加入</Button> }
|
||||
{ memberStatus === memberStatusEnum.applying && <div className="mt20 tips" ><Icon type="check-circle" theme="filled" />您的申请已提交,请耐心等待管理员审核!</div> }
|
||||
|
|
@ -83,8 +83,10 @@ function ZoneVIP(props){
|
|||
<Spin spinning={isSpin}>
|
||||
<div style={{minHeight:400}}>
|
||||
{
|
||||
vipLists && (vipLists.length > 0 ? <MemberList vipLists={vipLists} temp={temp}/> : <div style={{marginTop:30,backgroundColor:"#fff",padding:"20px"}}>
|
||||
<Nodata _html={"暂无数据"}/>
|
||||
vipLists && (vipLists.length > 0 ? <MemberList vipLists={vipLists} temp={temp}/> : <div style={{marginTop:30,padding:"20px"}}>
|
||||
{
|
||||
temp === tempEnum.zone1 ? <Nodata _html="暂无数据" img={ nodata }/> : <Nodata _html="暂无数据" />
|
||||
}
|
||||
</div>)
|
||||
}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -252,4 +252,40 @@ export function updateMyResource(data) {
|
|||
method: 'PUT',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 评论相关
|
||||
// 评论列表
|
||||
export function getCommentList(id, params) {
|
||||
return fetch({
|
||||
url: `cms/doc/open/${ id }/journalList`,
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 新增评论
|
||||
export function addComment(id, data) {
|
||||
return fetch({
|
||||
url: `cms/docComment/${ id }`,
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 编辑评论
|
||||
export function editComment(id, data) {
|
||||
return fetch({
|
||||
url: `cms/docComment/${ id }/${ data.id }`,
|
||||
method: 'PUT',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除评论
|
||||
export function deleteComment(docId, id) {
|
||||
return fetch({
|
||||
url: `cms/docComment/${ docId }/${ id }`,
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
|
@ -177,7 +177,7 @@ function Index(props){
|
|||
<Route
|
||||
path="/zone/:deptId/news/:cateId"
|
||||
render={(p) => (
|
||||
<Main {...props} {...p} id={id} temp={ temp } role={role}/>
|
||||
<Main {...props} {...p} id={id} temp={ temp } role={role} sectionCmsTitle={data && data.sectionCmsTitle}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
|
|
@ -213,25 +213,25 @@ function Index(props){
|
|||
<Route
|
||||
path="/zone/:deptId/source"
|
||||
render={(p) => (
|
||||
<Source {...props} {...p} id={id} temp={ temp } role={role}/>
|
||||
<Source {...props} {...p} id={id} temp={ temp } role={role} sectionResourceTitle={data && data.sectionResourceTitle}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/VIP"
|
||||
render={(p) => (
|
||||
<VIP {...props} {...p} id={id} temp={ temp }/>
|
||||
<VIP {...props} {...p} id={id} temp={ temp } sectionMemberTitle={data && data.sectionMemberTitle}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/projects"
|
||||
render={(p) => (
|
||||
<ProjectSource {...props} {...p} id={id} temp={ temp }/>
|
||||
<ProjectSource {...props} {...p} id={id} temp={ temp } sectionProjectTitle={data && data.sectionProjectTitle}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/zone/:deptId/news"
|
||||
render={(p) => (
|
||||
<Main {...props} {...p} id={id} temp={ temp } role={role}/>
|
||||
<Main {...props} {...p} id={id} temp={ temp } role={role} sectionCmsTitle={data && data.sectionCmsTitle}/>
|
||||
)}
|
||||
></Route>
|
||||
{data && data.helperShow === 1 && <Route
|
||||
|
|
|
|||
|
|
@ -1126,10 +1126,12 @@
|
|||
margin-right: 7px;
|
||||
}
|
||||
}
|
||||
.none_panels {
|
||||
background-color: #FFFFFF;
|
||||
margin: 25px 25px 25px 0;
|
||||
border-radius: 12px;
|
||||
.vip_list {
|
||||
.none_panels {
|
||||
background-color: #FFFFFF;
|
||||
margin: 25px 25px 25px 0;
|
||||
border-radius: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.zone_parter{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ html[data-theme="zone"] {
|
|||
--more-light-color: rgba(70, 106, 255, 0.05);
|
||||
--linear-back-color: linear-gradient(89.9deg,rgba(70, 106, 255, 0) 0%,rgba(70, 106, 255, 0.09) 100%);
|
||||
--tag-back: rgba(70, 106, 255, 0.12);
|
||||
--light-color-2: rgba(70,106,255,0.23);
|
||||
--light-color-3: rgba(70,106,255,0.55);
|
||||
}
|
||||
html[data-theme="zone1"] {
|
||||
--primary-color: #089f7f;
|
||||
|
|
@ -11,4 +13,6 @@ html[data-theme="zone1"] {
|
|||
--light-color: rgba(7, 165, 131, 0.85);
|
||||
--linear-back-color: linear-gradient(89.9deg,rgba(7, 165, 131, 0) 0%,rgba(7, 165, 131, 0.09) 100%);
|
||||
--tag-back: rgba(142, 147, 161, 0.1);
|
||||
--light-color-2: rgba(7, 165, 131, 0.23);
|
||||
--light-color-3: rgba(7, 165, 131, 0.55);
|
||||
}
|
||||
|
|
@ -82,7 +82,9 @@ function AllMenus({owner,projectsId,chooseFunc,update,defaultNames,defaultIds,op
|
|||
const url = `/v1/${owner}/${projectsId}/issue_tags`;
|
||||
axios.get(url,{params:{keyword:tag,only_name:true}}).then(result=>{
|
||||
if(result && result.data){
|
||||
setTagList(result.data.issue_tags);
|
||||
let list = [{id:-1,name:"无标记"}];
|
||||
list = [...list,...result.data.issue_tags];
|
||||
setTagList(list);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -95,7 +97,9 @@ function AllMenus({owner,projectsId,chooseFunc,update,defaultNames,defaultIds,op
|
|||
const url = `/v1/${owner}/${projectsId}/milestones`;
|
||||
axios.get(url,{params:{keyword:millstone,only_name:true}}).then(result=>{
|
||||
if(result && result.data){
|
||||
setMillstoneList(result.data.milestones);
|
||||
let list = [{id:-1,name:"无里程碑"}];
|
||||
list = [...list,...result.data.milestones];
|
||||
setMillstoneList(list);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -106,18 +110,21 @@ function AllMenus({owner,projectsId,chooseFunc,update,defaultNames,defaultIds,op
|
|||
},[charge,update])
|
||||
|
||||
function getCharge(){
|
||||
let list = [{id:-1,name:"未指派负责人"}];
|
||||
if(update){
|
||||
const url = `/v1/${owner}/${projectsId}/collaborators`;
|
||||
axios.get(url,{params:{keyword:charge,only_name:true}}).then(result=>{
|
||||
if(result && result.data){
|
||||
setChargeList(result.data.collaborators);
|
||||
list = [...list,...result.data.collaborators];
|
||||
setChargeList(list);
|
||||
}
|
||||
})
|
||||
}else{
|
||||
const url = `/v1/${owner}/${projectsId}/issue_assigners`;
|
||||
axios.get(url,{params:{keyword:charge,only_name:true}}).then(result=>{
|
||||
if(result && result.data){
|
||||
setChargeList(result.data.assigners);
|
||||
list = [...list,...result.data.assigners];
|
||||
setChargeList(list);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Attachments from "../../../../forge/Upload/attachment";
|
|||
import UploadImg from "../../../../forge/Images/upload.png";
|
||||
import './list.scss';
|
||||
import '../../../../forge/Order/order.scss';
|
||||
import { useState } from 'react';
|
||||
import { useState,useEffect } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ function EditComment(props){
|
|||
const [attachmentClean, setAttachmentClean] = useState(true);
|
||||
const [ save , setSave ] = useState(undefined);
|
||||
|
||||
useState(()=>{
|
||||
useEffect(()=>{
|
||||
setSave(props.defaultFileList);
|
||||
},[props.defaultFileList])
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@ function Menus({className,name, ids , lists , size , imgControl , searchFunc , c
|
|||
function changeMenusValue(i){
|
||||
let l = ids;
|
||||
let id = i.id.toString();
|
||||
if(double){
|
||||
if(double && id!=="-1"){
|
||||
l = ids ? ids.split(",") : [] ;
|
||||
l = l && l.length>0 ? l.filter(i=>i.toString()!=="-1") :[];
|
||||
let nameArr = names ? names.split(",") : [] ;
|
||||
if(l && l.indexOf(id)>=0){
|
||||
l = l.filter(k=>k.toString() !== id);
|
||||
|
|
@ -69,7 +70,7 @@ function Menus({className,name, ids , lists , size , imgControl , searchFunc , c
|
|||
{
|
||||
data.map((i,j)=>{
|
||||
return <Menu.Item key={i.id}>
|
||||
{imgControl && <img src={getImageUrl(i.image_url)} alt=""/>}
|
||||
{imgControl && i.image_url && <img src={getImageUrl(i.image_url)} alt=""/>}
|
||||
{i.color && <span style={{backgroundColor:i.color,marginRight:"0px"}} className="colorpiece"></span>}
|
||||
<span className="task-hide" onClick={()=>changeMenusValue(i)}>{i.name}</span>
|
||||
</Menu.Item>
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ function Details(props){
|
|||
}).then(result=>{
|
||||
if(result && result.data && result.data.project_issues_index){
|
||||
window.scrollTo(0,0);
|
||||
props.showNotification("任务复制成功!");
|
||||
props.showNotification("疑修复制成功!");
|
||||
props.history.push(`/${owner}/${projectsId}/issues/${result.data.project_issues_index}`);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
|
|
|
|||
|
|
@ -237,13 +237,17 @@ function List(props){
|
|||
// 确认修改 allValue updateIds
|
||||
function sureUpdate(){
|
||||
const url = `/v1/${owner}/${projectsId}/issues/batch_update`;
|
||||
const { assigner_id ,issue_tag_ids , milestone_id ,issue_priorities_id , status_id } = updateChooseIds;
|
||||
let assigner = assigner_id ? assigner_id === "-1" ? [] : assigner_id.split(",") : undefined;
|
||||
let issueTag = issue_tag_ids ? issue_tag_ids === "-1" ? [] : issue_tag_ids.split(",") : undefined;
|
||||
let milestone = milestone_id ? milestone_id === "-1" ? "" : milestone_id : undefined;
|
||||
axios.patch(url,{
|
||||
assigner_ids: updateChooseIds && updateChooseIds.assigner_id && updateChooseIds.assigner_id.split(","),
|
||||
assigner_ids: assigner ,
|
||||
ids: allValue,
|
||||
issue_tag_ids: updateChooseIds && updateChooseIds.issue_tag_ids && updateChooseIds.issue_tag_ids.split(","),
|
||||
milestone_id: updateChooseIds && updateChooseIds.milestone_id,
|
||||
priority_id: updateChooseIds && updateChooseIds.issue_priorities_id,
|
||||
status_id: updateChooseIds && updateChooseIds.status_id
|
||||
issue_tag_ids: issueTag,
|
||||
milestone_id: milestone,
|
||||
priority_id: issue_priorities_id,
|
||||
status_id: status_id
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setUpdateIds(undefined);
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ function New(props){
|
|||
}).then(result=>{
|
||||
if(result && result.data && result.data.project_issues_index){
|
||||
window.scrollTo(0,0);
|
||||
props.showNotification("任务创建成功!");
|
||||
props.showNotification("疑修创建成功!");
|
||||
props.history.push(`/${owner}/${projectsId}/issues/${result.data.project_issues_index}`);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
|
|
|
|||
|
|
@ -93,12 +93,12 @@ function Sign(props){
|
|||
<Menu.Item key={"4"} value="asc" createName="issues_count">
|
||||
按疑修数量升序排序
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"5"} value="desc" createName="pull_requests_count">
|
||||
{/* <Menu.Item key={"5"} value="desc" createName="pull_requests_count">
|
||||
按合并请求数量降序排序
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"6"} value="asc" createName="pull_requests_count">
|
||||
按合并请求数量升序排序
|
||||
</Menu.Item>
|
||||
</Menu.Item> */}
|
||||
</Menu>
|
||||
);
|
||||
|
||||
|
|
@ -240,8 +240,8 @@ function Sign(props){
|
|||
</p>
|
||||
<p style={{flex:2}} className="task-hide">{i.description}</p>
|
||||
<p>
|
||||
<span className="mr12">{i.issues_count || 0} 疑修</span>
|
||||
<span className="line">{i.pull_requests_count || 0} 合并请求</span>
|
||||
<span>{i.issues_count || 0} 疑修</span>
|
||||
{/* <span className="line">{i.pull_requests_count || 0} 合并请求</span> */}
|
||||
</p>
|
||||
<p>
|
||||
<a className="color-blue mr12" onClick={()=>editFunc(i)}>编辑</a>
|
||||
|
|
|
|||
|
|
@ -62,9 +62,11 @@ function CoderDepot(props){
|
|||
let branchName = props.match.params.branchName;
|
||||
branchName = returnbar(branchName);
|
||||
let pathname = props.history.location.pathname;
|
||||
let search = props.history.location.search
|
||||
const { platform , mirror_status , bannerList , projectDetail } = props ;
|
||||
//distribution:判断此用户是否可以创建发行版
|
||||
const distribution = projectDetail && projectDetail.type ===0 && ( projectDetail.permission && projectDetail.permission !== "Reporter");
|
||||
|
||||
useEffect(()=>{
|
||||
if(bannerList && bannerList.length>0){
|
||||
let a = bannerList.filter(i=>i.menu_name === "pulls");
|
||||
|
|
@ -138,6 +140,15 @@ function CoderDepot(props){
|
|||
}
|
||||
},[projectsId,owner,pathname,defaultBranch,mirror_status])
|
||||
|
||||
// 编辑完回来重新获取
|
||||
useEffect(()=>{
|
||||
if (projectsId && owner && defaultBranch && mirror_status===0 && !search){
|
||||
let b = turnbar(branchName) ;
|
||||
let url = pathname.split(`/tree/${b}/`)[1];
|
||||
getFileInfo(url,branchName);
|
||||
}
|
||||
},[search])
|
||||
|
||||
useEffect(()=>{
|
||||
if(platform && mirror_status===0){
|
||||
setReadOnly(props.history.location.search.indexOf('edit') !== -1);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId , platform
|
|||
</span>
|
||||
<span title="init project">
|
||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.commit && item.commit.sha}`)}`} title={item.commit && item.commit.message}>
|
||||
{getEmoji(getMessage(item.commit && item.commit.message))}
|
||||
{getEmoji(getMessage(item.commit && item.commit.message.split('\n')[0]))}
|
||||
</Link>
|
||||
</span>
|
||||
<span title={item.commit && item.commit.created_at}>{item.commit && item.commit.time_from_now}</span>
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ class UserSubmitComponent extends Component {
|
|||
let b = currentBranch || branch;
|
||||
let src = `/${owner}/${projectsId}${(values.branchname ? `/tree/${turnbar(values.branchname)}` : (b ? `/tree/${turnbar(b)}`:""))}${detail.path ? `/${returnbar(detail.path)}` : ""}`;
|
||||
this.props.history.push(src);
|
||||
this.props.showNotification("文件修改成功!");
|
||||
this.props.showNotification("文件修改成功! ");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import axios from "axios";
|
|||
import { AlignCenter, AlignTop } from "../../Component/layout";
|
||||
import { Link } from "react-router-dom";
|
||||
import { getImageUrl } from "../../../common/UrlTool";
|
||||
import { ImageLayerOfCommentHOC } from "../../../modules/page/layers/ImageLayerOfCommentHOC";
|
||||
import { withRouter } from "react-router";
|
||||
const { TextArea } = Input;
|
||||
|
||||
function CreateSite(props) {
|
||||
|
|
@ -18,6 +20,11 @@ function CreateSite(props) {
|
|||
|
||||
useEffect(() => {
|
||||
document.title = "创建站点";
|
||||
setFieldsValue({
|
||||
identifier: `http://${current_user.login}.${site_page_deploy_domain || 'gitlink.net'}`,
|
||||
repository_name: `${current_user.login}.${site_page_deploy_domain || 'gitlink.net'}`,
|
||||
name: `${current_user.login}.${site_page_deploy_domain || 'gitlink.net'}`
|
||||
})
|
||||
}, []);
|
||||
|
||||
useEffect(()=>{
|
||||
|
|
@ -56,7 +63,8 @@ function CreateSite(props) {
|
|||
...values,
|
||||
clone_addr: theme && theme.clone_url,
|
||||
theme: theme && theme.name,
|
||||
user_id: current_user.user_id
|
||||
user_id: current_user.user_id,
|
||||
identifier: values.identifier.split("http://")[1]
|
||||
}).then(res=>{
|
||||
if(res && res.status === 200){
|
||||
message.success("新建成功");
|
||||
|
|
@ -94,18 +102,20 @@ function CreateSite(props) {
|
|||
>
|
||||
{getFieldDecorator("identifier", {
|
||||
rules: [{ required: true, message: "请输入站点标识" },
|
||||
{pattern: /^[a-zA-Z0-9]{2,100}$/, message: '长度2-100,只能包含数字和字母'}],
|
||||
// {pattern: /^[a-zA-Z0-9]{2,100}$/, message: '长度2-100,只能包含数字和字母'}
|
||||
],
|
||||
})(
|
||||
<Input
|
||||
onChange={(e) => {
|
||||
setTag(e.target.value);
|
||||
}}
|
||||
placeholder="请输入站点标识"
|
||||
disabled
|
||||
/>
|
||||
)}
|
||||
<span style={{wordBreak: 'break-all'}}>
|
||||
{/* <span style={{wordBreak: 'break-all'}}>
|
||||
http://{current_user.login}.{site_page_deploy_domain}/{tag}
|
||||
</span>
|
||||
</span> */}
|
||||
</Form.Item>
|
||||
<Form.Item name="建站工具" label="建站工具">
|
||||
{getFieldDecorator("language_frame", {initialValue: 0})(
|
||||
|
|
@ -124,9 +134,9 @@ function CreateSite(props) {
|
|||
<AlignTop style={{flexWrap: 'wrap'}}>
|
||||
{themes && themes.map(item=>{
|
||||
const {image, name, clone_url} = item;
|
||||
return <div className="mr20 themeBox" onClick={()=>{setTheme(item)}}>
|
||||
return <div className="mr20 themeBox imageLayerParent" onClick={()=>{setTheme(item)}}>
|
||||
<i className={`iconfont icon-wancheng ${theme && theme.clone_url === clone_url ? 'active' : ''}`}></i>
|
||||
<img src={getImageUrl(image)} alt="" width="125px" height="85px"/>
|
||||
<img src={getImageUrl(image)} alt="" width="125px" height="85px" className="imageTarget"/>
|
||||
<p className="task-hide" style={{maxWidth: '120px'}}>{name}</p>
|
||||
</div>
|
||||
})}
|
||||
|
|
@ -147,7 +157,7 @@ function CreateSite(props) {
|
|||
rules: [{ required: true, message: "请输入项目标识" },
|
||||
{pattern: /^[a-zA-Z0-9][a-zA-Z0-9_.-]{2,100}[a-zA-Z0-9]$/, message: "长度2-100,只能包含数字、字母、下划线、中划线、英文句号,必须以数字和字母开头,不能以下划线/中划线/英文句号开头和结尾"}],
|
||||
})(
|
||||
<Input placeholder="请输入项目标识"/>
|
||||
<Input placeholder="请输入项目标识" disabled/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</AlignCenter>
|
||||
|
|
@ -159,7 +169,7 @@ function CreateSite(props) {
|
|||
rules: [{ required: true, message: "请输入项目名称" },
|
||||
{type: 'string', max: 50, min: 1, message: "长度1-50"}],
|
||||
})(
|
||||
<Input placeholder="请输入项目名称"/>
|
||||
<Input placeholder="请输入项目名称" disabled/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item name="项目简介" label="项目简介">
|
||||
|
|
@ -185,4 +195,7 @@ function CreateSite(props) {
|
|||
</Fragment>
|
||||
);
|
||||
}
|
||||
export default Form.create()(CreateSite);
|
||||
export default withRouter(ImageLayerOfCommentHOC({
|
||||
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
||||
parentSelector: ".newContainer",
|
||||
})(Form.create()(CreateSite)));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
.mySites_head{
|
||||
height: 65px;
|
||||
line-height: 64px;
|
||||
border-bottom: 1px solid rgba(224, 230, 245, 1);
|
||||
color:#151d40;
|
||||
font-size:17px;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useEffect, Fragment } from "react";
|
||||
import { Button, Pagination, Spin } from "antd";
|
||||
import { Button, Pagination, Spin, Tooltip } from "antd";
|
||||
import './index.scss';
|
||||
import '../../users/Material/Index.scss';
|
||||
import '../bot/exploit/index.scss'
|
||||
|
|
@ -38,7 +38,9 @@ function MySiteList(props){
|
|||
return <Spin spinning={loading}>
|
||||
<FlexAJ className="mySites_head">
|
||||
<span>我的站点</span>
|
||||
{id_card_verify && website_permission && <Button type="primary" onClick={()=>{history.push(`/settings/mysite/create`)}}>新建站点</Button>}
|
||||
{id_card_verify && website_permission && total >= 1 ? <Tooltip title="您已存在站点,请勿重复创建">
|
||||
<Button type="primary" disabled>新建站点</Button>
|
||||
</Tooltip> : <Button type="primary" onClick={()=>{history.push(`/settings/mysite/create`)}}>新建站点</Button>}
|
||||
</FlexAJ>
|
||||
{/* 站点权限被管理员关闭 */}
|
||||
{id_card_verify && !website_permission && <div className="tipsBox font-15 mt20">您的站点权限被锁定,请联系平台管理员。</div>}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ function ServerIndex(props){
|
|||
}
|
||||
></Route>
|
||||
{/* 个人建站服务 */}
|
||||
{projectDetail && projectDetail.author.type === "User" && <Route path="/:owner/:projectsId/service/pages"
|
||||
{projectDetail && projectDetail.web_site && projectDetail.author.type === "User" && <Route path="/:owner/:projectsId/service/pages"
|
||||
render={
|
||||
() => (<Pages {...props}/>)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ function Main(props){
|
|||
<Link to={`/${owner}/${projectsId}/service/reposyncer`} className="btnhover">查看详情</Link>
|
||||
</span>
|
||||
</li> */}
|
||||
{projectDetail && projectDetail.author.type === "User" && <li>
|
||||
{/* 是站点仓库则显示,否则隐藏 */}
|
||||
{projectDetail && projectDetail.web_site && projectDetail.author.type === "User" && <li>
|
||||
<span className="servername">
|
||||
<img src={require('./img/logo.png')} alt=""/>
|
||||
<a onClick={openDetail}>个人建站服务</a>
|
||||
|
|
|
|||
|
|
@ -277,6 +277,8 @@ class Setting extends Component {
|
|||
let mirror = projectDetail && projectDetail.mirror;
|
||||
let type = projectDetail && projectDetail.type;
|
||||
const forked_from_project_id = this.props && this.props.projectDetail && this.props.projectDetail.forked_from_project_id;
|
||||
// 站点仓库不允许修改项目名称和标识
|
||||
const isWebSiteRepo = projectDetail && projectDetail.web_site;
|
||||
return (
|
||||
<div>
|
||||
<DivertModal
|
||||
|
|
@ -298,7 +300,7 @@ class Setting extends Component {
|
|||
message: "请输入项目名称",
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="请输入项目名称" />)}
|
||||
})(<Input placeholder="请输入项目名称" disabled={isWebSiteRepo}/>)}
|
||||
{
|
||||
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
|
||||
<span className="color-grey-9">该项目导入于 <a className="color-grey-6" target="_blank" href={projectDetail.mirror_url}>{projectDetail.mirror_url}</a></span>
|
||||
|
|
@ -335,7 +337,7 @@ class Setting extends Component {
|
|||
},
|
||||
],
|
||||
})(
|
||||
<Input placeholder="项目标识请使用与项目相关的英文关键字" maxLength="100" />
|
||||
<Input placeholder="项目标识请使用与项目相关的英文关键字" maxLength="100" disabled={isWebSiteRepo}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="项目简介">
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
|
|||
const content = Base64.decode(res.data.md_content);
|
||||
setContent(content);
|
||||
setFieldsValue({
|
||||
title: res.data.name,
|
||||
title: search === "?copy" ? `${res.data.name}(复制)` : res.data.name,
|
||||
md_content: content,
|
||||
});
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
|
|||
return;
|
||||
}
|
||||
const {md_content, title} = values;
|
||||
if (wikiName) {
|
||||
if (wikiName && search!== "?copy") {
|
||||
updateWiki({
|
||||
owner,
|
||||
repo: projectsId,
|
||||
|
|
@ -160,7 +160,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
|
|||
|
||||
function dealRes(res, title) {
|
||||
if (res && (res.message === "201" || res.message === "200")) {
|
||||
if(wikiName){
|
||||
if(wikiName && search!== "?copy"){
|
||||
// 如果有更改wiki文件名,则修改sidebar
|
||||
if(wikiName === title){
|
||||
message.success("操作成功");
|
||||
|
|
@ -173,7 +173,14 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
|
|||
}
|
||||
}else{
|
||||
// 根据路由判断是新增的一级页面还是子页面
|
||||
if(search.includes("?key")){
|
||||
if(search === "?copy"){
|
||||
// 截断key的前几位,获取父元素的key值
|
||||
const keyArr = key.split('-');
|
||||
keyArr.pop();
|
||||
const list = menuList;
|
||||
addChildrenByKey(list, keyArr.join('-'), title);
|
||||
updateSidebar(treeToMd(list), title);
|
||||
}else if(search.includes("?key")){
|
||||
// 遍历menuList找到相同key的节点,children push[[页面]]
|
||||
const list = menuList;
|
||||
addChildrenByKey(list, key, title);
|
||||
|
|
@ -316,7 +323,7 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
|
|||
return (
|
||||
<div className="wiki-main">
|
||||
<div className="wiki-head">
|
||||
<span className="head-title"><span className="back-wiki" onClick={goBack}>Wiki</span> <Icon type="right" /> {wikiName ? '编辑' : '新增'}页面</span>
|
||||
<span className="head-title"><span className="back-wiki" onClick={goBack}>Wiki</span> <Icon type="right" /> {wikiName ? search === "?copy" ? '复制' : '编辑' : '新增'}页面</span>
|
||||
</div>
|
||||
|
||||
<div >
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ export default (props) => {
|
|||
...firstWiki,
|
||||
key: firstWikiNode.key
|
||||
})
|
||||
if(window.location.pathname.indexOf('/wiki') === -1) return
|
||||
history.push(`/${owner}/${projectsId}/wiki/${title}/${firstWikiNode.key}`);
|
||||
} else {
|
||||
setFileArr([]);
|
||||
|
|
@ -231,8 +232,8 @@ export default (props) => {
|
|||
});
|
||||
}
|
||||
|
||||
function goEdit() {
|
||||
history.push(`/${owner}/${projectsId}/wiki/${encodeURI(checkItem.name)}/${checkItem.key}/edit`);
|
||||
function goEdit(params) {
|
||||
history.push(`/${owner}/${projectsId}/wiki/${encodeURI(checkItem.name)}/${checkItem.key}/edit${params}`);
|
||||
}
|
||||
|
||||
function preview() {
|
||||
|
|
@ -327,7 +328,8 @@ export default (props) => {
|
|||
</span>
|
||||
<span className="time-ago font-14">上次修改于{checkItem.commit ? timeAgo(checkItem.commit.author.date) : '刚刚'}</span>
|
||||
</div>
|
||||
{permission && <Button type="primary" onClick={goEdit}>编辑</Button>}
|
||||
{permission && <Button type="primary" ghost onClick={()=>{goEdit(`?copy`)}} className='mr10'>复制</Button>}
|
||||
{permission && <Button type="primary" onClick={()=>{goEdit("")}}>编辑</Button>}
|
||||
</div>
|
||||
|
||||
{itemDetail&&itemDetail.md_content&&<RenderHtml className="wiki-content-detail editor-content-panel imageLayerParent" value={ itemDetail && Base64.decode(itemDetail.md_content) } url={history.location}/>}
|
||||
|
|
|
|||
|
|
@ -179,14 +179,14 @@ export function findNodeByKey(list, key){
|
|||
}
|
||||
|
||||
// 找到children中有相同key的数组
|
||||
export function findNodeByChildrenKey(list, key){
|
||||
export function findBrotherNodesByKey(list, key){
|
||||
for (let index = 0; index < list.length; index++) {
|
||||
const element = list[index];
|
||||
if (element.key == key) {
|
||||
return list;
|
||||
}else if (element.children.length) {
|
||||
let result = findNodeByChildrenKey(element.children, key);
|
||||
if (result) {
|
||||
}else if (element.children && element.children.length) {
|
||||
let result = findBrotherNodesByKey(element.children, key);
|
||||
if (result.length) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Tree, Dropdown, Menu, message, Modal, Input } from 'antd';
|
|||
import DelModal from '../../components/ModalFun';
|
||||
import './index.scss';
|
||||
import '../../components/ModalFun/index.scss';
|
||||
import { deleteWiki, findNodeByChildrenKey, findNodeByKey, getWiki, treeToMd, updateWiki } from '../../api';
|
||||
import { deleteWiki, findBrotherNodesByKey, findNodeByKey, getWiki, treeToMd, updateWiki } from '../../api';
|
||||
import { useEffect } from 'react';
|
||||
import { Base64 } from 'js-base64';
|
||||
import { splicingTabs } from '../../utils';
|
||||
|
|
@ -356,20 +356,21 @@ export default function Sidebar(props) {
|
|||
}else{
|
||||
// isEditName 1 编辑目录名称 2编辑页面名称
|
||||
const titleToJudge = isEditName === 2 ? `[[${menuName}]]` : `- ${menuName}`;
|
||||
const {children, node, title, key} = visible;
|
||||
const list = findNodeByChildrenKey(menuList, key) || [];
|
||||
const {title, key} = visible;
|
||||
if(title.trim() === titleToJudge){
|
||||
setAddMenuError("请修改名称");
|
||||
return
|
||||
}
|
||||
// 找兄弟节点
|
||||
const list = findBrotherNodesByKey(menuList, key) || [];
|
||||
if(list.map(item=>item.title.trim()).includes(titleToJudge)){
|
||||
message.error("不能与同级目录名称相同");
|
||||
setAddMenuError("不能与同级目录名称相同");
|
||||
return
|
||||
}
|
||||
// wiki名称不可重复
|
||||
const sameNameWiki = fileArrInit.filter(item=>item.name === menuName)
|
||||
if(isEditName === 2 && sameNameWiki.length){
|
||||
message.error("wiki名称不可重复");
|
||||
setAddMenuError("wiki名称不可重复");
|
||||
return
|
||||
}
|
||||
// 编辑sidebar
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ export default function UploadWiki(props) {
|
|||
},
|
||||
beforeUpload: beforeUpload,
|
||||
onChange(info) {
|
||||
// 截取文件名称
|
||||
const fileName = info.file.name.substring(0,info.file.name.lastIndexOf("."))
|
||||
if (info.file.status === 'done') {
|
||||
if (info.file.response.message === '201') {
|
||||
// 截取文件名称
|
||||
const fileName = info.file.name.substring(0,info.file.name.lastIndexOf("."))
|
||||
// 修改sidebar文件
|
||||
if(!fileArrInit.length){
|
||||
// 仓库没有wiki文件
|
||||
|
|
@ -42,13 +42,14 @@ export default function UploadWiki(props) {
|
|||
message.success(`${fileName} 上传成功`);
|
||||
history.push(`/${owner}/${projectsId}/wiki/${encodeURI(fileName)}/0`);
|
||||
setReload(Math.random());
|
||||
} else if (info.file.response.message === '500') {
|
||||
message.error(info.file.response.data || '文件上传失败');
|
||||
} else {
|
||||
message.error('文件上传失败');
|
||||
}
|
||||
} else if (info.file.status === 'error') {
|
||||
message.error(`${info.file.name} 上传失败`);
|
||||
const {message: responseMes} = info.file.response;
|
||||
if(responseMes.indexOf('wiki page already exists') !== -1){
|
||||
message.error("已存在相同文件名的文件")
|
||||
}else{
|
||||
message.error(responseMes || `${fileName} 上传失败`);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ import { Link } from 'react-router-dom';
|
|||
import { AlignCenter } from '../../Component/layout';
|
||||
import { TagInfo } from '../../Utils/TagColor';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { truncateCommitId } from "../../common/util";
|
||||
|
||||
function Activity({list}) {
|
||||
function typeForUrl(trend_type,project,id){
|
||||
function typeForUrl(trend_type,project,id,commit_log){
|
||||
const { owner , identifier } = project;
|
||||
switch(trend_type){
|
||||
case 'Issue':
|
||||
|
|
@ -14,6 +15,9 @@ function Activity({list}) {
|
|||
return `/${owner && owner.login}/${identifier}/releases`;
|
||||
case 'PullRequest':
|
||||
return `/${owner && owner.login}/${identifier}/pulls/${id}`;
|
||||
case 'CommitLog':
|
||||
const commit = commit_log && commit_log.commit_id;
|
||||
return `/${owner && owner.login}/${identifier}/commits/${truncateCommitId(commit)}`;
|
||||
default :
|
||||
return '';
|
||||
}
|
||||
|
|
@ -32,7 +36,7 @@ function Activity({list}) {
|
|||
{i.priority && TagInfo(`${i.priority}`,"")}
|
||||
{i.issue_status && <span className="status">{i.issue_status}</span> }
|
||||
</AlignCenter>
|
||||
<p className="aDesc"><Link to={typeForUrl(i.trend_type,i.project,i.trend_id)}>{i.action_type}:{i.name}</Link></p>
|
||||
<p className="aDesc"><Link to={typeForUrl(i.trend_type,i.project,i.trend_id,i.commit_log)}>{i.action_type}:{i.name}</Link></p>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -320,7 +320,6 @@ const Glcc = (propsF) => {
|
|||
<FreeResult id={id} round={round} period={period} current_user={current_user} history={props.history}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* openmmlab列表 */}
|
||||
<Route
|
||||
path="/glcc/openmmlab"
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
cursor: pointer;
|
||||
/* 行内样式 */
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
/* height: auto !important; */
|
||||
}
|
||||
.markdown-body pre ol.linenums,.markdown-body pre ul.linenums{
|
||||
padding-left: 0px;
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
.markdown-body video{
|
||||
/* 行内样式 */
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
/* height: auto !important; */
|
||||
}
|
||||
|
||||
ol,
|
||||
|
|
|
|||
Loading…
Reference in New Issue