mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-14 14:21:23 +00:00
Optimize internal link dialog cod (#5466)
* optimize code * optimize code
This commit is contained in:
@@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
|
||||
import { Link } from '@gatsbyjs/reach-router';
|
||||
import { UncontrolledTooltip } from 'reactstrap';
|
||||
import { siteRoot, gettext } from '../../utils/constants';
|
||||
import InternalLinkDialog from '../dialog/internal-link-dialog';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import { InternalLinkOperation } from '../operations';
|
||||
|
||||
const propTypes = {
|
||||
repoName: PropTypes.string.isRequired,
|
||||
@@ -103,12 +103,9 @@ class DirPath extends React.Component {
|
||||
<a className="path-link" data-path="/" onClick={this.onPathClick}>{repoName}</a>
|
||||
}
|
||||
{pathElem}
|
||||
{this.props.isViewFile &&
|
||||
<InternalLinkDialog
|
||||
repoID={this.props.repoID}
|
||||
path={this.props.currentPath}
|
||||
/>
|
||||
}
|
||||
{this.props.isViewFile && (
|
||||
<InternalLinkOperation repoID={this.props.repoID} path={this.props.currentPath}/>
|
||||
)}
|
||||
{(this.props.isViewFile && fileTags.length !== 0) &&
|
||||
<span id='column-mode-file-tags' className="tag-list tag-list-stacked align-middle ml-1">
|
||||
{fileTags.map((fileTag, index) => {
|
||||
|
@@ -7,69 +7,63 @@ import { gettext } from '../../utils/constants';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
|
||||
import '../../css/internal-link.css';
|
||||
|
||||
const propTypes = {
|
||||
path: PropTypes.string.isRequired,
|
||||
repoID: PropTypes.string.isRequired,
|
||||
onInternalLinkDialogToggle: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
class InternalLinkDialog extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isOpen: false,
|
||||
smartLink: '',
|
||||
isLoading: true,
|
||||
};
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.getInternalLink = this.getInternalLink.bind(this);
|
||||
this.copyToClipBoard = this.copyToClipBoard.bind(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
isOpen: !this.state.isOpen,
|
||||
});
|
||||
componentDidMount() {
|
||||
this.getInternalLink();
|
||||
}
|
||||
|
||||
getInternalLink() {
|
||||
getInternalLink = () => {
|
||||
let repoID = this.props.repoID;
|
||||
let path = this.props.path;
|
||||
seafileAPI.getInternalLink(repoID, path).then(res => {
|
||||
const { smart_link } = res.data;
|
||||
this.setState({
|
||||
isOpen: true,
|
||||
smartLink: res.data.smart_link
|
||||
isLoading: false,
|
||||
smartLink: smart_link,
|
||||
});
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
this.setState({isLoading: false});
|
||||
});
|
||||
}
|
||||
|
||||
copyToClipBoard() {
|
||||
copyToClipBoard = () => {
|
||||
copy(this.state.smartLink);
|
||||
this.setState({
|
||||
isOpen: false
|
||||
});
|
||||
let message = gettext('Internal link has been copied to clipboard');
|
||||
toaster.success(message), {
|
||||
duration: 2
|
||||
};
|
||||
const message = gettext('Internal link has been copied to clipboard');
|
||||
toaster.success(message, {duration: 2});
|
||||
this.toggle();
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
this.props.onInternalLinkDialogToggle();
|
||||
}
|
||||
|
||||
render() {
|
||||
const tipMessage = gettext('An internal link is a link to a file or folder that can be accessed by users with read permission to the file or folder.');
|
||||
return (
|
||||
<Fragment>
|
||||
<i title={gettext('Internal Link')} role="button" tabIndex="0" aria-label={gettext('Internal Link')} className="file-internal-link fa fa-link" onClick={this.getInternalLink}></i>
|
||||
<Modal isOpen={this.state.isOpen} toggle={this.toggle}>
|
||||
<Modal isOpen={true} toggle={this.toggle}>
|
||||
<ModalHeader toggle={this.toggle}>{gettext('Internal Link')}</ModalHeader>
|
||||
<ModalBody>
|
||||
<p className="tip mb-1">
|
||||
{gettext('An internal link is a link to a file or folder that can be accessed by users with read permission to the file or folder.')}
|
||||
</p>
|
||||
<p className="tip mb-1">{tipMessage}</p>
|
||||
<p>
|
||||
<a target="_blank" href={this.state.smartLink}>{this.state.smartLink}</a>
|
||||
<a target="_blank" href={this.state.smartLink} rel='noreferrer'>{this.state.smartLink}</a>
|
||||
</p>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
|
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import { isPro, gettext, mediaUrl, siteRoot } from '../../utils/constants';
|
||||
import InternalLinkDialog from '../dialog/internal-link-dialog';
|
||||
import { InternalLinkOperation } from '../operations';
|
||||
|
||||
const propTypes = {
|
||||
toggleStar: PropTypes.func.isRequired,
|
||||
@@ -40,7 +40,7 @@ class FileInfo extends React.PureComponent {
|
||||
aria-label={isStarred ? gettext('Unstar') : gettext('Star')}
|
||||
onClick={this.toggleStar}>
|
||||
</a>
|
||||
<InternalLinkDialog repoID={repoID} path={filePath} />
|
||||
<InternalLinkOperation repoID={repoID} path={filePath} />
|
||||
{(isPro && isLocked) &&
|
||||
<img className="file-locked-icon" width="16"
|
||||
src={`${mediaUrl}img/file-locked-32.png`}
|
||||
|
6
frontend/src/components/operations/index.js
Normal file
6
frontend/src/components/operations/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import InternalLinkOperation from './internal-link-operation';
|
||||
import './style.css';
|
||||
|
||||
export {
|
||||
InternalLinkOperation,
|
||||
};
|
@@ -0,0 +1,48 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { gettext } from '../../../utils/constants';
|
||||
import InternalLinkDialog from '../../dialog/internal-link-dialog';
|
||||
|
||||
const propTypes = {
|
||||
repoID: PropTypes.string.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
class InternalLinkOperation extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isShowInternalLinkDialog: false
|
||||
};
|
||||
}
|
||||
|
||||
onInternalLinkDialogToggle = () => {
|
||||
this.setState({isShowInternalLinkDialog: !this.state.isShowInternalLinkDialog});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { repoID, path } = this.props;
|
||||
const { isShowInternalLinkDialog } = this.state;
|
||||
const title = gettext('Internal Link');
|
||||
return (
|
||||
<Fragment>
|
||||
<span className='dialog-operation'>
|
||||
<i className="file-internal-link fa fa-link" title={title} aria-label={title} onClick={this.onInternalLinkDialogToggle}/>
|
||||
</span>
|
||||
{isShowInternalLinkDialog && (
|
||||
<InternalLinkDialog
|
||||
repoID={repoID}
|
||||
path={path}
|
||||
onInternalLinkDialogToggle={this.onInternalLinkDialogToggle}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InternalLinkOperation.propTypes = propTypes;
|
||||
|
||||
export default InternalLinkOperation;
|
17
frontend/src/components/operations/style.css
Normal file
17
frontend/src/components/operations/style.css
Normal file
@@ -0,0 +1,17 @@
|
||||
.dialog-operation {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dialog-operation .file-internal-link {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
margin-left: 0.5rem;
|
||||
color: #999;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.dialog-operation .file-internal-link:hover {
|
||||
color: #333;
|
||||
}
|
@@ -15,8 +15,7 @@ body {
|
||||
line-height: 1.5;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.file-star,
|
||||
.file-internal-link {
|
||||
.file-star {
|
||||
font-size: .875rem;
|
||||
color: #999;
|
||||
margin-left: .5rem;
|
||||
|
@@ -1,10 +0,0 @@
|
||||
.file-internal-link {
|
||||
font-size: .8em;
|
||||
color: #808080;
|
||||
cursor: pointer;
|
||||
margin-left: .5rem;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
.file-internal-link:hover {
|
||||
color: #333;
|
||||
}
|
@@ -200,8 +200,7 @@
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.topbar-file-info .file-title .file-star,
|
||||
.topbar-file-info .file-title .file-internal-link {
|
||||
.topbar-file-info .file-title .file-star {
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
margin-left: 0.5rem;
|
||||
@@ -209,15 +208,6 @@
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.topbar-file-info .file-title .file-internal-link {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.topbar-file-info .file-title .file-internal-link:hover {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.topbar-file-info .file-title .file-star .star {
|
||||
color: #999;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { gettext } from '../../../utils/constants';
|
||||
import InternalLinkDialog from '../../../components/dialog/internal-link-dialog';
|
||||
import { InternalLinkOperation } from '../../../components/operations';
|
||||
|
||||
const { repoID, filePath } = window.app.pageOptions;
|
||||
|
||||
@@ -22,7 +22,7 @@ class FileInfo extends React.PureComponent {
|
||||
<span className="file-star" title={starTitle}>
|
||||
<i className={starIconClass} onClick={this.props.toggleStar}/>
|
||||
</span>
|
||||
<InternalLinkDialog path={filePath} repoID={repoID} />
|
||||
<InternalLinkOperation path={filePath} repoID={repoID} />
|
||||
{(isPro && isLocked) && (
|
||||
<img
|
||||
className="file-locked-icon mx-2"
|
||||
|
@@ -5,7 +5,6 @@ import { I18nextProvider } from 'react-i18next';
|
||||
import i18n from './_i18n/i18n-sdoc-editor';
|
||||
import { Utils } from './utils/utils';
|
||||
import Loading from './components/loading';
|
||||
import InternalLinkDialog from './components/dialog/internal-link-dialog';
|
||||
|
||||
const { serviceURL, avatarURL, siteRoot } = window.app.config;
|
||||
const { username, name } = window.app.userInfo;
|
||||
@@ -30,7 +29,6 @@ window.seafile = {
|
||||
docPerm: filePerm,
|
||||
historyURL: Utils.generateHistoryURL(siteRoot, repoID, docPath),
|
||||
parentFolderURL: `${siteRoot}library/${repoID}/${Utils.encodePath(repoName + parentDir)}`,
|
||||
internalLink: <InternalLinkDialog repoID={repoID} path={docPath} />
|
||||
};
|
||||
|
||||
ReactDom.render(
|
||||
|
Reference in New Issue
Block a user