mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-12 21:30:39 +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/resumablejs": "1.1.16",
|
||||
"@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",
|
||||
"classnames": "^2.2.6",
|
||||
"copy-to-clipboard": "^3.0.8",
|
||||
@@ -15,7 +16,6 @@
|
||||
"i18next": "^17.0.13",
|
||||
"i18next-browser-languagedetector": "^3.0.3",
|
||||
"i18next-xhr-backend": "^3.1.2",
|
||||
"MD5": "^1.3.0",
|
||||
"merge": "^1.2.1",
|
||||
"moment": "^2.22.2",
|
||||
"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 PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import { gettext, siteRoot } from '../../utils/constants';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||
import ModalPortal from '../modal-portal';
|
||||
import RelatedFileDialogs from '../dialog/related-file-dialogs';
|
||||
import ParticipantsList from '../file-view/participants-list';
|
||||
|
||||
const propTypes = {
|
||||
@@ -16,9 +15,7 @@ const propTypes = {
|
||||
direntDetail: PropTypes.object.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
fileTagList: PropTypes.array.isRequired,
|
||||
relatedFiles: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func.isRequired,
|
||||
onRelatedFileChange: PropTypes.func.isRequired,
|
||||
onParticipantsChange: PropTypes.func.isRequired,
|
||||
fileParticipantList: PropTypes.array.isRequired,
|
||||
};
|
||||
@@ -28,8 +25,7 @@ class DetailListView extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isEditFileTagShow: false,
|
||||
showRelatedFileDialog: false,
|
||||
isEditFileTagShow: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,25 +60,8 @@ class DetailListView extends React.Component {
|
||||
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() {
|
||||
let { direntType, direntDetail, fileTagList, relatedFiles, fileParticipantList } = this.props;
|
||||
let { direntType, direntDetail, fileTagList, fileParticipantList } = this.props;
|
||||
let position = this.getDirentPostion();
|
||||
let direntPath = this.getDirentPath();
|
||||
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>
|
||||
</td>
|
||||
</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">
|
||||
<th>{gettext('Participants')}</th>
|
||||
<td>
|
||||
@@ -156,19 +119,6 @@ class DetailListView extends React.Component {
|
||||
</tr>
|
||||
</tbody>
|
||||
</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 &&
|
||||
<ModalPortal>
|
||||
<EditFileTagDialog
|
||||
@@ -188,4 +138,4 @@ class DetailListView extends React.Component {
|
||||
|
||||
DetailListView.propTypes = propTypes;
|
||||
|
||||
export default DetailListView;
|
||||
export default DetailListView;
|
||||
|
@@ -30,7 +30,6 @@ class DirentDetail extends React.Component {
|
||||
direntType: '',
|
||||
direntDetail: '',
|
||||
fileTagList: [],
|
||||
relatedFiles: [],
|
||||
folderDirent: null,
|
||||
activeTab: 'info',
|
||||
fileParticipantList: [],
|
||||
@@ -106,21 +105,6 @@ class DirentDetail extends React.Component {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
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);
|
||||
} else {
|
||||
seafileAPI.getDirInfo(repoID, direntPath).then(res => {
|
||||
@@ -145,10 +129,6 @@ class DirentDetail extends React.Component {
|
||||
this.listParticipants(repoID, filePath);
|
||||
}
|
||||
|
||||
onRelatedFileChange = (dirent, direntPath) => {
|
||||
this.updateDetailView(dirent, direntPath);
|
||||
}
|
||||
|
||||
tabItemClick = (tab) => {
|
||||
if (this.state.activeTab !== tab) {
|
||||
this.setState({ activeTab: tab });
|
||||
@@ -203,9 +183,7 @@ class DirentDetail extends React.Component {
|
||||
direntType={this.state.direntType}
|
||||
direntDetail={this.state.direntDetail}
|
||||
fileTagList={this.state.fileTagList}
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
onRelatedFileChange={this.onRelatedFileChange}
|
||||
fileParticipantList={this.state.fileParticipantList}
|
||||
onParticipantsChange={this.onParticipantsChange}
|
||||
/>
|
||||
|
@@ -1,15 +1,13 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
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 { seafileAPI } from '../../utils/seafile-api';
|
||||
import URLDecorator from '../../utils/url-decorator';
|
||||
import TextTranslation from '../../utils/text-translation';
|
||||
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
||||
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
||||
import ShareDialog from '../dialog/share-dialog';
|
||||
import RelatedFileDialogs from '../dialog/related-file-dialogs';
|
||||
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
||||
import Rename from '../dialog/rename-dirent';
|
||||
@@ -55,8 +53,6 @@ class MultipleDirOperationToolbar extends React.Component {
|
||||
showEditFileTagDialog: false,
|
||||
fileTagList: [],
|
||||
multiFileTagList: [],
|
||||
showRelatedFileDialog: false,
|
||||
viewMode: 'list_related_file',
|
||||
isRenameDialogOpen: false,
|
||||
isPermissionDialogOpen: false
|
||||
};
|
||||
@@ -178,9 +174,6 @@ class MultipleDirOperationToolbar extends React.Component {
|
||||
case 'Comment':
|
||||
this.onCommentItem();
|
||||
break;
|
||||
case 'Related Files':
|
||||
this.openRelatedFilesDialog(dirent);
|
||||
break;
|
||||
case 'History':
|
||||
this.onHistory(dirent);
|
||||
break;
|
||||
@@ -251,37 +244,11 @@ class MultipleDirOperationToolbar extends React.Component {
|
||||
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 = () => {
|
||||
this.setState({
|
||||
showLibContentViewDialogs: false,
|
||||
showShareDialog: false,
|
||||
showEditFileTagDialog: false,
|
||||
showRelatedFileDialog: false,
|
||||
isRenameDialogOpen: 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) => {
|
||||
if (dirent) return Utils.joinPath(this.props.path, dirent.name);
|
||||
}
|
||||
@@ -467,19 +418,6 @@ class MultipleDirOperationToolbar extends React.Component {
|
||||
/>
|
||||
</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>
|
||||
|
@@ -8,7 +8,6 @@ import toaster from '../toast';
|
||||
import ModalPotal from '../modal-portal';
|
||||
import ShareDialog from '../dialog/share-dialog';
|
||||
import EditFileTagDialog from '../dialog/edit-filetag-dialog';
|
||||
import RelatedFileDialogs from '../dialog/related-file-dialogs';
|
||||
|
||||
const propTypes = {
|
||||
path: PropTypes.string.isRequired,
|
||||
@@ -21,9 +20,7 @@ const propTypes = {
|
||||
isDraft: PropTypes.bool.isRequired,
|
||||
hasDraft: PropTypes.bool.isRequired,
|
||||
fileTags: PropTypes.array.isRequired,
|
||||
relatedFiles: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func.isRequired,
|
||||
onRelatedFileChange: PropTypes.func.isRequired,
|
||||
showShareBtn: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
@@ -36,8 +33,6 @@ class ViewFileToolbar extends React.Component {
|
||||
isMoreMenuShow: false,
|
||||
isShareDialogShow: false,
|
||||
isEditTagDialogShow: false,
|
||||
isRelatedFileDialogShow: false,
|
||||
showRelatedFileDialog: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -75,20 +70,6 @@ class ViewFileToolbar extends React.Component {
|
||||
this.setState({isEditTagDialogShow: !this.state.isEditTagDialogShow});
|
||||
}
|
||||
|
||||
onListRelatedFileToggle = () => {
|
||||
this.setState({
|
||||
isRelatedFileDialogShow: true,
|
||||
showRelatedFileDialog: true,
|
||||
});
|
||||
}
|
||||
|
||||
toggleCancel = () => {
|
||||
this.setState({
|
||||
isRelatedFileDialogShow: false,
|
||||
showRelatedFileDialog: false,
|
||||
});
|
||||
}
|
||||
|
||||
onHistoryClick = () => {
|
||||
let historyUrl = siteRoot + 'repo/file_revisions/' + this.props.repoID + '/?p=' + Utils.encodePath(this.props.path);
|
||||
location.href = historyUrl;
|
||||
@@ -122,7 +103,6 @@ class ViewFileToolbar extends React.Component {
|
||||
<DropdownItem onClick={this.onShareToggle}>{gettext('Share')}</DropdownItem>
|
||||
}
|
||||
<DropdownItem onClick={this.onEditFileTagToggle}>{gettext('Tags')}</DropdownItem>
|
||||
<DropdownItem onClick={this.onListRelatedFileToggle}>{gettext('Related Files')}</DropdownItem>
|
||||
<DropdownItem onClick={this.onHistoryClick}>{gettext('History')}</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
@@ -154,19 +134,6 @@ class ViewFileToolbar extends React.Component {
|
||||
/>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
@@ -1,13 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer';
|
||||
import { gettext, repoID, slug, serviceURL, isPublicWiki, siteRoot, sharedToken, mediaUrl } from '../utils/constants';
|
||||
import { Card, CardTitle, CardText } from 'reactstrap';
|
||||
import { gettext, repoID, slug, serviceURL, isPublicWiki, sharedToken, mediaUrl } from '../utils/constants';
|
||||
import Loading from './loading';
|
||||
import { seafileAPI } from '../utils/seafile-api';
|
||||
import { Utils } from '../utils/utils';
|
||||
import toaster from './toast';
|
||||
import '../css/related-files-list.css';
|
||||
|
||||
const propTypes = {
|
||||
children: PropTypes.object,
|
||||
@@ -31,7 +27,6 @@ class WikiMarkdownViewer extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
activeTitleIndex: 0,
|
||||
relatedFiles: [],
|
||||
};
|
||||
this.markdownContainer = React.createRef();
|
||||
this.links = [];
|
||||
@@ -44,7 +39,6 @@ class WikiMarkdownViewer extends React.Component {
|
||||
this.links.forEach(link => {
|
||||
link.addEventListener('click', this.onLinkClick);
|
||||
});
|
||||
this.listRelatedFiles();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
@@ -55,7 +49,6 @@ class WikiMarkdownViewer extends React.Component {
|
||||
this.links.forEach(link => {
|
||||
link.removeEventListener('click', this.onLinkClick);
|
||||
});
|
||||
this.listRelatedFiles();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
@@ -77,20 +70,6 @@ class WikiMarkdownViewer extends React.Component {
|
||||
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) => {
|
||||
event.preventDefault();
|
||||
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() {
|
||||
if (this.props.isFileLoading) {
|
||||
return <Loading />;
|
||||
@@ -250,7 +198,6 @@ class WikiMarkdownViewer extends React.Component {
|
||||
<div className={contentClassName}>
|
||||
{this.props.children}
|
||||
{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>
|
||||
</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 MarkdownViewerToolbar from './components/toolbar/markdown-viewer-toolbar';
|
||||
import EditFileTagDialog from './components/dialog/edit-filetag-dialog';
|
||||
import RelatedFileDialogs from './components/dialog/related-file-dialogs';
|
||||
|
||||
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';
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
uploadLocalImage = (imageFile) => {
|
||||
return (
|
||||
seafileAPI.getFileServerUploadLink(repoID, '/').then((res) => {
|
||||
@@ -290,11 +289,8 @@ class MarkdownEditor extends React.Component {
|
||||
saving: false,
|
||||
isLocked: isLocked,
|
||||
lockedByMe: lockedByMe,
|
||||
relatedFiles: [],
|
||||
fileTagList: [],
|
||||
showRelatedFileDialog: false,
|
||||
showEditFileTagDialog: false,
|
||||
viewMode: 'list_related_file',
|
||||
participants: [],
|
||||
};
|
||||
|
||||
@@ -393,7 +389,6 @@ class MarkdownEditor extends React.Component {
|
||||
showShareLinkDialog: false,
|
||||
showInsertFileDialog: false,
|
||||
showInsertRepoImageDialog: false,
|
||||
showRelatedFileDialog: false,
|
||||
showEditFileTagDialog: false,
|
||||
showFileParticipantDialog: false,
|
||||
});
|
||||
@@ -490,22 +485,6 @@ class MarkdownEditor extends React.Component {
|
||||
showInsertRepoImageDialog: true,
|
||||
});
|
||||
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':
|
||||
this.setState({
|
||||
showEditFileTagDialog: true,
|
||||
@@ -547,7 +526,7 @@ class MarkdownEditor extends React.Component {
|
||||
const fileDownloadUrlRes = await seafileAPI.getFileDownloadLink(repoID, filePath);
|
||||
const downloadUrl = fileDownloadUrlRes.data;
|
||||
|
||||
// get file content
|
||||
// get file content
|
||||
const fileContentRes = await seafileAPI.getFileContent(downloadUrl);
|
||||
const markdownContent = fileContentRes.data;
|
||||
const value = deserialize(markdownContent);
|
||||
@@ -597,7 +576,6 @@ class MarkdownEditor extends React.Component {
|
||||
});
|
||||
}
|
||||
this.checkDraft();
|
||||
this.listRelatedFiles();
|
||||
this.listFileTags();
|
||||
|
||||
this.listFileParticipants();
|
||||
@@ -610,12 +588,6 @@ class MarkdownEditor extends React.Component {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
listRelatedFiles = () => {
|
||||
seafileAPI.listRelatedFiles(repoID, filePath).then(res => {
|
||||
this.setState({ relatedFiles: res.data.related_files });
|
||||
});
|
||||
}
|
||||
|
||||
listFileTags = () => {
|
||||
seafileAPI.listFileTags(repoID, filePath).then(res => {
|
||||
let fileTagList = res.data.file_tags;
|
||||
@@ -626,10 +598,6 @@ class MarkdownEditor extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
onRelatedFileChange = () => {
|
||||
this.listRelatedFiles();
|
||||
}
|
||||
|
||||
onFileTagChanged = () => {
|
||||
this.listFileTags();
|
||||
}
|
||||
@@ -817,7 +785,6 @@ class MarkdownEditor extends React.Component {
|
||||
contentChanged={this.state.contentChanged}
|
||||
saving={this.state.saving}
|
||||
fileTagList={this.state.fileTagList}
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
participants={this.state.participants}
|
||||
onParticipantsChange={this.onParticipantsChange}
|
||||
markdownLint={fileName.toLowerCase() !== 'index.md'}
|
||||
@@ -883,19 +850,6 @@ class MarkdownEditor extends React.Component {
|
||||
/>
|
||||
</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 &&
|
||||
<ModalPortal>
|
||||
<FileParticipantDialog
|
||||
|
@@ -14,9 +14,7 @@ const propTypes = {
|
||||
isDraft: PropTypes.bool.isRequired,
|
||||
hasDraft: PropTypes.bool.isRequired,
|
||||
fileTags: PropTypes.array.isRequired,
|
||||
relatedFiles: PropTypes.array.isRequired,
|
||||
onFileTagChanged: PropTypes.func.isRequired, // for file-view-toolbar
|
||||
onRelatedFileChange: PropTypes.func.isRequired,
|
||||
// side-panel
|
||||
onSideNavMenuClick: PropTypes.func.isRequired,
|
||||
// mutiple-dir
|
||||
@@ -75,9 +73,7 @@ class LibContentToolbar extends React.Component {
|
||||
isDraft={this.props.isDraft}
|
||||
hasDraft={this.props.hasDraft}
|
||||
fileTags={this.props.fileTags}
|
||||
relatedFiles={this.props.relatedFiles}
|
||||
onFileTagChanged={this.props.onFileTagChanged}
|
||||
onRelatedFileChange={this.props.onRelatedFileChange}
|
||||
showShareBtn={this.props.showShareBtn}
|
||||
/>
|
||||
<ViewModeToolbar currentMode={this.props.currentMode} switchViewMode={this.props.switchViewMode} isCustomPermission={isCustomPermission} />
|
||||
@@ -107,7 +103,6 @@ class LibContentToolbar extends React.Component {
|
||||
currentRepoInfo={this.props.currentRepoInfo}
|
||||
enableDirPrivateShare={this.props.enableDirPrivateShare}
|
||||
updateDirent={this.props.updateDirent}
|
||||
relatedFiles={this.props.relatedFiles}
|
||||
unSelectDirent={this.props.unSelectDirent}
|
||||
onFilesTagChanged={this.props.onFilesTagChanged}
|
||||
showShareBtn={this.props.showShareBtn}
|
||||
|
@@ -47,7 +47,6 @@ class LibContentView extends React.Component {
|
||||
isDraft: false,
|
||||
hasDraft: false,
|
||||
fileTags: [],
|
||||
relatedFiles: [],
|
||||
draftID: '',
|
||||
draftCounts: 0,
|
||||
usedRepoTags: [],
|
||||
@@ -420,17 +419,6 @@ class LibContentView extends React.Component {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
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
|
||||
@@ -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 = () => {
|
||||
this.setState({
|
||||
isDirentSelected: false,
|
||||
@@ -1818,9 +1790,7 @@ class LibContentView extends React.Component {
|
||||
isDraft={this.state.isDraft}
|
||||
hasDraft={this.state.hasDraft}
|
||||
fileTags={this.state.fileTags}
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
onFileTagChanged={this.onToolbarFileTagChanged}
|
||||
onRelatedFileChange={this.onToolbarRelatedFileChange}
|
||||
onSideNavMenuClick={this.props.onMenuClick}
|
||||
repoID={this.props.repoID}
|
||||
path={this.state.path}
|
||||
@@ -1849,7 +1819,6 @@ class LibContentView extends React.Component {
|
||||
updateDirent={this.updateDirent}
|
||||
onDirentSelected={this.onDirentSelected}
|
||||
showDirentDetail={this.showDirentDetail}
|
||||
listRelatedFiles={this.listRelatedFiles}
|
||||
unSelectDirent={this.unSelectDirent}
|
||||
onFilesTagChanged={this.onFileTagChanged}
|
||||
/>
|
||||
@@ -1872,7 +1841,6 @@ class LibContentView extends React.Component {
|
||||
isDraft={this.state.isDraft}
|
||||
hasDraft={this.state.hasDraft}
|
||||
fileTags={this.state.fileTags}
|
||||
relatedFiles={this.state.relatedFiles}
|
||||
goDraftPage={this.goDraftPage}
|
||||
isFileLoading={this.state.isFileLoading}
|
||||
isFileLoadedErr={this.state.isFileLoadedErr}
|
||||
|
@@ -20,8 +20,7 @@ const TextTranslation = {
|
||||
'HISTORY' : {key : 'History', value : gettext('History')},
|
||||
'ACCESS_LOG' : {key : 'Access Log', value : gettext('Access Log')},
|
||||
'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')}
|
||||
};
|
||||
|
||||
export default TextTranslation;
|
||||
export default TextTranslation;
|
||||
|
Reference in New Issue
Block a user