1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-09 10:50:24 +00:00
Files
seahub/frontend/src/components/file-chooser/repo-list-item.js

233 lines
7.0 KiB
JavaScript
Raw Normal View History

import React from 'react';
import PropTypes from 'prop-types';
import TreeListView from './tree-list-view';
import TreeNode from '../../components/tree-view/tree-node';
import Dirent from '../../models/dirent';
import { seafileAPI } from '../../utils/seafile-api';
import treeHelper from '../../components/tree-view/tree-helper';
import { Utils } from '../../utils/utils';
import toaster from '../toast';
const propTypes = {
2024-02-21 17:39:19 +08:00
isCurrentRepo: PropTypes.bool,
currentPath: PropTypes.string,
2018-12-28 14:25:25 +08:00
isShowFile: PropTypes.bool,
selectedPath: PropTypes.string,
selectedRepo: PropTypes.object,
repo: PropTypes.object.isRequired,
initToShowChildren: PropTypes.bool.isRequired,
onDirentItemClick: PropTypes.func.isRequired,
onRepoItemClick: PropTypes.func.isRequired,
2019-04-23 22:51:20 +08:00
fileSuffixes: PropTypes.array,
selectedItemInfo: PropTypes.object,
};
class RepoListItem extends React.Component {
constructor(props) {
super(props);
this.state = {
isShowChildren: this.props.initToShowChildren,
treeData: treeHelper.buildTree(),
2024-02-21 17:39:19 +08:00
hasLoaded: false,
};
}
componentDidMount () {
2024-02-21 17:39:19 +08:00
const { isCurrentRepo, currentPath, repo, selectedItemInfo } = this.props;
// render search result
const { repoID, filePath } = selectedItemInfo || {};
if (repoID && repoID === repo.repo_id) {
this.loadRepoDirentList(repo);
setTimeout(() => {
this.setState({isShowChildren: true});
this.loadNodeAndParentsByPath(repoID, filePath);
}, 0);
return;
}
// the repo is current repo and currentPath is not '/'
if (isCurrentRepo && !repoID) {
this.loadRepoDirentList(repo);
setTimeout(() => {
const repoID = repo.repo_id;
if (isCurrentRepo && currentPath && currentPath != '/') {
const expandNode = true;
this.loadNodeAndParentsByPath(repoID, currentPath, expandNode);
}
}, 0);
}
}
loadRepoDirentList = (repo) => {
const { hasLoaded } = this.state;
if (hasLoaded) return;
const repoID = repo.repo_id;
seafileAPI.listDir(repoID, '/').then(res => {
let tree = this.state.treeData.clone();
2019-05-30 10:22:40 +08:00
let direntList = [];
if (this.props.isShowFile === true) {
direntList = res.data.dirent_list;
} else {
direntList = res.data.dirent_list.filter(item => item.type === 'dir');
}
this.addResponseListToNode(direntList, tree.root);
2024-02-21 17:39:19 +08:00
this.setState({ treeData: tree, hasLoaded: true });
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
addResponseListToNode = (list, node) => {
node.isLoaded = true;
node.isExpanded = true;
let direntList = list.map(item => {
return new Dirent(item);
});
direntList = Utils.sortDirents(direntList, 'name', 'asc');
let nodeList = direntList.map(object => {
return new TreeNode({object});
});
node.addChildren(nodeList);
};
onNodeExpanded = (node) => {
let repoID = this.props.repo.repo_id;
let tree = this.state.treeData.clone();
node = tree.getNodeByPath(node.path);
if (!node.isLoaded) {
seafileAPI.listDir(repoID, node.path).then(res => {
2019-05-30 10:22:40 +08:00
let direntList = [];
if (this.props.isShowFile === true) {
direntList = res.data.dirent_list;
} else {
direntList = res.data.dirent_list.filter(item => item.type === 'dir');
}
this.addResponseListToNode(direntList, node);
this.setState({treeData: tree});
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
} else {
tree.expandNode(node);
this.setState({treeData: tree});
}
};
onNodeCollapse = (node) => {
let tree = treeHelper.collapseNode(this.state.treeData, node);
this.setState({treeData: tree});
};
loadNodeAndParentsByPath = (repoID, path, expandNode) => {
let tree = this.state.treeData.clone();
seafileAPI.listDir(repoID, path, {with_parents: true}).then(res => {
let direntList = res.data.dirent_list;
direntList = direntList.filter(item => item.type === 'dir');
let results = {};
for (let i = 0; i < direntList.length; i++) {
let object = direntList[i];
let parentDir = object.parent_dir;
let key = parentDir === '/' ? '/' : parentDir.slice(0, parentDir.length - 1);
if (!results[key]) {
results[key] = [];
}
results[key].push(object);
}
for (let key in results) {
let node = tree.getNodeByPath(key);
if (!node.isLoaded) {
this.addResponseListToNode(results[key], node);
}
}
this.setState({
treeData: tree
}, () => {
if (expandNode) {
this.onNodeExpanded(tree.getNodeByPath(path));
}
});
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
};
2019-06-03 18:10:11 +08:00
onToggleClick = (e) => {
e.stopPropagation();
2024-02-21 17:39:19 +08:00
let repo = this.props.repo;
this.loadRepoDirentList(repo);
this.setState({isShowChildren: !this.state.isShowChildren});
};
2018-12-28 14:25:25 +08:00
onDirentItemClick = (filePath, dirent) => {
let repo = this.props.repo;
2018-12-28 14:25:25 +08:00
this.props.onDirentItemClick(repo, filePath, dirent);
};
2019-06-03 21:04:19 +08:00
onRepoItemClick = (e) => {
2024-02-21 17:39:19 +08:00
const { repo, selectedPath } = this.props;
if (!this.isCurrentRepo() || (selectedPath !== '' && selectedPath !== '/')) {
this.props.onRepoItemClick(repo);
2019-01-09 11:28:16 +08:00
} else {
2019-06-03 21:04:19 +08:00
this.onToggleClick(e);
2019-01-09 11:28:16 +08:00
}
};
2019-01-09 11:28:16 +08:00
isCurrentRepo = () => {
let { selectedRepo, repo } = this.props;
return selectedRepo && (repo.repo_id === selectedRepo.repo_id);
};
render() {
let repoActive = false;
2019-01-09 11:28:16 +08:00
let isCurrentRepo = this.isCurrentRepo();
if (isCurrentRepo && this.props.selectedPath == '/') {
repoActive = true;
}
return (
2019-06-03 17:39:01 +08:00
<li>
<div className={`${repoActive ? 'item-active' : ''} item-info`} onClick={this.onRepoItemClick}>
<div className="item-text">
<span className="name user-select-none ellipsis" title={this.props.repo.repo_name}>{this.props.repo.repo_name}</span>
2019-06-03 17:39:01 +08:00
</div>
<div className="item-left-icon">
<span className={`item-toggle icon fa ${this.state.isShowChildren ? 'fa-caret-down' : 'fa-caret-right'}`} onClick={this.onToggleClick}></span>
<i className="tree-node-icon">
<span className="icon far fa-folder tree-node-icon"></span>
2019-06-03 17:39:01 +08:00
</i>
</div>
2019-06-04 17:59:54 +08:00
</div>
2018-12-18 10:36:42 +08:00
{this.state.isShowChildren && (
<TreeListView
repo={this.props.repo}
onDirentItemClick={this.onDirentItemClick}
2019-02-19 16:52:54 +08:00
selectedRepo={this.props.selectedRepo}
selectedPath={this.props.selectedPath}
2019-04-23 22:51:20 +08:00
fileSuffixes={this.props.fileSuffixes}
treeData={this.state.treeData}
onNodeCollapse={this.onNodeCollapse}
onNodeExpanded={this.onNodeExpanded}
/>
2018-12-18 10:36:42 +08:00
)}
</li>
);
}
}
RepoListItem.propTypes = propTypes;
export default RepoListItem;