mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-01 23:20:51 +00:00
Draft dashboard optimized (#2384)
* create a common toolbar component * optimized code * combine side-panel * add change state
This commit is contained in:
committed by
Daniel Pan
parent
7a17e908b0
commit
ba583d6efd
@@ -1,9 +1,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { keyCodes, bytesToSize } from './utils';
|
import { keyCodes, bytesToSize } from '../utils';
|
||||||
import editorUtilities from '../utils/editor-utilties';
|
import editorUtilities from '../../utils/editor-utilties';
|
||||||
|
|
||||||
import { siteRoot, gettext } from './constants';
|
import { siteRoot, gettext } from '../constants';
|
||||||
|
|
||||||
class Account extends Component {
|
class Account extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { seafileAPI } from '../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
const gettext = window.gettext;
|
const gettext = window.gettext;
|
||||||
|
|
||||||
class Notification extends React.Component {
|
class Notification extends React.Component {
|
@@ -1,12 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropsType from 'prop-types';
|
import PropsType from 'prop-types';
|
||||||
|
import { siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './constants';
|
||||||
const siteRoot = window.app.config.siteRoot;
|
|
||||||
const mediaUrl = window.app.config.mediaUrl;
|
|
||||||
const logoPath = window.app.config.logoPath;
|
|
||||||
const logoWidth = window.app.config.logoWidth;
|
|
||||||
const logoHeight = window.app.config.logoHeight;
|
|
||||||
const siteTitle = window.app.config.siteTitle;
|
|
||||||
|
|
||||||
const propsType = {
|
const propsType = {
|
||||||
onCloseSidePanel: PropsType.func.isRequired,
|
onCloseSidePanel: PropsType.func.isRequired,
|
||||||
@@ -20,24 +14,18 @@ class Logo extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="logo">
|
<div className="top-logo">
|
||||||
<a href={siteRoot} id="logo">
|
<a href={siteRoot} id="logo">
|
||||||
<img
|
<img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
|
||||||
src={mediaUrl + logoPath}
|
</a>
|
||||||
height={logoHeight}
|
<a
|
||||||
width={logoWidth}
|
className="sf2-icon-x1 sf-popover-close side-panel-close op-icon d-md-none"
|
||||||
title={siteTitle}
|
onClick={this.closeSide}
|
||||||
alt="logo"
|
title="Close"
|
||||||
/>
|
aria-label="Close"
|
||||||
</a>
|
>
|
||||||
<a
|
</a>
|
||||||
className="sf2-icon-x1 sf-popover-close side-panel-close op-icon d-md-none"
|
</div>
|
||||||
onClick={this.closeSide}
|
|
||||||
title="Close"
|
|
||||||
aria-label="Close"
|
|
||||||
>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { siteRoot } from './constants';
|
import { gettext, siteRoot } from './constants';
|
||||||
import { seafileAPI } from '../utils/seafile-api';
|
import { seafileAPI } from '../utils/seafile-api';
|
||||||
|
|
||||||
class MainSideNav extends React.Component {
|
class MainSideNav extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
let currentTab = this.props.currentTab || '';
|
||||||
this.state = {
|
this.state = {
|
||||||
groupsExtended: false,
|
groupsExtended: false,
|
||||||
sharedExtended: false,
|
sharedExtended: false,
|
||||||
closeSideBar:false,
|
closeSideBar:false,
|
||||||
groupItems: []
|
groupItems: [],
|
||||||
|
currentTab: currentTab,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.listHeight = 24; //for caculate tabheight
|
this.listHeight = 24; //for caculate tabheight
|
||||||
@@ -41,6 +43,12 @@ class MainSideNav extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tabItemClick = (param) => {
|
||||||
|
this.setState({
|
||||||
|
currentTab: param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
renderSharedGroups() {
|
renderSharedGroups() {
|
||||||
let style = {height: 0};
|
let style = {height: 0};
|
||||||
if (this.state.groupsExtended) {
|
if (this.state.groupsExtended) {
|
||||||
@@ -48,15 +56,19 @@ class MainSideNav extends React.Component {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ul className={`grp-list ${this.state.groupsExtended ? 'side-panel-slide' : 'side-panel-slide-up'}`} style={style}>
|
<ul className={`grp-list ${this.state.groupsExtended ? 'side-panel-slide' : 'side-panel-slide-up'}`} style={style}>
|
||||||
<li>
|
<li className={this.state.currentTab === 'groups' ? 'tab-cur' : ''}>
|
||||||
<a href={siteRoot + '#groups/'}>
|
<a href={siteRoot + '#groups/'} onClick={() => this.tabItemClick('groups')}>
|
||||||
<span className="sharp" aria-hidden="true">#</span>All Groups</a>
|
<span className="sharp" aria-hidden="true">#</span>
|
||||||
|
All Groups
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{this.state.groupItems.map(item => {
|
{this.state.groupItems.map(item => {
|
||||||
return (
|
return (
|
||||||
<li key={item.id}>
|
<li key={item.id} className={this.state.currentTab === item.id ? 'tab-cur' : ''}>
|
||||||
<a href={siteRoot + '#group/' + item.id + '/'}>
|
<a href={siteRoot + '#group/' + item.id + '/'} className="ellipsis" onClick={() => this.tabItemClick(item.id)}>
|
||||||
<span className="sharp" aria-hidden="true">#</span>{item.name}</a>
|
<span className="sharp" aria-hidden="true">#</span>
|
||||||
|
{item.name}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
@@ -75,14 +87,23 @@ class MainSideNav extends React.Component {
|
|||||||
let style = {height: height};
|
let style = {height: height};
|
||||||
return (
|
return (
|
||||||
<ul className={`${this.state.sharedExtended ? 'side-panel-slide' : 'side-panel-slide-up'}`} style={style} >
|
<ul className={`${this.state.sharedExtended ? 'side-panel-slide' : 'side-panel-slide-up'}`} style={style} >
|
||||||
<li>
|
<li className={this.state.currentTab === 'share-admin-libs' ? 'tab-cur' : ''}>
|
||||||
<a href={siteRoot + '#share-admin-libs/'}><span aria-hidden="true" className="sharp">#</span>Libraries</a>
|
<a href={siteRoot + '#share-admin-libs/'} className="ellipsis" title={gettext('Libraries')} onClick={() => this.tabItemClick('share-admin-libs')}>
|
||||||
|
<span aria-hidden="true" className="sharp">#</span>
|
||||||
|
{gettext('Libraries')}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li className={this.state.currentTab === 'share-admin-folders' ? 'tab-cur' : ''}>
|
||||||
<a href={siteRoot + '#share-admin-folders/'}><span aria-hidden="true" className="sharp">#</span>Folders</a>
|
<a href={siteRoot + '#share-admin-folders/'} className="ellipsis" title={gettext('Folders')} onClick={() => this.tabItemClick('share-admin-folders')}>
|
||||||
|
<span aria-hidden="true" className="sharp">#</span>
|
||||||
|
{gettext('Folders')}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li className={this.state.currentTab === 'share-admin-share-links' ? 'tab-cur' : ''}>
|
||||||
<a href={siteRoot + '#share-admin-share-links/'}><span aria-hidden="true" className="sharp">#</span>Links</a>
|
<a href={siteRoot + '#share-admin-share-links/'} className="ellipsis" title={gettext('Links')} onClick={() => this.tabItemClick('share-admin-share-links')}>
|
||||||
|
<span aria-hidden="true" className="sharp">#</span>
|
||||||
|
{gettext('Links')}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
)
|
)
|
||||||
@@ -94,31 +115,68 @@ class MainSideNav extends React.Component {
|
|||||||
<div className="side-nav-con">
|
<div className="side-nav-con">
|
||||||
<h3 className="sf-heading">Files</h3>
|
<h3 className="sf-heading">Files</h3>
|
||||||
<ul className="side-tabnav-tabs">
|
<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 ${this.state.currentTab === 'my-libs' ? 'tab-cur' : ''}`}>
|
||||||
<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>
|
<a href={ siteRoot + '#my-libs' } className="ellipsis" title={gettext('My Libraries')} onClick={() => this.tabItemClick('my-libs')}>
|
||||||
<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>
|
<span className="sf2-icon-user" aria-hidden="true"></span>
|
||||||
|
{gettext('My Libraries')}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className={`tab ${this.state.currentTab === 'shared-libs' ? 'tab-cur' : ''}`}>
|
||||||
|
<a href={ siteRoot + '#shared-libs/'} className="ellipsis" title={gettext('Shared with me')} onClick={() => this.tabItemClick('shared-libs')}>
|
||||||
|
<span className="sf2-icon-share" aria-hidden="true"></span>
|
||||||
|
{gettext('Shared with me')}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className={`tab ${this.state.currentTab === 'org' ? 'tab-cur' : ''}`} onClick={() => this.tabItemClick('org')}>
|
||||||
|
<a href={ siteRoot + '#org/' } className="ellipsis" title={gettext('Shared with all')}>
|
||||||
|
<span className="sf2-icon-organization" aria-hidden="true"></span>
|
||||||
|
{gettext('Shared with all')}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li className="tab" id="group-nav">
|
<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>
|
<a className="ellipsis user-select-no" title={gettext('Shared with groups')} onClick={this.grpsExtend}>
|
||||||
|
<span className={`toggle-icon float-right fas ${this.state.groupsExtended ?'fa-caret-down':'fa-caret-left'}`} aria-hidden="true"></span>
|
||||||
|
<span className="sf2-icon-group" aria-hidden="true"></span>
|
||||||
|
{gettext('Shared with groups')}
|
||||||
|
</a>
|
||||||
{this.renderSharedGroups()}
|
{this.renderSharedGroups()}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div className="hd w-100 o-hidden">
|
<h3 className="sf-heading">Tools</h3>
|
||||||
<h3 className="float-left sf-heading">Tools</h3>
|
|
||||||
</div>
|
|
||||||
<ul className="side-tabnav-tabs">
|
<ul className="side-tabnav-tabs">
|
||||||
<li className="tab"><a href={siteRoot + '#starred/'}><span className="sf2-icon-star" aria-hidden="true"></span>Favorites</a></li>
|
<li className={`tab ${this.state.currentTab === 'favorites' ? 'tab-cur' : ''}`}>
|
||||||
<li className="tab"><a href={siteRoot + 'dashboard'}><span className="sf2-icon-clock" aria-hidden="true"></span>Acitivities</a></li>
|
<a href={siteRoot + '#starred/'} title={gettext('Favorites')} onClick={() => this.tabItemClick('favorites')}>
|
||||||
<li className="tab"><a href={siteRoot + '#devices/'} className="ellipsis" title="Linked Devices"><span className="sf2-icon-monitor" aria-hidden="true"></span>Linked Devices</a></li>
|
<span className="sf2-icon-star" aria-hidden="true"></span>
|
||||||
<li className="tab" id="share-admin-nav">
|
{gettext('Favorites')}
|
||||||
<a className="ellipsis user-select-no" title="Share Admin" onClick={this.shExtend}><span className={`toggle-icon float-right fas ${this.state.sharedExtended ? 'fa-caret-down':'fa-caret-left'}`} aria-hidden="true"></span><span aria-hidden="true" className="sf2-icon-wrench"></span>Share Admin</a>
|
|
||||||
{this.renderSharedAdmin()}
|
|
||||||
</li>
|
|
||||||
<li className="tab">
|
|
||||||
<a href={siteRoot + 'drafts/'}>
|
|
||||||
<span className="sf2-icon-edit" aria-hidden="true"></span>Drafts
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li className={`tab ${this.state.currentTab === 'dashboard' ? 'tab-cur' : ''}`}>
|
||||||
|
<a href={siteRoot + 'dashboard'} title={gettext('Acitivities')} onClick={() => this.tabItemClick('dashboard')}>
|
||||||
|
<span className="sf2-icon-clock" aria-hidden="true"></span>
|
||||||
|
{gettext('Acitivities')}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className={`tab ${this.state.currentTab === 'devices' ? 'tab-cur' : ''}`}>
|
||||||
|
<a href={siteRoot + '#devices/'} className="ellipsis" title={gettext('Linked Devices')} onClick={() => this.tabItemClick('devices')}>
|
||||||
|
<span className="sf2-icon-monitor" aria-hidden="true"></span>
|
||||||
|
{gettext('Linked Devices')}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className={`tab ${this.state.currentTab === 'drafts' ? 'tab-cur' : ''}`} onClick={() => this.tabItemClick('drafts')}>
|
||||||
|
<a href={siteRoot + 'drafts/'} title={gettext('Drafts')}>
|
||||||
|
<span className="sf2-icon-edit" aria-hidden="true"></span>
|
||||||
|
{gettext('Drafts')}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className="tab" id="share-admin-nav">
|
||||||
|
<a className="ellipsis user-select-no" title={gettext('Share Admin')} onClick={this.shExtend}>
|
||||||
|
<span className={`toggle-icon float-right fas ${this.state.sharedExtended ? 'fa-caret-down':'fa-caret-left'}`} aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true" className="sf2-icon-wrench"></span>
|
||||||
|
{gettext('Share Admin')}
|
||||||
|
</a>
|
||||||
|
{this.renderSharedAdmin()}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
30
frontend/src/components/side-panel.js
Normal file
30
frontend/src/components/side-panel.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Logo from './logo';
|
||||||
|
import MainSideNav from './main-side-nav';
|
||||||
|
import SideNavFooter from './side-nav-footer';
|
||||||
|
|
||||||
|
|
||||||
|
class SidePanel extends React.Component {
|
||||||
|
|
||||||
|
onCloseSidePanel = () => {
|
||||||
|
//todos;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="side-panel">
|
||||||
|
<div className="side-panel-north">
|
||||||
|
<Logo onCloseSidePanel={this.onCloseSidePanel}/>
|
||||||
|
</div>
|
||||||
|
<div className="side-panel-center">
|
||||||
|
<MainSideNav currentTab={this.props.currentTab}/>
|
||||||
|
</div>
|
||||||
|
<div className="side-panel-footer">
|
||||||
|
<SideNavFooter />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SidePanel;
|
26
frontend/src/components/toolbar/common-toolbar.js
Normal file
26
frontend/src/components/toolbar/common-toolbar.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { isPro, gettext } from '../../components/constants';
|
||||||
|
import Search from '../search/search';
|
||||||
|
import Notification from '../common/notification';
|
||||||
|
import Account from '../common/account';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
onSearchedClick: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
class CommonToolbar extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="common-toolbar">
|
||||||
|
{isPro && <Search onSearchedClick={this.props.onSearchedClick} placeholder={gettext("Search files")}/>}
|
||||||
|
<Notification />
|
||||||
|
<Account />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonToolbar.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default CommonToolbar;
|
@@ -1,3 +1,11 @@
|
|||||||
|
/* begin top logo */
|
||||||
|
.top-logo {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end top logo */
|
||||||
.panel-heading {
|
.panel-heading {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
|
@@ -1,29 +1,68 @@
|
|||||||
.side-panel {
|
#wrapper {
|
||||||
flex: 1 1 20%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for top bottom layout*/
|
||||||
|
#header {
|
||||||
|
height: 49px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for left right layout */
|
||||||
|
#main {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-panel {
|
||||||
|
flex: 0 0 25%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.main-panel {
|
.main-panel {
|
||||||
flex: 1 1 80%;
|
flex: 1 0 75%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.side-panel {
|
||||||
|
position:fixed;
|
||||||
|
left:-300px;
|
||||||
|
z-index:1; /* important! */
|
||||||
|
width:300px;
|
||||||
|
height:100%;
|
||||||
|
background:#f8f8f8;
|
||||||
|
-webkit-transition: all 0.3s ease;
|
||||||
|
-moz-transition: all 0.3s ease;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-panel-north,
|
.side-panel-north,
|
||||||
.main-panel-north {
|
.main-panel-north {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
background: #f4f4f7;
|
background: #f4f4f7;
|
||||||
border-bottom: 1px solid #e8e8e8;
|
border-bottom: 1px solid #e8e8e8;
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.side-panel-center {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border-right: 1px solid #eee;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.side-panel-center,
|
||||||
.main-panel-center {
|
.main-panel-center {
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.side-panel-center,
|
||||||
|
.side-panel-footer {
|
||||||
|
min-height: 0;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cur-view-toolbar:before {
|
.border-left-show:before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 3px;
|
top: 3px;
|
||||||
bottom: 3px;
|
bottom: 3px;
|
||||||
|
@@ -1,16 +1,13 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import SidePanel from './pages/dashboard/side-panel';
|
import { siteRoot } from './components/constants';
|
||||||
|
import SidePanel from './components/side-panel';
|
||||||
import MainPanel from './pages/dashboard/main-panel';
|
import MainPanel from './pages/dashboard/main-panel';
|
||||||
import Account from './components/account';
|
|
||||||
import Search from './components/search/search';
|
|
||||||
import Notification from './components/notification';
|
|
||||||
import cookie from 'react-cookies';
|
|
||||||
import { isPro, gettext, siteRoot } from './components/constants';
|
|
||||||
import 'seafile-ui';
|
import 'seafile-ui';
|
||||||
import './assets/css/fa-solid.css';
|
import './assets/css/fa-solid.css';
|
||||||
import './assets/css/fa-regular.css';
|
import './assets/css/fa-regular.css';
|
||||||
import './assets/css/fontawesome.css';
|
import './assets/css/fontawesome.css';
|
||||||
|
import './css/layout.css'
|
||||||
import './css/dashboard.css';
|
import './css/dashboard.css';
|
||||||
import './css/toolbar.css';
|
import './css/toolbar.css';
|
||||||
import './css/search.css';
|
import './css/search.css';
|
||||||
@@ -22,13 +19,14 @@ class DashBoard extends Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isOpen: false
|
isOpen: false
|
||||||
}
|
};
|
||||||
|
this.currentTab = 'dashboard';
|
||||||
}
|
}
|
||||||
|
|
||||||
isOpen = () => {
|
isOpen = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
isOpen: !this.state.isOpen,
|
isOpen: !this.state.isOpen,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearchedClick = (item) => {
|
onSearchedClick = (item) => {
|
||||||
@@ -43,17 +41,10 @@ class DashBoard extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<SidePanel isOpen={this.state.isOpen} toggleClose={this.isOpen} />
|
<SidePanel isOpen={this.state.isOpen} toggleClose={this.isOpen} currentTab={this.currentTab}/>
|
||||||
<MainPanel isOpen={this.isOpen}>
|
<MainPanel isOpen={this.isOpen}></MainPanel>
|
||||||
{isPro && <Search onSearchedClick={this.onSearchedClick}
|
|
||||||
placeholder={gettext("Search files")}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
<Notification />
|
|
||||||
<Account />
|
|
||||||
</MainPanel>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import editUtilties from './utils/editor-utilties';
|
import editUtilties from './utils/editor-utilties';
|
||||||
import SidePanel from './pages/drafts/side-panel';
|
import SidePanel from './components/side-panel';
|
||||||
import MainPanel from './pages/drafts/main-panel';
|
import MainPanel from './pages/drafts/main-panel';
|
||||||
|
|
||||||
import 'seafile-ui';
|
import 'seafile-ui';
|
||||||
@@ -11,6 +11,7 @@ import './assets/css/fontawesome.css';
|
|||||||
import './css/layout.css';
|
import './css/layout.css';
|
||||||
import './css/common.css';
|
import './css/common.css';
|
||||||
import './css/toolbar.css';
|
import './css/toolbar.css';
|
||||||
|
import './css/search.css';
|
||||||
|
|
||||||
class Drafts extends Component {
|
class Drafts extends Component {
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ class Drafts extends Component {
|
|||||||
draftList: [],
|
draftList: [],
|
||||||
isLoadingDraft: true,
|
isLoadingDraft: true,
|
||||||
};
|
};
|
||||||
|
this.currentTab = 'drafts';
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -38,19 +40,19 @@ class Drafts extends Component {
|
|||||||
deleteDraft = (draft) => {
|
deleteDraft = (draft) => {
|
||||||
editUtilties.deleteDraft(draft.id).then(res => {
|
editUtilties.deleteDraft(draft.id).then(res => {
|
||||||
this.initDraftList();
|
this.initDraftList();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
publishDraft = (draft) => {
|
publishDraft = (draft) => {
|
||||||
editUtilties.publishDraft(draft.id).then(res => {
|
editUtilties.publishDraft(draft.id).then(res => {
|
||||||
this.initDraftList();
|
this.initDraftList();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<SidePanel></SidePanel>
|
<SidePanel currentTab={this.currentTab}></SidePanel>
|
||||||
<MainPanel
|
<MainPanel
|
||||||
isLoadingDraft={this.state.isLoadingDraft}
|
isLoadingDraft={this.state.isLoadingDraft}
|
||||||
draftList={this.state.draftList}
|
draftList={this.state.draftList}
|
||||||
|
@@ -13,6 +13,7 @@ import './assets/css/fontawesome.css';
|
|||||||
import './css/layout.css';
|
import './css/layout.css';
|
||||||
import './css/file-history.css';
|
import './css/file-history.css';
|
||||||
import './css/toolbar.css';
|
import './css/toolbar.css';
|
||||||
|
import './css/search.css';
|
||||||
|
|
||||||
class FileHistory extends React.Component {
|
class FileHistory extends React.Component {
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||||
import FilesActivities from '../../components/files-activities';
|
import FilesActivities from '../../components/files-activities';
|
||||||
|
|
||||||
class MainPanel extends Component {
|
class MainPanel extends Component {
|
||||||
@@ -9,19 +10,24 @@ class MainPanel extends Component {
|
|||||||
onMenuClick = () => {
|
onMenuClick = () => {
|
||||||
this.props.isOpen();
|
this.props.isOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSearchedClick = () => {
|
||||||
|
//todos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props
|
|
||||||
return (
|
return (
|
||||||
<div className="main-panel o-hidden">
|
<div className="main-panel o-hidden">
|
||||||
<div className="main-panel-top panel-top">
|
<div className="main-panel-north">
|
||||||
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.onMenuClick}></span>
|
<div className="cur-view-toolbar">
|
||||||
<div className="common-toolbar">
|
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.onMenuClick}></span>
|
||||||
{children}
|
</div>
|
||||||
|
<CommonToolbar onSearchedClick={this.onSearchedClick}/>
|
||||||
|
</div>
|
||||||
|
<div className="main-panel-center">
|
||||||
|
<FilesActivities />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<FilesActivities />
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
import SideNavFooter from '../../components/side-nav-footer';
|
|
||||||
import MainSideNav from '../../components/main-side-nav';
|
|
||||||
|
|
||||||
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
|
|
||||||
|
|
||||||
class SidePanel extends Component {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className={`side-panel ${this.props.isOpen ? "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} />
|
|
||||||
</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 />
|
|
||||||
<SideNavFooter />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default SidePanel;
|
|
@@ -1,15 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { gettext } from '../../components/constants';
|
import { gettext } from '../../components/constants';
|
||||||
|
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||||
import Loading from '../../components/loading';
|
import Loading from '../../components/loading';
|
||||||
import Account from '../../components/account';
|
|
||||||
import { seafileAPI } from '../../utils/editor-utilties';
|
|
||||||
import Notification from '../../components/notification';
|
|
||||||
import ListView from '../../components/list-view/list-view';
|
import ListView from '../../components/list-view/list-view';
|
||||||
import ListMenu from '../../components/list-view/list-menu';
|
import ListMenu from '../../components/list-view/list-menu';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
isLoadingDraft: PropTypes.bool.isRequired,
|
||||||
draftList: PropTypes.array.isRequired,
|
draftList: PropTypes.array.isRequired,
|
||||||
|
publishDraft: PropTypes.func.isRequired,
|
||||||
|
deleteDraft: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
class MainPanel extends React.Component {
|
class MainPanel extends React.Component {
|
||||||
@@ -67,15 +68,16 @@ class MainPanel extends React.Component {
|
|||||||
onDeleteHandler = () => {
|
onDeleteHandler = () => {
|
||||||
this.props.deleteDraft(this.state.currentDraft);
|
this.props.deleteDraft(this.state.currentDraft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSearchedClick = () => {
|
||||||
|
//todos;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="main-panel">
|
<div className="main-panel">
|
||||||
<div className="main-panel-north flex-right">
|
<div className="main-panel-north flex-right">
|
||||||
<div className="common-toolbar">
|
<CommonToolbar onSearchedClick={this.onSearchedClick}/>
|
||||||
<Notification seafileAPI={seafileAPI}/>
|
|
||||||
<Account />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="main-panel-center">
|
<div className="main-panel-center">
|
||||||
<div className="panel-heading text-left">{gettext('Drafts')}</div>
|
<div className="panel-heading text-left">{gettext('Drafts')}</div>
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import Logo from '../../components/logo';
|
|
||||||
import MainSideNav from '../../components/main-side-nav';
|
|
||||||
import SideNavFooter from '../../components/side-nav-footer';
|
|
||||||
|
|
||||||
|
|
||||||
class SidePanel extends React.Component {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className="side-panel">
|
|
||||||
<div className="side-panel-north"><Logo /></div>
|
|
||||||
<div className="side-panel-center">
|
|
||||||
<MainSideNav />
|
|
||||||
</div>
|
|
||||||
<div className="side-panel-footer">
|
|
||||||
<SideNavFooter />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SidePanel;
|
|
@@ -2,8 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Prism from 'prismjs';
|
import Prism from 'prismjs';
|
||||||
import Loading from '../../components/loading';
|
import Loading from '../../components/loading';
|
||||||
import Account from '../../components/account';
|
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||||
import Notification from '../../components/notification';
|
|
||||||
import '../../css/initial-style.css';
|
import '../../css/initial-style.css';
|
||||||
require('@seafile/seafile-editor/src/lib/code-hight-package');
|
require('@seafile/seafile-editor/src/lib/code-hight-package');
|
||||||
|
|
||||||
@@ -19,14 +18,15 @@ class MainPanel extends React.Component {
|
|||||||
Prism.highlightAll();
|
Prism.highlightAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelectedClick = () => {
|
||||||
|
//todos;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="main-panel viewer">
|
<div className="main-panel viewer">
|
||||||
<div className="main-panel-north">
|
<div className="main-panel-north">
|
||||||
<div className="common-toolbar">
|
<CommonToolbar onSelectedClick={this.onSelectedClick} />
|
||||||
<Notification />
|
|
||||||
<Account />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="main-panel-center history-viewer-contanier">
|
<div className="main-panel-center history-viewer-contanier">
|
||||||
<div className="content-viewer">
|
<div className="content-viewer">
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constants';
|
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constants';
|
||||||
import Search from '../../components/search/search';
|
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||||
import Account from '../../components/account';
|
|
||||||
import Notification from '../../components/notification';
|
|
||||||
import PathToolbar from '../../components/toolbar/path-toolbar';
|
import PathToolbar from '../../components/toolbar/path-toolbar';
|
||||||
import MarkdownViewer from '../../components/markdown-viewer';
|
import MarkdownViewer from '../../components/markdown-viewer';
|
||||||
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
|
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
|
||||||
@@ -70,7 +68,7 @@ class MainPanel extends Component {
|
|||||||
return (
|
return (
|
||||||
<div className="wiki-main-panel o-hidden">
|
<div className="wiki-main-panel o-hidden">
|
||||||
<div className="main-panel-top panel-top">
|
<div className="main-panel-top panel-top">
|
||||||
<div className="cur-view-toolbar">
|
<div className="cur-view-toolbar border-left-show">
|
||||||
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.onMenuClick}></span>
|
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.onMenuClick}></span>
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
@@ -84,14 +82,7 @@ class MainPanel extends Component {
|
|||||||
<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-wiki-view ${this.state.isWikiMode ? 'current-mode' : ''}`} id='wiki' title={gettext("wiki")} onClick={this.switchViewMode}></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="common-toolbar">
|
<CommonToolbar onSearchedClick={this.props.onSearchedClick} />
|
||||||
{
|
|
||||||
isPro &&
|
|
||||||
<Search onSearchedClick={this.props.onSearchedClick} placeholder={gettext("Search files in this library")} />
|
|
||||||
}
|
|
||||||
<Notification />
|
|
||||||
<Account />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="cur-view-main">
|
<div className="cur-view-main">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
|
@@ -1,14 +1,12 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import TreeView from '../../components/tree-view/tree-view';
|
import TreeView from '../../components/tree-view/tree-view';
|
||||||
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
|
import { gettext, siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
|
||||||
import NodeMenu from '../../components/menu-component/node-menu';
|
import NodeMenu from '../../components/menu-component/node-menu';
|
||||||
import MenuControl from '../../components/menu-component/node-menu-control';
|
import MenuControl from '../../components/menu-component/node-menu-control';
|
||||||
import Delete from '../../components/menu-component/menu-dialog/delete-dialog';
|
import Delete from '../../components/menu-component/menu-dialog/delete-dialog';
|
||||||
import Rename from '../../components/menu-component/menu-dialog/rename-dialog';
|
import Rename from '../../components/menu-component/menu-dialog/rename-dialog';
|
||||||
import CreateFlieFolder from '../../components/menu-component/menu-dialog/create-fileforder-dialog';
|
import CreateFlieFolder from '../../components/menu-component/menu-dialog/create-fileforder-dialog';
|
||||||
|
|
||||||
const gettext = window.gettext;
|
|
||||||
|
|
||||||
class SidePanel extends Component {
|
class SidePanel extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@@ -1,8 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constants';
|
import { gettext, repoID, serviceUrl, slug, siteRoot, isPro } from '../../components/constants';
|
||||||
import Search from '../../components/search/search';
|
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||||
import Account from '../../components/account';
|
|
||||||
import Notification from '../../components/notification';
|
|
||||||
import MarkdownViewer from '../../components/markdown-viewer';
|
import MarkdownViewer from '../../components/markdown-viewer';
|
||||||
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
|
import TreeDirView from '../../components/tree-dir-view/tree-dir-view';
|
||||||
|
|
||||||
@@ -53,21 +51,14 @@ class MainPanel extends Component {
|
|||||||
return (
|
return (
|
||||||
<div className="wiki-main-panel o-hidden">
|
<div className="wiki-main-panel o-hidden">
|
||||||
<div className="main-panel-top panel-top">
|
<div className="main-panel-top panel-top">
|
||||||
<div className="cur-view-toolbar">
|
<div className="cur-view-toolbar border-left-show">
|
||||||
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.onMenuClick}></span>
|
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.onMenuClick}></span>
|
||||||
{
|
{
|
||||||
this.props.permission === 'rw' &&
|
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>
|
</div>
|
||||||
<div className="common-toolbar">
|
<CommonToolbar onSearchedClick={this.props.onSearchedClick} />
|
||||||
{
|
|
||||||
isPro &&
|
|
||||||
<Search onSearchedClick={this.props.onSearchedClick} placeholder={gettext("Search files in this wiki")}/>
|
|
||||||
}
|
|
||||||
<Notification />
|
|
||||||
<Account />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="cur-view-main">
|
<div className="cur-view-main">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
|
@@ -1,14 +1,12 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import TreeView from '../../components/tree-view/tree-view';
|
import TreeView from '../../components/tree-view/tree-view';
|
||||||
import { siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
|
import { gettext, siteRoot, logoPath, mediaUrl, siteTitle, logoWidth, logoHeight } from '../../components/constants';
|
||||||
import NodeMenu from '../../components/menu-component/node-menu';
|
import NodeMenu from '../../components/menu-component/node-menu';
|
||||||
import MenuControl from '../../components/menu-component/node-menu-control';
|
import MenuControl from '../../components/menu-component/node-menu-control';
|
||||||
import Delete from '../../components/menu-component/menu-dialog/delete-dialog';
|
import Delete from '../../components/menu-component/menu-dialog/delete-dialog';
|
||||||
import Rename from '../../components/menu-component/menu-dialog/rename-dialog';
|
import Rename from '../../components/menu-component/menu-dialog/rename-dialog';
|
||||||
import CreateFlieFolder from '../../components/menu-component/menu-dialog/create-fileforder-dialog';
|
import CreateFlieFolder from '../../components/menu-component/menu-dialog/create-fileforder-dialog';
|
||||||
|
|
||||||
const gettext = window.gettext;
|
|
||||||
|
|
||||||
class SidePanel extends Component {
|
class SidePanel extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@@ -371,6 +371,7 @@ a.op-icon:focus {
|
|||||||
padding:12px 20px 16px;
|
padding:12px 20px 16px;
|
||||||
background:#f8f8f8;
|
background:#f8f8f8;
|
||||||
border-top:1px solid #eee;
|
border-top:1px solid #eee;
|
||||||
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
.side-nav-footer .item {
|
.side-nav-footer .item {
|
||||||
color:#666;
|
color:#666;
|
||||||
@@ -696,22 +697,7 @@ a.op-icon:focus {
|
|||||||
.side-panel-close {
|
.side-panel-close {
|
||||||
margin:10px 0 0 auto;
|
margin:10px 0 0 auto;
|
||||||
}
|
}
|
||||||
.side-nav-footer {
|
|
||||||
display:flex;
|
|
||||||
flex-shrink:0;
|
|
||||||
padding:12px 20px 16px;
|
|
||||||
background:#f8f8f8;
|
|
||||||
border-top:1px solid #eee;
|
|
||||||
border-right: 1px solid #eee;
|
|
||||||
}
|
|
||||||
.side-nav-footer .item {
|
|
||||||
color:#666;
|
|
||||||
font-weight: normal;
|
|
||||||
margin-right:10px;
|
|
||||||
}
|
|
||||||
.side-nav-footer .last-item {
|
|
||||||
margin-left:auto;
|
|
||||||
}
|
|
||||||
.cur-view-main {
|
.cur-view-main {
|
||||||
flex:1 1 auto;
|
flex:1 1 auto;
|
||||||
display:flex;
|
display:flex;
|
||||||
|
Reference in New Issue
Block a user