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

clean package.json and repair code style (#2411)

* clean package.json and repair code style

* update css style

* repair bug
This commit is contained in:
shanshuirenjia
2018-09-29 18:32:53 +08:00
committed by Daniel Pan
parent 3ab4cbff4f
commit 3a67d78016
40 changed files with 549 additions and 547 deletions

View File

@@ -6,54 +6,30 @@
"@reach/router": "^1.2.0",
"@seafile/seafile-editor": "^0.1.26",
"autoprefixer": "7.1.6",
"chalk": "1.1.3",
"css-loader": "0.28.7",
"dayjs": "^1.6.2",
"deep-equal": "^1.0.1",
"deepmerge": "^2.1.0",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"file-loader": "1.1.5",
"filesize": "^3.6.1",
"fs-extra": "3.0.1",
"hast-util-sanitize": "^1.1.2",
"html-webpack-plugin": "2.29.0",
"immutable": "^3.8.2",
"jest": "20.0.4",
"lodash": "^4.17.5",
"markup-it": "^7.0.0",
"mdast-util-definitions": "^1.2.2",
"moment": "^2.22.2",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.8",
"prismjs": "^1.15.0",
"promise": "8.0.1",
"prop-types": "^15.6.2",
"raf": "3.4.0",
"react": "^16.4.2",
"react-cookies": "^0.1.0",
"react-dom": "^16.5.2",
"react-moment": "^0.7.9",
"react-s-alert": "^1.4.1",
"reactstrap": "^6.4.0",
"rehype-format": "^2.2.0",
"rehype-raw": "^2.0.0",
"rehype-stringify": "^3.0.0",
"remark": "^9.0.0",
"remark-breaks": "^1.0.0",
"remark-parse": "^5.0.0",
"remark-rehype": "^3.0.0",
"remark-slug": "^5.0.0",
"seafile-js": "^0.2.18",
"seafile-js": "^0.2.20",
"seafile-ui": "^0.1.10",
"sw-precache-webpack-plugin": "0.11.4",
"unified": "^6.1.6",
"url-loader": "0.6.2",
"url-parse": "^1.4.0",
"valid-url": "^1.0.9",
"whatwg-fetch": "2.0.3",
"xtend": "^4.0.1"
"whatwg-fetch": "2.0.3"
},
"scripts": {
"start": "node scripts/start.js",

View File

@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Router } from '@reach/router'
import { Router } from '@reach/router';
import { siteRoot } from './components/constants';
import SidePanel from './components/side-panel';
import MainPanel from './components/main-panel';
@@ -12,7 +12,6 @@ import './assets/css/fa-solid.css';
import './assets/css/fa-regular.css';
import './assets/css/fontawesome.css';
import './css/layout.css';
import './css/common.css';
import './css/toolbar.css';
import './css/search.css';

View File

@@ -17,7 +17,7 @@ class Account extends Component {
isStaff: false,
usageRate: '',
avatarURL: '',
}
};
}
componentDidMount(){
@@ -62,34 +62,34 @@ class Account extends Component {
this.setState({
showInfo: !this.state.showInfo,
})
});
}
onClickAccount = () => {
this.setState({
showInfo: !this.state.showInfo,
})
this.setState({
showInfo: !this.state.showInfo,
});
}
getAccountInfo = () => {
editorUtilities.getAccountInfo().then(resp => {
this.setState({
userName: resp.data.name,
contactEmail: resp.data.email,
usageRate: resp.data.space_usage,
quotaUsage: bytesToSize(resp.data.usage),
quotaTotal: bytesToSize(resp.data.total),
isStaff: resp.data.is_staff,
avatarURL: resp.data.avatar_url
})
})
this.setState({
userName: resp.data.name,
contactEmail: resp.data.email,
usageRate: resp.data.space_usage,
quotaUsage: bytesToSize(resp.data.usage),
quotaTotal: bytesToSize(resp.data.total),
isStaff: resp.data.is_staff,
avatarURL: resp.data.avatar_url
});
});
}
renderMenu = () => {
if(this.state.isStaff){
return (
<a href={siteRoot + 'sys/useradmin/'} title={gettext("System Admin")} className="item">{gettext("System Admin")}</a>
)
<a href={siteRoot + 'sys/useradmin/'} title={gettext('System Admin')} className="item">{gettext('System Admin')}</a>
);
}
}
@@ -97,46 +97,43 @@ class Account extends Component {
if (this.state.avatarURL) {
return (
<img src={this.state.avatarURL} width="36" height="36" className="avatar" />
)
);
}
return (
<img src="" width="36" height="36" className="avatar" />
)
);
}
render() {
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 className="fas fa-caret-down vam"></span>
<span><img src={this.state.avatarURL} width="36" height="36" className="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>
<div id="user-info-popup" className={`account-popup sf-popover ${this.state.showInfo? '':'hide'}`}>
<div className="outer-caret up-outer-caret"><div className="inner-caret"></div></div>
<div className="sf-popover-con">
<div className="item o-hidden">
{this.renderAvatar()}
<div className="txt">
{this.state.userName}
</div>
</div>
<div id="space-traffic">
<div className="item">
<p>{gettext("Used")}: {this.state.quotaUsage} / {this.state.quotaTotal}</p>
<div id="quota-bar">
<span id="quota-usage" className="usage" style={{width: this.state.usageRate}}></span>
</div>
</div>
</div>
<a href={siteRoot + 'profile/'} className="item">{gettext("Settings")}</a>
{this.renderMenu()}
<a href={siteRoot + 'accounts/logout/'} className="item">{gettext("Log out")}</a>
</div>
<div className="outer-caret up-outer-caret">
<div className="inner-caret"></div>
</div>
<div className="sf-popover-con">
<div className="item o-hidden">
{this.renderAvatar()}
<div className="txt">{this.state.userName}</div>
</div>
<div id="space-traffic">
<div className="item">
<p>{gettext('Used')}: {this.state.quotaUsage} / {this.state.quotaTotal}</p>
<div id="quota-bar"><span id="quota-usage" className="usage" style={{width: this.state.usageRate}}></span></div>
</div>
</div>
<a href={siteRoot + 'profile/'} className="item">{gettext('Settings')}</a>
{this.renderMenu()}
<a href={siteRoot + 'accounts/logout/'} className="item">{gettext('Log out')}</a>
</div>
</div>
</div>
)
);
}
}

View File

@@ -1,4 +1,4 @@
import React from 'react'
import React from 'react';
import { Modal, ModalHeader, ModalBody } from 'reactstrap';
class ZipDownloadDialog extends React.Component {
@@ -15,7 +15,7 @@ class ZipDownloadDialog extends React.Component {
<div>{this.props.progress}</div>
</ModalBody>
</Modal>
)
);
}
}

View File

@@ -1,6 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../constants';
const propTypes = {
currentItem: PropTypes.object.isRequired,
menuPosition: PropTypes.object.isRequired,
};
class OperationMenu extends React.Component {
getItemType() {
@@ -31,12 +37,11 @@ class OperationMenu extends React.Component {
<span className="user-select-none" title={gettext('Details')} aria-label={gettext('Details')}>{gettext('Details')}</span>
</li>
<li className="dropdown-item menu-inner-divider"></li>
<li className="dropdown-item operation-menu-item">
<span className="user-select-none" title={gettext('Open via Client')} aria-label={gettext('Open via Client')}>{gettext('Open via Client')}</span>
</li>
</ul>
)
);
}
if (this.props.currentItem.permission === 'r') {
@@ -49,7 +54,7 @@ class OperationMenu extends React.Component {
<span className="user-select-none" title={gettext('Details')} aria-label={gettext('Details')}>{gettext('Details')}</span>
</li>
</ul>
)
);
}
}
@@ -79,7 +84,6 @@ class OperationMenu extends React.Component {
<span className="user-select-none" title={gettext('New Draft')} aria-label={gettext('New Draft')}>{gettext('New Draft')}</span>
</li>
<li className="dropdown-item menu-inner-divider"></li>
<li className="dropdown-item operation-menu-item">
<span className="user-select-none" title={gettext('Comment')} aria-label={gettext('Comment')}>{gettext('Comment')}</span>
</li>
@@ -98,7 +102,7 @@ class OperationMenu extends React.Component {
<span className="user-select-none" title={gettext('Open via Client')} aria-label={gettext('Open via Client')}>{gettext('Open via Client')}</span>
</li>
</ul>
)
);
}
if (this.props.currentItem.permission === "r") {
@@ -117,7 +121,7 @@ class OperationMenu extends React.Component {
<span className="user-select-none" title={gettext('Details')} aria-label={gettext('Details')}>{gettext('Details')}</span>
</li>
</ul>
)
);
}
}
@@ -139,4 +143,6 @@ class OperationMenu extends React.Component {
}
}
OperationMenu.propTypes = propTypes;
export default OperationMenu;

View File

@@ -8,7 +8,8 @@ moment.locale(lang);
const propTypes = {
isItemFreezed: PropTypes.bool.isRequired,
onMenuToggleClick: PropTypes.func.isRequired,
}
};
class DraftListItem extends React.Component {
constructor(props) {
@@ -51,7 +52,7 @@ class DraftListItem extends React.Component {
}
getFileName(filePath) {
let lastIndex = filePath.lastIndexOf("/");
let lastIndex = filePath.lastIndexOf('/');
return filePath.slice(lastIndex+1);
}
@@ -62,7 +63,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'} /></td>
<td className="name a-simulate" onClick={this.onDraftEditClick}>{fileName}</td>
<td className="owner">{draft.owner}</td>
<td className="update">{localTime}</td>

View File

@@ -12,10 +12,10 @@ const propTypes = {
class DraftListMenu extends React.Component {
render() {
let style = '';
let style = {};
let {isMenuShow, menuPosition} = this.props;
if (isMenuShow) {
style = {position: 'fixed', top: menuPosition.top, left: menuPosition.left, display: 'block'}
style = {position: 'fixed', top: menuPosition.top, left: menuPosition.left, display: 'block'};
}
return (
<div>

View File

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

View File

@@ -7,6 +7,7 @@ moment.locale(window.app.config.lang);
const propTypes = {
isItemFrezeed: PropTypes.bool.isRequired,
isFirstItem: PropTypes.bool.isRequired,
preCommitID: PropTypes.string.isRequired,
item: PropTypes.object.isRequired,
currentItem: PropTypes.object.isRequired,
onMenuControlClick: PropTypes.func.isRequired,

View File

@@ -16,6 +16,7 @@ const propTypes = {
reloadMore: PropTypes.func.isRequired,
onMenuControlClick: PropTypes.func.isRequired,
onHistoryItemClick: PropTypes.func.isRequired,
setDiffContent: PropTypes.func.isRequired,
};
class HistoryListView extends React.Component {

View File

@@ -7,7 +7,6 @@ class MainPanel extends Component {
//todos;
}
render() {
return (
<div className="main-panel o-hidden">
@@ -20,8 +19,8 @@ class MainPanel extends Component {
<div className="main-panel-center">
{this.props.children}
</div>
</div>
)
</div>
);
}
}

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { processor, processorGetAST } from '@seafile/seafile-editor/src/lib/seafile-markdown2html';
import TreeView from './tree-view/tree-view';
import Prism from 'prismjs';
import WikiOutline from './wiki-outline';

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { gettext } from '../../constants';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label, Col, FormText } from 'reactstrap';
const gettext = window.gettext;
class CreateFileForder extends React.Component {
constructor(props) {

View File

@@ -1,7 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../constants';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
const gettext = window.gettext;
const propTypes = {
currentNode: PropTypes.object.isRequired,
toggleCancel: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
};
class Delete extends React.Component {
@@ -13,17 +19,19 @@ class Delete extends React.Component {
let name = this.props.currentNode.name;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext("Delete")}</ModalHeader>
<ModalHeader toggle={this.toggle}>{gettext('Delete')}</ModalHeader>
<ModalBody>
<p>{gettext("Are you sure to delete")}{' '}<b>{name}</b> ?</p>
<p>{gettext('Are you sure to delete')}{' '}<b>{name}</b> ?</p>
</ModalBody>
<ModalFooter>
<Button outline color="danger" onClick={this.props.handleSubmit}>{gettext("YES")}</Button>
<Button outline color="secondary" onClick={this.toggle}>{gettext("NO")}</Button>
<Button outline color="danger" onClick={this.props.handleSubmit}>{gettext('YES')}</Button>
<Button outline color="secondary" onClick={this.toggle}>{gettext('NO')}</Button>
</ModalFooter>
</Modal>
)
);
}
}
Delete.propTypes = propTypes;
export default Delete;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { gettext } from '../../constants';
import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter } from 'reactstrap';
const gettext = window.gettext;
class Rename extends React.Component {
constructor(props) {
@@ -23,7 +23,7 @@ class Rename extends React.Component {
handleKeyPress = (e) => {
if (e.key === 'Enter') {
this.handleSubmit()
this.handleSubmit();
}
}
@@ -34,16 +34,16 @@ class Rename extends React.Component {
componentWillMount() {
this.setState({
newName: this.props.currentNode.name
})
});
}
componentDidMount() {
this.changeState(this.props.currentNode);
this.newInput.focus();
let type = this.props.currentNode.type;
if (type === "file") {
var endIndex = this.props.currentNode.name.lastIndexOf(".md");
this.newInput.setSelectionRange(0, endIndex, "forward");
if (type === 'file') {
var endIndex = this.props.currentNode.name.lastIndexOf('.md');
this.newInput.setSelectionRange(0, endIndex, 'forward');
} else {
this.newInput.setSelectionRange(0, -1);
}
@@ -61,17 +61,17 @@ class Rename extends React.Component {
let type = this.props.currentNode.type;
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{type === 'file' ? gettext("Rename File") : gettext("Rename Folder") }</ModalHeader>
<ModalHeader toggle={this.toggle}>{type === 'file' ? gettext('Rename File') : gettext('Rename Folder') }</ModalHeader>
<ModalBody>
<p>{type === 'file' ? gettext("Enter the new file name:"): gettext("Enter the new folder name:")}</p>
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input}} placeholder="newName" value={this.state.newName} onChange={this.handleChange} />
<p>{type === 'file' ? gettext('Enter the new file name:'): gettext('Enter the new folder name:')}</p>
<Input onKeyPress={this.handleKeyPress} innerRef={input => {this.newInput = input;}} placeholder="newName" value={this.state.newName} onChange={this.handleChange} />
</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>
)
);
}
}

View File

@@ -1,6 +1,5 @@
import React from 'react'
const gettext = window.gettext;
import React from 'react';
import { gettext } from '../constants';
class NodeMenu extends React.Component {
@@ -18,47 +17,46 @@ class NodeMenu extends React.Component {
renderNodeMenu() {
let position = this.props.menuPosition;
let style = {position: "fixed",left: position.left, top: position.top, display: 'block'};
let style = {position: 'fixed',left: position.left, top: position.top, display: 'block'};
if (this.props.currentNode.type === "dir") {
if (this.props.currentNode.name === "/") {
if (this.props.currentNode.type === 'dir') {
if (this.props.currentNode.name === '/') {
return (
<ul className="dropdown-menu" style={style}>
<li className="dropdown-item" onClick={this.toggleAddFileFolder}>{gettext("New Folder")}</li>
<li className="dropdown-item" onClick={(ev,flag) => this.toggleAddFileFolder(ev,true)}>{gettext("New File")}</li>
<li className="dropdown-item" onClick={this.toggleAddFileFolder}>{gettext('New Folder')}</li>
<li className="dropdown-item" onClick={(ev,flag) => this.toggleAddFileFolder(ev,true)}>{gettext('New File')}</li>
</ul>
)
);
}
return (
<ul className="dropdown-menu" style={style}>
<li className="dropdown-item" onClick={this.toggleAddFileFolder}>{gettext("New Folder")}</li>
<li className="dropdown-item" onClick={(ev,flag) => this.toggleAddFileFolder(ev,true)}>{gettext("New File")}</li>
<li className="dropdown-item" onClick={this.toggleRename}>{gettext("Rename")}</li>
<li className="dropdown-item" onClick={this.toggleDelete}>{gettext("Delete")}</li>
<li className="dropdown-item" onClick={this.toggleAddFileFolder}>{gettext('New Folder')}</li>
<li className="dropdown-item" onClick={(ev,flag) => this.toggleAddFileFolder(ev,true)}>{gettext('New File')}</li>
<li className="dropdown-item" onClick={this.toggleRename}>{gettext('Rename')}</li>
<li className="dropdown-item" onClick={this.toggleDelete}>{gettext('Delete')}</li>
</ul>
)
);
}
return (
<ul className="dropdown-menu" style={style}>
<li className="dropdown-item" onClick={this.toggleRename}>{gettext("Rename")}</li>
<li className="dropdown-item" onClick={this.toggleDelete}>{gettext("Delete")}</li>
<li className="dropdown-item" onClick={this.toggleRename}>{gettext('Rename')}</li>
<li className="dropdown-item" onClick={this.toggleDelete}>{gettext('Delete')}</li>
</ul>
)
);
}
render() {
if (!this.props.currentNode) {
return (<div className="node-menu-module"></div>)
return (<div className="node-menu-module"></div>);
}
return (
<div className="node-menu-module">
{this.renderNodeMenu()}
</div>
)
);
}
}

View File

@@ -13,7 +13,7 @@ class More extends React.Component {
<li className="list-show-more" onClick={this.props.onShowMore}>
<span className="more-message">{gettext('show more')}</span>
</li>
)
);
}
}

View File

@@ -1,4 +1,10 @@
import React from 'react';
import PropTypes from 'prop-types';
const propTypes = {
item: PropTypes.object.isRequired,
onItemClickHandler: PropTypes.func.isRequired,
};
class SearchResultItem extends React.Component {
@@ -11,12 +17,14 @@ class SearchResultItem extends React.Component {
let item = this.props.item;
return (
<li className="search-result-item" onClick={this.onClickHandler}>
<span className="item-content item-name">{item.name}</span>
<span className="item-content item-link">{item.link_content}</span>
<div className="item-content item-text" dangerouslySetInnerHTML={{__html: item.content}}></div>
<span className="item-content item-name">{item.name}</span>
<span className="item-content item-link">{item.link_content}</span>
<div className="item-content item-text" dangerouslySetInnerHTML={{__html: item.content}}></div>
</li>
)
);
}
}
SearchResultItem.propTypes = propTypes;
export default SearchResultItem;

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { gettext, repoID, siteRoot } from '../constants';
import { repoID, siteRoot } from '../constants';
import SearchResultItem from './search-result-item';
import editorUtilities from '../../utils/editor-utilties';
import More from '../more';
@@ -26,7 +26,7 @@ class Search extends Component {
width: '30rem',
isMaskShow: true,
isCloseShow: true
})
});
}
onCloseHandler = () => {
@@ -51,7 +51,7 @@ class Search extends Component {
this.setState({
isResultShow: false,
isResultGetted: false
})
});
return false;
}
@@ -61,7 +61,7 @@ class Search extends Component {
search_ftypes: repoID ? 'custom' : 'all',
ftype: repoID ? 'Markdown' : '',
input_fexts: repoID ? 'md' : ''
}
};
if (this.timer) {
clearTimeout(this.timer);
@@ -78,7 +78,7 @@ class Search extends Component {
this.setState({
isResultShow: true,
isResultGetted: false
})
});
this.source = editorUtilities.getSource();
this.sendRequest(queryData, this.source.token);
@@ -91,7 +91,7 @@ class Search extends Component {
_this.setState({
resultItems: [],
isResultGetted: true
})
});
_this.source = null;
return;
}
@@ -100,15 +100,17 @@ class Search extends Component {
_this.setState({
resultItems: items,
isResultGetted: true
})
});
_this.source = null;
}).catch(res => {
/* eslint-disable */
console.log(res);
})
/* eslint-enable */
});
}
cancelRequest() {
this.source.cancel("prev request is cancelled");
this.source.cancel('prev request is cancelled');
}
getValueLength(str) {
@@ -153,7 +155,7 @@ class Search extends Component {
isResultShow: false,
isResultGetted: false,
resultItems: []
})
});
}
onShowMore = () => {
@@ -180,12 +182,12 @@ class Search extends Component {
if (!this.state.isResultGetted || this.getValueLength(this.inputValue) < 3) {
return (
<span className="loading-icon loading-tip"></span>
)
);
}
if (!this.state.resultItems.length) {
return (
<div className="search-result-none">No results matching.</div>
)
);
}
let isShowMore = this.state.resultItems.length >= 5 ? true : false;
return (
@@ -197,11 +199,11 @@ class Search extends Component {
item={item}
onItemClickHandler={_this.onItemClickHandler}
/>
)
);
})}
{isShowMore && <More onShowMore={this.onShowMore}/>}
</ul>
)
);
}
render() {
@@ -209,7 +211,7 @@ class Search extends Component {
let style = {'width': width};
return (
<div className="search">
<div className={`search-mask ${this.state.isMaskShow ? "" : "hide"}`} onClick={this.onCloseHandler}></div>
<div className={`search-mask ${this.state.isMaskShow ? '' : 'hide'}`} onClick={this.onCloseHandler}></div>
<div className="search-container">
<div className="input-icon">
<i className="search-icon-left input-icon-addon fas fa-search"></i>
@@ -231,7 +233,7 @@ class Search extends Component {
</div>
</div>
</div>
)
);
}
}

View File

@@ -40,7 +40,7 @@ class PathToolbar extends React.Component {
<ul className="path-toolbar">
<li className="toolbar-item"><a className="op-link sf2-icon-history" href={historyUrl} title={gettext('History')} aria-label={gettext('History')}></a></li>
</ul>
)
);
}
return '';
}

View File

@@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React from 'react';
import { serviceUrl } from '../constants';
import OperationGroup from '../dirent-operation/operation-group';
@@ -66,9 +66,9 @@ class TreeDirList extends React.Component {
render() {
let node = this.props.node;
return (
<tr className={this.state.highlight ? "tr-highlight" : ''} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onMouseOver={this.onMouseOver}>
<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'}></img>
</td>
<td className="name a-simulate" onClick={this.onMainNodeClick}>{node.name}</td>
{
@@ -89,7 +89,7 @@ class TreeDirList extends React.Component {
<td>{node.size}</td>
<td title={node.last_update_time}>{node.last_update_time}</td>
</tr>
)
);
}
}

View File

@@ -1,10 +1,17 @@
import React from "react";
import React from 'react';
import PropTypes from 'prop-types';
import { gettext, repoID } from '../constants';
import editorUtilities from '../../utils/editor-utilties';
import URLDecorator from '../../utils/url-decorator';
import ZipDownloadDialog from '../dialog/zip-download-dialog';
import TreeDirList from './tree-dir-list'
import "../../css/common.css";
import TreeDirList from './tree-dir-list';
const propTypes = {
needOperationGroup: PropTypes.bool.isRequired,
node: PropTypes.object.isRequired,
onMainNodeClick: PropTypes.func.isRequired,
onDeleteItem: PropTypes.func.isRequired,
}
class TreeDirView extends React.Component {
@@ -61,13 +68,13 @@ class TreeDirView extends React.Component {
this.setState({
isProgressDialogShow: false,
});
})
});
}
onItemMenuShow = () => {
this.setState({
isItemFreezed: true,
})
});
}
onItemMenuHide = () => {
@@ -84,21 +91,20 @@ class TreeDirView extends React.Component {
<div className="table-container">
<table>
<thead>
{
this.props.needOperationGroup ?
{this.props.needOperationGroup ?
<tr>
<th style={{width: "4%"}}></th>
<th style={{width: "46%"}}>{gettext('Name')}</th>
<th style={{width: "20%"}}></th>
<th style={{width: "15%"}}>{gettext('Size')}</th>
<th style={{width: "15%"}}>{gettext('Last Update')}</th>
<th style={{width: '4%'}}></th>
<th style={{width: '46%'}}>{gettext('Name')}</th>
<th style={{width: '20%'}}></th>
<th style={{width: '15%'}}>{gettext('Size')}</th>
<th style={{width: '15%'}}>{gettext('Last Update')}</th>
</tr>
:
<tr>
<th style={{width: "4%"}}></th>
<th style={{width: "66%"}}>{gettext('Name')}</th>
<th style={{width: "15%"}}>{gettext('Size')}</th>
<th style={{width: "15%"}}>{gettext('Last Update')}</th>
<th style={{width: '4%'}}></th>
<th style={{width: '66%'}}>{gettext('Name')}</th>
<th style={{width: '15%'}}>{gettext('Size')}</th>
<th style={{width: '15%'}}>{gettext('Last Update')}</th>
</tr>
}
</thead>
@@ -116,7 +122,7 @@ class TreeDirView extends React.Component {
onDelete={this.props.onDeleteItem}
needOperationGroup={this.props.needOperationGroup}
/>
)
);
})}
</tbody>
</table>
@@ -125,8 +131,10 @@ class TreeDirView extends React.Component {
<ZipDownloadDialog progress={this.state.progress} onCancleDownload={this.onCancelDownload}/>
}
</div>
)
);
}
}
TreeDirView.propTypes = propTypes;
export default TreeDirView;

View File

@@ -52,7 +52,7 @@ class Node {
return this.name;
} else {
let p = this.parent.path;
return p === "/" ? (p + this.name) : (p + "/" + this.name);
return p === '/' ? (p + this.name) : (p + '/' + this.name);
}
}
@@ -65,12 +65,12 @@ class Node {
}
isMarkdown() {
let index = this.name.lastIndexOf(".");
let index = this.name.lastIndexOf('.');
if (index == -1) {
return false;
} else {
let type = this.name.substring(index).toLowerCase();
if (type == ".md" || type == ".markdown") {
if (type == '.md' || type == '.markdown') {
return true;
} else {
return false;
@@ -79,16 +79,16 @@ class Node {
}
isDir() {
return this.type == "dir";
return this.type == 'dir';
}
isImage() {
let index = this.name.lastIndexOf(".");
let index = this.name.lastIndexOf('.');
if (index == -1) {
return false;
} else {
let type = this.name.substring(index).toLowerCase();
if (type == ".png" || type == ".jpg") {
if (type == '.png' || type == '.jpg') {
return true;
} else {
return false;
@@ -97,7 +97,7 @@ class Node {
}
serializeToJson() {
var children = []
var children = [];
if (this.hasChildren()) {
children = this.children.map(m => m.toJSON());
}
@@ -111,9 +111,9 @@ class Node {
parent_path: this.parent_path,
isExpanded: this.isExpanded,
children: children
}
};
return object
return object;
}
}

View File

@@ -3,9 +3,9 @@ import MenuControl from '../menu-component/node-menu-control';
import { permission } from '../constants';
function sortByType(a, b) {
if (a.type == "dir" && b.type != "dir") {
if (a.type == 'dir' && b.type != 'dir') {
return -1;
} else if (a.type != "dir" && b.type == "dir") {
} else if (a.type != 'dir' && b.type == 'dir') {
return 1;
} else {
return a.name.localeCompare(b.name);
@@ -18,7 +18,7 @@ class TreeNodeView extends React.Component {
super(props);
this.state = {
isMenuIconShow: false
}
};
}
onClick = (e) => {
@@ -31,7 +31,7 @@ class TreeNodeView extends React.Component {
if (!this.props.isNodeItemFrezee) {
this.setState({
isMenuIconShow: true
})
});
}
}
@@ -39,7 +39,7 @@ class TreeNodeView extends React.Component {
if (!this.props.isNodeItemFrezee) {
this.setState({
isMenuIconShow: false
})
});
}
}
@@ -133,7 +133,7 @@ class TreeNodeView extends React.Component {
onClick={this.onMenuControlClick}
/>
</div>
)
);
}
return;
}
@@ -146,13 +146,13 @@ class TreeNodeView extends React.Component {
icon = <i className="far fa-folder"/>;
type = 'dir';
} else {
let index = node.name.lastIndexOf(".");
let index = node.name.lastIndexOf('.');
if (index === -1) {
icon = <i className="far fa-file"/>;
type = 'file';
} else {
type = node.name.substring(index).toLowerCase();
if (type === ".png" || type === ".jpg") {
if (type === '.png' || type === '.jpg') {
icon = <i className="far fa-image"/>;
type = 'image';
} else {
@@ -163,17 +163,15 @@ class TreeNodeView extends React.Component {
}
return { type, icon };
}
render() {
const styles = {};
let node = this.props.node;
let { type, icon } = this.getNodeTypeAndIcon();
let hlClass = "";
let hlClass = '';
if (node.path === this.props.currentFilePath) {
hlClass = "tree-node-hight-light";
hlClass = 'tree-node-hight-light';
}
return (

View File

@@ -1,6 +1,6 @@
import React from 'react';
import TreeNodeView from './tree-node-view';
import editorUtilities from '../../utils/editor-utilties'
import editorUtilities from '../../utils/editor-utilties';
class TreeView extends React.PureComponent {
@@ -17,8 +17,8 @@ class TreeView extends React.PureComponent {
onDragStart = (e, node) => {
const url = editorUtilities.getFileURL(node);
e.dataTransfer.setData("text/uri-list", url);
e.dataTransfer.setData("text/plain", url);
e.dataTransfer.setData('text/uri-list', url);
e.dataTransfer.setData('text/plain', url);
}
onNodeClick = (e, node) => {

View File

@@ -3,7 +3,7 @@ import moment from 'moment';
import { bytesToSize } from '../utils';
const lang = window.app.config.lang;
moment.locale(lang)
moment.locale(lang);
class Tree {
@@ -201,7 +201,7 @@ class Tree {
parseListToTree(nodeList) {
function getNodePath(parentPath, nodeName) {
return parentPath === "/" ? (parentPath + nodeName) : (parentPath + "/" + nodeName);
return parentPath === '/' ? (parentPath + nodeName) : (parentPath + '/' + nodeName);
}
let root = new Node({name: '/', type: 'dir', isExpanded: true});
@@ -230,7 +230,9 @@ class Tree {
for (let node of treeNodeList) {
let p = map.get(node.parent_path);
if (p === undefined) {
console.log("warning: node " + node.parent_path + " not exist");
/* eslint-disable */
console.log('warning: node ' + node.parent_path + ' not exist');
/* eslint-enable */
} else {
this.addNodeToParent(node, p);
}
@@ -239,7 +241,7 @@ class Tree {
}
parseNodeToTree(node) {
var node = new Node({
var newNode = new Node({
name: node.name,
type: node.type,
size: bytesToSize(node.size),
@@ -250,10 +252,10 @@ class Tree {
});
if (node.children instanceof Array) {
for (let child of node.children) {
this.addNodeToParent(this.parseNodeToTree(child), node);
this.addNodeToParent(this.parseNodeToTree(child), newNode);
}
}
return node;
return newNode;
}
}

View File

@@ -1,4 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
const itemPropTypes = {
activeIndex: PropTypes.number.isRequired,
item: PropTypes.object.isRequired,
handleNavItemClick: PropTypes.func.isRequired,
};
class WikiOutlineItem extends React.Component {
@@ -17,11 +24,18 @@ class WikiOutlineItem extends React.Component {
<li className={clazz} data-index={item.key} onClick={this.handleNavItemClick}>
<a href={item.id} title={item.text}>{item.text}</a>
</li>
)
);
}
}
WikiOutlineItem.propTypes = itemPropTypes;
const outlinePropTypes = {
navItems: PropTypes.array.isRequired,
handleNavItemClick: PropTypes.func.isRequired,
}
class WikiOutline extends React.Component {
constructor(props) {
@@ -79,4 +93,6 @@ class WikiOutline extends React.Component {
}
}
WikiOutline.propTypes = outlinePropTypes;
export default WikiOutline;

View File

@@ -1,211 +0,0 @@
/* begin top logo */
.top-logo {
display: flex;
justify-content: space-between;
flex: 1;
}
/* end top logo */
.panel-heading {
position: relative;
padding: .5rem 1rem;
width: 100%;
height: 2.5rem;
font-size: 1rem;
font-weight: normal;
line-height: 1.5;
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.a-simulate {
color: #eb8205 !important;
text-decoration: none;
font-weight: normal;
cursor: pointer;
}
.a-simulate:hover {
text-decoration: underline;
}
.flex-right {
justify-content: flex-end;
}
/* begin path navigation */
.path-containter { /* for the real path */
font-size:16px;
word-break: break-all;
}
.path-split {
display: inline-block;
padding: 0 5px;
color: #818a91;
}
.path-link {
color: #eb8205 !important;
text-decoration: none;
}
.path-link:hover {
cursor: pointer;
text-decoration: underline !important;
}
/* end path navigation */
/* begin main table list style */
.table-container {
flex: 1;
padding: 10px 16px 20px;
overflow: auto;
}
.table-container table {
width: 100%;
}
.table-container table th {
text-align: left;
font-weight: normal;
font-size: 13px;
line-height: 1.6;
color: #9c9c9c;
}
.table-container table td {
color: #333;
font-size: 14px;
word-break: break-all;
}
.table-container table th, .table-container table td {
padding: 5px 3px;
border-bottom: 1px solid #eee;
}
.table-container table th {
padding-top: 1rem;
}
.table-container table .icon {
text-align: center;
}
.table-container table .icon img {
width: 1.5rem;
height: 1.5rem;
}
/* specific handler */
.table-container table .menu-toggle {
text-align: center;
cursor: pointer;
}
.tr-highlight {
background-color: #f8f8f8;
}
/* end main list style */
/* begin dropdown-menu style */
.dropdown-menu {
min-width: 8rem;
}
.dropdown-item {
cursor: pointer;
}
.dropdown-item.menu-inner-divider {
margin: 0.25rem 0;
border-bottom: 1px solid #ddd;
}
/* end dropdown-menu style */
/* begin tip */
.empty-tip {
margin: auto 1rem;
padding: 30px 40px;
background-color: #FAFAFA;
border: solid 1px #DDD;
border-radius: 3px;
box-shadow: inset 0 0 8px #EEE;
margin-top: 5.5em;
}
.empty-tip h2 {
font-size: 1.25rem;
text-align: center;
color: #222;
font-weight: bold;
}
/* end tip */
/* begin more component */
.list-show-more {
padding: 0.25rem 0.75rem;
line-height: 2rem;
text-align: center;
color: #eb8205;
cursor: pointer;
}
.list-show-more:hover {
background-color: #eee;
}
.list-show-more .more-message {
font-size: 0.875rem;
color: #888;
text-decoration: underline;
}
/* end more component */
/* begin operation menu */
.operation {
display: flex;
}
.operation .operation-group {
list-style: none;
}
.operation-group .operation-group-item {
display: inline-block;
color: #f89a68;
margin-right: 0.5rem;
}
.operation-group-item i {
font-style: normal;
font-size: 1.25rem;
line-height: 1;
cursor: pointer;
vertical-align: middle;
}
.operation-group-item i:hover {
text-decoration: underline;
}
.operation-group-item .sf-dropdown-toggle {
font-size: 0.85rem;
color: #888;
}
.operation-group-item .sf-dropdown-toggle:hover {
text-decoration: none;
}
/* end operaton menu */

View File

@@ -39,7 +39,6 @@ class FileHistory extends React.Component {
onHistoryItemClick = (item, preCommitID)=> {
let _this = this;
let objID = item.rev_file_id;
let downLoadURL = URLDecorator.getUrl({type: 'download_historic_file', filePath: filePath, objID: objID});
let downLoadURL1 = URLDecorator.getUrl({type: 'download_historic_file', filePath: filePath, objID: preCommitID});

View File

@@ -22,7 +22,7 @@ seafileAPI.initForSeahubUsage({ siteRoot, xcsrfHeaders });
function getImageFileNameWithTimestamp() {
var d = Date.now();
return "image-" + d.toString() + ".png";
return 'image-' + d.toString() + '.png';
}
class EditorUtilities {
@@ -37,26 +37,26 @@ class EditorUtilities {
return (
seafileAPI.getUpdateLink(repoID, dirPath).then((res) => {
const uploadLink = res.data;
return seafileAPI.updateFile(uploadLink, filePath, fileName, content)
return seafileAPI.updateFile(uploadLink, filePath, fileName, content);
})
)
);
}
unStarFile () {
return (
seafileAPI.unStarFile(repoID, this.filePath)
)
);
}
starFile() {
return (
seafileAPI.starFile(this.repoID, this.filePath)
)
);
}
getParentDectionaryUrl() {
let parentPath = this.filePath.substring(0, this.filePath.lastIndexOf('/'));
return this.serviceUrl + "/#common/lib/" + this.repoID + parentPath;
return this.serviceUrl + '/#common/lib/' + this.repoID + parentPath;
}
_getImageURL(fileName) {
@@ -68,47 +68,47 @@ class EditorUtilities {
return (
seafileAPI.getUploadLink(repoID, dirPath).then((res) => {
let uploadLinkComponent = res.data;
const uploadLink = uploadLinkComponent + "?ret-json=1";
const uploadLink = uploadLinkComponent + '?ret-json=1';
const name = getImageFileNameWithTimestamp();
const blob = imageFile.slice(0, -1, 'image/png');
const newFile = new File([blob], name, {type: 'image/png'});
const formData = new FormData();
formData.append("parent_dir", "/");
formData.append("relative_path", "images");
formData.append("file", newFile);
return {uploadLink, formData}
formData.append('parent_dir', '/');
formData.append('relative_path', 'images');
formData.append('file', newFile);
return {uploadLink, formData};
}).then(({ uploadLink, formData}) => {
return seafileAPI.uploadImage(uploadLink, formData)
return seafileAPI.uploadImage(uploadLink, formData);
}).then ((res) => {
let resArr = res.data[0];
let filename = resArr.name;
return this._getImageURL(filename);
})
)
);
}
getFileURL(fileNode) {
var url;
if (fileNode.type === 'file') {
if (fileNode.isImage()) {
url = serviceUrl + "/lib/" + repoID + "/file" + encodeURIComponent(fileNode.path()) + "?raw=1";
url = serviceUrl + '/lib/' + repoID + '/file' + encodeURIComponent(fileNode.path()) + '?raw=1';
} else {
url = serviceUrl + "/lib/" + repoID + "/file" + encodeURIComponent(fileNode.path());
url = serviceUrl + '/lib/' + repoID + '/file' + encodeURIComponent(fileNode.path());
}
} else {
url = serviceUrl + "/#common/lib/" + repoID + encodeURIComponent(fileNode.path());
url = serviceUrl + '/#common/lib/' + repoID + encodeURIComponent(fileNode.path());
}
return url;
}
isInternalFileLink(url) {
var re = new RegExp(this.serviceUrl + "/lib/[0-9a-f-]{36}/file.*");
var re = new RegExp(this.serviceUrl + '/lib/[0-9a-f-]{36}/file.*');
return re.test(url);
}
isInternalDirLink(url) {
var re = new RegExp(serviceUrl + "/#[a-z\-]*?/lib/" + "[0-9a-f\-]{36}.*");
var re = new RegExp(serviceUrl + '/#[a-z\-]*?/lib/' + '[0-9a-f\-]{36}.*');
return re.test(url);
}
@@ -119,26 +119,26 @@ class EditorUtilities {
name: item.name,
type: item.type === 'dir' ? 'dir' : 'file',
parent_path: item.parent_dir
}
})
};
});
return files;
})
});
}
getFileHistory() {
return (
seafileAPI.getFileHistory(repoID, filePath)
)
);
}
getFileInfo() {
return (
seafileAPI.getFileInfo(repoID, filePath)
)
);
}
getInternalLink() {
return seafileAPI.getInternalLink(repoID, filePath)
return seafileAPI.getInternalLink(repoID, filePath);
}
getShareLink() {
@@ -146,16 +146,16 @@ class EditorUtilities {
}
createShareLink (repoID, filePath, userPassword, userValidDays) {
return seafileAPI.createShareLink(repoID, filePath, userPassword, userValidDays);
return seafileAPI.createShareLink(repoID, filePath, userPassword, userValidDays);
}
deleteShareLink(token){
return seafileAPI.deleteShareLink(token)
return seafileAPI.deleteShareLink(token);
}
getDraftKey() {
return (repoID + filePath);
}
return (repoID + filePath);
}
getFileContent(url) {
return seafileAPI.getFileContent(url);
@@ -164,7 +164,7 @@ class EditorUtilities {
listFileHistoryRecords(page, perPage) {
return (
seafileAPI.listFileHistoryRecords(repoID, filePath, page, perPage)
)
);
}
getFileHistoryVersion(commitID) {
@@ -178,30 +178,30 @@ const editorUtilities = new EditorUtilities();
class MarkdownEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
markdownContent: "",
loading: true,
mode: "editor",
fileInfo: {
repoID: repoID,
name: fileName,
path: filePath,
mtime: null,
size: 0,
starred: false,
permission: '',
lastModifier: '',
},
collabServer: seafileCollabServer ? seafileCollabServer : null,
};
}
super(props);
this.state = {
markdownContent: '',
loading: true,
mode: 'editor',
fileInfo: {
repoID: repoID,
name: fileName,
path: filePath,
mtime: null,
size: 0,
starred: false,
permission: '',
lastModifier: '',
},
collabServer: seafileCollabServer ? seafileCollabServer : null,
};
}
componentDidMount() {
seafileAPI.getFileInfo(repoID, filePath).then((res) => {
let { mtime, size, starred, permission, last_modifier_name } = res.data;
let lastModifier = last_modifier_name
let lastModifier = last_modifier_name;
this.setState((prevState, props) => ({
fileInfo: {
@@ -220,10 +220,10 @@ class MarkdownEditor extends React.Component {
this.setState({
markdownContent: res.data,
loading: false
})
})
});
});
});
})
});
}
render() {
@@ -232,8 +232,8 @@ class MarkdownEditor extends React.Component {
<div className="empty-loading-page">
<div className="lds-ripple page-centered"><div></div><div></div></div>
</div>
)
} else if (this.state.mode === "editor") {
);
} else if (this.state.mode === 'editor') {
return (
<SeafileEditor
fileInfo={this.state.fileInfo}
@@ -241,11 +241,12 @@ class MarkdownEditor extends React.Component {
editorUtilities={editorUtilities}
userInfo={this.state.collabServer ? userInfo : null}
collabServer={this.state.collabServer}
showFileHistory={true}
showFileHistory={true}
mode={mode}
/>
);
}
}
}
export default MarkdownEditor;

View File

@@ -2,8 +2,6 @@ import React, { Component } from 'react';
import { seafileAPI } from '../../utils/seafile-api';
import { gettext, siteRoot } from '../../components/constants';
const per_page = 25; // default
class FileActivitiesContent extends Component {
render() {
@@ -19,10 +17,10 @@ class FileActivitiesContent extends Component {
<thead>
<tr>
<th width="8%">{/* avatar */}</th>
<th width="10%">{gettext("User")}</th>
<th width="25%">{gettext("Operation")}</th>
<th width="37%">{gettext("File")} / {gettext("Library")}</th>
<th width="20%">{gettext("Time")}</th>
<th width="10%">{gettext('User')}</th>
<th width="25%">{gettext('Operation')}</th>
<th width="37%">{gettext('File')} / {gettext('Library')}</th>
<th width="20%">{gettext('Time')}</th>
</tr>
</thead>
<TableBody items={items} />
@@ -202,13 +200,13 @@ class FilesActivities extends Component {
const pageNum = this.state.page + 1;
this.setState({
page: pageNum
})
});
seafileAPI.listActivities(pageNum)
.then(res => {
if (res.status == 403) {
this.setState({
loading: false,
error_msg: gettext("Permission denied")
error_msg: gettext('Permission denied')
});
} else {
// {"events":[...]}
@@ -235,7 +233,7 @@ class FilesActivities extends Component {
return (
<div className="cur-view-container" id="activities">
<div className="cur-view-path">
<h3 className="sf-heading">{gettext("Activities")}</h3>
<h3 className="sf-heading">{gettext('Activities')}</h3>
</div>
<div className="cur-view-content" onScroll={this.handleScroll}>
<FileActivitiesContent data={this.state} />

View File

@@ -12,6 +12,8 @@ const contentClass = 'markdown-viewer-render-content';
const propTypes = {
renderingContent: PropTypes.bool.isRequired,
content: PropTypes.string.isRequired,
markdownContent: PropTypes.string.isRequired,
markdownContentOld: PropTypes.string.isRequired,
};
class MainPanel extends React.Component {

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constants';
import { gettext, repoID, serviceUrl, slug, siteRoot } from '../../components/constants';
import CommonToolbar from '../../components/toolbar/common-toolbar';
import PathToolbar from '../../components/toolbar/path-toolbar';
import MarkdownViewer from '../../components/markdown-viewer';
@@ -41,17 +41,17 @@ class MainPanel extends Component {
render() {
let filePathList = this.props.filePath.split('/');
let nodePath = "";
let nodePath = '';
let pathElem = filePathList.map((item, index) => {
if (item === "") {
if (item === '') {
return;
}
if (index === (filePathList.length - 1)) {
return (
<span key={index}><span className="path-split">/</span>{item}</span>
)
);
} else {
nodePath += "/" + item;
nodePath += '/' + item;
return (
<span key={index} >
<span className="path-split">/</span>
@@ -62,7 +62,7 @@ class MainPanel extends Component {
{item}
</a>
</span>
)
);
}
});
@@ -73,12 +73,12 @@ class MainPanel extends Component {
<span className="sf2-icon-menu hidden-md-up d-md-none side-nav-toggle" title={gettext('Side Nav Menu')} onClick={this.onMenuClick}></span>
{
this.props.permission === 'rw' &&
<button className="btn btn-secondary top-toolbar-btn" title={gettext('Edit File')} onClick={this.onEditClick}>{gettext("Edit")}</button>
<button className="btn btn-secondary top-toolbar-btn" title={gettext('Edit File')} onClick={this.onEditClick}>{gettext('Edit')}</button>
}
<div className="btn-group">
<button className="btn btn-secondary btn-icon sf-view-mode-change-btn sf2-icon-list-view" id='list' title={gettext("List")} onClick={this.switchViewMode}></button>
<button className="btn btn-secondary btn-icon sf-view-mode-change-btn sf2-icon-grid-view" id='grid' title={gettext("Grid")} onClick={this.switchViewMode}></button>
<button className={`btn btn-secondary btn-icon sf-view-mode-change-btn sf2-icon-wiki-view ${this.state.isWikiMode ? 'current-mode' : ''}`} id='wiki' title={gettext("wiki")} onClick={this.switchViewMode}></button>
<button className="btn btn-secondary btn-icon sf-view-mode-change-btn sf2-icon-list-view" id='list' title={gettext('List')} onClick={this.switchViewMode}></button>
<button className="btn btn-secondary btn-icon sf-view-mode-change-btn sf2-icon-grid-view" id='grid' title={gettext('Grid')} onClick={this.switchViewMode}></button>
<button className={`btn btn-secondary btn-icon sf-view-mode-change-btn sf2-icon-wiki-view ${this.state.isWikiMode ? 'current-mode' : ''}`} id='wiki' title={gettext('wiki')} onClick={this.switchViewMode}></button>
</div>
</div>
<CommonToolbar onSearchedClick={this.props.onSearchedClick} searchPlaceholder={'Search files in this library'}/>
@@ -86,7 +86,7 @@ class MainPanel extends Component {
<div className="cur-view-container">
<div className="cur-view-path">
<div className="path-containter">
<a href={siteRoot + '#common/'} className="normal">{gettext("Libraries")}</a>
<a href={siteRoot + '#common/'} className="normal">{gettext('Libraries')}</a>
<span className="path-split">/</span>
<a href={siteRoot + 'wiki/lib/' + repoID + '/'} className="normal">{slug}</a>
{pathElem}
@@ -115,8 +115,8 @@ class MainPanel extends Component {
}
</div>
</div>
</div>
)
</div>
);
}
}

View File

@@ -25,7 +25,7 @@ class SidePanel extends Component {
showAddFileFolder: false,
showRename: false,
isFile: false
}
};
this.searchedPath = null;
}
@@ -36,18 +36,18 @@ class SidePanel extends Component {
onMouseEnter = () => {
this.setState({
isMenuIconShow: true
})
});
}
onMouseLeave = () => {
this.setState({
isMenuIconShow: false
})
});
}
onNodeClick = (e, node) => {
this.setState({currentNode: node})
this.props.onNodeClick(e, node)
this.setState({currentNode: node});
this.props.onNodeClick(e, node);
}
onShowContextMenu = (e, node) => {
@@ -59,7 +59,7 @@ class SidePanel extends Component {
currentNode: node,
menuPosition: position,
isNodeItemFrezee: true
})
});
}
onHeadingMenuClick = (e) => {
@@ -72,7 +72,7 @@ class SidePanel extends Component {
isShowMenu: !this.state.isShowMenu,
currentNode: node,
menuPosition: position
})
});
}
onHideContextMenu = () => {
@@ -82,7 +82,7 @@ class SidePanel extends Component {
this.setState({
isShowMenu: false,
isNodeItemFrezee: false
})
});
}
toggleAddFileFolder = (flag) => {
@@ -115,13 +115,13 @@ class SidePanel extends Component {
}
onRenameNode = (newName) => {
this.setState({showRename: !this.state.showRename})
this.setState({showRename: !this.state.showRename});
let node = this.state.currentNode;
this.props.onRenameNode(node, newName)
this.props.onRenameNode(node, newName);
}
onDeleteNode = () => {
this.setState({showDelete: !this.state.showDelete})
this.setState({showDelete: !this.state.showDelete});
let node = this.state.currentNode;
this.props.onDeleteNode(node);
}
@@ -133,7 +133,7 @@ class SidePanel extends Component {
componentWillReceiveProps(nextProps) {
this.setState({
currentNode: nextProps.changedNode
})
});
}
componentWillUnmount() {
@@ -149,16 +149,16 @@ class SidePanel extends Component {
}
deleteCancel = () => {
this.setState({showDelete: !this.state.showDelete})
this.setState({showDelete: !this.state.showDelete});
}
renameCancel = () => {
this.setState({showRename: !this.state.showRename})
this.setState({showRename: !this.state.showRename});
}
render() {
return (
<div className={`side-panel wiki-side-panel ${this.props.closeSideBar ? "": "left-zero"}`}>
<div className={`side-panel wiki-side-panel ${this.props.closeSideBar ? '': 'left-zero'}`}>
<div className="side-panel-top panel-top">
<a href={siteRoot} id="logo">
<img src={mediaUrl + logoPath} title={siteTitle} alt="logo" width={logoWidth} height={logoHeight} />
@@ -171,7 +171,7 @@ class SidePanel extends Component {
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
>
{gettext("Files")}
{gettext('Files')}
<div className="heading-icon">
<MenuControl
isShow={this.state.isMenuIconShow}
@@ -227,7 +227,7 @@ class SidePanel extends Component {
</div>
</div>
</div>
)
);
}
}
export default SidePanel;

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constants';
import { gettext, repoID, serviceUrl, slug, siteRoot } from '../../components/constants';
import CommonToolbar from '../../components/toolbar/common-toolbar';
import MarkdownViewer from '../../components/markdown-viewer';
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
@@ -9,7 +9,7 @@ class MainPanel extends Component {
constructor(props) {
super(props);
this.state = {
needOperationGroupo: false
needOperationGroup: false
};
}
@@ -30,17 +30,17 @@ class MainPanel extends Component {
render() {
let filePathList = this.props.filePath.split('/');
let nodePath = "";
let nodePath = '';
let pathElem = filePathList.map((item, index) => {
if (item === "") {
if (item === '') {
return;
}
if (index === (filePathList.length - 1)) {
return (
<span key={index}><span className="path-split">/</span>{item}</span>
)
);
} else {
nodePath += "/" + item;
nodePath += '/' + item;
return (
<span key={index} >
<span className="path-split">/</span>
@@ -51,7 +51,7 @@ class MainPanel extends Component {
{item}
</a>
</span>
)
);
}
});
@@ -62,7 +62,7 @@ class MainPanel extends Component {
<span className="sf2-icon-menu hidden-md-up d-md-none side-nav-toggle" title="Side Nav Menu" onClick={this.onMenuClick}></span>
{
this.props.permission === 'rw' &&
<button className="btn btn-secondary top-toolbar-btn" title="Edit File" onClick={this.onEditClick}>{gettext("Edit Page")}</button>
<button className="btn btn-secondary top-toolbar-btn" title="Edit File" onClick={this.onEditClick}>{gettext('Edit Page')}</button>
}
</div>
<CommonToolbar onSearchedClick={this.props.onSearchedClick} searchPlaceholder={'Search files in this library'}/>
@@ -70,7 +70,7 @@ class MainPanel extends Component {
<div className="cur-view-container">
<div className="cur-view-path">
<div className="path-containter">
<a href={siteRoot + 'wikis/'} className="normal">{gettext("Wikis")}</a>
<a href={siteRoot + 'wikis/'} className="normal">{gettext('Wikis')}</a>
<span className="path-split">/</span>
<a href={siteRoot + 'wikis/' + slug} className="normal">{slug}</a>
{pathElem}
@@ -89,7 +89,7 @@ class MainPanel extends Component {
{ !this.props.isViewFileState &&
<TreeDirView
node={this.props.changedNode}
needOperationGroupo={this.state.needOperationGroupo}
needOperationGroup={this.state.needOperationGroup}
onMainNodeClick={this.props.onMainNodeClick}
onDeleteItem={this.props.onDeleteNode}
onRenameItem={this.props.onRenameNode}
@@ -98,8 +98,8 @@ class MainPanel extends Component {
}
</div>
</div>
</div>
)
</div>
);
}
}

View File

@@ -25,7 +25,7 @@ class SidePanel extends Component {
showAddFileFolder: false,
showRename: false,
isFile: false
}
};
this.searchedPath = null;
}
@@ -36,18 +36,18 @@ class SidePanel extends Component {
onMouseEnter = () => {
this.setState({
isMenuIconShow: true
})
});
}
onMouseLeave = () => {
this.setState({
isMenuIconShow: false
})
});
}
onNodeClick = (e, node) => {
this.setState({currentNode: node})
this.props.onNodeClick(e, node)
this.setState({currentNode: node});
this.props.onNodeClick(e, node);
}
onShowContextMenu = (e, node) => {
@@ -59,7 +59,7 @@ class SidePanel extends Component {
currentNode: node,
menuPosition: position,
isNodeItemFrezee: true
})
});
}
onHeadingMenuClick = (e) => {
@@ -72,7 +72,7 @@ class SidePanel extends Component {
isShowMenu: !this.state.isShowMenu,
currentNode: node,
menuPosition: position
})
});
}
onHideContextMenu = () => {
@@ -82,7 +82,7 @@ class SidePanel extends Component {
this.setState({
isShowMenu: false,
isNodeItemFrezee: false
})
});
}
toggleAddFileFolder = (flag) => {
@@ -115,13 +115,13 @@ class SidePanel extends Component {
}
onRenameNode = (newName) => {
this.setState({showRename: !this.state.showRename})
this.setState({showRename: !this.state.showRename});
let node = this.state.currentNode;
this.props.onRenameNode(node, newName)
this.props.onRenameNode(node, newName);
}
onDeleteNode = () => {
this.setState({showDelete: !this.state.showDelete})
this.setState({showDelete: !this.state.showDelete});
let node = this.state.currentNode;
this.props.onDeleteNode(node);
}
@@ -133,7 +133,7 @@ class SidePanel extends Component {
componentWillReceiveProps(nextProps) {
this.setState({
currentNode: nextProps.changedNode
})
});
}
componentWillUnmount() {
@@ -149,16 +149,16 @@ class SidePanel extends Component {
}
deleteCancel = () => {
this.setState({showDelete: !this.state.showDelete})
this.setState({showDelete: !this.state.showDelete});
}
renameCancel = () => {
this.setState({showRename: !this.state.showRename})
this.setState({showRename: !this.state.showRename});
}
render() {
return (
<div className={`side-panel wiki-side-panel ${this.props.closeSideBar ? "": "left-zero"}`}>
<div className={`side-panel wiki-side-panel ${this.props.closeSideBar ? '': 'left-zero'}`}>
<div className="side-panel-top panel-top">
<a href={siteRoot} id="logo">
<img src={mediaUrl + logoPath} title={siteTitle} alt="logo" width={logoWidth} height={logoHeight} />
@@ -171,7 +171,7 @@ class SidePanel extends Component {
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
>
{gettext("Pages")}
{gettext('Pages')}
<div className="heading-icon">
<MenuControl
isShow={this.state.isMenuIconShow}
@@ -227,7 +227,7 @@ class SidePanel extends Component {
</div>
</div>
</div>
)
);
}
}
export default SidePanel;

View File

@@ -55,7 +55,7 @@ class Wiki extends Component {
this.setState({isFileLoading: false});
} else {
seafileAPI.getFileInfo(repoID, filePath).then((res) => {
let { mtime, size, starred, permission, last_modifier_name } = res.data;
let { mtime, permission, last_modifier_name } = res.data;
this.setState({
tree_data: treeData,
@@ -81,7 +81,9 @@ class Wiki extends Component {
window.history.pushState({urlPath: fileUrl, filePath: filePath}, filePath, fileUrl);
}
}, () => {
/* eslint-disable */
console.log('failed to load files');
/* eslint-enable */
this.setState({
isLoadFailed: true
});
@@ -92,7 +94,7 @@ class Wiki extends Component {
this.setState({isFileLoading: true});
seafileAPI.getFileInfo(repoID, filePath).then((res) => {
let { mtime, size, starred, permission, last_modifier_name } = res.data;
let { mtime, permission, last_modifier_name } = res.data;
this.setState({
latestContributor: last_modifier_name,
@@ -543,4 +545,4 @@ class Wiki extends Component {
ReactDOM.render (
<Wiki />,
document.getElementById('wrapper')
)
);

View File

@@ -1,4 +1,4 @@
import { slug, repoID, siteRoot, historyRepoID } from '../components/constants';
import { slug, repoID, historyRepoID } from '../components/constants';
import { seafileAPI } from './seafile-api';
class EditorUtilities {
@@ -116,7 +116,7 @@ class EditorUtilities {
}
cancelZipTask(zip_token) {
return seafileAPI.cancelZipTask(zip_token)
return seafileAPI.cancelZipTask(zip_token);
}
}

View File

@@ -14,7 +14,7 @@ class URLDecorator {
url = fileServerRoot + 'zip/' + options.token;
break;
case 'download_file_url':
url = siteRoot + 'lib/' + options.repoID + "/file" + encodePath(options.filePath) + "?dl=1";
url = siteRoot + 'lib/' + options.repoID + '/file' + encodePath(options.filePath) + '?dl=1';
break;
default:
url = '';

View File

@@ -21,8 +21,12 @@
* notifications
* sf-popover
* go-back
* Container
* Container ......... common container styles
* top-logo
* table-list
* dropdown-menu
* empty-tip
* more-btn
* list-operation
*
*/
/****** sf2-icon-xx ********/
@@ -101,6 +105,29 @@ ul,ol,li {
line-height: 1.5;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.a-simulate {
color: #eb8205 !important;
text-decoration: none;
font-weight: normal;
cursor: pointer;
}
.a-simulate:hover {
text-decoration: underline;
}
.flex-right {
justify-content: flex-end;
}
/* UI Widget */
/**** caret ****/
@@ -680,3 +707,168 @@ a.op-icon:focus {
display:flex;
flex-shrink:0;
}
/* begin top logo */
.top-logo {
display: flex;
justify-content: space-between;
flex: 1;
}
/* end top logo */
.panel-heading {
position: relative;
padding: .5rem 1rem;
width: 100%;
height: 2.5rem;
font-size: 1rem;
font-weight: normal;
line-height: 1.5;
text-align: center;
}
/* begin path navigation */
.path-containter { /* for the real path */
font-size:16px;
word-break: break-all;
}
.path-split {
display: inline-block;
padding: 0 5px;
color: #818a91;
}
.path-link {
color: #eb8205 !important;
text-decoration: none;
}
.path-link:hover {
cursor: pointer;
text-decoration: underline !important;
}
/* end path navigation */
/* begin main table list style */
.table-container {
flex: 1;
padding: 10px 16px 20px;
overflow: auto;
}
.table-container table {
width: 100%;
}
.table-container table th {
text-align: left;
font-weight: normal;
font-size: 13px;
line-height: 1.6;
color: #9c9c9c;
}
.table-container table td {
color: #333;
font-size: 14px;
word-break: break-all;
}
.table-container table th, .table-container table td {
padding: 5px 3px;
border-bottom: 1px solid #eee;
}
.table-container table th {
padding-top: 1rem;
}
.table-container table .icon {
text-align: center;
}
.table-container table .icon img {
width: 1.5rem;
height: 1.5rem;
}
.table-container table .menu-toggle {
text-align: center;
cursor: pointer;
}
.tr-highlight {
background-color: #f8f8f8;
}
/* end table list style */
/* begin dropdown-menu style */
.dropdown-menu {
min-width: 8rem;
}
.dropdown-item {
cursor: pointer;
}
.dropdown-item.menu-inner-divider {
margin: 0.25rem 0;
border-bottom: 1px solid #ddd;
}
/* end dropdown-menu style */
/* begin tip */
.empty-tip {
margin: auto 1rem;
padding: 30px 40px;
background-color: #FAFAFA;
border: solid 1px #DDD;
border-radius: 3px;
box-shadow: inset 0 0 8px #EEE;
margin-top: 5.5em;
}
.empty-tip h2 {
font-size: 1.25rem;
text-align: center;
color: #222;
font-weight: bold;
}
/* end tip */
/* begin more component */
.list-show-more {
padding: 0.25rem 0.75rem;
line-height: 2rem;
text-align: center;
color: #eb8205;
cursor: pointer;
}
.list-show-more:hover {
background-color: #eee;
}
.list-show-more .more-message {
font-size: 0.875rem;
color: #888;
text-decoration: underline;
}
/* end more component */
/* begin operation menu */
.operations {
display: flex;
}
.operations .operation-group {
list-style: none;
}
.operation-group .operation-group-item {
display: inline-block;
color: #f89a68;
margin-right: 0.5rem;
}
.operation-group-item i {
font-style: normal;
font-size: 1.25rem;
line-height: 1;
cursor: pointer;
vertical-align: middle;
}
.operation-group-item i:hover {
text-decoration: underline;
}
.operation-group-item .sf-dropdown-toggle {
font-size: 0.85rem;
color: #888;
}
.operation-group-item .sf-dropdown-toggle:hover {
text-decoration: none;
}
/* end operaton menu */