1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-10-22 03:16:34 +00:00
Files
seahub/frontend/src/pages/sys-admin/repos/dir-view.js

223 lines
6.9 KiB
JavaScript

import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Button } from 'reactstrap';
import axios from 'axios';
import { Utils } from '../../../utils/utils';
import { systemAdminAPI } from '../../../utils/system-admin-api';
import { siteRoot, gettext } from '../../../utils/constants';
import toaster from '../../../components/toast';
import CreateFolderDialog from '../../../components/dialog/create-folder-dialog';
import Dirent from '../../../models/system-admin/dirent';
import MainPanelTopbar from '../main-panel-topbar';
import DirPathBar from './dir-path-bar';
import DirContent from './dir-content';
class DirView extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
errorMsg: '',
isSystemRepo: false,
repoName: '',
path: '',
direntList: [],
isNewFolderDialogOpen: false
};
this.fileInput = React.createRef();
}
componentDidMount() {
this.loadDirentList('/');
}
onPathClick = (path) => {
this.loadDirentList(path);
};
toggleNewFolderDialog = () => {
this.setState({ isNewFolderDialogOpen: !this.state.isNewFolderDialogOpen });
};
createNewFolder = (path) => {
let folderName = Utils.getFileName(path);
systemAdminAPI.sysAdminCreateSysRepoFolder(this.props.repoID, this.state.path, folderName).then(res => {
let new_dirent = new Dirent(res.data);
let direntList = this.state.direntList;
direntList.unshift(new_dirent);
this.setState({
direntList: direntList
});
this.toggleNewFolderDialog();
}).catch((err) => {
let errMessage = Utils.getErrorMsg(err);
toaster.danger(errMessage);
});
};
openFolder = (dirent) => {
let direntPath = Utils.joinPath(this.state.path, dirent.name);
if (!dirent.is_file) {
this.loadDirentList(direntPath);
}
};
loadDirentList = (path) => {
const repoID = this.props.repoID;
systemAdminAPI.sysAdminListRepoDirents(repoID, path).then(res => {
const { is_system_library: isSystemRepo, repo_name: repoName, dirent_list } = res.data;
let direntList = [];
dirent_list.forEach(item => {
let dirent = new Dirent(item);
direntList.push(dirent);
});
this.setState({
loading: false,
repoName: repoName,
isSystemRepo: isSystemRepo,
direntList: direntList,
path: path,
}, () => {
let url = siteRoot + 'sys/libraries/' + repoID + '/' + encodeURIComponent(this.state.repoName) + Utils.encodePath(path);
window.history.replaceState({ url: url, path: path }, path, url);
});
}).catch((error) => {
this.setState({
loading: false,
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
});
});
};
deleteDirent = (dirent) => {
let path = Utils.joinPath(this.state.path, dirent.name);
systemAdminAPI.sysAdminDeleteRepoDirent(this.props.repoID, path).then(res => {
toaster.success(gettext('Successfully deleted 1 item.'));
let direntList = this.state.direntList.filter(item => {
return item.name != dirent.name;
});
this.setState({
direntList: direntList
});
}).catch((err) => {
let errMessage = Utils.getErrorMsg(err);
toaster.danger(errMessage);
});
};
downloadDirent = (dirent) => {
let path = Utils.joinPath(this.state.path, dirent.name);
systemAdminAPI.sysAdminGetRepoFileDownloadURL(this.props.repoID, path).then(res => {
location.href = res.data.download_url;
}).catch((err) => {
let errMessage = Utils.getErrorMsg(err);
toaster.danger(errMessage);
});
};
openFileInput = () => {
this.fileInput.current.click();
};
onFileInputChange = () => {
if (!this.fileInput.current.files.length) {
return;
}
const file = this.fileInput.current.files[0];
let { path } = this.state;
systemAdminAPI.sysAdminGetSysRepoItemUploadURL(path).then(res => {
let formData = new FormData();
formData.append('parent_dir', path);
formData.append('file', file);
axios.post(res.data.upload_link, formData).then(res => {
const fileObj = res.data[0];
let newDirent = new Dirent({
'is_file': true,
'type': 'file',
'obj_name': fileObj.name,
'file_size': Utils.bytesToSize(fileObj.size),
'last_update': (new Date()).getTime()
});
let direntList = this.state.direntList;
const dirs = direntList.filter(item => { return !item.is_file; });
direntList.splice(dirs.length, 0, newDirent);
this.setState({
direntList: direntList
});
});
}).catch((err) => {
let errMessage = Utils.getErrorMsg(err);
toaster.danger(errMessage);
});
};
checkDuplicatedName = (newName) => {
let direntList = this.state.direntList;
let isDuplicated = direntList.some(object => {
return object.name === newName;
});
return isDuplicated;
};
render() {
const { loading, errorMsg,
repoName, direntList, isSystemRepo, path,
isNewFolderDialogOpen } = this.state;
const { repoID } = this.props;
return (
<Fragment>
{isSystemRepo ?
<MainPanelTopbar {...this.props}>
<Fragment>
<input className="d-none" type="file" onChange={this.onFileInputChange} ref={this.fileInput} />
<Button className="operation-item" onClick={this.openFileInput}>{gettext('Upload')}</Button>
<Button className="operation-item" onClick={this.toggleNewFolderDialog}>{gettext('New Folder')}</Button>
</Fragment>
</MainPanelTopbar> : <MainPanelTopbar {...this.props} />
}
<div className="main-panel-center flex-row">
<div className="cur-view-container">
<div className="cur-view-path align-items-center">
<DirPathBar
isSystemRepo={isSystemRepo}
repoID={repoID}
repoName={repoName}
currentPath={path}
onPathClick={this.onPathClick}
/>
</div>
<div className="cur-view-content">
<DirContent
loading={loading}
errorMsg={errorMsg}
fromSystemRepo={isSystemRepo}
direntList={direntList}
openFolder={this.openFolder}
deleteDirent={this.deleteDirent}
downloadDirent={this.downloadDirent}
/>
</div>
</div>
</div>
{isNewFolderDialogOpen &&
<CreateFolderDialog
parentPath={path}
checkDuplicatedName={this.checkDuplicatedName}
onAddFolder={this.createNewFolder}
addFolderCancel={this.toggleNewFolderDialog}
/>
}
</Fragment>
);
}
}
DirView.propTypes = {
repoID: PropTypes.string,
};
export default DirView;