1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-20 10:00:00 +00:00
seahub/frontend/src/components/dialog/trash-dialog/index.js
Michael An 08abceb14b
custom modal header close icon (#7240)
* seahub custom modal header

* add custom modal header

* special modal use custom close
2024-12-24 11:20:40 +08:00

257 lines
8.0 KiB
JavaScript

import React from 'react';
import PropTypes from 'prop-types';
import { navigate } from '@gatsbyjs/reach-router';
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
import { Utils } from '../../../utils/utils';
import { gettext, siteRoot, enableUserCleanTrash, username } from '../../../utils/constants';
import { seafileAPI } from '../../../utils/seafile-api';
import { repoTrashAPI } from '../../../utils/repo-trash-api';
import ModalPortal from '../../modal-portal';
import Table from './table';
import CleanTrash from '../clean-trash';
import Paginator from '../../paginator';
import Loading from '../../loading';
import EmptyTip from '../../empty-tip';
import '../../../css/toolbar.css';
import '../../../css/search.css';
import './index.css';
class TrashDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
errorMsg: '',
items: [],
scanStat: null,
more: false,
isCleanTrashDialogOpen: false,
trashType: 0,
isOldTrashDialogOpen: false,
currentPage: 1,
perPage: 100,
hasNextPage: false
};
}
componentDidMount() {
this.getFolderTrash();
}
getFolderTrash = (page) => {
repoTrashAPI.getRepoFolderTrash(this.props.repoID, page, this.state.perPage).then((res) => {
const { items, total_count } = res.data;
if (!page) {
page = 1;
}
this.setState({
currentPage: page,
hasNextPage: total_count - page * this.state.perPage > 0,
isLoading: false,
items: items,
more: false
});
});
};
onSearchedClick = (selectedItem) => {
if (selectedItem.is_dir === true) {
let url = siteRoot + 'library/' + selectedItem.repo_id + '/' + selectedItem.repo_name + selectedItem.path;
navigate(url, { replace: true });
} else {
let url = siteRoot + 'lib/' + selectedItem.repo_id + '/file' + Utils.encodePath(selectedItem.path);
let newWindow = window.open('about:blank');
newWindow.location.href = url;
}
};
getPreviousPage = () => {
this.getFolderTrash(this.state.currentPage - 1);
};
getNextPage = () => {
this.getFolderTrash(this.state.currentPage + 1);
};
resetPerPage = (perPage) => {
this.setState({
perPage: perPage
}, () => {
this.getFolderTrash(1);
});
};
cleanTrash = () => {
this.toggleCleanTrashDialog();
};
toggleCleanTrashDialog = () => {
this.setState({
isCleanTrashDialogOpen: !this.state.isCleanTrashDialogOpen
});
};
refreshTrash2 = () => {
this.setState({
isLoading: true,
errorMsg: '',
items: [],
scanStat: null,
more: false,
showFolder: false
});
this.getFolderTrash();
};
renderFolder = (commitID, baseDir, folderPath) => {
this.setState({
showFolder: true,
commitID: commitID,
baseDir: baseDir,
folderPath: folderPath,
folderItems: [],
isLoading: true
});
seafileAPI.listCommitDir(this.props.repoID, commitID, `${baseDir.substr(0, baseDir.length - 1)}${folderPath}`).then((res) => {
this.setState({
isLoading: false,
folderItems: res.data.dirent_list
});
}).catch((error) => {
if (error.response) {
if (error.response.status == 403) {
this.setState({
isLoading: false,
errorMsg: gettext('Permission denied')
});
} else {
this.setState({
isLoading: false,
errorMsg: gettext('Error')
});
}
} else {
this.setState({
isLoading: false,
errorMsg: gettext('Please check the network.')
});
}
});
};
clickFolderPath = (folderPath, e) => {
e.preventDefault();
const { commitID, baseDir } = this.state;
this.renderFolder(commitID, baseDir, folderPath);
};
clickRoot = (e) => {
e.preventDefault();
this.refreshTrash2();
};
renderFolderPath = () => {
const pathList = this.state.folderPath.split('/');
const repoFolderName = this.props.currentRepoInfo.repo_name;
return (
<React.Fragment>
<a href="#" onClick={this.clickRoot} className="path-item" title={repoFolderName}>{repoFolderName}</a>
<span className="path-split">/</span>
{pathList.map((item, index) => {
if (index > 0 && index != pathList.length - 1) {
return (
<React.Fragment key={index}>
<a className="path-item" href="#" onClick={this.clickFolderPath.bind(this, pathList.slice(0, index + 1).join('/'))} title={pathList[index]}>{pathList[index]}</a>
<span className="path-split">/</span>
</React.Fragment>
);
}
return null;
}
)}
<span className="last-path-item" title={pathList[pathList.length - 1]}>{pathList[pathList.length - 1]}</span>
</React.Fragment>
);
};
render() {
const { showTrashDialog, toggleTrashDialog, repoID } = this.props;
const { isCleanTrashDialogOpen, showFolder, isLoading, items, perPage, currentPage, hasNextPage } = this.state;
const isRepoAdmin = this.props.currentRepoInfo.owner_email === username || this.props.currentRepoInfo.is_admin;
const repoFolderName = this.props.currentRepoInfo.repo_name;
const oldTrashUrl = siteRoot + 'repo/' + this.props.repoID + '/trash/';
let title = gettext('{placeholder} Trash');
title = title.replace('{placeholder}', '<span class="op-target text-truncate mr-1">' + Utils.HTMLescape(repoFolderName) + '</span>');
return (
<>
<Modal className="trash-dialog" isOpen={showTrashDialog} toggle={toggleTrashDialog}>
<ModalHeader
close={
<>
<a className="trash-dialog-old-page" href={oldTrashUrl}>{gettext('Visit old version page')}</a>
{(enableUserCleanTrash && !showFolder && isRepoAdmin) &&
<button className="btn btn-secondary clean flex-shrink-0 ml-4" onClick={this.cleanTrash}>{gettext('Clean')}</button>
}
<span aria-hidden="true" className="trash-dialog-close-icon sf3-font sf3-font-x-01 ml-4" onClick={toggleTrashDialog}></span>
</>
}
>
<div dangerouslySetInnerHTML={{ __html: title }}></div>
</ModalHeader>
<ModalBody>
{isLoading && <Loading />}
{!isLoading && items.length === 0 &&
<EmptyTip text={gettext('No file')} className="m-0" />
}
{!isLoading && items.length > 0 &&
<div>
<div className="path-container dir-view-path mb-2">
<span className="path-label mr-1">{gettext('Current path: ')}</span>
{showFolder ?
this.renderFolderPath() :
<span className="last-path-item" title={repoFolderName}>{repoFolderName}</span>
}
</div>
<Table repoID={repoID} data={this.state} renderFolder={this.renderFolder} />
<Paginator
gotoPreviousPage={this.getPreviousPage}
gotoNextPage={this.getNextPage}
currentPage={currentPage}
hasNextPage={hasNextPage}
curPerPage={perPage}
resetPerPage={this.resetPerPage}
noURLUpdate={true}
/>
</div>
}
</ModalBody>
</Modal>
{isCleanTrashDialogOpen && (
<ModalPortal>
<CleanTrash
repoID={repoID}
refreshTrash={this.refreshTrash2}
toggleDialog={this.toggleCleanTrashDialog}
/>
</ModalPortal>
)}
</>
);
}
}
TrashDialog.propTypes = {
repoID: PropTypes.string.isRequired,
currentRepoInfo: PropTypes.object.isRequired,
showTrashDialog: PropTypes.bool.isRequired,
toggleTrashDialog: PropTypes.func.isRequired
};
export default TrashDialog;