1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-04 08:28:11 +00:00

Grid view support drag drop item to path (#6429)

* feature - drag and drop file to target path in grid view

fix typo

* update target path item background color when drag enter

* fix bug - select-all checkbox is actived after the last item is moved to another path

* fix bug - drag drop action conflict with multi-select by keyboard

* remove console log

* fix type error
This commit is contained in:
Aries
2024-07-27 12:04:33 +08:00
committed by GitHub
parent 953f17e717
commit 559dfff42b
7 changed files with 85 additions and 9 deletions

View File

@@ -10,6 +10,7 @@ import ViewFileToolbar from '../../components/toolbar/view-file-toolbar';
import { PRIVATE_FILE_TYPE } from '../../constants';
const propTypes = {
currentRepoInfo: PropTypes.object.isRequired,
repoID: PropTypes.string.isRequired,
repoName: PropTypes.string.isRequired,
currentPath: PropTypes.string.isRequired,
@@ -32,10 +33,18 @@ const propTypes = {
repoTags: PropTypes.array.isRequired,
filePermission: PropTypes.string,
onFileTagChanged: PropTypes.func.isRequired,
onItemMove: PropTypes.func.isRequired,
};
class DirPath extends React.Component {
constructor(props) {
super(props);
this.state = {
dropTargetPath: '',
};
}
onPathClick = (e) => {
let path = Utils.getEventData(e, 'path');
this.props.onPathClick(path);
@@ -54,6 +63,54 @@ class DirPath extends React.Component {
this.props.onTabNavClick(tabName, id);
};
onDragEnter = (e) => {
e.preventDefault();
if (Utils.isIEBrower()) {
return false;
}
this.setState({
dropTargetPath: e.target.dataset.path,
});
};
onDragLeave = (e) => {
e.preventDefault();
if (Utils.isIEBrower()) {
return false;
}
this.setState({
dropTargetPath: '',
});
};
onDragOver = (e) => {
if (Utils.isIEBrower()) {
return false;
}
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
};
onDrop = (e) => {
if (Utils.isIEBrower()) {
return false;
}
if (e.dataTransfer.files.length) {
return;
}
let dragStartItemData = e.dataTransfer.getData('application/drag-item-info');
dragStartItemData = JSON.parse(dragStartItemData);
let { nodeDirent, nodeParentPath } = dragStartItemData;
let selectedPath = Utils.getEventData(e, 'path');
this.props.onItemMove(this.props.currentRepoInfo, nodeDirent, selectedPath, nodeParentPath);
this.setState({
dropTargetPath: '',
});
};
turnPathToLink = (path) => {
path = path[path.length - 1] === '/' ? path.slice(0, path.length - 1) : path;
let pathList = path.split('/');
@@ -126,7 +183,16 @@ class DirPath extends React.Component {
return (
<Fragment key={index} >
<span className="path-split">/</span>
<span className="path-item" data-path={nodePath} onClick={this.onPathClick} role="button">{item}</span>
<span
className={`path-item ${nodePath === this.state.dropTargetPath ? 'path-item-drop' : ''}`}
data-path={nodePath} onClick={this.onPathClick}
onDragEnter={this.onDragEnter}
onDragLeave={this.onDragLeave}
onDragOver={this.onDragOver}
onDrop={this.onDrop}
role="button">
{item}
</span>
</Fragment>
);
}

View File

@@ -6,6 +6,7 @@ import DirPath from './dir-path';
import DirTool from './dir-tool';
const propTypes = {
currentRepoInfo: PropTypes.object.isRequired,
repoID: PropTypes.string.isRequired,
repoName: PropTypes.string.isRequired,
userPerm: PropTypes.string,
@@ -38,6 +39,7 @@ const propTypes = {
repoTags: PropTypes.array.isRequired,
onFileTagChanged: PropTypes.func.isRequired,
metadataViewId: PropTypes.string,
onItemMove: PropTypes.func.isRequired,
};
class CurDirPath extends React.Component {
@@ -60,6 +62,7 @@ class CurDirPath extends React.Component {
return (
<div className="cur-dir-path d-flex justify-content-between align-items-center">
<DirPath
currentRepoInfo={this.props.currentRepoInfo}
repoID={this.props.repoID}
repoName={this.props.repoName}
repoEncrypted={this.props.repoEncrypted}
@@ -82,6 +85,7 @@ class CurDirPath extends React.Component {
filePermission={this.props.filePermission}
onFileTagChanged={this.props.onFileTagChanged}
repoTags={this.props.repoTags}
onItemMove={this.props.onItemMove}
/>
{isDesktop &&
<DirTool

View File

@@ -56,27 +56,27 @@ class DirentGridItem extends React.Component {
e.preventDefault();
e.stopPropagation();
const { dirent, activeDirent } = this.props;
const { dirent } = this.props;
if (this.clickTimeout) {
clearTimeout(this.clickTimeout);
this.clickTimeout = null;
this.handleSingleClick(dirent, activeDirent, e);
this.handleSingleClick(dirent, e);
return;
}
this.clickTimeout = setTimeout(() => {
this.clickTimeout = null;
this.handleSingleClick(dirent, activeDirent, e);
this.handleSingleClick(dirent, e);
}, 100); // Clicks within 100 milliseconds is considered a single click.
};
handleSingleClick = (dirent, activeDirent, event) => {
handleSingleClick = (dirent, event) => {
if (!this.canPreview) {
return;
}
if (dirent === activeDirent && !event.metaKey && !event.ctrlKey) {
if (dirent.isSelected && !event.metaKey && !event.ctrlKey) {
this.handleDoubleClick(dirent, event);
} else {
this.props.onGridItemClick(dirent, event);
@@ -113,6 +113,7 @@ class DirentGridItem extends React.Component {
if (Utils.isIEBrower() || !this.canDrag) {
return false;
}
let dragStartItemData = { nodeDirent: this.props.dirent, nodeParentPath: this.props.path };
dragStartItemData = JSON.stringify(dragStartItemData);

View File

@@ -597,7 +597,6 @@ class DirentGridView extends React.Component {
onGridItemMouseDown = (event) => {
event.stopPropagation();
event.preventDefault();
if (event.button === 2) {
return;
}

View File

@@ -130,7 +130,7 @@
}
.tree-node-drop {
background-color: rgb(255, 239, 178);
background-color: #FFEFB2;
}
.tree-node-icon {
@@ -282,6 +282,10 @@
color: #666;
}
.dir-view-path .path-item-drop{
background-color: #FFEFB2;
}
.dir-view-path .path-split {
padding: 0 2px;
}

View File

@@ -191,6 +191,7 @@ class LibContentContainer extends React.Component {
}
<div className="cur-view-path d-block" style={curViewPathStyle}>
<CurDirPath
currentRepoInfo={this.props.currentRepoInfo}
repoID={repoID}
repoName={this.props.currentRepoInfo.repo_name}
repoEncrypted={this.props.repoEncrypted}
@@ -223,6 +224,7 @@ class LibContentContainer extends React.Component {
onFileTagChanged={this.props.onToolbarFileTagChanged}
repoTags={this.props.repoTags}
metadataViewId={this.props.metadataViewId}
onItemMove={this.props.onItemMove}
/>
<ToolbarForSelectedDirents
repoID={this.props.repoID}

View File

@@ -1912,7 +1912,7 @@ class LibContentView extends React.Component {
this.setState({
selectedDirentList: selectedDirentList,
isDirentSelected: selectedDirentList.length > 0,
isAllDirentSelected: selectedDirentList.length === newDirentList.length,
isAllDirentSelected: newDirentList.length ? selectedDirentList.length === newDirentList.length : false,
});
};