mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-04 16:31:13 +00:00
Draft review (#2416)
This commit is contained in:
@@ -47,8 +47,22 @@ class DraftListItem extends React.Component {
|
||||
onDraftEditClick = () => {
|
||||
let draft = this.props.draft;
|
||||
let filePath = draft.draft_file_path;
|
||||
let repoID = draft.draft_repo_id;
|
||||
window.location.href= siteRoot + 'lib/' + repoID + '/file' + filePath + '?mode=edit';
|
||||
let repoID = draft.origin_repo_id;
|
||||
let url = siteRoot + 'lib/' + repoID + '/file' + filePath + '?mode=edit&draft_id=' + draft.id;
|
||||
window.open(url)
|
||||
}
|
||||
|
||||
onLibraryClick = () => {
|
||||
let draft = this.props.draft;
|
||||
let repoID = draft.origin_repo_id;
|
||||
let url = siteRoot + '#common/lib/' + repoID;
|
||||
window.open(url)
|
||||
}
|
||||
|
||||
onReviewClick = () => {
|
||||
let draft = this.props.draft;
|
||||
let url = siteRoot + 'drafts/review/' + draft.review_id + '/';
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
getFileName(filePath) {
|
||||
@@ -65,13 +79,19 @@ class DraftListItem extends React.Component {
|
||||
<tr className={this.state.highlight} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
||||
<td className="icon"><img src={siteRoot + 'media/img/file/192/txt.png'} /></td>
|
||||
<td className="name a-simulate" onClick={this.onDraftEditClick}>{fileName}</td>
|
||||
<td className="owner">{draft.owner}</td>
|
||||
<td className="library a-simulate" onClick={this.onLibraryClick}>{draft.repo_name}</td>
|
||||
<td className="review">
|
||||
{ draft.review_id && draft.review_status === 'open' ? <span className="a-simulate" onClick={this.onReviewClick}>#{draft.review_id}</span> : <span>--</span> }
|
||||
</td>
|
||||
<td className="update">{localTime}</td>
|
||||
<td className="menu-toggle">
|
||||
<NodeMenuControl
|
||||
isShow={this.state.isMenuControlShow}
|
||||
onClick={this.onMenuToggleClick}
|
||||
/>
|
||||
{
|
||||
this.props.draft.review_status !== 'open' &&
|
||||
<NodeMenuControl
|
||||
isShow={this.state.isMenuControlShow}
|
||||
onClick={this.onMenuToggleClick}
|
||||
/>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
@@ -13,18 +13,28 @@ class DraftListMenu extends React.Component {
|
||||
|
||||
render() {
|
||||
let style = {};
|
||||
let {isMenuShow, menuPosition} = this.props;
|
||||
let {isMenuShow, menuPosition, currentDraft} = this.props;
|
||||
if (isMenuShow) {
|
||||
style = {position: 'fixed', top: menuPosition.top, left: menuPosition.left, display: 'block'};
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
if (currentDraft.review_status === null) {
|
||||
return (
|
||||
<ul className="dropdown-menu" style={style}>
|
||||
<li className="dropdown-item" onClick={this.props.onDeleteHandler}>{gettext('Delete')}</li>
|
||||
<li className="dropdown-item" onClick={this.props.onPublishHandler}>{gettext('Publish')}</li>
|
||||
<li className="dropdown-item" onClick={this.props.onReviewHandler}>{gettext('Ask for review')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
if (currentDraft.review_status === 'closed' ) {
|
||||
return (
|
||||
<ul className="dropdown-menu" style={style}>
|
||||
<li className="dropdown-item" onClick={this.props.onDeleteHandler}>{gettext('Delete')}</li>
|
||||
<li className="dropdown-item" onClick={this.props.onReviewHandler}>{gettext('Ask for review')}</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -20,8 +20,9 @@ class DraftListView extends React.Component {
|
||||
<tr>
|
||||
<th style={{width: '4%'}}>{/*img*/}</th>
|
||||
<th style={{width: '46%'}}>{gettext('Name')}</th>
|
||||
<th style={{width: '20%'}}>{gettext('Owner')}</th>
|
||||
<th style={{width: '20%'}}>{gettext('Last Update')}</th>
|
||||
<th style={{width: '20%'}}>{gettext('Library')}</th>
|
||||
<th style={{width: '10%'}}>{gettext('Review')}</th>
|
||||
<th style={{width: '10%'}}>{gettext('Last Update')}</th>
|
||||
<th style={{width: '10%'}}></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@@ -147,13 +147,13 @@ class MainSideNav extends React.Component {
|
||||
<h3 className="sf-heading">Tools</h3>
|
||||
<ul className="side-tabnav-tabs">
|
||||
<li className={`tab ${this.state.currentTab === 'starred' ? 'tab-cur' : ''}`}>
|
||||
<a href={siteRoot + 'starred/'} title={gettext('Favorites')} onClick={() => this.tabItemClick('favorites')}>
|
||||
<Link to={siteRoot + 'starred/'} title={gettext('Favorites')} onClick={() => this.tabItemClick('favorites')}>
|
||||
<span className="sf2-icon-star" aria-hidden="true"></span>
|
||||
{gettext('Favorites')}
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li className={`tab ${this.state.currentTab === 'dashboard' ? 'tab-cur' : ''}`}>
|
||||
<Link to={siteRoot + 'dashboard'} title={gettext('Acitivities')} onClick={() => this.tabItemClick('dashboard')}>
|
||||
<Link to={siteRoot + 'dashboard/'} title={gettext('Acitivities')} onClick={() => this.tabItemClick('dashboard')}>
|
||||
<span className="sf2-icon-clock" aria-hidden="true"></span>
|
||||
{gettext('Acitivities')}
|
||||
</Link>
|
||||
@@ -165,7 +165,7 @@ class MainSideNav extends React.Component {
|
||||
</a>
|
||||
</li>
|
||||
<li className={`tab ${this.state.currentTab === 'drafts' ? 'tab-cur' : ''}`} onClick={() => this.tabItemClick('drafts')}>
|
||||
<Link to={siteRoot + 'drafts'} title={gettext('Drafts')}>
|
||||
<Link to={siteRoot + 'drafts/'} title={gettext('Drafts')}>
|
||||
<span className="sf2-icon-edit" aria-hidden="true"></span>
|
||||
{gettext('Drafts')}
|
||||
</Link>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { processor, processorGetAST } from '@seafile/seafile-editor/src/lib/seafile-markdown2html';
|
||||
import { processor, processorGetAST } from '@seafile/seafile-editor/dist/utils/seafile-markdown2html';
|
||||
import Prism from 'prismjs';
|
||||
import WikiOutline from './wiki-outline';
|
||||
|
||||
@@ -7,7 +7,7 @@ var URL = require('url-parse');
|
||||
|
||||
const gettext = window.gettext;
|
||||
|
||||
require('@seafile/seafile-editor/src/lib/code-hight-package');
|
||||
require('@seafile/seafile-editor/dist/editor/code-hight-package');
|
||||
|
||||
const contentClass = "wiki-md-viewer-rendered-content";
|
||||
|
||||
|
68
frontend/src/components/review-list-view/review-list-item.js
Normal file
68
frontend/src/components/review-list-view/review-list-item.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { siteRoot, lang } from '../../utils/constants';
|
||||
import moment from 'moment';
|
||||
|
||||
moment.locale(lang);
|
||||
const propTypes = {
|
||||
isItemFreezed: PropTypes.bool.isRequired,
|
||||
}
|
||||
class ReviewListItem extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
highlight: '',
|
||||
};
|
||||
}
|
||||
|
||||
onMouseEnter = () => {
|
||||
if (!this.props.isItemFreezed) {
|
||||
this.setState({
|
||||
highlight: 'tr-highlight'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onMouseLeave = () => {
|
||||
if (!this.props.isItemFreezed) {
|
||||
this.setState({
|
||||
highlight: ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onReviewsClick = () => {
|
||||
let item = this.props.item;
|
||||
let filePath = item.draft_file_path;
|
||||
let itemID = item.id;
|
||||
window.open(siteRoot + 'drafts/review/' + itemID);
|
||||
}
|
||||
|
||||
getFileName(filePath) {
|
||||
let lastIndex = filePath.lastIndexOf("/");
|
||||
return filePath.slice(lastIndex+1);
|
||||
}
|
||||
|
||||
render() {
|
||||
let item = this.props.item;
|
||||
let fileName = this.getFileName(item.draft_file_path);
|
||||
let localTime = moment.utc(item.updated_at).toDate();
|
||||
localTime = moment(localTime).fromNow();
|
||||
|
||||
return (
|
||||
<tr className={this.state.highlight} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
||||
<td className="icon" style={{width: "4%"}}><img src={siteRoot + "media/img/file/192/txt.png"} /></td>
|
||||
<td className="name a-simulate" style={{width: "46%"}} onClick={this.onReviewsClick}>{fileName}</td>
|
||||
<td className='library'>{item.draft_origin_repo_name}</td>
|
||||
<td className="status" style={{width: "20%"}}>{item.status}</td>
|
||||
<td className="update" style={{width: "20%"}}>{localTime}</td>
|
||||
<td className="menu-toggle"></td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReviewListItem.propTypes = propTypes;
|
||||
|
||||
export default ReviewListItem;
|
47
frontend/src/components/review-list-view/review-list-view.js
Normal file
47
frontend/src/components/review-list-view/review-list-view.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import ReviewListItem from './review-list-item';
|
||||
|
||||
const propTypes = {
|
||||
isItemFreezed: PropTypes.bool.isRequired,
|
||||
itemsList: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
class ReviewListView extends React.Component {
|
||||
|
||||
render() {
|
||||
let items = this.props.itemsList;
|
||||
return (
|
||||
<div className="table-container">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{width: '4%'}}>{/*img*/}</th>
|
||||
<th style={{width: '26%'}}>{gettext('Name')}</th>
|
||||
<th style={{width: '20%'}}>{gettext('Library')}</th>
|
||||
<th style={{width: '20%'}}>{gettext('Status')}</th>
|
||||
<th style={{width: '20%'}}>{gettext('Last Update')}</th>
|
||||
<th style={{width: '10%'}}></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ items && items.map((item) => {
|
||||
return (
|
||||
<ReviewListItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
isItemFreezed={this.props.isItemFreezed}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReviewListView.propTypes = propTypes;
|
||||
|
||||
export default ReviewListView;
|
Reference in New Issue
Block a user