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:
committed by
Daniel Pan
parent
3ab4cbff4f
commit
3a67d78016
@@ -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",
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -38,7 +38,7 @@ class DraftListView extends React.Component {
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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 {
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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';
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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 '';
|
||||
}
|
||||
|
@@ -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>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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 (
|
||||
|
@@ -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) => {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
@@ -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});
|
||||
|
@@ -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;
|
||||
|
@@ -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} />
|
||||
|
@@ -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 {
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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')
|
||||
)
|
||||
);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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 = '';
|
||||
|
@@ -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 */
|
||||
|
Reference in New Issue
Block a user