forked from Gitlink/forgeplus-react
issue改版2稿+用户反馈问题
This commit is contained in:
parent
3b25249b24
commit
457289ea2b
|
@ -25,7 +25,7 @@ if (isDev) {
|
|||
}
|
||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || ''
|
||||
}
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
|
|
|
@ -12,7 +12,7 @@ import axios from 'axios';
|
|||
|
||||
function EditComment(props){
|
||||
const {owner, projectsId, index} = props.match.params;
|
||||
const {current_user, current_user:{login}, showLoginDialog, showNotification, reloadComment, cancelMd, parentId, replyId, updateId} = props;
|
||||
const {current_user, current_user:{login}, showLoginDialog, showNotification, reloadComment, cancelMd, parentId, replyId, updateId, showUserImg=true} = props;
|
||||
const [content, setContent] = useState(props.content);
|
||||
const [quillFlag, setQuillFlag] = useState(false);
|
||||
// 确认评论按钮loading效果
|
||||
|
@ -80,6 +80,7 @@ function EditComment(props){
|
|||
alt=""
|
||||
width="30"
|
||||
height="30"
|
||||
style={{display: showUserImg ? '' : 'none'}}
|
||||
/>
|
||||
</Link>
|
||||
<div style={{position:"relative"}}>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Popconfirm, Radio, Input, message, Tooltip } from 'antd';
|
||||
import { Button, Popconfirm, Radio, Input, message, Tooltip, Spin } from 'antd';
|
||||
import axios from 'axios';
|
||||
import { getImageUrl, timeAgo } from 'educoder';
|
||||
import RenderHtml from '../../../../components/render-html';
|
||||
|
@ -13,7 +13,7 @@ import { Link } from 'react-router-dom';
|
|||
function IssueCommentList(props){
|
||||
const{history, history: {location}, reload, reloadComment, showNotification, current_user:{login, admin, image_url, user_id}, isManager, showLoginDialog, issueInfo:{author}} = props;
|
||||
const {owner, projectsId, index} = props.match.params;
|
||||
const [category, setCategory] = useState('all');
|
||||
const [category, setCategory] = useState('comment');
|
||||
const [journals, setJournals] = useState(undefined);
|
||||
// 是否展示新建/编辑评论markdown部分新建评论1 编辑父级评论2 回复评论3 编辑回复内容4 回复子机评论5
|
||||
const [showEdit, setShowEdit] = useState(false);
|
||||
|
@ -23,6 +23,8 @@ function IssueCommentList(props){
|
|||
const [updateId, setUpdateId] = useState(undefined);
|
||||
// 操作日志展开效果
|
||||
const [open, setOpen] = useState(undefined);
|
||||
// 加载中效果(缓冲css 线条效果)
|
||||
const [spin, setSpin] = useState(false);
|
||||
// 操作记录 icon
|
||||
const journalsIcon ={
|
||||
'issue': 'icon-chuangjianqianbao',
|
||||
|
@ -40,6 +42,7 @@ function IssueCommentList(props){
|
|||
}
|
||||
|
||||
useEffect(()=>{
|
||||
setSpin(true);
|
||||
axios.get(`/v1/${owner}/${projectsId}/issues/${index}/journals`,{params:{
|
||||
category
|
||||
}}).then(res=>{
|
||||
|
@ -70,12 +73,13 @@ function IssueCommentList(props){
|
|||
})
|
||||
}
|
||||
setJournals(journals);
|
||||
setSpin(false)
|
||||
}
|
||||
})
|
||||
}, [reload, category])
|
||||
|
||||
function commentCtx(v){
|
||||
return <RenderHtml className="break_word_comments imageLayerParent" value={v} url={location}/>;
|
||||
return <RenderHtml className="break_word_comments imageLayerParent commentRenderHtml" value={v} url={location}/>;
|
||||
};
|
||||
|
||||
// 删除评论内容
|
||||
|
@ -95,13 +99,21 @@ function IssueCommentList(props){
|
|||
|
||||
return(
|
||||
<div className="commentListBox">
|
||||
{/* 全部 / 评论 / 操作日志 */}
|
||||
<div className='typeActionBox mt30 mb20'>
|
||||
<Radio.Group onChange={(e)=>{setSpin(true);setCategory(e.target.value)}} value={category}>
|
||||
<Radio value={'comment'} className='typeActionRadio font-14'>评论</Radio>
|
||||
<Radio value={'operate'} className='typeActionRadio font-14'>操作日志</Radio>
|
||||
<Radio value={'all'} className='typeActionRadio font-14'>全部</Radio>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
{/* 添加评论 */}
|
||||
<div className="pt20 pb30">
|
||||
{login ? showEdit === 1 ? <EditComment {...props} cancelMd={cancelMd}/> : <div className="addcomments">
|
||||
<div className="pt5 pb25">
|
||||
{login ? showEdit === 1 ? <EditComment {...props} cancelMd={cancelMd}/> : <div className="addComments">
|
||||
<img src={getImageUrl(image_url)} alt="" />
|
||||
<div style={{flex:1}}>
|
||||
<CheckProfile {...props} sureFunc={()=>{setShowEdit(1)}}>
|
||||
<Input placeholder="添加评论" style={{width:"100%",height:"36px"}}/>
|
||||
<Input className='addCommentBox' placeholder="添加评论"/>
|
||||
</CheckProfile>
|
||||
</div>
|
||||
</div> : <div className='unLoginComment font-15 pl20'>
|
||||
|
@ -109,107 +121,104 @@ function IssueCommentList(props){
|
|||
<a className='mr5 loginBtn' onClick={()=>{showLoginDialog()}}>登录</a>并参与评论与回复
|
||||
</div>}
|
||||
</div>
|
||||
{/* 全部 / 评论 / 操作日志 */}
|
||||
<div className='typeActionBox mb20'>
|
||||
<Radio.Group onChange={(e)=>{setCategory(e.target.value)}} value={category}>
|
||||
<Radio value={'all'} className='typeActionRadio font-16'>全部</Radio>
|
||||
<Radio value={'comment'} className='typeActionRadio font-16'>评论</Radio>
|
||||
<Radio value={'operate'} className='typeActionRadio font-16'>操作日志</Radio>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
{/* 评论/操作日志 展示列表 */}
|
||||
<div className='commentsBox'>
|
||||
{journals && (journals.length > 0 && journals.map(item=>{return item.is_journal_detail ? (!item.closeAndSpan || item.id === item.start || open === item.start) ? <div key={item.id} className='operationLog'>
|
||||
{/* 操作日志 */}
|
||||
<div className='operationLogTopBor'></div>
|
||||
<div className='flexCenter font-15'>
|
||||
<div className='flexCenter'>
|
||||
<span className='iconBackBox mr10'><i className={`iconfont font-12 ${journalsIcon[item.operate_category]}`}></i></span>
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr5'/></Link>
|
||||
<Link to={`/${item.user.login}`}>{item.user.name} </Link>
|
||||
<Tooltip title={<div><span>{item.user.name} </span><span dangerouslySetInnerHTML={{__html:item.operate_content}}></span></div>}><span className='task-hide' dangerouslySetInnerHTML={{__html:item.operate_content}} style={{maxWidth: '450px'}}></span></Tooltip>
|
||||
<span className='ml15 timeAgo'>{timeAgo(item.created_at)}</span>
|
||||
</div>
|
||||
{(item.closeAndSpan && item.id === item.start) && <a className='primaryColor' onClick={()=>{setOpen(open === item.id ? undefined : item.id)}}>{open === item.id ? `点击收起操作日志` : `已折叠${item.numCount}条, 点击查看`}</a>}
|
||||
</div>
|
||||
<div className='operationLogBottomBor'></div>
|
||||
</div> : '' : <div key={item.id} className='commentContentBox'>
|
||||
{/* 评论 */}
|
||||
{/* 判断是否是编辑状态 */}
|
||||
{(showEdit === 2 && updateId === item.id) ? <div className='mt15 mr20'><EditComment {...props} cancelMd={cancelMd} updateId={updateId} reloadComment={reloadComment} content={item.notes} defaultFileList={item.attachments}/></div> : <div>
|
||||
<div className='issueCommentTopBor'></div>
|
||||
<div className='commentContent'>
|
||||
<div className='flexCenter mt15 font-15'>
|
||||
<div>
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr8'/></Link>
|
||||
<Link to={`/${item.user.login}`}>{item.user.name}</Link>
|
||||
<span className='ml15 timeAgo'>{timeAgo(item.created_at)}</span>
|
||||
<Spin spinning={spin}>
|
||||
<div className={`issueCommentsBox ${category === 'comment' && !spin && 'justComment'}`}>
|
||||
{journals && (journals.length > 0 && journals.map(item=>{return item.is_journal_detail ? (!item.closeAndSpan || item.id === item.start || open === item.start) ? <div key={item.id} className='operationLog'>
|
||||
{/* 操作日志 */}
|
||||
<div className='operationCommentBor'></div>
|
||||
<div className='flexCenter font-13' style={{flex: 1}}>
|
||||
<div className='flexCenter opBox'>
|
||||
<span className='iconBackBox mr10'><i className={`iconfont font-12 ${journalsIcon[item.operate_category]}`}></i></span>
|
||||
<div className='task-hide' style={{flex: '1'}}>
|
||||
<Link to={`/${item.user.login}`}><img src={getImageUrl(item.user.image_url)} alt="" className='commentUserImg mr5'/></Link>
|
||||
<Link to={`/${item.user.login}`}>{item.user.name} </Link>
|
||||
{(item.user.name.length + item.operate_content.length) > 62 ? <Tooltip title={<div><span>{item.user.name} </span><span dangerouslySetInnerHTML={{__html:item.operate_content}}></span></div>}><span dangerouslySetInnerHTML={{__html:item.operate_content}}></span></Tooltip> : <span dangerouslySetInnerHTML={{__html:item.operate_content}}></span>}
|
||||
</div>
|
||||
{login && <div>
|
||||
{/* 平台管理员/仓库管理员/发布评论者/issue创建者 */}
|
||||
{(admin || isManager || login === item.user.login || user_id === author.id) && <Popconfirm
|
||||
placement="bottom"
|
||||
title={`确定要删除此条评论吗?${item.children_journals.length > 0 ? '子评论也将被一起删除。' : ''}`}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() => deleteComment(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-13 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-13 mr8'></i>回复</Button></CheckProfile>
|
||||
</div>}
|
||||
<span className='ml15 timeAgo font-12'>{timeAgo(item.created_at)}</span>
|
||||
</div>
|
||||
<div className='contentHtml mb15 mt5'>{commentCtx(item.notes)}</div>
|
||||
{item && item.attachments && item.attachments.length > 0 && <div className='attachmentBox'><Attachment
|
||||
attachments={item.attachments}
|
||||
showNotification={showNotification}
|
||||
canDelete={false}
|
||||
/></div>}
|
||||
{(item.closeAndSpan && item.id === item.start) && <a className='primaryColor' onClick={()=>{setOpen(open === item.id ? undefined : item.id)}}>{open === item.id ? `点击收起操作日志` : `已折叠${item.numCount}条, 点击查看`}<i className={`iconfont ${open === item.id ? `icon-sanjiaoxing-up` : 'icon-sanjiaoxing-down'} font-15`}></i></a>}
|
||||
</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='mt15 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>
|
||||
<span className='ml5 timeAgo mr3'>回复</span>
|
||||
<span>{i.reply_user.name}</span>
|
||||
<span className='ml15 timeAgo'>{timeAgo(i.created_at)}</span>
|
||||
</div> : '' : <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-15'>{timeAgo(item.created_at)}</span>
|
||||
</div>
|
||||
{login && <div>
|
||||
{/* 平台管理员/仓库管理员/发布评论者/issue创建者 */}
|
||||
{(admin || isManager || login === item.user.login || user_id === author.id) && <Popconfirm
|
||||
placement="bottom"
|
||||
title={`确定要删除此条评论吗?${item.children_journals.length > 0 ? '子评论也将被一起删除。' : ''}`}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() => deleteComment(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-13 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-13 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>
|
||||
{login && <div>
|
||||
{/* 平台管理员/仓库管理员/发布评论者/回复评论者/issue创建者 */}
|
||||
{(admin || isManager || login === i.user.login || login === i.reply_user.login || user_id === author.id) && <Popconfirm
|
||||
placement="bottom"
|
||||
title={"确定要删除当前回复吗?"}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() => deleteComment(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-13 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-13 mr8'></i>回复</Button>
|
||||
</CheckProfile>
|
||||
</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>
|
||||
<span className='ml5 timeAgo mr3'>回复</span>
|
||||
<span>{i.reply_user.name}</span>
|
||||
<span className='ml15 timeAgo font-15'>{timeAgo(i.created_at)}</span>
|
||||
</div>
|
||||
{login && <div>
|
||||
{/* 平台管理员/仓库管理员/发布评论者/回复评论者/issue创建者 */}
|
||||
{(admin || isManager || login === i.user.login || login === i.reply_user.login || user_id === author.id) && <Popconfirm
|
||||
placement="bottom"
|
||||
title={"确定要删除当前回复吗?"}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() => deleteComment(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-13 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-13 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>}
|
||||
</div>
|
||||
<div className='contentHtml mt5'>{commentCtx(i.notes)}</div>
|
||||
{i && i.attachments && i.attachments.length > 0 && <div className='ml30'><Attachment
|
||||
attachments={i.attachments}
|
||||
showNotification={showNotification}
|
||||
canDelete={false}
|
||||
/></div>}
|
||||
</div>}
|
||||
{showEdit === 5 && replyId === i.id && <div className='contentHtml mt20 mr20'><EditComment {...props} cancelMd={cancelMd} parentId={parentId} replyId={replyId} reloadComment={reloadComment}/></div>}
|
||||
</div>})}
|
||||
<div className='issueCommentBottomBor'></div></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>
|
||||
{/* 无数据 */}
|
||||
{journals && !journals.length && <Nodata _html="暂无数据"/>}
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
.typeActionBox{
|
||||
padding: 17px 20px 10px;
|
||||
background-color:#fafcff;
|
||||
border:1px solid rgba(42, 97, 255, 0.23);
|
||||
padding: 10px 20px 4px;
|
||||
background-color:rgba(241, 243, 252, 0.55);
|
||||
border-radius:4px;
|
||||
.typeActionRadio{
|
||||
color: #333;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-right: 35px;
|
||||
margin-right: 25px;
|
||||
&.ant-radio-wrapper-checked{
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.commentUserImg{
|
||||
|
@ -16,7 +18,7 @@
|
|||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.commentsBox{
|
||||
.issueCommentsBox{
|
||||
.iconBackBox{
|
||||
display: inline-block;
|
||||
width:24px;
|
||||
|
@ -26,43 +28,115 @@
|
|||
text-align: center;
|
||||
background-color:#f2f3f5;
|
||||
}
|
||||
.operationLogTopBor, .operationLogBottomBor{
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
background-color:#eeeeee;
|
||||
margin-left: 12px;
|
||||
.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%;
|
||||
}
|
||||
}
|
||||
.operationLogTopBor{
|
||||
margin-bottom: -3px;
|
||||
.commentContentBox+.operationLog .operationCommentBor, .operationLog+.commentContentBox .commentOperationBor{
|
||||
border-top: 1px solid #eee;
|
||||
width: 98.5%;
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
}
|
||||
.operationLogBottomBor{
|
||||
margin-top: -4px;
|
||||
.operationLog+.commentContentBox{
|
||||
&>a, &>.commentContentRight{
|
||||
margin-top: 25px;
|
||||
}
|
||||
}
|
||||
.timeAgo{
|
||||
color:#acb0bf;
|
||||
}
|
||||
.operationLog:last-child .operationLogBottomBor, .operationLog:first-child .operationLogTopBor{
|
||||
.operationLog:last-child::after, .operationLog:first-child::before, .commentContentBox:last-child::after, &.justComment .commentContentBox::before, &.justComment .commentContentBox::after{
|
||||
display: none;
|
||||
}
|
||||
.commentContent, .commentContentBox+.operationLog{
|
||||
border-top: 1px solid #eeeeee;
|
||||
.operationLog:first-child, .commentContentBox+.operationLog{
|
||||
margin-top: -15px;
|
||||
}
|
||||
.commentContentBox:first-of-type .commentContent{
|
||||
border-top: none;
|
||||
.commentContentBox:last-child::before{
|
||||
height: 35%;
|
||||
}
|
||||
.flexCenter{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.contentHtml, .commentReply{
|
||||
margin-left: 34px;
|
||||
.commentRenderHtml.markdown-body p{
|
||||
font-size: 13px !important;
|
||||
}
|
||||
.commentReply{
|
||||
padding: 15px 0 15px 20px;
|
||||
padding: 15px 0 0 20px;
|
||||
background-color: rgba(238, 240, 246, 0.41);
|
||||
&+.commentReply{
|
||||
border-top: 1px dashed #eeeeee;
|
||||
&>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;
|
||||
}
|
||||
.commentContentRight{
|
||||
flex: 1;
|
||||
background-color:#fafafc;
|
||||
border:1px solid rgba(42, 97, 255, 0.23);
|
||||
border-radius:6px;
|
||||
position: relative;
|
||||
top: -6px;
|
||||
padding: 10px 15px 16px;
|
||||
&::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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,14 +145,12 @@
|
|||
}
|
||||
.attachmentBox{
|
||||
margin-top: -8px;
|
||||
margin-left: 27px;
|
||||
}
|
||||
.color-grey-89{
|
||||
color: #898d9d;
|
||||
}
|
||||
// 添加评论样式
|
||||
.unLoginComment{
|
||||
width:871px;
|
||||
height:58px;
|
||||
line-height: 58px;
|
||||
background-color:rgba(241, 243, 252, 0.55);
|
||||
|
@ -92,4 +164,22 @@
|
|||
color: red;
|
||||
margin-top: -10px;
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
.addComments{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color:rgba(241, 243, 252, 0.55);
|
||||
border-radius:4px;
|
||||
padding:7px 10px;
|
||||
&>img{
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
border-radius: 50%;
|
||||
margin-right: 13px;
|
||||
}
|
||||
}
|
||||
.addCommentBox{
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
border: none;
|
||||
}
|
|
@ -652,20 +652,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 评论相关
|
||||
.addcomments{
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
background-color:rgba(241, 243, 252, 0.55);
|
||||
border-radius:4px;
|
||||
padding:11px 20px;
|
||||
&>img{
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
border-radius: 50%;
|
||||
margin-right: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.overlaydrop{
|
||||
&.large{
|
||||
width: 260px;
|
||||
|
|
|
@ -263,16 +263,10 @@ function Index(props) {
|
|||
// 新建分支按钮点击函数
|
||||
function addBranchBtn(){
|
||||
setAddBranch(true);
|
||||
const url = `/v1/${owner}/${projectsId}/branches.json`;
|
||||
Axios.get(url,{
|
||||
params:{
|
||||
page: 1,
|
||||
limit: total
|
||||
}
|
||||
}).then(result=>{
|
||||
const url = `/v1/${owner}/${projectsId}/branches/all.json`;
|
||||
Axios.get(url).then(result=>{
|
||||
if(result){
|
||||
const {branches} = result.data;
|
||||
setBranchList(branches);
|
||||
setBranchList(result.data);
|
||||
}
|
||||
}).catch(error=>{console.log('error', error);})
|
||||
}
|
||||
|
@ -393,7 +387,7 @@ function Index(props) {
|
|||
<Input placeholder='请输入分支名称' className='createBranchInput' onChange={checkNewBranchName} maxLength={100}/>
|
||||
<div className='newBranchError mt5'>{newBranchError}</div>
|
||||
<div className='font-15 createBranchLabel mt20'>分支起点</div>
|
||||
<Select showSearch style={{width: '340px'}} className='createBranchInput' defaultValue={list[0] && list[0].name} onChange={(value)=>{setNewFormBranchName(value)}} getPopupContainer={triggerNode => triggerNode.parentNode}>
|
||||
<Select showSearch style={{width: '340px'}} className='createBranchInput' placeholder="请选择分支起点" onChange={(value)=>{setNewFormBranchName(value)}} getPopupContainer={triggerNode => triggerNode.parentNode}>
|
||||
{branchList && branchList.map((item, index)=>{
|
||||
return <Select.Option value={item.name} key={index}>{item.name}</Select.Option>
|
||||
})}
|
||||
|
|
|
@ -15,7 +15,9 @@ class Milepost extends Component {
|
|||
// 里程碑 开启/关闭 状态
|
||||
status: 'open',
|
||||
order_name: undefined,
|
||||
spinings: true
|
||||
spinings: true,
|
||||
// tooltip显隐
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
componentDidUpdate(){
|
||||
|
@ -129,8 +131,16 @@ class Milepost extends Component {
|
|||
this.getList(1, pageSize, this.state.status, this.state.order_name, this.state.order_type);
|
||||
}
|
||||
|
||||
// tooltip判断是否显示
|
||||
// onVisibleChange = (visible, value) => {
|
||||
// console.log('visible, value', visible, value);
|
||||
// this.setState({
|
||||
// visible: value.length >24 ? visible : false
|
||||
// })
|
||||
// }
|
||||
|
||||
render() {
|
||||
const { data, limit, page, spinings, status, order_name, order_type } = this.state;
|
||||
const { data, limit, page, spinings, status, order_name, order_type, visible } = this.state;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { isManager, isDeveloper} = this.props;
|
||||
const menu = (
|
||||
|
@ -168,18 +178,21 @@ class Milepost extends Component {
|
|||
<Spin spinning={spinings}>
|
||||
<div className="main milepostBox">
|
||||
{/* 创建里程碑按钮 */}
|
||||
<div className='createMilepost mb25'>
|
||||
{/* <div className='createMilepost mb25'>
|
||||
{(isManager || isDeveloper) && <Button type='primary' onClick={() => {this.props.history.push(`/${owner}/${projectsId}/milestones/new`)}} className='createMilepostBtn'>+ 创建里程碑</Button>}
|
||||
</div>
|
||||
</div> */}
|
||||
{/* 里程碑列表表头 */}
|
||||
<div className='milepostHead flexSpaceBetween'>
|
||||
<div>
|
||||
<span className={`pointBox font-15 postStatus ${status === "closed" ? "" : "active"}`} onClick={() => this.opneMilelist(1)}>开启中<span className='statusCount font-13'>{data && data.opening_milestone_count}</span></span>
|
||||
<span className={`pointBox ml35 font-15 postStatus ${status === "closed" ? "active" : ""}`} onClick={() => this.opneMilelist(2)}>已关闭<span className='statusCount font-13'>{data && data.closed_milestone_count}</span></span>
|
||||
</div>
|
||||
<div>
|
||||
{(isManager || isDeveloper) && <Button type='primary' onClick={() => {this.props.history.push(`/${owner}/${projectsId}/milestones/new`)}} className='createMilepostBtn mr20'>+ 创建里程碑</Button>}
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span className='pointBox'>{order_name ? sortByMile[order_name][order_type] : '排序'}<Icon type="caret-down" className="ml5"/></span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
{/* 里程碑列表展示 */}
|
||||
{data && data.milestones && data.milestones.length === 0 && <div className="milestonesNoDate"><img src={emp} alt=""/></div>}
|
||||
|
@ -191,12 +204,12 @@ class Milepost extends Component {
|
|||
<i className="iconfont icon-lichengbeiicon1 font-12 mr10 primaryColor"></i>
|
||||
<Link to={`/${owner}/${projectsId}/milestones/${item.id}`} className="font-16 task-hide milepostInfo">{item.name}</Link>
|
||||
</div>
|
||||
<Tooltip title={item.description} placement={'topLeft'} overlayStyle={{width: '600px'}}><span className='color-grey-89 task-hide milepostInfo'>{item.description}</span></Tooltip>
|
||||
{item.description && item.description.length > 44 ? <Tooltip title={item.description} placement={'topLeft'} overlayStyle={{width: '600px'}}><span className='color-grey-89 task-hide milepostInfo'>{item.description}</span></Tooltip> : <span className='color-grey-89 milepostInfo'>{item.description}</span>}
|
||||
</div>
|
||||
<div className="flexSpaceBetween actionMileBox">
|
||||
<div className="grid-item effectiveDate">
|
||||
<i className={`iconfont icon-a-31shijian font-15 mr10 ${item.effective_date ? "effectiveDate" : "color-grey-89"}`}></i>
|
||||
<span className={item.effective_date ? "" : "color-grey-89"}>{item.effective_date || "暂无截止时间"}</span>
|
||||
<span className={`${item.effective_date ? "" : "color-grey-89"} ${item.effective_date && status !== 'closed' && new Date().getTime()-new Date(`${item.effective_date} 24:0`).getTime() > 0 ? 'outTime' : ''}`}>{item.effective_date || "暂无截止时间"}</span>
|
||||
</div>
|
||||
<div className="mr10 effectiveDate">
|
||||
<span>{item.opened_issues_count || 0}个开启</span>
|
||||
|
|
|
@ -52,10 +52,13 @@
|
|||
}
|
||||
.milepostInfo{
|
||||
display: inline-block;
|
||||
width: 500px;
|
||||
width: 640px;
|
||||
}
|
||||
.actionMileBox{
|
||||
width: 550px;
|
||||
.outTime{
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
.createMilepostBtn{
|
||||
|
|
|
@ -20,7 +20,7 @@ export default Form.create()(
|
|||
function checkPsd(rule, value, callback){
|
||||
const map = passMap;
|
||||
if(value){
|
||||
current_user && Axios.post(`/v1/${current_user.login}/check_password.json`,{
|
||||
current_user && value.length > 8 && Axios.post(`/v1/${current_user.login}/check_password.json`,{
|
||||
password: value
|
||||
}).then(res=>{
|
||||
if(res && !res.data.status){
|
||||
|
@ -50,7 +50,7 @@ export default Form.create()(
|
|||
callback("请先输入登录密码");
|
||||
}
|
||||
if(value){
|
||||
current_user && value && value.length > 4 && Axios.post(`/v1/${current_user.login}/check_phone_verify_code.json`,{
|
||||
current_user && value && value.length > 5 && Axios.post(`/v1/${current_user.login}/check_phone_verify_code.json`,{
|
||||
code_type: 4,
|
||||
phone: phoneValue,
|
||||
code: value
|
||||
|
@ -192,7 +192,7 @@ export default Form.create()(
|
|||
{required:true,message:"请输入登录密码"},
|
||||
{validator:(rule, value, callback)=>checkPsd(rule, value, callback)}
|
||||
],
|
||||
validateTrigger:"onBlur",
|
||||
validateTrigger:"onChange",
|
||||
})(
|
||||
<Input.Password placeholder="请输入登录密码" autoComplete={"new-password"} style={{width:"400px"}}/>
|
||||
)}
|
||||
|
@ -203,7 +203,7 @@ export default Form.create()(
|
|||
{required:true,message:"请输入新手机号码"},
|
||||
{validator:(rule, value, callback)=>checkPhone(rule, value, callback)}
|
||||
],
|
||||
validateTrigger:"onBlur",
|
||||
validateTrigger:"onChange",
|
||||
})(
|
||||
<Input placeholder="请输入新手机号码" style={{width:"400px"}} autoComplete={"off"}/>
|
||||
)}
|
||||
|
@ -215,7 +215,7 @@ export default Form.create()(
|
|||
{required:true,message:"请输入短信验证码"},
|
||||
{validator:(rule, value, callback)=>checkCode(rule, value, callback)}
|
||||
],
|
||||
validateTrigger:"onBlur",
|
||||
validateTrigger:"onChange",
|
||||
})(
|
||||
<Input placeholder="请输入短信验证码" style={{width:"400px"}}/>
|
||||
)}
|
||||
|
|
Loading…
Reference in New Issue