1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-09 19:01:42 +00:00

root path show file_tag && tagged_files_count (#2715)

This commit is contained in:
王健辉
2019-01-02 16:45:40 +08:00
committed by Daniel Pan
parent 1d675cfc45
commit 01bc288865
9 changed files with 198 additions and 2 deletions

View File

@@ -12,6 +12,7 @@ import DirentDetail from '../dirent-detail/dirent-details';
import FileUploader from '../file-uploader/file-uploader';
import ModalPortal from '../modal-portal';
import LibDecryptDialog from '../dialog/lib-decrypt-dialog';
import FileTagsViewer from '../../components/filetags-viewer';
const propTypes = {
currentRepoInfo: PropTypes.object,
@@ -46,6 +47,7 @@ const propTypes = {
updateDirent: PropTypes.func.isRequired,
onSearchedClick: PropTypes.func.isRequired,
onFileUploadSuccess: PropTypes.func.isRequired,
usedRepoTags: PropTypes.array.isRequired,
};
class DirPanel extends React.Component {
@@ -171,6 +173,15 @@ class DirPanel extends React.Component {
onTabNavClick={this.props.onTabNavClick}
/>
</div>
{(this.props.usedRepoTags.length > 0 && this.props.path === '/') && (
<div className="tags-summary-bar">
<FileTagsViewer
repoID={this.props.repoID}
currentPath={this.props.path}
usedRepoTags={this.props.usedRepoTags}
/>
</div>
)}
<div className="cur-view-content">
{this.props.errorMsg ?
<p className="error text-center">{this.props.errorMsg}</p> :

View File

@@ -9,6 +9,7 @@ import toaster from '../toast';
import DirPanel from './dir-panel';
import Dirent from '../../models/dirent';
import FileTag from '../../models/file-tag';
import RepoTag from '../../models/repo-tag';
import RepoInfo from '../../models/repo-info';
const propTypes = {
@@ -37,6 +38,7 @@ class DirView extends React.Component {
selectedDirentList: [],
dirID: '',
errorMsg: '',
usedRepoTags: [],
};
window.onpopstate = this.onpopstate;
this.lastModifyTime = new Date();
@@ -54,6 +56,16 @@ class DirView extends React.Component {
let location = decodeURIComponent(window.location.href);
let repoID = this.props.repoID;
collabServer.watchRepo(repoID, this.onRepoUpdateEvent);
seafileAPI.listRepoTags(repoID).then(res => {
let usedRepoTags = [];
res.data.repo_tags.forEach(item => {
let usedRepoTag = new RepoTag(item);
if (usedRepoTag.fileCount > 0) {
usedRepoTags.push(usedRepoTag);
}
});
this.setState({usedRepoTags: usedRepoTags});
});
seafileAPI.getRepoInfo(repoID).then(res => {
let repoInfo = new RepoInfo(res.data);
this.setState({
@@ -122,6 +134,10 @@ class DirView extends React.Component {
})
}
updateUsedRepoTags = (newUsedRepoTags) => {
this.setState({usedRepoTags: newUsedRepoTags});
}
updateDirentList = (filePath) => {
let repoID = this.state.repoID;
this.setState({isDirentListLoading: true});
@@ -368,6 +384,17 @@ class DirView extends React.Component {
});
this.updateDirent(dirent, 'file_tags', fileTags);
});
seafileAPI.listRepoTags(repoID).then(res => {
let usedRepoTags = [];
res.data.repo_tags.forEach(item => {
let usedRepoTag = new RepoTag(item);
if (usedRepoTag.fileCount > 0) {
usedRepoTags.push(usedRepoTag);
}
});
this.updateUsedRepoTags(usedRepoTags);
});
}
onMenuClick = () => {
@@ -549,6 +576,7 @@ class DirView extends React.Component {
onFileUploadSuccess={this.onFileUploadSuccess}
libNeedDecrypt={this.state.libNeedDecrypt}
onLibDecryptDialog={this.onLibDecryptDialog}
usedRepoTags={this.state.usedRepoTags}
/>
);
}

View File

@@ -426,7 +426,7 @@ class DirentListItem extends React.Component {
<a href={dirent.type === 'dir' ? dirHref : fileHref} onClick={this.onItemClick}>{dirent.name}</a>
}
</td>
<td>
<td className="tag-list-title">
{(dirent.type !== 'dir' && dirent.file_tags) && (
<Fragment>
<div id={`tag-list-title-${toolTipID}`} className="dirent-item tag-list tag-list-stacked">

View File

@@ -0,0 +1,74 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import ModalPortal from './modal-portal';
import { Modal } from 'reactstrap';
import ListTaggedFilesDialog from './dialog/list-taggedfiles-dialog';
const propTypes = {
repoID: PropTypes.string.isRequired,
currentPath: PropTypes.string.isRequired,
usedRepoTags: PropTypes.array.isRequired,
};
class FileTagsViewer extends React.Component {
constructor(props) {
super(props);
this.state = {
usedRepoTags: [],
currentTag: null,
isListTaggedFileShow: false,
};
}
onListTaggedFiles = (currentTag) => {
this.setState({
currentTag: currentTag,
isListTaggedFileShow: !this.state.isListTaggedFileShow,
});
}
onCloseDialog = () => {
this.setState({
isListTaggedFileShow: false
});
}
render() {
let {usedRepoTags, repoID} = this.props;
return (
<Fragment>
<ul className="used-tag-list">
{usedRepoTags.map((usedRepoTag) => {
return (
<li key={usedRepoTag.id} className="used-tag-item">
<span className={`used-tag bg-${usedRepoTag.color}`}></span>
<span className="used-tag-name" title={usedRepoTag.name}>{usedRepoTag.name}</span>
<span className="used-tag-files" onClick={this.onListTaggedFiles.bind(this, usedRepoTag)}>
{usedRepoTag.fileCount > 1 ? usedRepoTag.fileCount + ' files' : usedRepoTag.fileCount + ' file'}
</span>
</li>
);
})}
</ul>
{this.state.isListTaggedFileShow && (
<ModalPortal>
<Modal isOpen={true}>
<ListTaggedFilesDialog
repoID={repoID}
currentTag={this.state.currentTag}
onClose={this.onCloseDialog}
toggleCancel={this.onListTaggedFiles}
/>
</Modal>
</ModalPortal>
)}
</Fragment>
);
}
}
FileTagsViewer.propTypes = propTypes;
export default FileTagsViewer;

View File

@@ -44,6 +44,8 @@
flex: 1;
display: flex;
flex-direction: column;
overflow-y: auto;
overflow-x: hidden;
}
.dirent-info .img {
@@ -103,11 +105,16 @@
.file-tag-list li {
display: flex;
align-items: center;
max-width: 180px;
}
.file-tag-list .tag-name {
display: inline-block;
margin-left: 0.5rem;
margin-left: 5px;
width: 100px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.file-related-files th {

View File

@@ -23,3 +23,7 @@
top: 50%;
left: 50%;
}
.tag-list-title {
overflow: hidden;
}

View File

@@ -31,6 +31,7 @@
align-items: center;
color: #ffffff;
overflow: hidden;
padding: 10px;
}
.show-tag-selected {
@@ -92,3 +93,35 @@
.tag-dialog-back:focus {
color: #444;
}
.tags-summary-bar {
margin: 16px 16px 4px;
padding: 0 10px;
border: 1px solid #e6e6dd;
border-radius: 5px;
}
.used-tag-list {
list-style: none;
line-height: 40px;
}
.used-tag-item {
display: inline-block;
margin: auto 15px;
}
.used-tag {
display: inline-block;
width: 0.8rem;
height: 0.8rem;
border-radius: 50%;
}
.used-tag-name {
margin: 0 0.25rem;
}
.used-tag-files {
color: #666;
font-size: 14px;
}
.used-tag-files:hover {
cursor: pointer;
text-decoration: underline;
}

View File

@@ -14,6 +14,7 @@ import MarkdownContentViewer from '../../components/markdown-viewer';
import DirentListView from '../../components/dirent-list-view/dirent-list-view';
import DirentDetail from '../../components/dirent-detail/dirent-details';
import FileUploader from '../../components/file-uploader/file-uploader';
import FileTagsViewer from '../../components/filetags-viewer';
const propTypes = {
content: PropTypes.string,
@@ -55,6 +56,7 @@ const propTypes = {
goReviewPage: PropTypes.func,
goDraftPage: PropTypes.func,
reviewID: PropTypes.any,
usedRepoTags: PropTypes.array.isRequired,
};
class MainPanel extends Component {
@@ -229,6 +231,15 @@ class MainPanel extends Component {
/>
)}
</div>
{(this.props.usedRepoTags.length > 0 && this.props.path === '/') && (
<div className="tags-summary-bar">
<FileTagsViewer
repoID={repoID}
currentPath={this.props.path}
usedRepoTags={this.props.usedRepoTags}
/>
</div>
)}
<div className="cur-view-content" onScroll={this.handlePageScroll} ref="curViewContent">
{!this.props.pathExist ?
ErrMessage :

View File

@@ -14,6 +14,7 @@ import LibDecryptDialog from './components/dialog/lib-decrypt-dialog';
import ModalPortal from './components/modal-portal';
import Dirent from './models/dirent';
import FileTag from './models/file-tag';
import RepoTag from './models/repo-tag';
import './assets/css/fa-solid.css';
import './assets/css/fa-regular.css';
import './assets/css/fontawesome.css';
@@ -50,6 +51,7 @@ class Wiki extends Component {
reviewID: '',
draftFilePath: '',
dirID: '',
usedRepoTags: [],
};
window.onpopstate = this.onpopstate;
this.hash = '';
@@ -65,6 +67,16 @@ class Wiki extends Component {
componentDidMount() {
collabServer.watchRepo(repoID, this.onRepoUpdateEvent);
seafileAPI.listRepoTags(repoID).then(res => {
let usedRepoTags = [];
res.data.repo_tags.forEach(item => {
let usedRepoTag = new RepoTag(item);
if (usedRepoTag.fileCount > 0) {
usedRepoTags.push(usedRepoTag);
}
});
this.setState({usedRepoTags: usedRepoTags});
});
seafileAPI.getRepoInfo(repoID).then(res => {
this.setState({
libNeedDecrypt: res.data.lib_need_decrypt,
@@ -325,6 +337,10 @@ class Wiki extends Component {
}
}
updateUsedRepoTags = (newUsedRepoTags) => {
this.setState({usedRepoTags: newUsedRepoTags});
}
updateDirent = (dirent, paramKey, paramValue) => {
let newDirentList = this.state.direntList.map(item => {
if (item.name === dirent.name) {
@@ -595,6 +611,17 @@ class Wiki extends Component {
});
this.updateDirent(dirent, 'file_tags', fileTags);
});
seafileAPI.listRepoTags(repoID).then(res => {
let usedRepoTags = [];
res.data.repo_tags.forEach(item => {
let usedRepoTag = new RepoTag(item);
if (usedRepoTag.fileCount > 0) {
usedRepoTags.push(usedRepoTag);
}
});
this.updateUsedRepoTags(usedRepoTags);
});
}
onTreeNodeClick = (node) => {
@@ -904,6 +931,7 @@ class Wiki extends Component {
reviewID={this.state.reviewID}
goDraftPage={this.goDraftPage}
goReviewPage={this.goReviewPage}
usedRepoTags={this.state.usedRepoTags}
/>
</div>
);