mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-08 02:10:24 +00:00
[dir view] Tags: don't send the 'get tags' request when open the 'tags' popover/dialog (handled 6 cases); removed the repeated 'get tags' request after creating a new tag; improved the 'no tags' tip (#5936)
This commit is contained in:
@@ -4,7 +4,6 @@ import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import RepoTag from '../../models/repo-tag';
|
||||
import CreateTagDialog from './create-tag-dialog';
|
||||
import toaster from '../toast';
|
||||
require('../../css/repo-tag.css');
|
||||
@@ -103,6 +102,7 @@ TagItem.propTypes = TagItemPropTypes;
|
||||
|
||||
const TagListPropTypes = {
|
||||
repoID: PropTypes.string.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
filePath: PropTypes.string.isRequired,
|
||||
fileTagList: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func.isRequired,
|
||||
@@ -111,39 +111,15 @@ const TagListPropTypes = {
|
||||
};
|
||||
|
||||
class TagList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
repotagList: [],
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getRepoTagList();
|
||||
}
|
||||
|
||||
getRepoTagList = () => {
|
||||
let repoID = this.props.repoID;
|
||||
seafileAPI.listRepoTags(repoID).then(res => {
|
||||
let repotagList = [];
|
||||
res.data.repo_tags.forEach(item => {
|
||||
let repoTag = new RepoTag(item);
|
||||
repotagList.push(repoTag);
|
||||
});
|
||||
this.setState({repotagList: repotagList});
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { repoTags } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
<ModalHeader toggle={this.props.toggleCancel}>{gettext('Select Tags')}</ModalHeader>
|
||||
<ModalBody className="px-0">
|
||||
<ul className="tag-list tag-list-container">
|
||||
{this.state.repotagList.map((repoTag) => {
|
||||
{repoTags.map((repoTag) => {
|
||||
return (
|
||||
<TagItem
|
||||
key={repoTag.id}
|
||||
@@ -177,6 +153,7 @@ TagList.propTypes = TagListPropTypes;
|
||||
|
||||
const propTypes = {
|
||||
repoID: PropTypes.string.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
filePath: PropTypes.string.isRequired,
|
||||
fileTagList: PropTypes.array.isRequired,
|
||||
toggleCancel: PropTypes.func.isRequired,
|
||||
@@ -215,6 +192,7 @@ class EditFileTagDialog extends React.Component {
|
||||
{this.state.isListRepoTagShow &&
|
||||
<TagList
|
||||
repoID={this.props.repoID}
|
||||
repoTags={this.props.repoTags}
|
||||
filePath={this.props.filePath}
|
||||
fileTagList={this.props.fileTagList}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
|
@@ -64,6 +64,7 @@ const propTypes = {
|
||||
onItemsMove: PropTypes.func.isRequired,
|
||||
onItemsCopy: PropTypes.func.isRequired,
|
||||
onItemsDelete: PropTypes.func.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func,
|
||||
showDirentDetail: PropTypes.func.isRequired,
|
||||
fullDirentList: PropTypes.array,
|
||||
@@ -226,6 +227,7 @@ class DirColumnView extends React.Component {
|
||||
onItemsMove={this.props.onItemsMove}
|
||||
onItemsCopy={this.props.onItemsCopy}
|
||||
onItemsDelete={this.props.onItemsDelete}
|
||||
repoTags={this.props.repoTags}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
showDirentDetail={this.props.showDirentDetail}
|
||||
/>
|
||||
|
@@ -29,6 +29,7 @@ const propTypes = {
|
||||
updateDirent: PropTypes.func.isRequired,
|
||||
showDirentDetail: PropTypes.func.isRequired,
|
||||
onAddFolder: PropTypes.func.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func,
|
||||
onItemRename: PropTypes.func.isRequired,
|
||||
fullDirentList: PropTypes.array,
|
||||
@@ -81,6 +82,7 @@ class DirGridView extends React.Component {
|
||||
isDirentDetailShow={this.props.isDirentDetailShow}
|
||||
onItemRename={this.props.onItemRename}
|
||||
onAddFolder={this.props.onAddFolder}
|
||||
repoTags={this.props.repoTags}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
/>
|
||||
</Fragment>
|
||||
|
@@ -12,6 +12,7 @@ const propTypes = {
|
||||
userPerm: PropTypes.string,
|
||||
enableDirPrivateShare: PropTypes.bool.isRequired,
|
||||
isRepoInfoBarShow: PropTypes.bool.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
usedRepoTags: PropTypes.array.isRequired,
|
||||
draftCounts: PropTypes.number,
|
||||
updateUsedRepoTags: PropTypes.func.isRequired,
|
||||
@@ -99,6 +100,7 @@ class DirListView extends React.Component {
|
||||
onItemsDelete={this.props.onItemsDelete}
|
||||
onAddFile={this.props.onAddFile}
|
||||
onAddFolder={this.props.onAddFolder}
|
||||
repoTags={this.props.repoTags}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
showDirentDetail={this.props.showDirentDetail}
|
||||
loadDirentList={this.props.loadDirentList}
|
||||
|
@@ -44,6 +44,7 @@ const propTypes = {
|
||||
updateDirent: PropTypes.func.isRequired,
|
||||
isDirentDetailShow: PropTypes.bool.isRequired,
|
||||
onGridItemClick: PropTypes.func,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func,
|
||||
onAddFolder: PropTypes.func.isRequired,
|
||||
showDirentDetail: PropTypes.func.isRequired,
|
||||
@@ -626,6 +627,7 @@ class DirentGridView extends React.Component {
|
||||
fileTagList={dirent.file_tags}
|
||||
filePath={direntPath}
|
||||
toggleCancel={this.onEditFileTagToggle}
|
||||
repoTags={this.props.repoTags}
|
||||
onFileTagChanged={this.onFileTagChanged}
|
||||
/>
|
||||
}
|
||||
|
@@ -51,6 +51,7 @@ const propTypes = {
|
||||
selectedDirentList: PropTypes.array.isRequired,
|
||||
activeDirent: PropTypes.object,
|
||||
getDirentItemMenuList: PropTypes.func.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func,
|
||||
enableDirPrivateShare: PropTypes.bool.isRequired,
|
||||
showDirentDetail: PropTypes.func.isRequired,
|
||||
@@ -892,6 +893,7 @@ class DirentListItem extends React.Component {
|
||||
{this.state.isEditFileTagShow &&
|
||||
<EditFileTagPopover
|
||||
repoID={this.props.repoID}
|
||||
repoTags={this.props.repoTags}
|
||||
fileTagList={dirent.file_tags}
|
||||
filePath={direntPath}
|
||||
toggleCancel={this.onEditFileTagToggle}
|
||||
@@ -905,6 +907,7 @@ class DirentListItem extends React.Component {
|
||||
{this.state.isEditFileTagShow &&
|
||||
<EditFileTagDialog
|
||||
repoID={this.props.repoID}
|
||||
repoTags={this.props.repoTags}
|
||||
fileTagList={dirent.file_tags}
|
||||
filePath={direntPath}
|
||||
toggleCancel={this.onEditFileTagToggle}
|
||||
|
@@ -44,6 +44,7 @@ const propTypes = {
|
||||
onItemsCopy: PropTypes.func.isRequired,
|
||||
onItemConvert: PropTypes.func.isRequired,
|
||||
onItemsDelete: PropTypes.func.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func,
|
||||
enableDirPrivateShare: PropTypes.bool.isRequired,
|
||||
isGroupOwnedRepo: PropTypes.bool.isRequired,
|
||||
@@ -671,6 +672,7 @@ class DirentListView extends React.Component {
|
||||
onItemContextMenu={this.onItemContextMenu}
|
||||
selectedDirentList={this.props.selectedDirentList}
|
||||
activeDirent={this.state.activeDirent}
|
||||
repoTags={this.props.repoTags}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
getDirentItemMenuList={this.getDirentItemMenuList}
|
||||
showDirentDetail={this.props.showDirentDetail}
|
||||
|
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import RepoTag from '../../models/repo-tag';
|
||||
import toaster from '../toast';
|
||||
import CommonAddTool from '../common/common-add-tool';
|
||||
import SearchInput from '../common/search-input';
|
||||
@@ -19,35 +18,15 @@ class EditFileTagPopover extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
repotagList: [],
|
||||
searchVal: '',
|
||||
highlightIndex: -1,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getRepoTagList();
|
||||
}
|
||||
|
||||
setHighlightIndex = (highlightIndex) => {
|
||||
this.setState({ highlightIndex });
|
||||
};
|
||||
|
||||
getRepoTagList = () => {
|
||||
let repoID = this.props.repoID;
|
||||
seafileAPI.listRepoTags(repoID).then(res => {
|
||||
let repotagList = [];
|
||||
res.data.repo_tags.forEach(item => {
|
||||
let repoTag = new RepoTag(item);
|
||||
repotagList.push(repoTag);
|
||||
});
|
||||
this.setState({repotagList: repotagList});
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
};
|
||||
|
||||
generateRandomColor = () => {
|
||||
return TAG_COLORS[Math.floor(Math.random() * TAG_COLORS.length)];
|
||||
};
|
||||
@@ -64,7 +43,6 @@ class EditFileTagPopover extends React.Component {
|
||||
searchVal: '',
|
||||
highlightIndex: -1,
|
||||
});
|
||||
this.getRepoTagList();
|
||||
}).catch((error) => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
@@ -116,13 +94,14 @@ class EditFileTagPopover extends React.Component {
|
||||
};
|
||||
|
||||
onKeyDown = (e) => {
|
||||
const { repoTags } = this.props;
|
||||
if (e.keyCode === KeyCodes.ChineseInputMethod || e.keyCode === KeyCodes.LeftArrow || e.keyCode === KeyCodes.RightArrow) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
else if (e.keyCode === KeyCodes.Enter) {
|
||||
const searchText = this.state.searchVal.trim();
|
||||
const repotagList = this.state.repotagList.filter(item => item.name.includes(searchText));
|
||||
const tag = repotagList[this.state.highlightIndex];
|
||||
const repoTagList = repoTags.filter(item => item.name.includes(searchText));
|
||||
const tag = repoTagList[this.state.highlightIndex];
|
||||
if (tag) {
|
||||
this.onEditFileTag(tag);
|
||||
}
|
||||
@@ -134,8 +113,8 @@ class EditFileTagPopover extends React.Component {
|
||||
}
|
||||
else if (e.keyCode === KeyCodes.DownArrow) {
|
||||
const searchText = this.state.searchVal.trim();
|
||||
const repotagList = this.state.repotagList.filter(item => item.name.includes(searchText));
|
||||
if (this.state.highlightIndex < repotagList.length) {
|
||||
const repoTagList = repoTags.filter(item => item.name.includes(searchText));
|
||||
if (this.state.highlightIndex < repoTagList.length) {
|
||||
this.setHighlightIndex(this.state.highlightIndex + 1);
|
||||
}
|
||||
}
|
||||
@@ -148,8 +127,21 @@ class EditFileTagPopover extends React.Component {
|
||||
|
||||
render() {
|
||||
const searchText = this.state.searchVal.trim();
|
||||
const repotagList = this.state.repotagList.filter(item => item.name.includes(searchText));
|
||||
const showAddTool = searchText && !this.state.repotagList.find(item => item.name === searchText);
|
||||
const { repoTags: repoTagList } = this.props;
|
||||
const filteredRepoTagList = repoTagList.filter(item => item.name.includes(searchText));
|
||||
const showAddTool = searchText && !repoTagList.find(item => item.name === searchText);
|
||||
|
||||
let noTagsTip = '';
|
||||
if (!searchText) {
|
||||
if (repoTagList.length == 0) {
|
||||
noTagsTip = gettext('No tags');
|
||||
}
|
||||
} else {
|
||||
if (filteredRepoTagList.length == 0) {
|
||||
noTagsTip = gettext('Tag not found');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<SeahubPopover
|
||||
popoverClassName="edit-filetag-popover"
|
||||
@@ -165,26 +157,25 @@ class EditFileTagPopover extends React.Component {
|
||||
onChange={this.onChangeSearch}
|
||||
autoFocus={true}
|
||||
/>
|
||||
<ul className="tag-list-container">
|
||||
{repotagList.length === 0 &&
|
||||
<div className='tag-not-found mt-2 mb-4 mx-1'>{gettext('Tag not found')}</div>
|
||||
}
|
||||
{repotagList.length > 0 && repotagList.map((repoTag, index) => {
|
||||
return (
|
||||
<TagItem
|
||||
index={index}
|
||||
highlightIndex={this.state.highlightIndex}
|
||||
setHighlightIndex={this.setHighlightIndex}
|
||||
key={repoTag.id}
|
||||
repoTag={repoTag}
|
||||
repoID={this.props.repoID}
|
||||
filePath={this.props.filePath}
|
||||
fileTagList={this.props.fileTagList}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
{noTagsTip ? <div className='tag-not-found my-4 mx-1'>{noTagsTip}</div> :
|
||||
<ul className="tag-list-container">
|
||||
{filteredRepoTagList.map((repoTag, index) => {
|
||||
return (
|
||||
<TagItem
|
||||
index={index}
|
||||
highlightIndex={this.state.highlightIndex}
|
||||
setHighlightIndex={this.setHighlightIndex}
|
||||
key={repoTag.id}
|
||||
repoTag={repoTag}
|
||||
repoID={this.props.repoID}
|
||||
filePath={this.props.filePath}
|
||||
fileTagList={this.props.fileTagList}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
}
|
||||
{showAddTool &&
|
||||
<CommonAddTool
|
||||
callBack={this.createNewTag}
|
||||
@@ -201,6 +192,7 @@ EditFileTagPopover.propTypes = {
|
||||
repoID: PropTypes.string.isRequired,
|
||||
filePath: PropTypes.string.isRequired,
|
||||
fileTagList: PropTypes.array.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
toggleCancel: PropTypes.func.isRequired,
|
||||
onFileTagChanged: PropTypes.func.isRequired,
|
||||
};
|
||||
|
@@ -25,6 +25,7 @@ const propTypes = {
|
||||
userPerm: PropTypes.string.isRequired,
|
||||
repoID: PropTypes.string.isRequired,
|
||||
repoEncrypted: PropTypes.bool.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
selectedDirentList: PropTypes.array.isRequired,
|
||||
onItemsMove: PropTypes.func.isRequired,
|
||||
onItemsCopy: PropTypes.func.isRequired,
|
||||
@@ -328,7 +329,7 @@ class MultipleDirOperationToolbar extends React.Component {
|
||||
|
||||
render() {
|
||||
|
||||
const { repoID, userPerm } = this.props;
|
||||
const { repoID, repoTags, userPerm } = this.props;
|
||||
const dirent = this.props.selectedDirentList[0];
|
||||
const direntPath = this.getDirentPath(dirent);
|
||||
|
||||
@@ -458,6 +459,7 @@ class MultipleDirOperationToolbar extends React.Component {
|
||||
<ModalPortal>
|
||||
<EditFileTagDialog
|
||||
repoID={repoID}
|
||||
repoTags={repoTags}
|
||||
filePath={direntPath}
|
||||
fileTagList={this.state.fileTagList}
|
||||
toggleCancel={this.toggleCancel}
|
||||
|
@@ -12,6 +12,7 @@ import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||
const propTypes = {
|
||||
path: PropTypes.string.isRequired,
|
||||
repoID: PropTypes.string.isRequired,
|
||||
repoTags: PropTypes.array.isRequired,
|
||||
userPerm: PropTypes.string.isRequired,
|
||||
repoEncrypted: PropTypes.bool.isRequired,
|
||||
enableDirPrivateShare: PropTypes.bool.isRequired,
|
||||
@@ -127,6 +128,7 @@ class ViewFileToolbar extends React.Component {
|
||||
<EditFileTagDialog
|
||||
filePath={this.props.path}
|
||||
repoID={this.props.repoID}
|
||||
repoTags={this.props.repoTags}
|
||||
fileTagList={this.props.fileTags}
|
||||
toggleCancel={this.onEditFileTagToggle}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
|
Reference in New Issue
Block a user