1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-06 17:33:18 +00:00
This commit is contained in:
zxj96
2019-04-17 10:48:44 +08:00
committed by Daniel Pan
parent b83197e2b0
commit 8d5b16505f
11 changed files with 115 additions and 6 deletions

View File

@@ -12,6 +12,9 @@ import CreateFile from '../../components/dialog/create-file-dialog';
import ImageDialog from '../../components/dialog/image-dialog'; import ImageDialog from '../../components/dialog/image-dialog';
import { siteRoot, thumbnailSizeForOriginal } from '../../utils/constants'; import { siteRoot, thumbnailSizeForOriginal } from '../../utils/constants';
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
import FileTag from '../../models/file-tag';
import { seafileAPI } from '../../utils/seafile-api';
const propTypes = { const propTypes = {
currentPath: PropTypes.string.isRequired, currentPath: PropTypes.string.isRequired,
@@ -31,6 +34,7 @@ const propTypes = {
inResizing: PropTypes.bool.isRequired, inResizing: PropTypes.bool.isRequired,
currentRepoInfo: PropTypes.object.isRequired, currentRepoInfo: PropTypes.object.isRequired,
selectedDirentList: PropTypes.array.isRequired, selectedDirentList: PropTypes.array.isRequired,
onFileTagChanged: PropTypes.func,
}; };
class DirColumnNav extends React.Component { class DirColumnNav extends React.Component {
@@ -49,12 +53,18 @@ class DirColumnNav extends React.Component {
isCopyDialogShow: false, isCopyDialogShow: false,
isMoveDialogShow: false, isMoveDialogShow: false,
isMutipleOperation: false, isMutipleOperation: false,
isEditFileTagShow: false,
fileTagList: [],
nodeDirent: '',
}; };
this.isNodeMenuShow = true; this.isNodeMenuShow = true;
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
this.setState({opNode: nextProps.currentNode}); this.setState({opNode: nextProps.currentNode});
if (this.state.nodeDirent.object) {
this.getTagFileList(this.state.nodeDirent);
}
} }
onNodeClick = (node) => { onNodeClick = (node) => {
@@ -92,6 +102,9 @@ class DirColumnNav extends React.Component {
case 'Copy': case 'Copy':
this.onCopyToggle(); this.onCopyToggle();
break; break;
case 'Tags':
this.onEditFileTagToggle(node);
break;
case 'Move': case 'Move':
this.onMoveToggle(); this.onMoveToggle();
break; break;
@@ -101,6 +114,51 @@ class DirColumnNav extends React.Component {
} }
} }
onEditFileTagToggle = (node) => {
this.setState({
isEditFileTagShow: !this.state.isEditFileTagShow,
nodeDirent: node,
});
if (node.object) {
this.getTagFileList(node);
}
}
onFileTagChanged = () => {
let currentPath;
if (this.props.currentPath.charAt(this.props.currentPath.length - 1) === '/') {
currentPath = Utils.joinPath(this.props.currentPath, this.state.nodeDirent.object.name);
} else {
currentPath = this.props.currentPath;
}
if (this.props.currentPath !== '/') {
if (currentPath === this.state.nodeDirent.path) {
this.props.onToolbarFileTagChanged();
}
}
if (this.props.currentPath !== this.state.nodeDirent.parentNode.path) {
this.getTagFileList(this.state.nodeDirent);
return;
}
this.props.onFileTagChanged(this.state.nodeDirent.object, this.state.nodeDirent.path);
}
getTagFileList = (node) => {
let {repoID} = this.props;
seafileAPI.listFileTags(repoID, node.path).then(res => {
let fileTagList = [];
res.data.file_tags.forEach(item => {
let file_tag = new FileTag(item);
fileTagList.push(file_tag);
});
this.setState({fileTagList: fileTagList});
});
}
onAddFileToggle = (type) => { onAddFileToggle = (type) => {
if (type === 'root') { if (type === 'root') {
let root = this.props.treeData.root; let root = this.props.treeData.root;
@@ -338,6 +396,15 @@ class DirColumnNav extends React.Component {
/> />
</ModalPortal> </ModalPortal>
)} )}
{this.state.isEditFileTagShow &&
<EditFileTagDialog
repoID={this.props.repoID}
fileTagList={this.state.fileTagList}
filePath={this.state.nodeDirent.path}
toggleCancel={this.onEditFileTagToggle}
onFileTagChanged={this.onFileTagChanged}
/>
}
{this.state.isNodeImagePopupOpen && ( {this.state.isNodeImagePopupOpen && (
<ModalPortal> <ModalPortal>
<ImageDialog <ImageDialog

View File

@@ -68,6 +68,7 @@ const propTypes = {
onItemsMove: PropTypes.func.isRequired, onItemsMove: PropTypes.func.isRequired,
onItemsCopy: PropTypes.func.isRequired, onItemsCopy: PropTypes.func.isRequired,
onItemsDelete: PropTypes.func.isRequired, onItemsDelete: PropTypes.func.isRequired,
onFileTagChanged: PropTypes.func,
}; };
class DirColumnView extends React.Component { class DirColumnView extends React.Component {
@@ -171,6 +172,8 @@ class DirColumnView extends React.Component {
onItemMove={this.props.onItemMove} onItemMove={this.props.onItemMove}
onItemCopy={this.props.onItemCopy} onItemCopy={this.props.onItemCopy}
selectedDirentList={this.props.selectedDirentList} selectedDirentList={this.props.selectedDirentList}
onFileTagChanged={this.props.onFileTagChanged}
onToolbarFileTagChanged={this.props.onToolbarFileTagChanged}
/> />
<div className="dir-content-resize" onMouseDown={this.onResizeMouseDown}></div> <div className="dir-content-resize" onMouseDown={this.onResizeMouseDown}></div>
<div className="dir-content-main" style={{userSelect: select, flex: mainFlex}}> <div className="dir-content-main" style={{userSelect: select, flex: mainFlex}}>
@@ -224,6 +227,7 @@ class DirColumnView extends React.Component {
onItemsMove={this.props.onItemsMove} onItemsMove={this.props.onItemsMove}
onItemsCopy={this.props.onItemsCopy} onItemsCopy={this.props.onItemsCopy}
onItemsDelete={this.props.onItemsDelete} onItemsDelete={this.props.onItemsDelete}
onFileTagChanged={this.props.onFileTagChanged}
/> />
)} )}
</div> </div>

View File

@@ -37,6 +37,7 @@ const propTypes = {
onItemsMove: PropTypes.func.isRequired, onItemsMove: PropTypes.func.isRequired,
onItemsCopy: PropTypes.func.isRequired, onItemsCopy: PropTypes.func.isRequired,
onItemsDelete: PropTypes.func.isRequired, onItemsDelete: PropTypes.func.isRequired,
onFileTagChanged: PropTypes.func,
}; };
class DirListView extends React.Component { class DirListView extends React.Component {
@@ -94,6 +95,7 @@ class DirListView extends React.Component {
onItemsDelete={this.props.onItemsDelete} onItemsDelete={this.props.onItemsDelete}
onAddFile={this.props.onAddFile} onAddFile={this.props.onAddFile}
onAddFolder={this.props.onAddFolder} onAddFolder={this.props.onAddFolder}
onFileTagChanged={this.props.onFileTagChanged}
/> />
</Fragment> </Fragment>
); );

View File

@@ -13,6 +13,7 @@ import MoveDirentDialog from '../dialog/move-dirent-dialog';
import CopyDirentDialog from '../dialog/copy-dirent-dialog'; import CopyDirentDialog from '../dialog/copy-dirent-dialog';
import ShareDialog from '../dialog/share-dialog'; import ShareDialog from '../dialog/share-dialog';
import ZipDownloadDialog from '../dialog/zip-download-dialog'; import ZipDownloadDialog from '../dialog/zip-download-dialog';
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
import '../../css/dirent-list-item.css'; import '../../css/dirent-list-item.css';
@@ -60,6 +61,7 @@ class DirentListItem extends React.Component {
isShowTagTooltip: false, isShowTagTooltip: false,
isDragTipShow: false, isDragTipShow: false,
isDropTipshow: false, isDropTipshow: false,
isEditFileTagShow: false,
}; };
} }
@@ -190,6 +192,9 @@ class DirentListItem extends React.Component {
case 'Copy': case 'Copy':
this.onItemCopyToggle(); this.onItemCopyToggle();
break; break;
case 'Tags':
this.onEditFileTagToggle();
break;
case 'Permission': case 'Permission':
this.onPermissionItem(); this.onPermissionItem();
break; break;
@@ -216,6 +221,17 @@ class DirentListItem extends React.Component {
} }
} }
onEditFileTagToggle = () => {
this.setState({
isEditFileTagShow: !this.state.isEditFileTagShow
});
}
onFileTagChanged = () => {
let direntPath = this.getDirentPath(this.props.dirent);
this.props.onFileTagChanged(this.props.dirent, direntPath);
}
onItemRenameToggle = () => { onItemRenameToggle = () => {
this.props.onItemRenameToggle(this.props.dirent); this.props.onItemRenameToggle(this.props.dirent);
this.setState({ this.setState({
@@ -557,6 +573,15 @@ class DirentListItem extends React.Component {
/> />
</ModalPortal> </ModalPortal>
} }
{this.state.isEditFileTagShow &&
<EditFileTagDialog
repoID={this.props.repoID}
fileTagList={dirent.file_tags}
filePath={direntPath}
toggleCancel={this.onEditFileTagToggle}
onFileTagChanged={this.onFileTagChanged}
/>
}
{this.state.isZipDialogOpen && {this.state.isZipDialogOpen &&
<ModalPortal> <ModalPortal>
<ZipDownloadDialog <ZipDownloadDialog

View File

@@ -44,6 +44,7 @@ const propTypes = {
onItemsMove: PropTypes.func.isRequired, onItemsMove: PropTypes.func.isRequired,
onItemsCopy: PropTypes.func.isRequired, onItemsCopy: PropTypes.func.isRequired,
onItemsDelete: PropTypes.func.isRequired, onItemsDelete: PropTypes.func.isRequired,
onFileTagChanged: PropTypes.func,
}; };
class DirentListView extends React.Component { class DirentListView extends React.Component {
@@ -221,6 +222,7 @@ class DirentListView extends React.Component {
this.setState({isCopyDialogShow: !this.state.isCopyDialogShow}); this.setState({isCopyDialogShow: !this.state.isCopyDialogShow});
} }
onItemsDownload = () => { onItemsDownload = () => {
let { path, repoID, selectedDirentList } = this.props; let { path, repoID, selectedDirentList } = this.props;
if (selectedDirentList.length) { if (selectedDirentList.length) {
@@ -454,7 +456,7 @@ class DirentListView extends React.Component {
contextmenuList = this.props.showShareBtn ? [SHARE, DOWNLOAD, DELETE, 'Divider'] : [DOWNLOAD, DELETE, 'Divider']; contextmenuList = this.props.showShareBtn ? [SHARE, DOWNLOAD, DELETE, 'Divider'] : [DOWNLOAD, DELETE, 'Divider'];
} }
let { RENAME, MOVE, COPY, PERMISSION, OPEN_VIA_CLIENT, LOCK, UNLOCK, COMMENT, HISTORY, ACCESS_LOG } = TextTranslation; let { RENAME, MOVE, COPY, PERMISSION, OPEN_VIA_CLIENT, LOCK, UNLOCK, COMMENT, HISTORY, ACCESS_LOG, TAGS } = TextTranslation;
if (type === 'dir' && permission === 'rw') { if (type === 'dir' && permission === 'rw') {
if (can_set_folder_perm) { if (can_set_folder_perm) {
menuList = [...contextmenuList, RENAME, MOVE, COPY, 'Divider', PERMISSION, 'Divider', OPEN_VIA_CLIENT]; menuList = [...contextmenuList, RENAME, MOVE, COPY, 'Divider', PERMISSION, 'Divider', OPEN_VIA_CLIENT];
@@ -476,6 +478,7 @@ class DirentListView extends React.Component {
menuList.push(MOVE); menuList.push(MOVE);
} }
menuList.push(COPY); menuList.push(COPY);
menuList.push(TAGS);
if (isPro) { if (isPro) {
if (dirent.is_locked) { if (dirent.is_locked) {
if (dirent.locked_by_me || (dirent.lock_owner === 'OnlineOffice' && permission === 'rw')) { if (dirent.locked_by_me || (dirent.lock_owner === 'OnlineOffice' && permission === 'rw')) {
@@ -573,6 +576,7 @@ class DirentListView extends React.Component {
onItemContextMenu={this.onItemContextMenu} onItemContextMenu={this.onItemContextMenu}
selectedDirentList={this.props.selectedDirentList} selectedDirentList={this.props.selectedDirentList}
activeDirent={this.state.activeDirent} activeDirent={this.state.activeDirent}
onFileTagChanged={this.props.onFileTagChanged}
/> />
); );
})} })}

View File

@@ -67,7 +67,8 @@ class TreeNodeView extends React.Component {
this.props.onNodeClick(this.props.node); this.props.onNodeClick(this.props.node);
} }
onLoadToggle = () => { onLoadToggle = (e) => {
e.stopPropagation();
let { node } = this.props; let { node } = this.props;
if (node.isExpanded) { if (node.isExpanded) {
this.props.onNodeCollapse(node); this.props.onNodeCollapse(node);

View File

@@ -2,7 +2,7 @@ class TreeNode {
constructor({ path, object, isLoaded, isPreload, isExpanded, parentNode }) { constructor({ path, object, isLoaded, isPreload, isExpanded, parentNode }) {
this.path = path || object.name, // The default setting is the object name, which is set to a relative path when the father is set. this.path = path || object.name, // The default setting is the object name, which is set to a relative path when the father is set.
this.object = object.clone(); this.object = object;
this.isLoaded = isLoaded || false; this.isLoaded = isLoaded || false;
this.isPreload = isPreload || false; this.isPreload = isPreload || false;
this.isExpanded = isExpanded || false; this.isExpanded = isExpanded || false;

View File

@@ -168,7 +168,7 @@ class TreeView extends React.Component {
getMenuList = (node) => { getMenuList = (node) => {
let menuList = []; let menuList = [];
let { NEW_FOLDER, NEW_FILE, COPY, MOVE, RENAME, DELETE, OPEN_VIA_CLIENT} = TextTranslation; let { NEW_FOLDER, NEW_FILE, COPY, MOVE, RENAME, DELETE, OPEN_VIA_CLIENT, TAGS} = TextTranslation;
if (!node) { if (!node) {
return [NEW_FOLDER, NEW_FILE]; return [NEW_FOLDER, NEW_FILE];
@@ -177,7 +177,7 @@ class TreeView extends React.Component {
if (node.object.type === 'dir') { if (node.object.type === 'dir') {
menuList = [NEW_FOLDER, NEW_FILE, COPY, MOVE, RENAME, DELETE]; menuList = [NEW_FOLDER, NEW_FILE, COPY, MOVE, RENAME, DELETE];
} else { } else {
menuList = [RENAME, DELETE, COPY, MOVE, OPEN_VIA_CLIENT]; menuList = [RENAME, DELETE, COPY, MOVE, TAGS, OPEN_VIA_CLIENT];
} }
return menuList; return menuList;

View File

@@ -187,6 +187,7 @@ class LibContentContainer extends React.Component {
onItemsMove={this.props.onItemsMove} onItemsMove={this.props.onItemsMove}
onItemsCopy={this.props.onItemsCopy} onItemsCopy={this.props.onItemsCopy}
onItemsDelete={this.props.onItemsDelete} onItemsDelete={this.props.onItemsDelete}
onFileTagChanged={this.props.onFileTagChanged}
/> />
)} )}
{this.props.currentMode === 'grid' && ( {this.props.currentMode === 'grid' && (
@@ -250,6 +251,8 @@ class LibContentContainer extends React.Component {
onItemsMove={this.props.onItemsMove} onItemsMove={this.props.onItemsMove}
onItemsCopy={this.props.onItemsCopy} onItemsCopy={this.props.onItemsCopy}
onItemsDelete={this.props.onItemsDelete} onItemsDelete={this.props.onItemsDelete}
onFileTagChanged={this.props.onFileTagChanged}
onToolbarFileTagChanged={this.props.onToolbarFileTagChanged}
/> />
)} )}
</Fragment> </Fragment>

View File

@@ -1031,7 +1031,8 @@ class LibContentView extends React.Component {
let results = {}; let results = {};
for (let i = 0; i < direntList.length; i++) { for (let i = 0; i < direntList.length; i++) {
let object = direntList[i]; let object = direntList[i];
let key = object.parent_dir; let parentDir = object.parent_dir;
let key = parentDir === '/' ? '/' : parentDir.slice(0, parentDir.length - 1);
if (!results[key]) { if (!results[key]) {
results[key] = []; results[key] = [];
} }
@@ -1444,6 +1445,7 @@ class LibContentView extends React.Component {
closeDirentDetail={this.closeDirentDetail} closeDirentDetail={this.closeDirentDetail}
showDirentDetail={this.showDirentDetail} showDirentDetail={this.showDirentDetail}
onDeleteRepoTag={this.onDeleteRepoTag} onDeleteRepoTag={this.onDeleteRepoTag}
onToolbarFileTagChanged={this.onToolbarFileTagChanged}
/> />
{this.state.pathExist && !this.state.isViewFile && ( {this.state.pathExist && !this.state.isViewFile && (
<FileUploader <FileUploader

View File

@@ -296,6 +296,7 @@ class DirView(APIView):
parent_dir_list.append(tmp_parent_dir) parent_dir_list.append(tmp_parent_dir)
for folder_name in parent_dir.strip('/').split('/'): for folder_name in parent_dir.strip('/').split('/'):
tmp_parent_dir = posixpath.join(tmp_parent_dir, folder_name) tmp_parent_dir = posixpath.join(tmp_parent_dir, folder_name)
tmp_parent_dir = normalize_dir_path(tmp_parent_dir)
parent_dir_list.append(tmp_parent_dir) parent_dir_list.append(tmp_parent_dir)
all_dir_info_list = [] all_dir_info_list = []