mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-09 02:42:47 +00:00
[related files] removed all the related functions
This commit is contained in:
@@ -7,7 +7,8 @@
|
|||||||
"@seafile/react-image-lightbox": "0.0.1",
|
"@seafile/react-image-lightbox": "0.0.1",
|
||||||
"@seafile/resumablejs": "1.1.16",
|
"@seafile/resumablejs": "1.1.16",
|
||||||
"@seafile/seafile-calendar": "0.0.12",
|
"@seafile/seafile-calendar": "0.0.12",
|
||||||
"@seafile/seafile-editor": "^0.3.93",
|
"@seafile/seafile-editor": "^0.3.94",
|
||||||
|
"MD5": "^1.3.0",
|
||||||
"chart.js": "2.9.4",
|
"chart.js": "2.9.4",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"copy-to-clipboard": "^3.0.8",
|
"copy-to-clipboard": "^3.0.8",
|
||||||
@@ -15,7 +16,6 @@
|
|||||||
"i18next": "^17.0.13",
|
"i18next": "^17.0.13",
|
||||||
"i18next-browser-languagedetector": "^3.0.3",
|
"i18next-browser-languagedetector": "^3.0.3",
|
||||||
"i18next-xhr-backend": "^3.1.2",
|
"i18next-xhr-backend": "^3.1.2",
|
||||||
"MD5": "^1.3.0",
|
|
||||||
"merge": "^1.2.1",
|
"merge": "^1.2.1",
|
||||||
"moment": "^2.22.2",
|
"moment": "^2.22.2",
|
||||||
"object-assign": "4.1.1",
|
"object-assign": "4.1.1",
|
||||||
|
@@ -1,118 +0,0 @@
|
|||||||
import React ,{ Fragment } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Button, ModalHeader, ModalBody, ModalFooter, Alert } from 'reactstrap';
|
|
||||||
import { gettext } from '../../utils/constants';
|
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
|
||||||
import { Utils } from '../../utils/utils';
|
|
||||||
import FileChooser from '../file-chooser/file-chooser';
|
|
||||||
import '../../css/dirent-detail.css';
|
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
repoID: PropTypes.string.isRequired,
|
|
||||||
filePath: PropTypes.string.isRequired,
|
|
||||||
toggleCancel: PropTypes.func.isRequired,
|
|
||||||
onRelatedFileChange: PropTypes.func.isRequired,
|
|
||||||
dirent: PropTypes.object.isRequired,
|
|
||||||
onClose: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
class AddRelatedFileDialog extends React.Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
repo: null,
|
|
||||||
selectedPath: '',
|
|
||||||
isShowFile: true,
|
|
||||||
errMessage: '',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSubmit = () => {
|
|
||||||
this.onAddRelatedFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
onAddRelatedFile = () => {
|
|
||||||
let { repo, selectedPath } = this.state;
|
|
||||||
let oRepoID = this.props.repoID;
|
|
||||||
let rRepoID = repo.repo_id;
|
|
||||||
let oFilePath = this.props.filePath;
|
|
||||||
let rFilePath = selectedPath;
|
|
||||||
|
|
||||||
if (oRepoID === rRepoID && oFilePath === rFilePath) {
|
|
||||||
let message = gettext('Can not select self as a related file.');
|
|
||||||
this.setState({errMessage: message});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
seafileAPI.addRelatedFile(oRepoID, rRepoID, oFilePath, rFilePath).then((res) => {
|
|
||||||
this.props.onRelatedFileChange();
|
|
||||||
this.toggle();
|
|
||||||
}).catch((error) => {
|
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
|
||||||
this.setState({errMessage: errMessage});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle = () => {
|
|
||||||
this.props.toggleCancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
onDirentItemClick = (repo, selectedPath, dirent) => {
|
|
||||||
if (dirent.type === 'file') {
|
|
||||||
this.setState({
|
|
||||||
repo: repo,
|
|
||||||
selectedPath: selectedPath,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.setState({
|
|
||||||
repo: null,
|
|
||||||
selectedPath: '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onRepoItemClick = (repo) => {
|
|
||||||
this.setState({
|
|
||||||
repo: null,
|
|
||||||
selectedPath: '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let subtitle = gettext('Select related file for {placeholder}');
|
|
||||||
subtitle = subtitle.replace('{placeholder}', '<span class="op-target">' + Utils.HTMLescape(this.props.dirent.name) + '</span>');
|
|
||||||
return (
|
|
||||||
<div className="sf-add-related-file">
|
|
||||||
<ModalHeader toggle={this.props.onClose}>
|
|
||||||
<span className="tag-dialog-back fas fa-sm fa-arrow-left" onClick={this.toggle} aria-label={gettext('Back')}></span>
|
|
||||||
{gettext('Select File')}
|
|
||||||
</ModalHeader>
|
|
||||||
<ModalBody>
|
|
||||||
<div className="related-file-subtitle" dangerouslySetInnerHTML={{__html: subtitle}}></div>
|
|
||||||
<FileChooser
|
|
||||||
isShowFile={this.state.isShowFile}
|
|
||||||
repoID={this.props.repoID}
|
|
||||||
onDirentItemClick={this.onDirentItemClick}
|
|
||||||
onRepoItemClick={this.onRepoItemClick}
|
|
||||||
mode="current_repo_and_other_repos"
|
|
||||||
/>
|
|
||||||
{this.state.errMessage && <Alert color="danger">{this.state.errMessage}</Alert>}
|
|
||||||
</ModalBody>
|
|
||||||
<ModalFooter>
|
|
||||||
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
|
|
||||||
{ this.state.selectedPath ?
|
|
||||||
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>
|
|
||||||
:
|
|
||||||
<Button color="primary" disabled>{gettext('Submit')}</Button>
|
|
||||||
}
|
|
||||||
</ModalFooter>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddRelatedFileDialog.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default AddRelatedFileDialog;
|
|
@@ -1,159 +0,0 @@
|
|||||||
import React ,{ Fragment } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Button, ModalHeader, ModalBody, ModalFooter, Table } from 'reactstrap';
|
|
||||||
import Dirent from '../../models/dirent';
|
|
||||||
import { gettext, siteRoot } from '../../utils/constants';
|
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
|
||||||
import { Utils } from '../../utils/utils';
|
|
||||||
import toaster from '../toast';
|
|
||||||
import '../../css/list-related-file-dialog.css';
|
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
relatedFiles: PropTypes.array.isRequired,
|
|
||||||
repoID: PropTypes.string.isRequired,
|
|
||||||
filePath: PropTypes.string.isRequired,
|
|
||||||
toggleCancel: PropTypes.func.isRequired,
|
|
||||||
addRelatedFileToggle: PropTypes.func.isRequired,
|
|
||||||
onRelatedFileChange: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
class ListRelatedFileDialog extends React.Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = ({
|
|
||||||
direntList: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onDeleteRelatedFile = (item) => {
|
|
||||||
let filePath = this.props.filePath;
|
|
||||||
let repoID = this.props.repoID;
|
|
||||||
let relatedID = item.related_id;
|
|
||||||
seafileAPI.deleteRelatedFile(repoID, filePath, relatedID).then((res) => {
|
|
||||||
this.props.onRelatedFileChange();
|
|
||||||
}).catch(error => {
|
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
|
||||||
toaster.danger(errMessage);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle = () => {
|
|
||||||
this.props.toggleCancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirentList = (relatedFiles) => {
|
|
||||||
if (relatedFiles.length === 0) {
|
|
||||||
this.setState({
|
|
||||||
direntList: [],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let direntList = [];
|
|
||||||
relatedFiles.map((item) => {
|
|
||||||
seafileAPI.getFileInfo(item.repo_id, item.path).then(res => {
|
|
||||||
let dirent = new Dirent(res.data);
|
|
||||||
dirent['repo_name'] = item.repo_name;
|
|
||||||
dirent['related_id'] = item.related_id;
|
|
||||||
dirent['link'] = siteRoot + 'lib/' + item.repo_id + '/file' + Utils.encodePath(item.path);
|
|
||||||
direntList.push(dirent);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.setState({direntList: direntList});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillMount() {
|
|
||||||
this.getDirentList(this.props.relatedFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
|
||||||
if (nextProps.relatedFiles.length !== this.props.relatedFiles.length) {
|
|
||||||
this.getDirentList(nextProps.relatedFiles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<ModalHeader toggle={this.toggle}>{gettext('Related Files')}</ModalHeader>
|
|
||||||
<ModalBody className={this.state.direntList.length > 0 ? 'list-related-file-body' : ''}>
|
|
||||||
<Table hover size="sm" className="list-related-file-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th width='40%'>{gettext('Name')}</th>
|
|
||||||
<th width='20%'>{gettext('Library Name')}</th>
|
|
||||||
<th width='13%'>{gettext('Size')}</th>
|
|
||||||
<th width='20%'>{gettext('Last Update')}</th>
|
|
||||||
<th width='5%'></th>
|
|
||||||
<th width='2%'></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{
|
|
||||||
this.state.direntList.map((relatedFile, index) => {
|
|
||||||
return (
|
|
||||||
<React.Fragment key={index}>
|
|
||||||
<RelatedFile relatedFile={relatedFile} onDeleteRelatedFile={this.onDeleteRelatedFile}/>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</Table>
|
|
||||||
<a href="#" className="add-related-file-link" onClick={this.props.addRelatedFileToggle}>{gettext('Add File')}</a>
|
|
||||||
</ModalBody>
|
|
||||||
<ModalFooter>
|
|
||||||
<Button color="secondary" onClick={this.toggle}>{gettext('Close')}</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListRelatedFileDialog.propTypes = propTypes;
|
|
||||||
|
|
||||||
const RelatedFilePropTypes = {
|
|
||||||
relatedFile: PropTypes.object,
|
|
||||||
onDeleteRelatedFile: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
class RelatedFile extends React.Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = ({
|
|
||||||
active: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMouseEnter = () => {
|
|
||||||
this.setState({
|
|
||||||
active: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMouseLeave = () => {
|
|
||||||
this.setState({
|
|
||||||
active: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let className = this.state.active ? 'action-icon sf2-icon-x3' : 'action-icon vh sf2-icon-x3';
|
|
||||||
const relatedFile = this.props.relatedFile;
|
|
||||||
return (
|
|
||||||
<tr onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
|
||||||
<td><a href={relatedFile.link} target='_blank'>{relatedFile.name}</a></td>
|
|
||||||
<td>{relatedFile.repo_name}</td>
|
|
||||||
<td>{relatedFile.size}</td>
|
|
||||||
<td>{relatedFile.mtime_relative}</td>
|
|
||||||
<td><i className={className} onClick={this.props.onDeleteRelatedFile.bind(this, relatedFile)}></i></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RelatedFile.propTypes = RelatedFilePropTypes;
|
|
||||||
|
|
||||||
export default ListRelatedFileDialog;
|
|
@@ -1,71 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Modal } from 'reactstrap';
|
|
||||||
import AddRelatedFileDialog from './add-related-file-dialog';
|
|
||||||
import ListRelatedFileDialog from './list-related-file-dialog';
|
|
||||||
import ModalPortal from '../modal-portal';
|
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
repoID: PropTypes.string.isRequired,
|
|
||||||
filePath: PropTypes.string.isRequired,
|
|
||||||
toggleCancel: PropTypes.func.isRequired,
|
|
||||||
onRelatedFileChange: PropTypes.func.isRequired,
|
|
||||||
dirent: PropTypes.object.isRequired,
|
|
||||||
relatedFiles: PropTypes.array,
|
|
||||||
viewMode: PropTypes.oneOf(['list_related_file','add_related_file']).isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
class RelatedFileDialogs extends React.Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
showListRelatedFileDialog: props.viewMode === 'list_related_file',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onAddRelatedFileToggle = () => {
|
|
||||||
this.setState({
|
|
||||||
showListRelatedFileDialog: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onCloseAddRelatedFileDialog = () => {
|
|
||||||
this.setState({
|
|
||||||
showListRelatedFileDialog: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<ModalPortal>
|
|
||||||
<Modal isOpen={true} toggle={this.props.toggleCancel} size='lg' style={{width:'650px'}}>
|
|
||||||
{this.state.showListRelatedFileDialog &&
|
|
||||||
<ListRelatedFileDialog
|
|
||||||
filePath={this.props.filePath}
|
|
||||||
relatedFiles={this.props.relatedFiles}
|
|
||||||
repoID={this.props.repoID}
|
|
||||||
toggleCancel={this.props.toggleCancel}
|
|
||||||
addRelatedFileToggle={this.onAddRelatedFileToggle}
|
|
||||||
onRelatedFileChange={this.props.onRelatedFileChange}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
{!this.state.showListRelatedFileDialog &&
|
|
||||||
<AddRelatedFileDialog
|
|
||||||
filePath={this.props.filePath}
|
|
||||||
repoID={this.props.repoID}
|
|
||||||
toggleCancel={this.onCloseAddRelatedFileDialog}
|
|
||||||
onRelatedFileChange={this.props.onRelatedFileChange}
|
|
||||||
dirent={this.props.dirent}
|
|
||||||
onClose={this.props.toggleCancel}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</Modal>
|
|
||||||
</ModalPortal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RelatedFileDialogs.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default RelatedFileDialogs;
|
|
@@ -1,11 +1,10 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { gettext, siteRoot } from '../../utils/constants';
|
import { gettext } from '../../utils/constants';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||||
import ModalPortal from '../modal-portal';
|
import ModalPortal from '../modal-portal';
|
||||||
import RelatedFileDialogs from '../dialog/related-file-dialogs';
|
|
||||||
import ParticipantsList from '../file-view/participants-list';
|
import ParticipantsList from '../file-view/participants-list';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
@@ -16,9 +15,7 @@ const propTypes = {
|
|||||||
direntDetail: PropTypes.object.isRequired,
|
direntDetail: PropTypes.object.isRequired,
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
fileTagList: PropTypes.array.isRequired,
|
fileTagList: PropTypes.array.isRequired,
|
||||||
relatedFiles: PropTypes.array.isRequired,
|
|
||||||
onFileTagChanged: PropTypes.func.isRequired,
|
onFileTagChanged: PropTypes.func.isRequired,
|
||||||
onRelatedFileChange: PropTypes.func.isRequired,
|
|
||||||
onParticipantsChange: PropTypes.func.isRequired,
|
onParticipantsChange: PropTypes.func.isRequired,
|
||||||
fileParticipantList: PropTypes.array.isRequired,
|
fileParticipantList: PropTypes.array.isRequired,
|
||||||
};
|
};
|
||||||
@@ -28,8 +25,7 @@ class DetailListView extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isEditFileTagShow: false,
|
isEditFileTagShow: false
|
||||||
showRelatedFileDialog: false,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,25 +60,8 @@ class DetailListView extends React.Component {
|
|||||||
return Utils.joinPath(path, dirent.name);
|
return Utils.joinPath(path, dirent.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRelatedFileChange = () => {
|
|
||||||
let direntPath = this.getDirentPath();
|
|
||||||
this.props.onRelatedFileChange(this.props.dirent, direntPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
onListRelatedFileToggle = () => {
|
|
||||||
this.setState({
|
|
||||||
showRelatedFileDialog: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleCancel = () => {
|
|
||||||
this.setState({
|
|
||||||
showRelatedFileDialog: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { direntType, direntDetail, fileTagList, relatedFiles, fileParticipantList } = this.props;
|
let { direntType, direntDetail, fileTagList, fileParticipantList } = this.props;
|
||||||
let position = this.getDirentPostion();
|
let position = this.getDirentPostion();
|
||||||
let direntPath = this.getDirentPath();
|
let direntPath = this.getDirentPath();
|
||||||
if (direntType === 'dir') {
|
if (direntType === 'dir') {
|
||||||
@@ -124,22 +103,6 @@ class DetailListView extends React.Component {
|
|||||||
<i className='fa fa-pencil-alt attr-action-icon' onClick={this.onEditFileTagToggle}></i>
|
<i className='fa fa-pencil-alt attr-action-icon' onClick={this.onEditFileTagToggle}></i>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr className="file-related-files">
|
|
||||||
<th>{gettext('Related Files')}</th>
|
|
||||||
<td>
|
|
||||||
<ul>
|
|
||||||
{relatedFiles.map((relatedFile, index) => {
|
|
||||||
let href = siteRoot + 'lib/' + relatedFile.repo_id + '/file' + Utils.encodePath(relatedFile.path);
|
|
||||||
return (
|
|
||||||
<li key={index}>
|
|
||||||
<a href={href} target='_blank'>{relatedFile.name}</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
<i className='fa fa-pencil-alt attr-action-icon' onClick={this.onListRelatedFileToggle}></i>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr className="file-participants">
|
<tr className="file-participants">
|
||||||
<th>{gettext('Participants')}</th>
|
<th>{gettext('Participants')}</th>
|
||||||
<td>
|
<td>
|
||||||
@@ -156,19 +119,6 @@ class DetailListView extends React.Component {
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{this.state.showRelatedFileDialog &&
|
|
||||||
<ModalPortal>
|
|
||||||
<RelatedFileDialogs
|
|
||||||
repoID={this.props.repoID}
|
|
||||||
filePath={direntPath}
|
|
||||||
relatedFiles={relatedFiles}
|
|
||||||
toggleCancel={this.toggleCancel}
|
|
||||||
onRelatedFileChange={this.onRelatedFileChange}
|
|
||||||
dirent={this.props.dirent}
|
|
||||||
viewMode="list_related_file"
|
|
||||||
/>
|
|
||||||
</ModalPortal>
|
|
||||||
}
|
|
||||||
{this.state.isEditFileTagShow &&
|
{this.state.isEditFileTagShow &&
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<EditFileTagDialog
|
<EditFileTagDialog
|
||||||
@@ -188,4 +138,4 @@ class DetailListView extends React.Component {
|
|||||||
|
|
||||||
DetailListView.propTypes = propTypes;
|
DetailListView.propTypes = propTypes;
|
||||||
|
|
||||||
export default DetailListView;
|
export default DetailListView;
|
||||||
|
@@ -30,7 +30,6 @@ class DirentDetail extends React.Component {
|
|||||||
direntType: '',
|
direntType: '',
|
||||||
direntDetail: '',
|
direntDetail: '',
|
||||||
fileTagList: [],
|
fileTagList: [],
|
||||||
relatedFiles: [],
|
|
||||||
folderDirent: null,
|
folderDirent: null,
|
||||||
activeTab: 'info',
|
activeTab: 'info',
|
||||||
fileParticipantList: [],
|
fileParticipantList: [],
|
||||||
@@ -106,21 +105,6 @@ class DirentDetail extends React.Component {
|
|||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
toaster.danger(errMessage);
|
toaster.danger(errMessage);
|
||||||
});
|
});
|
||||||
seafileAPI.listRelatedFiles(repoID, direntPath).then(res => {
|
|
||||||
let relatedFiles = [];
|
|
||||||
res.data.related_files.map((relatedFile) => {
|
|
||||||
relatedFiles.push(relatedFile);
|
|
||||||
});
|
|
||||||
this.setState({
|
|
||||||
relatedFiles: relatedFiles,
|
|
||||||
});
|
|
||||||
}).catch((error) => {
|
|
||||||
if (error.response.status === 500) {
|
|
||||||
this.setState({
|
|
||||||
relatedFiles: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.listParticipants(repoID, direntPath);
|
this.listParticipants(repoID, direntPath);
|
||||||
} else {
|
} else {
|
||||||
seafileAPI.getDirInfo(repoID, direntPath).then(res => {
|
seafileAPI.getDirInfo(repoID, direntPath).then(res => {
|
||||||
@@ -145,10 +129,6 @@ class DirentDetail extends React.Component {
|
|||||||
this.listParticipants(repoID, filePath);
|
this.listParticipants(repoID, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRelatedFileChange = (dirent, direntPath) => {
|
|
||||||
this.updateDetailView(dirent, direntPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
tabItemClick = (tab) => {
|
tabItemClick = (tab) => {
|
||||||
if (this.state.activeTab !== tab) {
|
if (this.state.activeTab !== tab) {
|
||||||
this.setState({ activeTab: tab });
|
this.setState({ activeTab: tab });
|
||||||
@@ -203,9 +183,7 @@ class DirentDetail extends React.Component {
|
|||||||
direntType={this.state.direntType}
|
direntType={this.state.direntType}
|
||||||
direntDetail={this.state.direntDetail}
|
direntDetail={this.state.direntDetail}
|
||||||
fileTagList={this.state.fileTagList}
|
fileTagList={this.state.fileTagList}
|
||||||
relatedFiles={this.state.relatedFiles}
|
|
||||||
onFileTagChanged={this.props.onFileTagChanged}
|
onFileTagChanged={this.props.onFileTagChanged}
|
||||||
onRelatedFileChange={this.onRelatedFileChange}
|
|
||||||
fileParticipantList={this.state.fileParticipantList}
|
fileParticipantList={this.state.fileParticipantList}
|
||||||
onParticipantsChange={this.onParticipantsChange}
|
onParticipantsChange={this.onParticipantsChange}
|
||||||
/>
|
/>
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Button, ButtonGroup } from 'reactstrap';
|
import { Button, ButtonGroup } from 'reactstrap';
|
||||||
import { gettext, siteRoot, canGenerateShareLink, isPro, fileAuditEnabled, name, fileServerRoot, useGoFileserver } from '../../utils/constants';
|
import { gettext, siteRoot, name, fileServerRoot, useGoFileserver } from '../../utils/constants';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import URLDecorator from '../../utils/url-decorator';
|
import URLDecorator from '../../utils/url-decorator';
|
||||||
import TextTranslation from '../../utils/text-translation';
|
|
||||||
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
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 RelatedFileDialogs from '../dialog/related-file-dialogs';
|
|
||||||
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||||
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
||||||
import Rename from '../dialog/rename-dirent';
|
import Rename from '../dialog/rename-dirent';
|
||||||
@@ -55,8 +53,6 @@ class MultipleDirOperationToolbar extends React.Component {
|
|||||||
showEditFileTagDialog: false,
|
showEditFileTagDialog: false,
|
||||||
fileTagList: [],
|
fileTagList: [],
|
||||||
multiFileTagList: [],
|
multiFileTagList: [],
|
||||||
showRelatedFileDialog: false,
|
|
||||||
viewMode: 'list_related_file',
|
|
||||||
isRenameDialogOpen: false,
|
isRenameDialogOpen: false,
|
||||||
isPermissionDialogOpen: false
|
isPermissionDialogOpen: false
|
||||||
};
|
};
|
||||||
@@ -178,9 +174,6 @@ class MultipleDirOperationToolbar extends React.Component {
|
|||||||
case 'Comment':
|
case 'Comment':
|
||||||
this.onCommentItem();
|
this.onCommentItem();
|
||||||
break;
|
break;
|
||||||
case 'Related Files':
|
|
||||||
this.openRelatedFilesDialog(dirent);
|
|
||||||
break;
|
|
||||||
case 'History':
|
case 'History':
|
||||||
this.onHistory(dirent);
|
this.onHistory(dirent);
|
||||||
break;
|
break;
|
||||||
@@ -251,37 +244,11 @@ class MultipleDirOperationToolbar extends React.Component {
|
|||||||
window.open(path);
|
window.open(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
openRelatedFilesDialog = (dirent) => {
|
|
||||||
let filePath = this.getDirentPath(dirent);
|
|
||||||
seafileAPI.listRelatedFiles(this.props.repoID, filePath).then(res => {
|
|
||||||
let relatedFiles = res.data.related_files;
|
|
||||||
if (relatedFiles.length > 0) {
|
|
||||||
this.setState({
|
|
||||||
relatedFiles: relatedFiles,
|
|
||||||
showLibContentViewDialogs: true,
|
|
||||||
showRelatedFileDialog: true,
|
|
||||||
viewMode: 'list_related_file',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
relatedFiles: relatedFiles,
|
|
||||||
showLibContentViewDialogs: true,
|
|
||||||
showRelatedFileDialog: true,
|
|
||||||
viewMode: 'add_related_file',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
|
||||||
toaster.danger(errMessage);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleCancel = () => {
|
toggleCancel = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showLibContentViewDialogs: false,
|
showLibContentViewDialogs: false,
|
||||||
showShareDialog: false,
|
showShareDialog: false,
|
||||||
showEditFileTagDialog: false,
|
showEditFileTagDialog: false,
|
||||||
showRelatedFileDialog: false,
|
|
||||||
isRenameDialogOpen: false,
|
isRenameDialogOpen: false,
|
||||||
isPermissionDialogOpen: false,
|
isPermissionDialogOpen: false,
|
||||||
});
|
});
|
||||||
@@ -315,22 +282,6 @@ class MultipleDirOperationToolbar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listRelatedFiles = (dirent) => {
|
|
||||||
let filePath = this.getDirentPath(dirent);
|
|
||||||
seafileAPI.listRelatedFiles(this.props.repoID, filePath).then(res => {
|
|
||||||
this.setState({
|
|
||||||
relatedFiles: res.data.related_files
|
|
||||||
});
|
|
||||||
}).catch(error => {
|
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
|
||||||
toaster.danger(errMessage);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onRelatedFileChange = () => {
|
|
||||||
this.listRelatedFiles(this.props.selectedDirentList[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
getDirentPath = (dirent) => {
|
getDirentPath = (dirent) => {
|
||||||
if (dirent) return Utils.joinPath(this.props.path, dirent.name);
|
if (dirent) return Utils.joinPath(this.props.path, dirent.name);
|
||||||
}
|
}
|
||||||
@@ -467,19 +418,6 @@ class MultipleDirOperationToolbar extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</ModalPortal>
|
</ModalPortal>
|
||||||
}
|
}
|
||||||
{this.state.showRelatedFileDialog &&
|
|
||||||
<ModalPortal>
|
|
||||||
<RelatedFileDialogs
|
|
||||||
repoID={repoID}
|
|
||||||
filePath={direntPath}
|
|
||||||
relatedFiles={this.state.relatedFiles}
|
|
||||||
toggleCancel={this.toggleCancel}
|
|
||||||
onRelatedFileChange={this.onRelatedFileChange}
|
|
||||||
dirent={this.props.selectedDirentList[0]}
|
|
||||||
viewMode={this.state.viewMode}
|
|
||||||
/>
|
|
||||||
</ModalPortal>
|
|
||||||
}
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@@ -8,7 +8,6 @@ import toaster from '../toast';
|
|||||||
import ModalPotal from '../modal-portal';
|
import ModalPotal from '../modal-portal';
|
||||||
import ShareDialog from '../dialog/share-dialog';
|
import ShareDialog from '../dialog/share-dialog';
|
||||||
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||||
import RelatedFileDialogs from '../dialog/related-file-dialogs';
|
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
@@ -21,9 +20,7 @@ const propTypes = {
|
|||||||
isDraft: PropTypes.bool.isRequired,
|
isDraft: PropTypes.bool.isRequired,
|
||||||
hasDraft: PropTypes.bool.isRequired,
|
hasDraft: PropTypes.bool.isRequired,
|
||||||
fileTags: PropTypes.array.isRequired,
|
fileTags: PropTypes.array.isRequired,
|
||||||
relatedFiles: PropTypes.array.isRequired,
|
|
||||||
onFileTagChanged: PropTypes.func.isRequired,
|
onFileTagChanged: PropTypes.func.isRequired,
|
||||||
onRelatedFileChange: PropTypes.func.isRequired,
|
|
||||||
showShareBtn: PropTypes.bool.isRequired,
|
showShareBtn: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,8 +33,6 @@ class ViewFileToolbar extends React.Component {
|
|||||||
isMoreMenuShow: false,
|
isMoreMenuShow: false,
|
||||||
isShareDialogShow: false,
|
isShareDialogShow: false,
|
||||||
isEditTagDialogShow: false,
|
isEditTagDialogShow: false,
|
||||||
isRelatedFileDialogShow: false,
|
|
||||||
showRelatedFileDialog: false,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,20 +70,6 @@ class ViewFileToolbar extends React.Component {
|
|||||||
this.setState({isEditTagDialogShow: !this.state.isEditTagDialogShow});
|
this.setState({isEditTagDialogShow: !this.state.isEditTagDialogShow});
|
||||||
}
|
}
|
||||||
|
|
||||||
onListRelatedFileToggle = () => {
|
|
||||||
this.setState({
|
|
||||||
isRelatedFileDialogShow: true,
|
|
||||||
showRelatedFileDialog: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleCancel = () => {
|
|
||||||
this.setState({
|
|
||||||
isRelatedFileDialogShow: false,
|
|
||||||
showRelatedFileDialog: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onHistoryClick = () => {
|
onHistoryClick = () => {
|
||||||
let historyUrl = siteRoot + 'repo/file_revisions/' + this.props.repoID + '/?p=' + Utils.encodePath(this.props.path);
|
let historyUrl = siteRoot + 'repo/file_revisions/' + this.props.repoID + '/?p=' + Utils.encodePath(this.props.path);
|
||||||
location.href = historyUrl;
|
location.href = historyUrl;
|
||||||
@@ -122,7 +103,6 @@ class ViewFileToolbar extends React.Component {
|
|||||||
<DropdownItem onClick={this.onShareToggle}>{gettext('Share')}</DropdownItem>
|
<DropdownItem onClick={this.onShareToggle}>{gettext('Share')}</DropdownItem>
|
||||||
}
|
}
|
||||||
<DropdownItem onClick={this.onEditFileTagToggle}>{gettext('Tags')}</DropdownItem>
|
<DropdownItem onClick={this.onEditFileTagToggle}>{gettext('Tags')}</DropdownItem>
|
||||||
<DropdownItem onClick={this.onListRelatedFileToggle}>{gettext('Related Files')}</DropdownItem>
|
|
||||||
<DropdownItem onClick={this.onHistoryClick}>{gettext('History')}</DropdownItem>
|
<DropdownItem onClick={this.onHistoryClick}>{gettext('History')}</DropdownItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
@@ -154,19 +134,6 @@ class ViewFileToolbar extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</ModalPotal>
|
</ModalPotal>
|
||||||
)}
|
)}
|
||||||
{this.state.showRelatedFileDialog &&
|
|
||||||
<ModalPotal>
|
|
||||||
<RelatedFileDialogs
|
|
||||||
repoID={this.props.repoID}
|
|
||||||
filePath={this.props.path}
|
|
||||||
relatedFiles={this.props.relatedFiles}
|
|
||||||
toggleCancel={this.toggleCancel}
|
|
||||||
onRelatedFileChange={this.props.onRelatedFileChange}
|
|
||||||
dirent={dirent}
|
|
||||||
viewMode="list_related_file"
|
|
||||||
/>
|
|
||||||
</ModalPotal>
|
|
||||||
}
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer';
|
import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer';
|
||||||
import { gettext, repoID, slug, serviceURL, isPublicWiki, siteRoot, sharedToken, mediaUrl } from '../utils/constants';
|
import { gettext, repoID, slug, serviceURL, isPublicWiki, sharedToken, mediaUrl } from '../utils/constants';
|
||||||
import { Card, CardTitle, CardText } from 'reactstrap';
|
|
||||||
import Loading from './loading';
|
import Loading from './loading';
|
||||||
import { seafileAPI } from '../utils/seafile-api';
|
|
||||||
import { Utils } from '../utils/utils';
|
import { Utils } from '../utils/utils';
|
||||||
import toaster from './toast';
|
|
||||||
import '../css/related-files-list.css';
|
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
children: PropTypes.object,
|
children: PropTypes.object,
|
||||||
@@ -31,7 +27,6 @@ class WikiMarkdownViewer extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
activeTitleIndex: 0,
|
activeTitleIndex: 0,
|
||||||
relatedFiles: [],
|
|
||||||
};
|
};
|
||||||
this.markdownContainer = React.createRef();
|
this.markdownContainer = React.createRef();
|
||||||
this.links = [];
|
this.links = [];
|
||||||
@@ -44,7 +39,6 @@ class WikiMarkdownViewer extends React.Component {
|
|||||||
this.links.forEach(link => {
|
this.links.forEach(link => {
|
||||||
link.addEventListener('click', this.onLinkClick);
|
link.addEventListener('click', this.onLinkClick);
|
||||||
});
|
});
|
||||||
this.listRelatedFiles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
@@ -55,7 +49,6 @@ class WikiMarkdownViewer extends React.Component {
|
|||||||
this.links.forEach(link => {
|
this.links.forEach(link => {
|
||||||
link.removeEventListener('click', this.onLinkClick);
|
link.removeEventListener('click', this.onLinkClick);
|
||||||
});
|
});
|
||||||
this.listRelatedFiles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
@@ -77,20 +70,6 @@ class WikiMarkdownViewer extends React.Component {
|
|||||||
this.titlesInfo = markdownViewer.titlesInfo;
|
this.titlesInfo = markdownViewer.titlesInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
listRelatedFiles = () => {
|
|
||||||
// for dir-column-file component(import repoID is undefined)
|
|
||||||
if (this.props.repoID && this.props.path) {
|
|
||||||
seafileAPI.listRelatedFiles(this.props.repoID, this.props.path).then(res => {
|
|
||||||
this.setState({
|
|
||||||
relatedFiles: res.data.related_files
|
|
||||||
});
|
|
||||||
}).catch(error => {
|
|
||||||
let errMessage = Utils.getErrorMsg(error);
|
|
||||||
toaster.danger(errMessage);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onLinkClick = (event) => {
|
onLinkClick = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@@ -208,37 +187,6 @@ class WikiMarkdownViewer extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderRelatedFiles = () => {
|
|
||||||
const relatedFiles = this.state.relatedFiles;
|
|
||||||
if (relatedFiles.length > 0) {
|
|
||||||
return (
|
|
||||||
<div className="sf-releted-files" id="sf-releted-files">
|
|
||||||
<div className="sf-releted-files-header">
|
|
||||||
<h4>{gettext('related files')}</h4>
|
|
||||||
</div>
|
|
||||||
{
|
|
||||||
relatedFiles.map((relatedFile, index) => {
|
|
||||||
let href = siteRoot + 'lib/' + relatedFile.repo_id + '/file' + Utils.encodePath(relatedFile.path);
|
|
||||||
return(
|
|
||||||
<div className="sf-releted-file" key={index}>
|
|
||||||
<a href={href} target="_blank">
|
|
||||||
<Card body size="sm">
|
|
||||||
<CardTitle>{relatedFile.name}</CardTitle>
|
|
||||||
<CardText>{relatedFile.repo_name}</CardText>
|
|
||||||
<span className="sf-releted-file-arrow"></span>
|
|
||||||
</Card>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.isFileLoading) {
|
if (this.props.isFileLoading) {
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
@@ -250,7 +198,6 @@ class WikiMarkdownViewer extends React.Component {
|
|||||||
<div className={contentClassName}>
|
<div className={contentClassName}>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
{this.renderMarkdown()}
|
{this.renderMarkdown()}
|
||||||
{this.props.isWiki && this.renderRelatedFiles()}
|
|
||||||
<p id="wiki-page-last-modified">{gettext('Last modified by')} {this.props.latestContributor}, <span>{this.props.lastModified}</span></p>
|
<p id="wiki-page-last-modified">{gettext('Last modified by')} {this.props.latestContributor}, <span>{this.props.lastModified}</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
.add-related-file-link {
|
|
||||||
color: #666;
|
|
||||||
padding-left: 10px;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-related-file-link:hover {
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-related-file-table {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-related-file-table td, .list-related-file-table th {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
@@ -1,56 +0,0 @@
|
|||||||
.sf-releted-files {
|
|
||||||
margin-top: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files-header {
|
|
||||||
border-top: 2px dashed #E6E6EB;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files-header h4 {
|
|
||||||
font-weight: 400;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files .sf-releted-file {
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files .sf-releted-files h4,
|
|
||||||
.sf-releted-files .sf-releted-files p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files .sf-releted-file a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files .sf-releted-file .card-body {
|
|
||||||
padding: 0.5rem 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files .sf-releted-file .card {
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: #e5e5ea;
|
|
||||||
border-color: #e5e5ea;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files .sf-releted-file .card-title {
|
|
||||||
margin: 0 0 2px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-files .sf-releted-file .card-text {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf-releted-file-arrow {
|
|
||||||
position: absolute;
|
|
||||||
right: 30px;
|
|
||||||
top: 50%;
|
|
||||||
margin-top: -8px;
|
|
||||||
border-top: 2px solid #aaa;
|
|
||||||
border-right: 2px solid #aaa;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
@@ -15,7 +15,6 @@ import { serialize, deserialize } from '@seafile/seafile-editor/dist/utils/slate
|
|||||||
import LocalDraftDialog from './components/dialog/local-draft-dialog';
|
import LocalDraftDialog from './components/dialog/local-draft-dialog';
|
||||||
import MarkdownViewerToolbar from './components/toolbar/markdown-viewer-toolbar';
|
import MarkdownViewerToolbar from './components/toolbar/markdown-viewer-toolbar';
|
||||||
import EditFileTagDialog from './components/dialog/edit-filetag-dialog';
|
import EditFileTagDialog from './components/dialog/edit-filetag-dialog';
|
||||||
import RelatedFileDialogs from './components/dialog/related-file-dialogs';
|
|
||||||
|
|
||||||
import './css/markdown-viewer/markdown-editor.css';
|
import './css/markdown-viewer/markdown-editor.css';
|
||||||
|
|
||||||
@@ -78,7 +77,7 @@ class EditorApi {
|
|||||||
const url = this.serviceUrl + '/lib/' + repoID + '/file/images/auto-upload/' + fileName + '?raw=1';
|
const url = this.serviceUrl + '/lib/' + repoID + '/file/images/auto-upload/' + fileName + '?raw=1';
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadLocalImage = (imageFile) => {
|
uploadLocalImage = (imageFile) => {
|
||||||
return (
|
return (
|
||||||
seafileAPI.getFileServerUploadLink(repoID, '/').then((res) => {
|
seafileAPI.getFileServerUploadLink(repoID, '/').then((res) => {
|
||||||
@@ -290,11 +289,8 @@ class MarkdownEditor extends React.Component {
|
|||||||
saving: false,
|
saving: false,
|
||||||
isLocked: isLocked,
|
isLocked: isLocked,
|
||||||
lockedByMe: lockedByMe,
|
lockedByMe: lockedByMe,
|
||||||
relatedFiles: [],
|
|
||||||
fileTagList: [],
|
fileTagList: [],
|
||||||
showRelatedFileDialog: false,
|
|
||||||
showEditFileTagDialog: false,
|
showEditFileTagDialog: false,
|
||||||
viewMode: 'list_related_file',
|
|
||||||
participants: [],
|
participants: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -393,7 +389,6 @@ class MarkdownEditor extends React.Component {
|
|||||||
showShareLinkDialog: false,
|
showShareLinkDialog: false,
|
||||||
showInsertFileDialog: false,
|
showInsertFileDialog: false,
|
||||||
showInsertRepoImageDialog: false,
|
showInsertRepoImageDialog: false,
|
||||||
showRelatedFileDialog: false,
|
|
||||||
showEditFileTagDialog: false,
|
showEditFileTagDialog: false,
|
||||||
showFileParticipantDialog: false,
|
showFileParticipantDialog: false,
|
||||||
});
|
});
|
||||||
@@ -490,22 +485,6 @@ class MarkdownEditor extends React.Component {
|
|||||||
showInsertRepoImageDialog: true,
|
showInsertRepoImageDialog: true,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'related_files':
|
|
||||||
if (this.state.relatedFiles.length > 0) {
|
|
||||||
this.setState({
|
|
||||||
showRelatedFileDialog: true,
|
|
||||||
showMarkdownEditorDialog: true,
|
|
||||||
viewMode: 'list_related_file',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.setState({
|
|
||||||
showRelatedFileDialog: true,
|
|
||||||
showMarkdownEditorDialog: true,
|
|
||||||
viewMode: 'add_related_file',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'file_tags':
|
case 'file_tags':
|
||||||
this.setState({
|
this.setState({
|
||||||
showEditFileTagDialog: true,
|
showEditFileTagDialog: true,
|
||||||
@@ -547,7 +526,7 @@ class MarkdownEditor extends React.Component {
|
|||||||
const fileDownloadUrlRes = await seafileAPI.getFileDownloadLink(repoID, filePath);
|
const fileDownloadUrlRes = await seafileAPI.getFileDownloadLink(repoID, filePath);
|
||||||
const downloadUrl = fileDownloadUrlRes.data;
|
const downloadUrl = fileDownloadUrlRes.data;
|
||||||
|
|
||||||
// get file content
|
// get file content
|
||||||
const fileContentRes = await seafileAPI.getFileContent(downloadUrl);
|
const fileContentRes = await seafileAPI.getFileContent(downloadUrl);
|
||||||
const markdownContent = fileContentRes.data;
|
const markdownContent = fileContentRes.data;
|
||||||
const value = deserialize(markdownContent);
|
const value = deserialize(markdownContent);
|
||||||
@@ -597,7 +576,6 @@ class MarkdownEditor extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.checkDraft();
|
this.checkDraft();
|
||||||
this.listRelatedFiles();
|
|
||||||
this.listFileTags();
|
this.listFileTags();
|
||||||
|
|
||||||
this.listFileParticipants();
|
this.listFileParticipants();
|
||||||
@@ -610,12 +588,6 @@ class MarkdownEditor extends React.Component {
|
|||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
listRelatedFiles = () => {
|
|
||||||
seafileAPI.listRelatedFiles(repoID, filePath).then(res => {
|
|
||||||
this.setState({ relatedFiles: res.data.related_files });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
listFileTags = () => {
|
listFileTags = () => {
|
||||||
seafileAPI.listFileTags(repoID, filePath).then(res => {
|
seafileAPI.listFileTags(repoID, filePath).then(res => {
|
||||||
let fileTagList = res.data.file_tags;
|
let fileTagList = res.data.file_tags;
|
||||||
@@ -626,10 +598,6 @@ class MarkdownEditor extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onRelatedFileChange = () => {
|
|
||||||
this.listRelatedFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
onFileTagChanged = () => {
|
onFileTagChanged = () => {
|
||||||
this.listFileTags();
|
this.listFileTags();
|
||||||
}
|
}
|
||||||
@@ -817,7 +785,6 @@ class MarkdownEditor extends React.Component {
|
|||||||
contentChanged={this.state.contentChanged}
|
contentChanged={this.state.contentChanged}
|
||||||
saving={this.state.saving}
|
saving={this.state.saving}
|
||||||
fileTagList={this.state.fileTagList}
|
fileTagList={this.state.fileTagList}
|
||||||
relatedFiles={this.state.relatedFiles}
|
|
||||||
participants={this.state.participants}
|
participants={this.state.participants}
|
||||||
onParticipantsChange={this.onParticipantsChange}
|
onParticipantsChange={this.onParticipantsChange}
|
||||||
markdownLint={fileName.toLowerCase() !== 'index.md'}
|
markdownLint={fileName.toLowerCase() !== 'index.md'}
|
||||||
@@ -883,19 +850,6 @@ class MarkdownEditor extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</ModalPortal>
|
</ModalPortal>
|
||||||
}
|
}
|
||||||
{this.state.showRelatedFileDialog &&
|
|
||||||
<ModalPortal>
|
|
||||||
<RelatedFileDialogs
|
|
||||||
repoID={repoID}
|
|
||||||
filePath={filePath}
|
|
||||||
relatedFiles={this.state.relatedFiles}
|
|
||||||
toggleCancel={this.toggleCancel}
|
|
||||||
onRelatedFileChange={this.onRelatedFileChange}
|
|
||||||
dirent={this.state.fileInfo}
|
|
||||||
viewMode={this.state.viewMode}
|
|
||||||
/>
|
|
||||||
</ModalPortal>
|
|
||||||
}
|
|
||||||
{this.state.showFileParticipantDialog &&
|
{this.state.showFileParticipantDialog &&
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<FileParticipantDialog
|
<FileParticipantDialog
|
||||||
|
@@ -14,9 +14,7 @@ const propTypes = {
|
|||||||
isDraft: PropTypes.bool.isRequired,
|
isDraft: PropTypes.bool.isRequired,
|
||||||
hasDraft: PropTypes.bool.isRequired,
|
hasDraft: PropTypes.bool.isRequired,
|
||||||
fileTags: PropTypes.array.isRequired,
|
fileTags: PropTypes.array.isRequired,
|
||||||
relatedFiles: PropTypes.array.isRequired,
|
|
||||||
onFileTagChanged: PropTypes.func.isRequired, // for file-view-toolbar
|
onFileTagChanged: PropTypes.func.isRequired, // for file-view-toolbar
|
||||||
onRelatedFileChange: PropTypes.func.isRequired,
|
|
||||||
// side-panel
|
// side-panel
|
||||||
onSideNavMenuClick: PropTypes.func.isRequired,
|
onSideNavMenuClick: PropTypes.func.isRequired,
|
||||||
// mutiple-dir
|
// mutiple-dir
|
||||||
@@ -75,9 +73,7 @@ class LibContentToolbar extends React.Component {
|
|||||||
isDraft={this.props.isDraft}
|
isDraft={this.props.isDraft}
|
||||||
hasDraft={this.props.hasDraft}
|
hasDraft={this.props.hasDraft}
|
||||||
fileTags={this.props.fileTags}
|
fileTags={this.props.fileTags}
|
||||||
relatedFiles={this.props.relatedFiles}
|
|
||||||
onFileTagChanged={this.props.onFileTagChanged}
|
onFileTagChanged={this.props.onFileTagChanged}
|
||||||
onRelatedFileChange={this.props.onRelatedFileChange}
|
|
||||||
showShareBtn={this.props.showShareBtn}
|
showShareBtn={this.props.showShareBtn}
|
||||||
/>
|
/>
|
||||||
<ViewModeToolbar currentMode={this.props.currentMode} switchViewMode={this.props.switchViewMode} isCustomPermission={isCustomPermission} />
|
<ViewModeToolbar currentMode={this.props.currentMode} switchViewMode={this.props.switchViewMode} isCustomPermission={isCustomPermission} />
|
||||||
@@ -107,7 +103,6 @@ class LibContentToolbar extends React.Component {
|
|||||||
currentRepoInfo={this.props.currentRepoInfo}
|
currentRepoInfo={this.props.currentRepoInfo}
|
||||||
enableDirPrivateShare={this.props.enableDirPrivateShare}
|
enableDirPrivateShare={this.props.enableDirPrivateShare}
|
||||||
updateDirent={this.props.updateDirent}
|
updateDirent={this.props.updateDirent}
|
||||||
relatedFiles={this.props.relatedFiles}
|
|
||||||
unSelectDirent={this.props.unSelectDirent}
|
unSelectDirent={this.props.unSelectDirent}
|
||||||
onFilesTagChanged={this.props.onFilesTagChanged}
|
onFilesTagChanged={this.props.onFilesTagChanged}
|
||||||
showShareBtn={this.props.showShareBtn}
|
showShareBtn={this.props.showShareBtn}
|
||||||
|
@@ -47,7 +47,6 @@ class LibContentView extends React.Component {
|
|||||||
isDraft: false,
|
isDraft: false,
|
||||||
hasDraft: false,
|
hasDraft: false,
|
||||||
fileTags: [],
|
fileTags: [],
|
||||||
relatedFiles: [],
|
|
||||||
draftID: '',
|
draftID: '',
|
||||||
draftCounts: 0,
|
draftCounts: 0,
|
||||||
usedRepoTags: [],
|
usedRepoTags: [],
|
||||||
@@ -420,17 +419,6 @@ class LibContentView extends React.Component {
|
|||||||
let errMessage = Utils.getErrorMsg(error);
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
toaster.danger(errMessage);
|
toaster.danger(errMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
seafileAPI.listRelatedFiles(repoID, filePath).then(res => {
|
|
||||||
let relatedFiles = res.data.related_files.map((relatedFile) => {
|
|
||||||
return relatedFile;
|
|
||||||
});
|
|
||||||
this.setState({relatedFiles: relatedFiles});
|
|
||||||
}).catch((error) => {
|
|
||||||
if (error.response.status === 500) {
|
|
||||||
this.setState({relatedFiles: []});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
@@ -1733,22 +1721,6 @@ class LibContentView extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onToolbarRelatedFileChange = () => {
|
|
||||||
let repoID = this.props.repoID;
|
|
||||||
let filePath = this.state.path;
|
|
||||||
|
|
||||||
seafileAPI.listRelatedFiles(repoID, filePath).then(res => {
|
|
||||||
let relatedFiles = res.data.related_files.map((relatedFile) => {
|
|
||||||
return relatedFile;
|
|
||||||
});
|
|
||||||
this.setState({relatedFiles: relatedFiles});
|
|
||||||
}).catch((error) => {
|
|
||||||
if (error.response.status === 500) {
|
|
||||||
this.setState({relatedFiles: []});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
unSelectDirent = () => {
|
unSelectDirent = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
isDirentSelected: false,
|
isDirentSelected: false,
|
||||||
@@ -1818,9 +1790,7 @@ class LibContentView extends React.Component {
|
|||||||
isDraft={this.state.isDraft}
|
isDraft={this.state.isDraft}
|
||||||
hasDraft={this.state.hasDraft}
|
hasDraft={this.state.hasDraft}
|
||||||
fileTags={this.state.fileTags}
|
fileTags={this.state.fileTags}
|
||||||
relatedFiles={this.state.relatedFiles}
|
|
||||||
onFileTagChanged={this.onToolbarFileTagChanged}
|
onFileTagChanged={this.onToolbarFileTagChanged}
|
||||||
onRelatedFileChange={this.onToolbarRelatedFileChange}
|
|
||||||
onSideNavMenuClick={this.props.onMenuClick}
|
onSideNavMenuClick={this.props.onMenuClick}
|
||||||
repoID={this.props.repoID}
|
repoID={this.props.repoID}
|
||||||
path={this.state.path}
|
path={this.state.path}
|
||||||
@@ -1849,7 +1819,6 @@ class LibContentView extends React.Component {
|
|||||||
updateDirent={this.updateDirent}
|
updateDirent={this.updateDirent}
|
||||||
onDirentSelected={this.onDirentSelected}
|
onDirentSelected={this.onDirentSelected}
|
||||||
showDirentDetail={this.showDirentDetail}
|
showDirentDetail={this.showDirentDetail}
|
||||||
listRelatedFiles={this.listRelatedFiles}
|
|
||||||
unSelectDirent={this.unSelectDirent}
|
unSelectDirent={this.unSelectDirent}
|
||||||
onFilesTagChanged={this.onFileTagChanged}
|
onFilesTagChanged={this.onFileTagChanged}
|
||||||
/>
|
/>
|
||||||
@@ -1872,7 +1841,6 @@ class LibContentView extends React.Component {
|
|||||||
isDraft={this.state.isDraft}
|
isDraft={this.state.isDraft}
|
||||||
hasDraft={this.state.hasDraft}
|
hasDraft={this.state.hasDraft}
|
||||||
fileTags={this.state.fileTags}
|
fileTags={this.state.fileTags}
|
||||||
relatedFiles={this.state.relatedFiles}
|
|
||||||
goDraftPage={this.goDraftPage}
|
goDraftPage={this.goDraftPage}
|
||||||
isFileLoading={this.state.isFileLoading}
|
isFileLoading={this.state.isFileLoading}
|
||||||
isFileLoadedErr={this.state.isFileLoadedErr}
|
isFileLoadedErr={this.state.isFileLoadedErr}
|
||||||
|
@@ -20,8 +20,7 @@ const TextTranslation = {
|
|||||||
'HISTORY' : {key : 'History', value : gettext('History')},
|
'HISTORY' : {key : 'History', value : gettext('History')},
|
||||||
'ACCESS_LOG' : {key : 'Access Log', value : gettext('Access Log')},
|
'ACCESS_LOG' : {key : 'Access Log', value : gettext('Access Log')},
|
||||||
'TAGS': {key: 'Tags', value: gettext('Tags')},
|
'TAGS': {key: 'Tags', value: gettext('Tags')},
|
||||||
'RELATED_FILES': {key: 'Related Files', value: gettext('Related Files')},
|
|
||||||
'ONLYOFFICE_CONVERT': {key: 'Convert with ONLYOFFICE', value: gettext('Convert with ONLYOFFICE')}
|
'ONLYOFFICE_CONVERT': {key: 'Convert with ONLYOFFICE', value: gettext('Convert with ONLYOFFICE')}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TextTranslation;
|
export default TextTranslation;
|
||||||
|
Reference in New Issue
Block a user