1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-01 23:20:51 +00:00

Repair eslint wraning (#2453)

This commit is contained in:
山水人家
2018-10-16 18:19:51 +08:00
committed by Daniel Pan
parent 80b7e562a0
commit fdbb39a6d3
43 changed files with 498 additions and 264 deletions

View File

@@ -17,7 +17,8 @@
"sourceType": "module"
},
"plugins": [
"react"
"react",
"jsx-a11y"
],
"rules": {
"indent": [
@@ -48,10 +49,12 @@
"no-irregular-whitespace": "warn",
"no-console": "warn",
"no-useless-escape": "warn",
"react/jsx-indent": ["warn", 2],
"react/prop-types": "warn",
"react/display-name": "warn"
"react/display-name": "warn",
"jsx-a11y/anchor-has-content": "off",
"jsx-a11y/href-no-hash": "off"
}
}

View File

@@ -95,11 +95,11 @@ class Account extends Component {
renderAvatar = () => {
if (this.state.avatarURL) {
return (
<img src={this.state.avatarURL} width="36" height="36" className="avatar" />
<img src={this.state.avatarURL} width="36" height="36" className="avatar" alt={gettext('avatar')} />
);
}
return (
<img src="" width="36" height="36" className="avatar" />
<img src="" width="36" height="36" className="avatar" alt={gettext('avatar')} />
);
}
@@ -107,7 +107,7 @@ class Account extends Component {
return (
<div id="account">
<a id="my-info" onClick={this.onClickAccount} className="account-toggle no-deco d-none d-md-block" aria-label="View profile and more">
<span><img src={this.state.avatarURL} width="36" height="36" className="avatar" /></span>
<span><img src={this.state.avatarURL} width="36" height="36" className="avatar" alt={gettext('avatar')} /></span>
<span className="fas fa-caret-down vam"></span>
</a>
<span className="account-toggle sf2-icon-more mobile-icon d-md-none" aria-label="View profile and more" onClick={this.onClickAccount}></span>

View File

@@ -8,20 +8,20 @@ class Notification extends React.Component {
this.state = {
showNotice: false,
notice_html: ''
}
};
}
onClick = () => {
this.setState({
showNotice: !this.state.showNotice
})
});
if (!this.state.showNotice) {
this.loadNotices()
this.loadNotices();
}
if (this.state.showNotice) {
seafileAPI.updateNotifications()
seafileAPI.updateNotifications();
}
}
@@ -29,8 +29,8 @@ class Notification extends React.Component {
seafileAPI.listPopupNotices().then(res => {
this.setState({
notice_html: res.data.notice_html
})
})
});
});
}
render() {
@@ -49,13 +49,12 @@ class Notification extends React.Component {
<a href="#" onClick={this.onClick} title={gettext('Close')} aria-label={gettext('Close')} className="sf-popover-close js-close sf2-icon-x1 op-icon float-right"></a>
</div>
<div className="sf-popover-con">
<ul className="notice-list" dangerouslySetInnerHTML={{__html: notice_html}}>
</ul>
<ul className="notice-list" dangerouslySetInnerHTML={{__html: notice_html}}></ul>
<a href="/notification/list/" className="view-all">{gettext('See All Notifications')}</a>
</div>
</div>
</div>
)
);
}
}

View File

@@ -1,7 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label, Col, FormText } from 'reactstrap';
import { gettext } from '../../utils/constants';
const propTypes = {
fileType: PropTypes.string,
parentPath: PropTypes.string.isRequired,
onAddFile: PropTypes.func.isRequired,
addFileCancel: PropTypes.func.isRequired,
};
class CreateFile extends React.Component {
constructor(props) {
super(props);
@@ -9,17 +17,17 @@ class CreateFile extends React.Component {
parentPath: '',
childName: props.fileType,
};
this.newInput = React.createRef()
this.newInput = React.createRef();
}
handleChange = (e) => {
this.setState({
childName: e.target.value,
})
}) ;
}
handleSubmit = () => {
let path = this.state.parentPath + this.state.childName
let path = this.state.parentPath + this.state.childName;
this.props.onAddFile(path);
}
@@ -34,10 +42,10 @@ class CreateFile extends React.Component {
}
componentDidMount() {
if (this.props.parentPath === "/") {
if (this.props.parentPath === '/') {
this.setState({parentPath: this.props.parentPath});
} else {
this.setState({parentPath: this.props.parentPath + "/"});
this.setState({parentPath: this.props.parentPath + '/'});
}
this.newInput.focus();
this.newInput.setSelectionRange(0,0);
@@ -46,7 +54,7 @@ class CreateFile extends React.Component {
render() {
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext("New File")}</ModalHeader>
<ModalHeader toggle={this.toggle}>{gettext('New File')}</ModalHeader>
<ModalBody>
<Form>
<FormGroup row>
@@ -54,20 +62,22 @@ class CreateFile extends React.Component {
<Col sm={9} className="parent-path"><FormText>{this.state.parentPath}</FormText></Col>
</FormGroup>
<FormGroup row>
<Label for="fileName" sm={3}>{gettext("Name")}: </Label>
<Label for="fileName" sm={3}>{gettext('Name')}: </Label>
<Col sm={9}>
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input}} id="fileName" placeholder={gettext("newName")} value={this.state.childName} onChange={this.handleChange}/>
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input;}} id="fileName" placeholder={gettext('newName')} value={this.state.childName} onChange={this.handleChange}/>
</Col>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={this.handleSubmit}>{gettext("Submit")}</Button>
<Button color="secondary" onClick={this.toggle}>{gettext("Cancel")}</Button>
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
</ModalFooter>
</Modal>
)
);
}
}
CreateFile.propTypes = propTypes;
export default CreateFile;

View File

@@ -1,7 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label, Col, FormText } from 'reactstrap';
import { gettext } from '../../utils/constants';
const propTypes = {
fileType: PropTypes.string,
parentPath: PropTypes.string.isRequired,
onAddFolder: PropTypes.func.isRequired,
addFolderCancel: PropTypes.func.isRequired,
};
class CreateForder extends React.Component {
constructor(props) {
super(props);
@@ -9,17 +17,17 @@ class CreateForder extends React.Component {
parentPath: '',
childName: ''
};
this.newInput = React.createRef()
this.newInput = React.createRef();
}
handleChange = (e) => {
this.setState({
childName: e.target.value,
})
});
}
handleSubmit = () => {
let path = this.state.parentPath + this.state.childName
let path = this.state.parentPath + this.state.childName;
this.props.onAddFolder(path);
}
@@ -34,10 +42,10 @@ class CreateForder extends React.Component {
}
componentDidMount() {
if (this.props.parentPath === "/") {
if (this.props.parentPath === '/') {
this.setState({parentPath: this.props.parentPath});
} else {
this.setState({parentPath: this.props.parentPath + "/"});
this.setState({parentPath: this.props.parentPath + '/'});
}
this.newInput.focus();
this.newInput.setSelectionRange(0,0);
@@ -46,7 +54,7 @@ class CreateForder extends React.Component {
render() {
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext("New Folder")}</ModalHeader>
<ModalHeader toggle={this.toggle}>{gettext('New Folder')}</ModalHeader>
<ModalBody>
<Form>
<FormGroup row>
@@ -54,20 +62,22 @@ class CreateForder extends React.Component {
<Col sm={9} className="parent-path"><FormText>{this.state.parentPath}</FormText></Col>
</FormGroup>
<FormGroup row>
<Label for="fileName" sm={3}>{gettext("Name")}: </Label>
<Label for="fileName" sm={3}>{gettext('Name')}: </Label>
<Col sm={9}>
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input}} id="fileName" placeholder={gettext("newName")} value={this.state.childName} onChange={this.handleChange}/>
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input;}} id="fileName" placeholder={gettext('newName')} value={this.state.childName} onChange={this.handleChange}/>
</Col>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={this.handleSubmit}>{gettext("Submit")}</Button>
<Button color="secondary" onClick={this.toggle}>{gettext("Cancel")}</Button>
<Button color="primary" onClick={this.handleSubmit}>{gettext('Submit')}</Button>
<Button color="secondary" onClick={this.toggle}>{gettext('Cancel')}</Button>
</ModalFooter>
</Modal>
)
);
}
}
CreateForder.propTypes = propTypes;
export default CreateForder;

View File

@@ -1,7 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter } from 'reactstrap';
const propTypes = {
currentNode: PropTypes.object,
onRename: PropTypes.func.isRequired,
toggleCancel: PropTypes.func.isRequired,
};
class Rename extends React.Component {
constructor(props) {
super(props);
@@ -75,4 +82,6 @@ class Rename extends React.Component {
}
}
Rename.propTypes = propTypes;
export default Rename;

View File

@@ -29,7 +29,7 @@ class OperationMenu extends React.Component {
repo: repo,
is_repo_owner: is_repo_owner
});
})
});
});
}

View File

@@ -8,6 +8,7 @@ moment.locale(lang);
const propTypes = {
isItemFreezed: PropTypes.bool.isRequired,
onMenuToggleClick: PropTypes.func.isRequired,
draft: PropTypes.object.isRequired,
};
class DraftListItem extends React.Component {
@@ -49,14 +50,14 @@ class DraftListItem extends React.Component {
let filePath = draft.draft_file_path;
let repoID = draft.origin_repo_id;
let url = siteRoot + 'lib/' + repoID + '/file' + filePath + '?mode=edit&draft_id=' + draft.id;
window.open(url)
window.open(url);
}
onLibraryClick = () => {
let draft = this.props.draft;
let repoID = draft.origin_repo_id;
let url = siteRoot + '#common/lib/' + repoID;
window.open(url)
window.open(url);
}
onReviewClick = () => {
@@ -77,7 +78,7 @@ class DraftListItem extends React.Component {
localTime = moment(localTime).fromNow();
return (
<tr className={this.state.highlight} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
<td className="icon"><img src={siteRoot + 'media/img/file/192/txt.png'} /></td>
<td className="icon"><img src={siteRoot + 'media/img/file/192/txt.png'} alt='icon' /></td>
<td className="name a-simulate" onClick={this.onDraftEditClick}>{fileName}</td>
<td className="library a-simulate" onClick={this.onLibraryClick}>{draft.repo_name}</td>
<td className="review">

View File

@@ -3,10 +3,12 @@ import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
const propTypes = {
currentDraft: PropTypes.object.isRequired,
isMenuShow: PropTypes.bool.isRequired,
menuPosition: PropTypes.object.isRequired,
onDeleteHandler: PropTypes.func.isRequired,
onPublishHandler: PropTypes.func.isRequired
onPublishHandler: PropTypes.func.isRequired,
onReviewHandler: PropTypes.func.isRequired,
};
class DraftListMenu extends React.Component {

View File

@@ -1,9 +1,9 @@
import React from 'react';
import PropsType from 'prop-types';
import PropTypes from 'prop-types';
import { siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from '../utils/constants';
const propsType = {
onCloseSidePanel: PropsType.func.isRequired,
const propTypes = {
onCloseSidePanel: PropTypes.func.isRequired,
};
class Logo extends React.Component {
@@ -14,22 +14,22 @@ class Logo extends React.Component {
render() {
return (
<div className="top-logo">
<a href={siteRoot} id="logo">
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
</a>
<a
className="sf2-icon-x1 sf-popover-close side-panel-close op-icon d-md-none"
onClick={this.closeSide}
title="Close"
aria-label="Close"
>
</a>
</div>
<div className="top-logo">
<a href={siteRoot} id="logo">
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
</a>
<a
className="sf2-icon-x1 sf-popover-close side-panel-close op-icon d-md-none"
onClick={this.closeSide}
title="Close"
aria-label="Close"
>
</a>
</div>
);
}
}
Logo.propsType = propsType;
Logo.propTypes = propTypes;
export default Logo;

View File

@@ -1,6 +1,12 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import CommonToolbar from './toolbar/common-toolbar';
const propTypes = {
children: PropTypes.object.isRequired,
onShowSidePanel: PropTypes.func.isRequired,
};
class MainPanel extends Component {
onSearchedClick = () => {
@@ -24,4 +30,6 @@ class MainPanel extends Component {
}
}
MainPanel.propTypes = propTypes;
export default MainPanel;

View File

@@ -1,8 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from '@reach/router';
import { gettext, siteRoot } from '../utils/constants';
import { seafileAPI } from '../utils/seafile-api';
const propTypes = {
currentTab: PropTypes.string.isRequired,
};
class MainSideNav extends React.Component {
constructor(props) {
super(props);
@@ -23,14 +28,14 @@ class MainSideNav extends React.Component {
grpsExtend = () => {
this.setState({
groupsExtended: !this.state.groupsExtended,
})
});
this.loadGroups();
}
shExtend = () => {
this.setState({
sharedExtended: !this.state.sharedExtended,
})
});
}
loadGroups = () => {
@@ -40,14 +45,14 @@ class MainSideNav extends React.Component {
this.groupsHeight = (data.length + 1) * _this.listHeight;
_this.setState({
groupItems: data
})
})
});
});
}
tabItemClick = (param) => {
this.setState({
currentTab: param
})
});
}
renderSharedGroups() {
@@ -59,8 +64,8 @@ class MainSideNav extends React.Component {
<ul className={`grp-list ${this.state.groupsExtended ? 'side-panel-slide' : 'side-panel-slide-up'}`} style={style}>
<li className={this.state.currentTab === 'groups' ? 'tab-cur' : ''}>
<a href={siteRoot + '#groups/'} onClick={() => this.tabItemClick('groups')}>
<span className="sharp" aria-hidden="true">#</span>
All Groups
<span className="sharp" aria-hidden="true">#</span>
{gettext('All Groups')}
</a>
</li>
{this.state.groupItems.map(item => {
@@ -71,10 +76,10 @@ class MainSideNav extends React.Component {
{item.name}
</a>
</li>
)
);
})}
</ul>
)
);
}
renderSharedAdmin() {
@@ -107,7 +112,7 @@ class MainSideNav extends React.Component {
</a>
</li>
</ul>
)
);
}
render() {
@@ -129,13 +134,13 @@ class MainSideNav extends React.Component {
</a>
</li>
<li className={`tab ${this.state.currentTab === 'org' ? 'tab-cur' : ''}`} onClick={() => this.tabItemClick('org')}>
<a href={ siteRoot + '#org/' } className="ellipsis" title={gettext('Shared with all')}>
<span className="sf2-icon-organization" aria-hidden="true"></span>
{gettext('Shared with all')}
<a href={ siteRoot + '#org/' } className="ellipsis" title={gettext('Shared with all')}>
<span className="sf2-icon-organization" aria-hidden="true"></span>
{gettext('Shared with all')}
</a>
</li>
<li className="tab" id="group-nav">
<a href="#" className="ellipsis user-select-no" title={gettext('Shared with groups')} onClick={this.grpsExtend}>
<a className="ellipsis user-select-no" title={gettext('Shared with groups')} onClick={this.grpsExtend}>
<span className={`toggle-icon float-right fas ${this.state.groupsExtended ?'fa-caret-down':'fa-caret-left'}`} aria-hidden="true"></span>
<span className="sf2-icon-group" aria-hidden="true"></span>
{gettext('Shared with groups')}
@@ -171,7 +176,7 @@ class MainSideNav extends React.Component {
</Link>
</li>
<li className="tab" id="share-admin-nav">
<a href="#" className="ellipsis user-select-no" title={gettext('Share Admin')} onClick={this.shExtend}>
<a className="ellipsis user-select-no" title={gettext('Share Admin')} onClick={this.shExtend}>
<span className={`toggle-icon float-right fas ${this.state.sharedExtended ? 'fa-caret-down':'fa-caret-left'}`} aria-hidden="true"></span>
<span aria-hidden="true" className="sf2-icon-wrench"></span>
{gettext('Share Admin')}
@@ -181,8 +186,10 @@ class MainSideNav extends React.Component {
</ul>
</div>
</div>
)
);
}
}
MainSideNav.propTypes = propTypes;
export default MainSideNav;

View File

@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { processor, processorGetAST } from '@seafile/seafile-editor/dist/utils/seafile-markdown2html';
import Prism from 'prismjs';
import WikiOutline from './wiki-outline';
@@ -9,7 +10,13 @@ const gettext = window.gettext;
require('@seafile/seafile-editor/dist/editor/code-hight-package');
const contentClass = "wiki-md-viewer-rendered-content";
const contentClass = 'wiki-md-viewer-rendered-content';
const contentPropTypes = {
html: PropTypes.string,
renderingContent: PropTypes.bool.isRequired,
onLinkClick: PropTypes.func.isRequired
};
class MarkdownViewerContent extends React.Component {
@@ -20,7 +27,7 @@ class MarkdownViewerContent extends React.Component {
componentDidUpdate () {
Prism.highlightAll();
var links = document.querySelectorAll(`.${contentClass} a`);
links.forEach((li) => {li.addEventListener("click", this.onLinkClick); });
links.forEach((li) => {li.addEventListener('click', this.onLinkClick); });
}
onLinkClick = (event) => {
@@ -32,17 +39,28 @@ class MarkdownViewerContent extends React.Component {
return (
<div>
{ this.props.renderingContent ? (
<div className={contentClass + " article"}>Loading...</div>
<div className={contentClass + ' article'}>Loading...</div>
) : (
<div ref={(mdContent) => {this.mdContentRef = mdContent;} }
className={contentClass + " article"}
className={contentClass + ' article'}
dangerouslySetInnerHTML={{ __html: this.props.html }}/>
)}
</div>
)
);
}
}
MarkdownViewerContent.propTypes = contentPropTypes;
const viewerPropTypes = {
isFileLoading: PropTypes.bool.isRequired,
lastModified: PropTypes.string,
latestContributor: PropTypes.string,
markdownContent: PropTypes.string,
onLinkClick: PropTypes.func.isRequired
};
class MarkdownViewer extends React.Component {
constructor(props) {
@@ -91,7 +109,7 @@ class MarkdownViewer extends React.Component {
if (currentId !== this.state.activeId) {
this.setState({
activeId: currentId
})
});
}
}
@@ -115,7 +133,7 @@ class MarkdownViewer extends React.Component {
window.location.href = window.location.href;
}
}, 100);
})
});
}
componentDidMount() {
@@ -139,11 +157,11 @@ class MarkdownViewer extends React.Component {
_this.setState({
navItems: navItems,
activeId: currentId
})
});
}else {
_this.setState({
navItems: []
})
});
}
});
}
@@ -155,12 +173,12 @@ class MarkdownViewer extends React.Component {
});
for (let i = 0; i < headingList.length; i++) {
navItems[i] = {};
navItems[i].id = '#user-content-' + headingList[i].data.id
navItems[i].id = '#user-content-' + headingList[i].data.id;
navItems[i].key = i;
navItems[i].clazz = '';
navItems[i].depth = headingList[i].depth;
for (let child of headingList[i].children) {
if (child.type === "text") {
if (child.type === 'text') {
navItems[i].text = child.value;
break;
}
@@ -173,7 +191,7 @@ class MarkdownViewer extends React.Component {
if (this.props.isFileLoading) {
return (
<span className="loading-icon loading-tip"></span>
)
);
}
return (
<div className="markdown-container" onScroll={this.scrollHandler}>
@@ -182,18 +200,20 @@ class MarkdownViewer extends React.Component {
renderingContent={this.state.renderingContent} html={this.state.html}
onLinkClick={this.props.onLinkClick}
/>
<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 className="markdown-outline">
<WikiOutline
navItems={this.state.navItems}
handleNavItemClick={this.handleNavItemClick}
activeId={this.state.activeId}
/>
<WikiOutline
navItems={this.state.navItems}
handleNavItemClick={this.handleNavItemClick}
activeId={this.state.activeId}
/>
</div>
</div>
)
);
}
}
MarkdownViewer.propTypes = viewerPropTypes;
export default MarkdownViewer;

View File

@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
const propTypes = {
isShow: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
};
class MenuControl extends React.Component {

View File

@@ -6,7 +6,9 @@ import { siteRoot, lang } from '../../utils/constants';
moment.locale(lang);
const propTypes = {
isItemFreezed: PropTypes.bool.isRequired,
}
item: PropTypes.object.isRequired,
};
class ReviewListItem extends React.Component {
constructor(props) {
@@ -34,13 +36,12 @@ class ReviewListItem extends React.Component {
onReviewsClick = () => {
let item = this.props.item;
let filePath = item.draft_file_path;
let itemID = item.id;
window.open(siteRoot + 'drafts/review/' + itemID);
}
getFileName(filePath) {
let lastIndex = filePath.lastIndexOf("/");
let lastIndex = filePath.lastIndexOf('/');
return filePath.slice(lastIndex+1);
}
@@ -52,11 +53,11 @@ class ReviewListItem extends React.Component {
return (
<tr className={this.state.highlight} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
<td className="icon" style={{width: "4%"}}><img src={siteRoot + "media/img/file/192/txt.png"} /></td>
<td className="name a-simulate" style={{width: "46%"}} onClick={this.onReviewsClick}>{fileName}</td>
<td className="icon" style={{width: '4%'}}><img src={siteRoot + 'media/img/file/192/txt.png'} alt="icon"/></td>
<td className="name a-simulate" style={{width: '46%'}} onClick={this.onReviewsClick}>{fileName}</td>
<td className='library'>{item.draft_origin_repo_name}</td>
<td className="status" style={{width: "20%"}}>{item.status}</td>
<td className="update" style={{width: "20%"}}>{localTime}</td>
<td className="status" style={{width: '20%'}}>{item.status}</td>
<td className="update" style={{width: '20%'}}>{localTime}</td>
<td className="menu-toggle"></td>
</tr>
);

View File

@@ -37,7 +37,7 @@ class ReviewListView extends React.Component {
})}
</tbody>
</table>
</div>
</div>
);
}
}

View File

@@ -1,9 +1,15 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { repoID, siteRoot } from '../../utils/constants';
import SearchResultItem from './search-result-item';
import editorUtilities from '../../utils/editor-utilties';
import More from '../more';
const propTypes = {
placeholder: PropTypes.string,
onSearchedClick: PropTypes.func.isRequired,
};
class Search extends Component {
constructor(props) {
@@ -237,4 +243,6 @@ class Search extends Component {
}
}
Search.propTypes = propTypes;
export default Search;

View File

@@ -1,7 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalBody } from 'reactstrap';
import { gettext, siteRoot } from '../utils/constants';
const propTypes = {
className: PropTypes.string,
};
class About extends React.Component {
constructor(props) {
super(props);
@@ -34,11 +39,13 @@ class About extends React.Component {
}
}
About.propTypes = propTypes;
class SideNavFooter extends React.Component {
render() {
return (
<div className="side-nav-footer">
<a href={siteRoot + 'help/'} target="_blank" className="item">{gettext('Help')}</a>
<a href={siteRoot + 'help/'} target="_blank" rel="noopener noreferrer" className="item">{gettext('Help')}</a>
<About />
<a href={siteRoot + 'download_client_program/'} className="item last-item">
<span aria-hidden="true" className="sf2-icon-monitor vam"></span>{' '}

View File

@@ -1,8 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import Logo from './logo';
import MainSideNav from './main-side-nav';
import SideNavFooter from './side-nav-footer';
const propTypes = {
isSidePanelClosed: PropTypes.bool.isRequired,
currentTab: PropTypes.string.isRequired,
onCloseSidePanel: PropTypes.func.isRequired,
};
class SidePanel extends React.Component {
@@ -23,4 +29,6 @@ class SidePanel extends React.Component {
}
}
SidePanel.propTypes = propTypes;
export default SidePanel;

View File

@@ -1,3 +1,3 @@
import Toast from './toast'
import Toast from './toast';
export default Toast;

View File

@@ -7,7 +7,7 @@ class NoticeContainer extends React.Component {
constructor(props) {
super(props);
this.transitionTime = 300;
this.state = {notices: []}
this.state = {notices: []};
}
addNotice = (notice) => {

View File

@@ -4,37 +4,37 @@ import NoticeContainer from './notice-container';
import './toast.css';
function createNotieContainer() {
const div = document.createElement('div')
document.body.appendChild(div)
const noticeContainer = ReactDOM.render(<NoticeContainer />, div)
const div = document.createElement('div');
document.body.appendChild(div);
const noticeContainer = ReactDOM.render(<NoticeContainer />, div);
return {
addNotice(notice) {
return noticeContainer.addNotice(notice)
},
destroy() {
ReactDOM.unmountComponentAtNode(div)
document.body.removeChild(div)
}
}
addNotice(notice) {
return noticeContainer.addNotice(notice);
},
destroy() {
ReactDOM.unmountComponentAtNode(div);
document.body.removeChild(div);
}
};
}
let noticeContainer
let noticeContainer = null;
const notice = (type, content, duration = 2000, onClose) => {
if (!noticeContainer) noticeContainer = createNotieContainer()
return noticeContainer.addNotice({ type, content, duration, onClose })
}
if (!noticeContainer) noticeContainer = createNotieContainer();
return noticeContainer.addNotice({ type, content, duration, onClose });
};
export default {
info(content, duration, onClose) {
return notice('info', content, duration, onClose)
return notice('info', content, duration, onClose);
},
success(content, duration, onClose) {
return notice('success', content, duration, onClose)
return notice('success', content, duration, onClose);
},
warning(content, duration, onClose) {
return notice('warning', content, duration, onClose)
return notice('warning', content, duration, onClose);
},
error(content, duration, onClose) {
return notice('danger', content, duration, onClose)
return notice('danger', content, duration, onClose);
}
}
};

View File

@@ -1,7 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import { serviceUrl } from '../../utils/constants';
import OperationGroup from '../dirent-operation/operation-group';
const propTypes = {
isItemFreezed: PropTypes.bool.isRequired,
node: PropTypes.object.isRequired,
needOperationGroup: PropTypes.bool.isRequired,
onItemMenuHide: PropTypes.func.isRequired,
onItemMenuShow: PropTypes.func.isRequired,
onMainNodeClick: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
onDownload: PropTypes.func.isRequired,
};
class TreeDirList extends React.Component {
constructor(props) {
@@ -68,7 +80,7 @@ class TreeDirList extends React.Component {
return (
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onMouseOver={this.onMouseOver}>
<td className="icon">
<img src={node.type === 'dir' ? serviceUrl + '/media/img/folder-192.png' : serviceUrl + '/media/img/file/192/txt.png'}></img>
<img src={node.type === 'dir' ? serviceUrl + '/media/img/folder-192.png' : serviceUrl + '/media/img/file/192/txt.png'} alt='icon'></img>
</td>
<td className="name a-simulate" onClick={this.onMainNodeClick}>{node.name}</td>
{
@@ -93,4 +105,6 @@ class TreeDirList extends React.Component {
}
}
TreeDirList.propTypes = propTypes;
export default TreeDirList;

View File

@@ -11,7 +11,7 @@ const propTypes = {
node: PropTypes.object.isRequired,
onMainNodeClick: PropTypes.func.isRequired,
onDeleteItem: PropTypes.func.isRequired,
}
};
class TreeDirView extends React.Component {

View File

@@ -1,6 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
const propTypes = {
menuPosition: PropTypes.object.isRequired,
currentNode: PropTypes.object.isRequired,
toggleRename: PropTypes.func.isRequired,
toggleDelete: PropTypes.func.isRequired,
toggleAddFile: PropTypes.func.isRequired,
toggleAddFolder: PropTypes.func.isRequired,
};
class NodeMenu extends React.Component {
toggleAddFile = () => {
@@ -64,4 +74,6 @@ class NodeMenu extends React.Component {
}
}
NodeMenu.propTypes = propTypes;
export default NodeMenu;

View File

@@ -1,7 +1,17 @@
import React from 'react';
import PropTypes from 'prop-types';
import MenuControl from '../menu-control';
import { permission } from '../../utils/constants';
const propTypes = {
isNodeItemFrezee: PropTypes.bool.isRequired,
currentFilePath: PropTypes.string.isRequired,
paddingLeft: PropTypes.number.isRequired,
node: PropTypes.object.isRequired,
treeView: PropTypes.object.isRequired,
onDirCollapse: PropTypes.func.isRequired,
};
function sortByType(a, b) {
if (a.type == 'dir' && b.type != 'dir') {
return -1;
@@ -197,4 +207,6 @@ class TreeNodeView extends React.Component {
}
TreeNodeView.propTypes = propTypes;
export default TreeNodeView;

View File

@@ -1,7 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
import TreeNodeView from './tree-node-view';
import editorUtilities from '../../utils/editor-utilties';
const propTypes = {
permission: PropTypes.string,
isNodeItemFrezee: PropTypes.bool.isRequired,
currentFilePath: PropTypes.string.isRequired,
treeData: PropTypes.object.isRequired,
onShowContextMenu: PropTypes.func.isRequired,
onNodeClick: PropTypes.func.isRequired,
onDirCollapse: PropTypes.func.isRequired,
};
class TreeView extends React.PureComponent {
change = (tree) => {
@@ -31,7 +42,7 @@ class TreeView extends React.PureComponent {
render() {
if (!this.props.treeData.root) {
return <div>Loading...</div>
return <div>Loading...</div>;
}
return (
@@ -52,4 +63,6 @@ class TreeView extends React.PureComponent {
}
TreeView.propTypes = propTypes;
export default TreeView;

View File

@@ -11,15 +11,15 @@ class WikiOutlineItem extends React.Component {
handleNavItemClick = () => {
var activeId = this.props.item.id;
this.props.handleNavItemClick(activeId)
this.props.handleNavItemClick(activeId);
}
render() {
let item = this.props.item;
let activeIndex = parseInt(this.props.activeIndex);
let levelClass = item.depth === 3 ? " textindent-2" : '';
let levelClass = item.depth === 3 ? ' textindent-2' : '';
let activeClass = item.key === activeIndex ? ' wiki-outline-item-active' : '';
let clazz = "wiki-outline-item"+ levelClass + activeClass;
let clazz = 'wiki-outline-item'+ levelClass + activeClass;
return (
<li className={clazz} data-index={item.key} onClick={this.handleNavItemClick}>
<a href={item.id} title={item.text}>{item.text}</a>
@@ -33,8 +33,12 @@ WikiOutlineItem.propTypes = itemPropTypes;
const outlinePropTypes = {
navItems: PropTypes.array.isRequired,
activeId: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]).isRequired,
handleNavItemClick: PropTypes.func.isRequired,
}
};
class WikiOutline extends React.Component {
@@ -43,7 +47,7 @@ class WikiOutline extends React.Component {
this.state = {
activeIndex : 0,
scrollTop: 0,
}
};
}
componentWillReceiveProps(nextProps) {
@@ -57,7 +61,7 @@ class WikiOutline extends React.Component {
if (item.id === activeId && item.key !== _this.state.activeIndex) {
let scrollTop = 0;
if (item.key > 20) {
scrollTop = - (item.key - 20)*27 + "px";
scrollTop = - (item.key - 20)*27 + 'px';
if (parseInt(scrollTop) > 0) { // handle scroll quickly;
scrollTop = 0;
}
@@ -65,7 +69,7 @@ class WikiOutline extends React.Component {
_this.setState({
activeIndex : item.key,
scrollTop: scrollTop
})
});
flag = true;
}
if (flag) {
@@ -86,10 +90,10 @@ class WikiOutline extends React.Component {
activeIndex={this.state.activeIndex}
handleNavItemClick={this.props.handleNavItemClick}
/>
)
);
})}
</ul>
)
);
}
}

View File

@@ -1,7 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom';
/* eslint-disable */
import Prism from 'prismjs';
import { siteRoot, gettext, draftID, reviewID, draftOriginFilePath, draftFilePath, draftOriginRepoID, draftFileName, opStatus, publishFileVersion, originFileVersion } from './utils/constants';
/* eslint-enable */
import { siteRoot, gettext, reviewID, draftOriginFilePath, draftFilePath, draftOriginRepoID, draftFileName, opStatus, publishFileVersion, originFileVersion } from './utils/constants';
import { seafileAPI } from './utils/seafile-api';
import axios from 'axios';
import DiffViewer from '@seafile/seafile-editor/dist/viewer/diff-viewer';
@@ -31,9 +33,9 @@ class DraftReview extends React.Component {
componentDidMount() {
if (publishFileVersion == 'None') {
axios.all([
seafileAPI.getFileDownloadLink(draftOriginRepoID, draftFilePath),
seafileAPI.getFileDownloadLink(draftOriginRepoID, draftOriginFilePath)
axios.all([
seafileAPI.getFileDownloadLink(draftOriginRepoID, draftFilePath),
seafileAPI.getFileDownloadLink(draftOriginRepoID, draftOriginFilePath)
]).then(axios.spread((res1, res2) => {
axios.all([
seafileAPI.getFileContent(res1.data),
@@ -65,18 +67,18 @@ class DraftReview extends React.Component {
onCloseReview = () => {
seafileAPI.updateReviewStatus(reviewID, 'closed').then(res => {
this.setState({reviewStatus: 'closed'});
Toast.success('Review close succeeded.')
Toast.success('Review close succeeded.');
}).catch(() => {
Toast.error('Review close failed.')
Toast.error('Review close failed.');
});
}
onPublishReview = () => {
seafileAPI.updateReviewStatus(reviewID, 'finished').then(res => {
this.setState({reviewStatus: 'finished'});
Toast.success('Review publish succeeded.')
Toast.success('Review publish succeeded.');
}).catch(() => {
Toast.error('Review publish failed.')
Toast.error('Review publish failed.');
});
}
@@ -96,8 +98,8 @@ class DraftReview extends React.Component {
{
this.state.reviewStatus === 'open' &&
<div className="cur-file-operation">
<button className="btn btn-secondary file-operation-btn" title={gettext('Close Review')} onClick={this.onCloseReview}>{gettext("Close")}</button>
<button className="btn btn-success file-operation-btn" title={gettext('Publish Review')} onClick={this.onPublishReview}>{gettext("Publish")}</button>
<button className="btn btn-secondary file-operation-btn" title={gettext('Close Review')} onClick={this.onCloseReview}>{gettext('Close')}</button>
<button className="btn btn-success file-operation-btn" title={gettext('Publish Review')} onClick={this.onPublishReview}>{gettext('Publish')}</button>
</div>
}
{
@@ -113,8 +115,7 @@ class DraftReview extends React.Component {
<div className="cur-view-container content-container">
<div className="cur-view-content">
<div className="markdown-viewer-render-content article">
{
this.state.isLoading ?
{this.state.isLoading ?
<Loading /> :
<DiffViewer markdownContent={this.state.draftContent} markdownContent1={this.state.draftOriginContent} />
}

View File

@@ -15,7 +15,9 @@ class DrawViewer {
loadFile() {
seafileAPI.getFileContent(window.app.config.rawPath).then((res) => {
var doc = mxUtils.parseXml(res.data);
/* eslint-disable */
console.log(doc.documentElement);
/* eslint-enable */
this.setGraphXml(doc.documentElement);
});
}

View File

@@ -13,10 +13,8 @@ function loadFile(editorUi) {
}
function saveFile(content) {
return seafileAPI.getUpdateLink(window.app.config.repoID, window.app.config.parentDir)
.then((res) => {
return seafileAPI.updateFile(res.data, window.app.config.path,
window.app.config.filename, content);
return seafileAPI.getUpdateLink(window.app.config.repoID, window.app.config.parentDir).then((res) => {
return seafileAPI.updateFile(res.data, window.app.config.path, window.app.config.filename, content);
});
}

View File

@@ -10,7 +10,7 @@ import './assets/css/fontawesome.css';
import 'seafile-ui';
import './index.css';
let lang = window.app.pageOptions.lang
let lang = window.app.pageOptions.lang;
ReactDOM.render(
<I18nextProvider i18n={ i18n } initialLanguage={ lang } >

View File

@@ -174,11 +174,10 @@ class EditorUtilities {
}
createDraftReview() {
return seafileAPI.createDraftReview(draftID)
.then(res => {
let url = serviceUrl + '/drafts/review/' + res.data.id;
return url;
})
return seafileAPI.createDraftReview(draftID).then(res => {
let url = serviceUrl + '/drafts/review/' + res.data.id;
return url;
});
}
}

View File

@@ -1,7 +1,12 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { seafileAPI } from '../../utils/seafile-api';
import { gettext, siteRoot } from '../../utils/constants';
const contentPropTypes = {
data: PropTypes.object.isRequired,
};
class FileActivitiesContent extends Component {
render() {
@@ -33,11 +38,18 @@ class FileActivitiesContent extends Component {
}
}
FileActivitiesContent.propTypes = contentPropTypes;
const tablePropTypes = {
items: PropTypes.array.isRequired,
};
class TableBody extends Component {
encodePath(path) {
let path_arr = path.split('/'),
path_arr_ = [];
let path_arr = path.split('/');
let path_arr_ = [];
for (let i = 0, len = path_arr.length; i < len; i++) {
path_arr_.push(encodeURIComponent(path_arr[i]));
}
@@ -55,86 +67,86 @@ class TableBody extends Component {
if (item.obj_type == 'repo') {
switch(item.op_type) {
case 'create':
op = gettext("Created library");
details = <td>{libLink}</td>;
break;
case 'rename':
op = gettext("Renamed library");
details = <td>{item.old_repo_name} => {libLink}</td>;
break;
case 'delete':
op = gettext("Deleted library");
details = <td>{item.repo_name}</td>;
break;
case 'recover':
op = gettext("Restored library");
details = <td>{libLink}</td>;
break;
case 'clean-up-trash':
if (item.days == 0) {
op = gettext("Removed all items from trash.");
} else {
op = gettext("Removed items older than {n} days from trash.").replace('{n}', item.days);
}
details = <td>{libLink}</td>;
break;
case 'create':
op = gettext('Created library');
details = <td>{libLink}</td>;
break;
case 'rename':
op = gettext('Renamed library');
details = <td>{item.old_repo_name} => {libLink}</td>;
break;
case 'delete':
op = gettext('Deleted library');
details = <td>{item.repo_name}</td>;
break;
case 'recover':
op = gettext('Restored library');
details = <td>{libLink}</td>;
break;
case 'clean-up-trash':
if (item.days == 0) {
op = gettext('Removed all items from trash.');
} else {
op = gettext('Removed items older than {n} days from trash.').replace('{n}', item.days);
}
details = <td>{libLink}</td>;
break;
}
} else if (item.obj_type == 'file') {
let fileURL = `${siteRoot}lib/${item.repo_id}/file${this.encodePath(item.path)}`;
let fileLink = <a href={fileURL}>{item.name}</a>;
switch(item.op_type) {
case 'create':
op = gettext("Created file");
details = <td>{fileLink}<br />{smallLibLink}</td>;
break;
case 'delete':
op = gettext("Deleted file");
details = <td>{item.name}<br />{smallLibLink}</td>;
break;
case 'recover':
op = gettext("Restored file");
details = <td>{fileLink}<br />{smallLibLink}</td>;
break;
case 'rename':
op = gettext("Renamed file");
details = <td>{item.old_name} => {fileLink}<br />{smallLibLink}</td>;
break;
case 'move':
let filePathLink = <a href={fileURL}>{item.path}</a>;
op = gettext("Moved file");
details = <td>{item.old_path} => {filePathLink}<br />{smallLibLink}</td>;
break;
case 'edit': // update
op = gettext("Updated file");
details = <td>{fileLink}<br />{smallLibLink}</td>;
break;
case 'create':
op = gettext('Created file');
details = <td>{fileLink}<br />{smallLibLink}</td>;
break;
case 'delete':
op = gettext('Deleted file');
details = <td>{item.name}<br />{smallLibLink}</td>;
break;
case 'recover':
op = gettext('Restored file');
details = <td>{fileLink}<br />{smallLibLink}</td>;
break;
case 'rename':
op = gettext('Renamed file');
details = <td>{item.old_name} => {fileLink}<br />{smallLibLink}</td>;
break;
case 'move':
var filePathLink = <a href={fileURL}>{item.path}</a>;
op = gettext('Moved file');
details = <td>{item.old_path} => {filePathLink}<br />{smallLibLink}</td>;
break;
case 'edit': // update
op = gettext('Updated file');
details = <td>{fileLink}<br />{smallLibLink}</td>;
break;
}
} else { // dir
let dirURL = `${siteRoot}#common/lib/${item.repo_id}${this.encodePath(item.path)}`;
let dirLink = <a href={dirURL}>{item.name}</a>;
switch(item.op_type) {
case 'create':
op = gettext("Created folder");
details = <td>{dirLink}<br />{smallLibLink}</td>;
break;
case 'delete':
op = gettext("Deleted folder");
details = <td>{item.name}<br />{smallLibLink}</td>;
break;
case 'recover':
op = gettext("Restored folder");
details = <td>{dirLink}<br />{smallLibLink}</td>;
break;
case 'rename':
op = gettext("Renamed folder");
details = <td>{item.old_name} => {dirLink}<br />{smallLibLink}</td>;
break;
case 'move':
let dirPathLink = <a href={dirURL}>{item.path}</a>;
op = gettext("Moved folder");
details = <td>{item.old_path} => {dirPathLink}<br />{smallLibLink}</td>;
break;
case 'create':
op = gettext('Created folder');
details = <td>{dirLink}<br />{smallLibLink}</td>;
break;
case 'delete':
op = gettext('Deleted folder');
details = <td>{item.name}<br />{smallLibLink}</td>;
break;
case 'recover':
op = gettext('Restored folder');
details = <td>{dirLink}<br />{smallLibLink}</td>;
break;
case 'rename':
op = gettext('Renamed folder');
details = <td>{item.old_name} => {dirLink}<br />{smallLibLink}</td>;
break;
case 'move':
var dirPathLink = <a href={dirURL}>{item.path}</a>;
op = gettext('Moved folder');
details = <td>{item.old_path} => {dirPathLink}<br />{smallLibLink}</td>;
break;
}
}
@@ -159,6 +171,8 @@ class TableBody extends Component {
}
}
TableBody.propTypes = tablePropTypes;
class FilesActivities extends Component {
constructor(props) {
super(props);
@@ -177,13 +191,12 @@ class FilesActivities extends Component {
componentDidMount() {
const pageNum = 1;
const avatarSize = 72;
seafileAPI.listActivities(pageNum, avatarSize)
.then(res => {
seafileAPI.listActivities(pageNum, avatarSize).then(res => {
// not logged in
if (res.status == 403) {
this.setState({
loading: false,
error_msg: gettext("Permission denied")
error_msg: gettext('Permission denied')
});
} else {
// {"events":[...]}

View File

@@ -65,10 +65,9 @@ class DraftContent extends React.Component {
editUtilties.createDraftReview(draft.id).then(res => {
window.open(siteRoot + 'drafts/review/' + res.data.id);
})
.catch((error) => {
}).catch((error) => {
if (error.response.status == '409') {
Toast.error("The draft review is existing.");
Toast.error('The draft review is existing.');
}
});
}
@@ -129,7 +128,7 @@ class DraftContent extends React.Component {
/>
}
</div>
);
);
}
}

View File

@@ -1,7 +1,16 @@
import React from 'react';
import PropTypes from 'prop-types';
import { siteRoot, gettext } from '../../utils/constants';
import { Link } from '@reach/router';
const propTypes = {
currentTab: PropTypes.string.isRequired,
children: PropTypes.oneOfType([
PropTypes.array,
PropTypes.object
]).isRequired,
};
class DraftsView extends React.Component {
constructor(props) {
@@ -14,7 +23,7 @@ class DraftsView extends React.Component {
tabItemClick = (param) => {
this.setState({
currentTab: param
})
});
}
render() {
@@ -40,4 +49,6 @@ class DraftsView extends React.Component {
}
}
DraftsView.propTypes = propTypes;
export default DraftsView;

View File

@@ -32,18 +32,18 @@ class ReviewContent extends React.Component {
render() {
return (
<div className="cur-view-content" style={{padding: 0}}>
{this.state.isLoadingReviews && <Loading /> }
{(!this.state.isLoadingReviews && this.state.reviewsList.length !==0) &&
<ReviewListView
itemsList={this.state.reviewsList}
isItemFreezed={this.state.isItemFreezed}
/>
}
{(!this.state.isLoadingReviews && this.state.reviewsList.length === 0) &&
<div className="message empty-tip">
<h2>{gettext('There is no Review file existing')}</h2>
</div>
}
{this.state.isLoadingReviews && <Loading /> }
{(!this.state.isLoadingReviews && this.state.reviewsList.length !==0) &&
<ReviewListView
itemsList={this.state.reviewsList}
isItemFreezed={this.state.isItemFreezed}
/>
}
{(!this.state.isLoadingReviews && this.state.reviewsList.length === 0) &&
<div className="message empty-tip">
<h2>{gettext('There is no Review file existing')}</h2>
</div>
}
</div>
);
}

View File

@@ -7,7 +7,8 @@ import HistoryListView from '../../components/history-list-view/history-list-vie
import HistoryListMenu from '../../components/history-list-view/history-list-menu';
const propTypes = {
onHistoryItemClick: PropTypes.func.isRequired
onHistoryItemClick: PropTypes.func.isRequired,
setDiffContent: PropTypes.func.isRequired,
};
class SidePanel extends React.Component {

View File

@@ -18,12 +18,17 @@ const propTypes = {
filePath: PropTypes.string.isRequired,
isFileLoading: PropTypes.bool.isRequired,
isViewFileState: PropTypes.bool.isRequired,
changedNode: PropTypes.object,
onMenuClick: PropTypes.func.isRequired,
onSearchedClick: PropTypes.func.isRequired,
onMainNavBarClick: PropTypes.func.isRequired,
onLinkClick: PropTypes.func.isRequired,
onMainItemClick: PropTypes.func.isRequired,
onMainItemDelete: PropTypes.func.isRequired,
}
onMainAddFile: PropTypes.func.isRequired,
onMainAddFolder: PropTypes.func.isRequired,
switchViewMode: PropTypes.func.isRequired,
};
class MainPanel extends Component {
@@ -215,10 +220,10 @@ class MainPanel extends Component {
{
this.state.newMenuShow &&
<ul className="menu dropdown-menu" style={this.state.operationMenuStyle}>
<li className="dropdown-item" onClick={this.addFolder}>{gettext('New Folder')}</li>
<li className="dropdown-item" onClick={this.addFile}>{gettext('New File')}</li>
<li className="dropdown-item menu-inner-divider"></li>
<li className="dropdown-item" onClick={this.addMarkdownFile}>{gettext('New Markdown File')}</li>
<li className="dropdown-item" onClick={this.addFolder}>{gettext('New Folder')}</li>
<li className="dropdown-item" onClick={this.addFile}>{gettext('New File')}</li>
<li className="dropdown-item menu-inner-divider"></li>
<li className="dropdown-item" onClick={this.addMarkdownFile}>{gettext('New Markdown File')}</li>
</ul>
}
</div>
@@ -235,8 +240,7 @@ class MainPanel extends Component {
<div className="path-containter">
<a href={siteRoot + '#common/'} className="normal">{gettext('Libraries')}</a>
<span className="path-split">/</span>
{
this.props.filePath === '/' ?
{this.props.filePath === '/' ?
<span>{slug}</span> :
<a className="path-link" data-path="/" onClick={this.onMainNavBarClick}>{slug}</a>
}

View File

@@ -1,4 +1,5 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { gettext, siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../utils/constants';
import TreeView from '../../components/tree-view/tree-view';
import NodeMenu from '../../components/tree-view/node-menu';
@@ -8,6 +9,20 @@ import Rename from '../../components/dialog/rename-dialog';
import CreateFolder from '../../components/dialog/create-folder-dialog';
import CreateFile from '../../components/dialog/create-file-dialog';
const propTypes = {
changedNode: PropTypes.object,
treeData: PropTypes.object.isRequired,
currentFilePath: PropTypes.string.isRequired,
closeSideBar: PropTypes.bool.isRequired,
onCloseSide: PropTypes.func.isRequired,
onDirCollapse: PropTypes.func.isRequired,
onNodeClick: PropTypes.func.isRequired,
onRenameNode: PropTypes.func.isRequired,
onDeleteNode: PropTypes.func.isRequired,
onAddFileNode: PropTypes.func.isRequired,
onAddFolderNode: PropTypes.func.isRequired,
};
class SidePanel extends Component {
constructor(props) {
@@ -239,4 +254,7 @@ class SidePanel extends Component {
);
}
}
SidePanel.propTypes = propTypes;
export default SidePanel;

View File

@@ -1,9 +1,28 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { gettext, repoID, serviceUrl, slug, siteRoot } from '../../utils/constants';
import CommonToolbar from '../../components/toolbar/common-toolbar';
import MarkdownViewer from '../../components/markdown-viewer';
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
const propTypes = {
content: PropTypes.string,
lastModified: PropTypes.string,
latestContributor: PropTypes.string,
permission: PropTypes.string,
filePath: PropTypes.string.isRequired,
isFileLoading: PropTypes.bool.isRequired,
isViewFileState: PropTypes.bool.isRequired,
changedNode: PropTypes.object,
onMenuClick: PropTypes.func.isRequired,
onSearchedClick: PropTypes.func.isRequired,
onMainNavBarClick: PropTypes.func.isRequired,
onMainNodeClick: PropTypes.func.isRequired,
onLinkClick: PropTypes.func.isRequired,
onDeleteNode: PropTypes.func.isRequired,
onRenameNode: PropTypes.func.isRequired,
};
class MainPanel extends Component {
constructor(props) {
@@ -103,4 +122,6 @@ class MainPanel extends Component {
}
}
MainPanel.propTypes = propTypes;
export default MainPanel;

View File

@@ -1,4 +1,5 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { gettext, siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../utils/constants';
import TreeView from '../../components/tree-view/tree-view';
import NodeMenu from '../../components/tree-view/node-menu';
@@ -8,6 +9,20 @@ import Rename from '../../components/dialog/rename-dialog';
import CreateFolder from '../../components/dialog/create-folder-dialog';
import CreateFile from '../../components/dialog/create-file-dialog';
const propTypes = {
changedNode: PropTypes.object,
treeData: PropTypes.object.isRequired,
currentFilePath: PropTypes.string.isRequired,
closeSideBar: PropTypes.bool.isRequired,
onCloseSide: PropTypes.func.isRequired,
onDirCollapse: PropTypes.func.isRequired,
onNodeClick: PropTypes.func.isRequired,
onRenameNode: PropTypes.func.isRequired,
onDeleteNode: PropTypes.func.isRequired,
onAddFileNode: PropTypes.func.isRequired,
onAddFolderNode: PropTypes.func.isRequired,
};
class SidePanel extends Component {
constructor(props) {
@@ -238,4 +253,7 @@ class SidePanel extends Component {
);
}
}
SidePanel.propTypes = propTypes;
export default SidePanel;

View File

@@ -97,16 +97,16 @@ export const Utils = {
var file_ext;
if (filename.lastIndexOf('.') == -1) {
return mediaUrl + "img/file/" + size + "/"
return mediaUrl + 'img/file/' + size + '/'
+ this.FILEEXT_ICON_MAP['default'];
} else {
file_ext = filename.substr(filename.lastIndexOf('.') + 1).toLowerCase();
}
if (this.FILEEXT_ICON_MAP[file_ext]) {
return mediaUrl + "img/file/" + size + "/" + this.FILEEXT_ICON_MAP[file_ext];
return mediaUrl + 'img/file/' + size + '/' + this.FILEEXT_ICON_MAP[file_ext];
} else {
return mediaUrl + "img/file/" + size + "/" + this.FILEEXT_ICON_MAP['default'];
return mediaUrl + 'img/file/' + size + '/' + this.FILEEXT_ICON_MAP['default'];
}
},
@@ -148,8 +148,8 @@ export const Utils = {
}).join('/');
*/
var path_arr = path.split('/'),
path_arr_ = [];
var path_arr = path.split('/');
var path_arr_ = [];
for (var i = 0, len = path_arr.length; i < len; i++) {
path_arr_.push(encodeURIComponent(path_arr[i]));
}