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

Update tmp (#2373)

* fix file history time

* change activities url to dashboard

* remove serverRoot from dashboard

* fix api name

* Repair some components are not display

* fix code style

* rename file

* init seafileAPI

* update search

* update seafile-editor seafile-js

* debug rebase

* fix activities loading

* fix drafts css

* add permission
This commit is contained in:
C_Q
2018-09-18 10:11:37 +08:00
committed by Daniel Pan
parent 180f388af1
commit 3d165ec733
35 changed files with 236 additions and 276 deletions

View File

@@ -3,8 +3,7 @@ import ReactDOM from 'react-dom';
import { keyCodes, bytesToSize } from './utils';
import editorUtilities from '../utils/editor-utilties';
const siteRoot = window.app.config.siteRoot;
const gettext = window.gettext;
import { siteRoot, gettext } from './constants';
class Account extends Component {
constructor(props) {

View File

@@ -16,6 +16,8 @@ export const slug = window.wiki ? window.wiki.config.slug : '';
export const repoID = window.wiki ? window.wiki.config.repoId : '';
export const serviceUrl = window.wiki ? window.wiki.config.serviceUrl : '';
export const initialFilePath = window.wiki ? window.wiki.config.initial_file_path : '';
export const permission = window.wiki ? window.wiki.config.permission : '';
// file history
export const PER_PAGE = 25;

View File

@@ -1,13 +1,13 @@
import React, { Component } from 'react';
import { seafileAPI } from '../utils/seafile-api';
import { gettext, siteRoot } from './constants';
const gettext = window.gettext;
const siteRoot = window.app.config.siteRoot;
const per_page = 25; // default
class FileActivitiesContent extends Component {
render() {
const {loading, error_msg, events} = this.props.data;
let {loading, error_msg, items, has_more} = this.props.data;
if (loading) {
return <span className="loading-icon loading-tip"></span>;
} else if (error_msg) {
@@ -25,10 +25,10 @@ class FileActivitiesContent extends Component {
<th width="20%">{gettext("Time")}</th>
</tr>
</thead>
<TableBody items={events.items} />
<TableBody items={items} />
</table>
{events.has_more ? <span className="loading-icon loading-tip"></span> : ''}
{events.error_msg ? <p className="error text-center">{events.error_msg}</p> : ''}
{has_more ? <span className="loading-icon loading-tip"></span> : ''}
{error_msg ? <p className="error text-center">{error_msg}</p> : ''}
</React.Fragment>
);
}
@@ -167,7 +167,10 @@ class FilesActivities extends Component {
this.state = {
loading: true,
error_msg: '',
events: {}
events: {},
items: [],
page: 1,
has_more: false
};
this.handleScroll = this.handleScroll.bind(this);
@@ -175,7 +178,7 @@ class FilesActivities extends Component {
componentDidMount() {
const pageNum = 1
this.props.seafileAPI.listActivities(pageNum)
seafileAPI.listActivities(pageNum)
.then(res => {
// not logged in
if (res.status == 403) {
@@ -187,41 +190,42 @@ class FilesActivities extends Component {
// {"events":[...]}
this.setState({
loading: false,
events: {
page: 1,
items: res.data.events,
has_more: res.data.events.length == per_page ? true : false
}
items: res.data.events,
has_more: res.data.events.length == '0' ? false : true
});
}
});
}
getMore() {
const pageNum = this.state.events.page + 1;
this.props.seafileAPI.getActivities(pageNum)
.then(res => {
this.setState(function(prevState, props) {
let events = prevState.events;
if (res.status == 403) { // log out
events.error_msg = gettext("Permission denied");
events.has_more = false;
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")
});
} else {
// {"events":[...]}
this.setState({
loading: false,
items: [...this.state.items, ...res.data.events],
has_more: res.data.events.length == '0' ? false : true
});
}
if (res.ok) {
events.page += 1;
events.items = events.items.concat(res.data.events);
events.has_more = res.data.events.length == per_page ? true : false;
}
return {events: events};
});
});
}
handleScroll(e) {
let $el = e.target;
if (this.state.events.has_more &&
$el.scrollTop > 0 &&
$el.clientHeight + $el.scrollTop == $el.scrollHeight) { // scroll to the bottom
handleScroll(event) {
const clientHeight = event.target.clientHeight;
const scrollHeight = event.target.scrollHeight;
const scrollTop = event.target.scrollTop;
const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight);
if (this.state.has_more && isBottom) { // scroll to the bottom
this.getMore();
}
}

View File

@@ -49,7 +49,8 @@ class HistoryListItem extends React.Component {
render() {
let item = this.props.item;
let time = moment(item.ctime).format('MMMDo Ah:mm');
let offset = moment.parseZone(item.ctime).utcOffset();
let time = moment(item.ctime).add(offset,'m').format('MMMDo Ah:mm');
let isHigtlightItem = false;
if (this.props.item && this.props.currentItem) {
isHigtlightItem = this.props.item.commit_id === this.props.currentItem.commit_id;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext, filePath } from '../constance';
import { gettext, filePath } from '../constants';
import URLDecorator from '../../utils/url-decorator';
const propTypes = {

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { siteRoot, lang } from '../constance';
import { siteRoot, lang } from '../constants';
import NodeMenuControl from '../menu-component/node-menu-control';
import moment from 'moment';

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../constance';
import { gettext } from '../constants';
const propTypes = {
isMenuShow: PropTypes.bool.isRequired,

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../constance';
import { gettext } from '../constants';
import ListItem from './list-item';
const propTypes = {

View File

@@ -1,6 +1,6 @@
import React from 'react';
const siteRoot = window.app.config.siteRoot;
const serverRoot = window.app.config.serverRoot;
import { siteRoot } from './constants';
import { seafileAPI } from '../utils/seafile-api';
class MainSideNav extends React.Component {
constructor(props) {
@@ -32,7 +32,7 @@ class MainSideNav extends React.Component {
loadGroups = () => {
let _this = this;
this.props.seafileAPI.listGroups().then(res =>{
seafileAPI.listGroups().then(res =>{
let data = res.data.groups;
this.groupsHeight = (data.length + 1) * _this.listHeight;
_this.setState({
@@ -94,9 +94,9 @@ class MainSideNav extends React.Component {
<div className="side-nav-con">
<h3 className="sf-heading">Files</h3>
<ul className="side-tabnav-tabs">
<li className="tab"><a href={siteRoot + '#my-libs'} className="ellipsis" title="My Libraries"><span className="sf2-icon-user" aria-hidden="true"></span>My Libraries</a></li>
<li className="tab"><a href={serverRoot + siteRoot + '#shared-libs/'} className="ellipsis" title="Shared with me"><span className="sf2-icon-share" aria-hidden="true"></span>Shared with me</a></li>
<li className="tab"><a href={serverRoot + siteRoot + '#org/'} className="ellipsis" title="Shared with all"><span className="sf2-icon-organization" aria-hidden="true"></span>Shared with all</a></li>
<li className="tab"><a href={ siteRoot + '#my-libs' } className="ellipsis" title="My Libraries"><span className="sf2-icon-user" aria-hidden="true"></span>My Libraries</a></li>
<li className="tab"><a href={ siteRoot + '#shared-libs/'} className="ellipsis" title="Shared with me"><span className="sf2-icon-share" aria-hidden="true"></span>Shared with me</a></li>
<li className="tab"><a href={ siteRoot + '#org/' } className="ellipsis" title="Shared with all"><span className="sf2-icon-organization" aria-hidden="true"></span>Shared with all</a></li>
<li className="tab" id="group-nav">
<a className="ellipsis user-select-no" title="Shared with groups" onClick={this.grpsExtend}><span className={`toggle-icon float-right fas ${this.state.groupsExtended ?'fa-caret-down':'icon-caret-left'}`} aria-hidden="true"></span><span className="sf2-icon-group" aria-hidden="true"></span>Shared with groups</a>
{this.renderSharedGroups()}

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { seafileAPI } from '../utils/seafile-api';
const gettext = window.gettext;
class Notification extends React.Component {
@@ -21,12 +21,12 @@ class Notification extends React.Component {
}
if (this.state.showNotice) {
this.props.seafileAPI.updateNotifications()
seafileAPI.updateNotifications()
}
}
loadNotices = () => {
this.props.seafileAPI.listPopupNotices().then(res => {
seafileAPI.listPopupNotices().then(res => {
this.setState({
notice_html: res.data.notice_html
})

View File

@@ -4,7 +4,7 @@ class SearchResultItem extends React.Component {
onClickHandler = () => {
var item = this.props.item;
this.props.onItemClickHandler(item.link);
this.props.onItemClickHandler(item);
}
render() {
@@ -19,4 +19,4 @@ class SearchResultItem extends React.Component {
}
}
export default SearchResultItem;
export default SearchResultItem;

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { gettext, repoID } from './constance';
import { gettext, repoID } from './constants';
import SearchResultItem from './search-result-item';
import editorUtilities from '../utils/editor-utilties';
@@ -32,9 +32,9 @@ class Search extends Component {
this.resetToDefault();
}
onItemClickHandler = (path) => {
onItemClickHandler = (item) => {
this.resetToDefault();
this.props.onSearchedClick(path);
this.props.onSearchedClick(item);
}
onChangeHandler = (event) => {
@@ -56,10 +56,10 @@ class Search extends Component {
let queryData = {
q: newValue,
search_repo: repoID,
search_ftypes: 'custom',
ftype: 'Markdown',
input_fexts: 'md'
search_repo: repoID ? repoID : 'all',
search_ftypes: repoID ? 'custom' : 'all',
ftype: repoID ? 'Markdown' : '',
input_fexts: repoID ? 'md' : ''
}
if (this.timer) {
@@ -134,7 +134,8 @@ class Search extends Component {
items[i] = {};
items[i]['index'] = [i];
items[i]['name'] = data[i].name;
items[i]['link'] = data[i].fullpath;
items[i]['path'] = data[i].fullpath;
items[i]['repo_id'] = data[i].repo_id;
items[i]['link_content'] = decodeURI(data[i].fullpath).substring(1);
items[i]['content'] = data[i].content_highlight;
}

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { serviceUrl } from '../constance';
import { serviceUrl } from '../constants';
class TreeDirList extends React.Component {
constructor(props) {
@@ -30,4 +30,4 @@ class TreeDirList extends React.Component {
}
}
export default TreeDirList;
export default TreeDirList;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import MenuControl from '../menu-component/node-menu-control';
import { permission } from '../constance';
import { permission } from '../constants';
function sortByType(a, b) {
if (a.type == "dir" && b.type != "dir") {

View File

@@ -24,4 +24,6 @@
.main-panel-center {
flex: 1;
display: flex;
flex-direction: column;
}

View File

@@ -2,23 +2,18 @@ import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import SidePanel from './pages/dashboard/side-panel';
import MainPanel from './pages/dashboard/main-panel';
import Account from './components/account';
import Search from './components/search';
import Notification from './components/notification';
import { SeafileAPI } from 'seafile-js';
import cookie from 'react-cookies';
import { isPro, gettext, siteRoot } from './components/constants';
import 'seafile-ui';
import './assets/css/fa-solid.css';
import './assets/css/fa-regular.css';
import './assets/css/fontawesome.css';
import './css/dashboard.css';
import './css/search.css';
const siteRoot = window.app.config.siteRoot;
let seafileAPI = new SeafileAPI();
let xcsrfHeaders = cookie.load('sfcsrftoken');
seafileAPI.initForSeahubUsage({ siteRoot, xcsrfHeaders });
class DashBoard extends Component {
@@ -34,14 +29,27 @@ class DashBoard extends Component {
isOpen: !this.state.isOpen,
})
}
onSearchedClick = (item) => {
let str = item.path.substr(item.path.length-1, 1);
if (str === '/'){
window.location.href= siteRoot + '#common/lib/' + item.repo_id + item.path;
} else {
window.location.href= siteRoot + 'lib/' + item.repo_id + '/file' + item.path;
}
}
render() {
return (
<div id="main">
<SidePanel isOpen={this.state.isOpen} toggleClose={this.isOpen} seafileAPI={seafileAPI}/>
<MainPanel isOpen={this.isOpen} seafileAPI={seafileAPI} >
<Notification seafileAPI={seafileAPI} />
<Account seafileAPI={seafileAPI}/>
<SidePanel isOpen={this.state.isOpen} toggleClose={this.isOpen} />
<MainPanel isOpen={this.isOpen}>
{isPro && <Search onSearchedClick={this.onSearchedClick}
placeholder={gettext("Search files")}
/>
}
<Notification />
<Account />
</MainPanel>
</div>
)

View File

@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import editUtilties from './utils/editor-utilties';
import { filePath } from './components/constance';
import { filePath } from './components/constants';
import URLDecorator from './utils/url-decorator';
import { processor } from '@seafile/seafile-editor/src/lib/seafile-markdown2html';
import SidePanel from './pages/file-history/side-panel';

View File

@@ -21,7 +21,7 @@ class MainPanel extends Component {
{children}
</div>
</div>
<FilesActivities seafileAPI={this.props.seafileAPI} />
<FilesActivities />
</div>
)
}

View File

@@ -2,13 +2,7 @@ import React, { Component } from 'react';
import SideNavFooter from '../../components/side-nav-footer';
import MainSideNav from '../../components/main-side-nav';
const siteRoot = window.app.config.siteRoot;
const serverRoot = window.app.config.serverRoot;
const logoPath = window.app.config.logoPath;
const mediaUrl = window.app.config.mediaUrl;
const siteTitle = window.app.config.siteTitle;
const logoWidth = window.app.config.logoWidth;
const logoHeight = window.app.config.logoHeight;
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
class SidePanel extends Component {
@@ -21,7 +15,7 @@ class SidePanel extends Component {
</a>
<a href="#" title="Close" aria-label="Close" onClick={this.props.toggleClose} className="sf2-icon-x1 sf-popover-close side-panel-close op-icon d-md-none "></a>
</div>
<MainSideNav seafileAPI={this.props.seafileAPI}/>
<MainSideNav />
<SideNavFooter />
</div>
)

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../components/constance';
import { gettext } from '../../components/constants';
import Loading from '../../components/loading';
import Account from '../../components/account';
import { seafileAPI } from '../../utils/editor-utilties';

View File

@@ -2,6 +2,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import Prism from 'prismjs';
import Loading from '../../components/loading';
import Account from '../../components/account';
import Notification from '../../components/notification';
import '../../css/initial-style.css';
require('@seafile/seafile-editor/src/lib/code-hight-package');
@@ -21,7 +23,10 @@ class MainPanel extends React.Component {
return (
<div className="main-panel viewer">
<div className="main-panel-north">
<div className="history-heading"></div>
<div className="history-heading">
<Notification />
<Account />
</div>
</div>
<div className="main-panel-center history-viewer-contanier">
<div className="content-viewer">

View File

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext, PER_PAGE, filePath, fileName } from '../../components/constance';
import { gettext, PER_PAGE, filePath, fileName } from '../../components/constants';
import editUtilties from '../../utils/editor-utilties';
import Loading from '../../components/loading';
import HistoryListView from '../../components/history-list-view/history-list-view';

View File

@@ -1,7 +1,8 @@
import React, { Component } from 'react';
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constance';
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro, permission } from '../../components/constants';
import Search from '../../components/search';
import Account from '../../components/account';
import Notification from '../../components/notification';
import MarkdownViewer from '../../components/markdown-viewer';
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
@@ -51,7 +52,7 @@ class MainPanel extends Component {
<div className="main-panel-top panel-top">
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.onMenuClick}></span>
<div className="wiki-page-ops">
{ this.props.permission === 'rw' &&
{ permission &&
<a className="btn btn-secondary btn-topbar" title="Edit File" onClick={this.onEditClick}>{gettext("Edit")}</a>
}
<a className="btn btn-secondary btn-topbar sf2-icon-list-view" id='list' title={gettext("List")} onClick={this.switchViewMode}></a>
@@ -59,10 +60,11 @@ class MainPanel extends Component {
</div>
<div className="common-toolbar">
{isPro && <Search onSearchedClick={this.props.onSearchedClick}
placeholder={gettext("Search files in this wiki")}
placeholder={gettext("Search files in this library")}
/>
}
<Account />
<Notification />
<Account />
</div>
</div>
<div className="cur-view-main">

View File

@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import TreeView from '../../components/tree-view/tree-view';
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constance';
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
import NodeMenu from '../../components/menu-component/node-menu';
import MenuControl from '../../components/menu-component/node-menu-control';
import Delete from '../../components/menu-component/menu-dialog/delete-dialog';

View File

@@ -1,7 +1,8 @@
import React, { Component } from 'react';
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constance';
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constants';
import Search from '../../components/search';
import Account from '../../components/account';
import Notification from '../../components/notification';
import MarkdownViewer from '../../components/markdown-viewer';
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
@@ -53,6 +54,7 @@ class MainPanel extends Component {
placeholder={gettext("Search files in this wiki")}
/>
}
<Notification />
<Account />
</div>
</div>

View File

@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import TreeView from '../../components/tree-view/tree-view';
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constance';
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
import NodeMenu from '../../components/menu-component/node-menu';
import MenuControl from '../../components/menu-component/node-menu-control';
import Delete from '../../components/menu-component/menu-dialog/delete-dialog';

View File

@@ -1,12 +1,12 @@
import React, { Component } from 'react';
import cookie from 'react-cookies';
import ReactDOM from 'react-dom';
import SidePanel from './pages/repo-wiki-mode/side-panel';
import MainPanel from './pages/repo-wiki-mode/main-panel';
import moment from 'moment';
import { slug, repoID, serviceUrl, initialFilePath } from './components/constance';
import { slug, repoID, serviceUrl, initialFilePath } from './components/constants';
import editorUtilities from './utils/editor-utilties';
import { seafileAPI } from './utils/editor-utilties';
import { seafileAPI } from './utils/seafile-api';
import cookie from 'react-cookies';
import Node from './components/tree-view/node'
import Tree from './components/tree-view/tree'
import 'seafile-ui';
@@ -149,7 +149,8 @@ class Wiki extends Component {
}
}
onSearchedClick = (path) => {
onSearchedClick = (item) => {
let path = item.path;
if (this.state.currentFilePath !== path) {
this.initMainPanelData(path);

View File

@@ -1,10 +1,5 @@
import { slug, repoID, siteRoot, historyRepoID } from '../components/constance';
import { SeafileAPI } from 'seafile-js';
import cookie from 'react-cookies';
let seafileAPI = new SeafileAPI();
let xcsrfHeaders = cookie.load('sfcsrftoken');
seafileAPI.initForSeahubUsage({ siteRoot, xcsrfHeaders });
import { slug, repoID, siteRoot, historyRepoID } from '../components/constants';
import { seafileAPI } from './seafile-api';
class EditorUtilities {
@@ -114,4 +109,3 @@ class EditorUtilities {
const editorUtilities = new EditorUtilities();
export default editorUtilities;
export { seafileAPI };

View File

@@ -0,0 +1,9 @@
import cookie from 'react-cookies';
import { SeafileAPI } from 'seafile-js';
import { siteRoot } from '../components/constants';
let seafileAPI = new SeafileAPI();
let xcsrfHeaders = cookie.load('sfcsrftoken');
seafileAPI.initForSeahubUsage({ siteRoot, xcsrfHeaders });
export { seafileAPI };

View File

@@ -3,7 +3,7 @@ import ReactDOM from 'react-dom';
import SidePanel from './pages/wiki/side-panel';
import MainPanel from './pages/wiki/main-panel';
import moment from 'moment';
import { slug, repoID, serviceUrl, initialFilePath } from './components/constance';
import { slug, repoID, serviceUrl, initialFilePath } from './components/constants';
import editorUtilities from './utils/editor-utilties';
import Node from './components/tree-view/node'
import Tree from './components/tree-view/tree'
@@ -112,7 +112,8 @@ class Wiki extends Component {
}
}
onSearchedClick = (path) => {
onSearchedClick = (item) => {
let path = item.path;
if (this.state.currentFilePath !== path) {
this.initMainPanelData(path);