mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 07:27:04 +00:00
12.0 change app structure (#6335)
* 01 change app structure * 02 change setting page * 03 optimize header style * 04 change app mobile side panel logo
This commit is contained in:
@@ -6,8 +6,8 @@ import { Modal } from 'reactstrap';
|
|||||||
import { siteRoot } from './utils/constants';
|
import { siteRoot } from './utils/constants';
|
||||||
import { Utils } from './utils/utils';
|
import { Utils } from './utils/utils';
|
||||||
import SystemNotification from './components/system-notification';
|
import SystemNotification from './components/system-notification';
|
||||||
//import Header from './components/header';
|
import EventBus from './components/common/event-bus';
|
||||||
import Logo from './components/logo';
|
import Header from './components/header';
|
||||||
import SidePanel from './components/side-panel';
|
import SidePanel from './components/side-panel';
|
||||||
import MainPanel from './components/main-panel';
|
import MainPanel from './components/main-panel';
|
||||||
import FilesActivities from './pages/dashboard/files-activities';
|
import FilesActivities from './pages/dashboard/files-activities';
|
||||||
@@ -30,22 +30,11 @@ import Group from './pages/groups/group-view';
|
|||||||
import InvitationsView from './pages/invitations/invitations-view';
|
import InvitationsView from './pages/invitations/invitations-view';
|
||||||
import Wikis from './pages/wikis/wikis';
|
import Wikis from './pages/wikis/wikis';
|
||||||
import Libraries from './pages/libraries';
|
import Libraries from './pages/libraries';
|
||||||
import MainContentWrapper from './components/main-content-wrapper';
|
|
||||||
|
|
||||||
import './css/layout.css';
|
import './css/layout.css';
|
||||||
import './css/toolbar.css';
|
import './css/toolbar.css';
|
||||||
import './css/search.css';
|
import './css/search.css';
|
||||||
|
|
||||||
const FilesActivitiesWrapper = MainContentWrapper(FilesActivities);
|
|
||||||
const MyFileActivitiesWrapper = MainContentWrapper(MyFileActivities);
|
|
||||||
const StarredWrapper = MainContentWrapper(Starred);
|
|
||||||
const LinkedDevicesWrapper = MainContentWrapper(LinkedDevices);
|
|
||||||
const SharedLibrariesWrapper = MainContentWrapper(SharedLibraries);
|
|
||||||
const SharedWithOCMWrapper = MainContentWrapper(ShareWithOCM);
|
|
||||||
const OCMViaWebdavWrapper = MainContentWrapper(OCMViaWebdav);
|
|
||||||
const InvitationsViewWrapper = MainContentWrapper(InvitationsView);
|
|
||||||
const ShareAdminLibrariesWrapper = MainContentWrapper(ShareAdminLibraries);
|
|
||||||
const ShareAdminFoldersWrapper = MainContentWrapper(ShareAdminFolders);
|
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
|
|
||||||
@@ -62,6 +51,8 @@ class App extends Component {
|
|||||||
};
|
};
|
||||||
this.dirViewPanels = ['libraries', 'my-libs', 'shared-libs', 'org']; // and group
|
this.dirViewPanels = ['libraries', 'my-libs', 'shared-libs', 'org']; // and group
|
||||||
window.onpopstate = this.onpopstate;
|
window.onpopstate = this.onpopstate;
|
||||||
|
const eventBus = new EventBus();
|
||||||
|
this.eventBus = eventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
onpopstate = (event) => {
|
onpopstate = (event) => {
|
||||||
@@ -222,52 +213,55 @@ class App extends Component {
|
|||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<SystemNotification />
|
<SystemNotification />
|
||||||
{/*<Header
|
<Header
|
||||||
isSidePanelClosed={isSidePanelClosed}
|
isSidePanelClosed={isSidePanelClosed}
|
||||||
onCloseSidePanel={this.onCloseSidePanel}
|
onCloseSidePanel={this.onCloseSidePanel}
|
||||||
onShowSidePanel={this.onShowSidePanel}
|
onShowSidePanel={this.onShowSidePanel}
|
||||||
onSearchedClick={this.onSearchedClick}
|
onSearchedClick={this.onSearchedClick}
|
||||||
|
eventBus={this.eventBus}
|
||||||
/>
|
/>
|
||||||
*/}
|
|
||||||
<div id="main" className="user-panel">
|
<div id="main" className="user-panel">
|
||||||
<Logo onCloseSidePanel={this.onCloseSidePanel} positioned={true} />
|
|
||||||
<SidePanel
|
<SidePanel
|
||||||
isSidePanelClosed={isSidePanelClosed}
|
isSidePanelClosed={isSidePanelClosed}
|
||||||
isSidePanelFolded={isSidePanelFolded}
|
isSidePanelFolded={isSidePanelFolded}
|
||||||
onCloseSidePanel={this.onCloseSidePanel}
|
onCloseSidePanel={this.onCloseSidePanel}
|
||||||
currentTab={currentTab}
|
currentTab={currentTab}
|
||||||
tabItemClick={this.tabItemClick}
|
tabItemClick={this.tabItemClick}
|
||||||
showLogoOnlyInMobile={true}
|
|
||||||
toggleFoldSideNav={this.toggleFoldSideNav}
|
toggleFoldSideNav={this.toggleFoldSideNav}
|
||||||
/>
|
/>
|
||||||
<MainPanel>
|
<MainPanel>
|
||||||
<Router className="reach-router">
|
<Router className="reach-router">
|
||||||
<Libraries path={ siteRoot } onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<Libraries path={siteRoot} />
|
||||||
<Libraries path={ siteRoot + 'libraries' } onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<Libraries path={siteRoot + 'libraries'} />
|
||||||
<FilesActivitiesWrapper path={siteRoot + 'dashboard'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<MyLibraries path={siteRoot + 'my-libs'} />
|
||||||
<MyFileActivitiesWrapper path={siteRoot + 'my-activities'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<MyLibDeleted path={siteRoot + 'my-libs/deleted/'} />
|
||||||
<StarredWrapper path={siteRoot + 'starred'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<ShareAdminShareLinks path={siteRoot + 'share-admin-share-links'} />
|
||||||
<LinkedDevicesWrapper path={siteRoot + 'linked-devices'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<ShareAdminUploadLinks path={siteRoot + 'share-admin-upload-links'} />
|
||||||
<ShareAdminLibrariesWrapper path={siteRoot + 'share-admin-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<PublicSharedView path={siteRoot + 'org/'} />
|
||||||
<ShareAdminFoldersWrapper path={siteRoot + 'share-admin-folders'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<Wikis path={siteRoot + 'published'} />
|
||||||
<ShareAdminShareLinks path={siteRoot + 'share-admin-share-links'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<Starred path={siteRoot + 'starred'} />
|
||||||
<ShareAdminUploadLinks path={siteRoot + 'share-admin-upload-links'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<InvitationsView path={siteRoot + 'invitations/'} />
|
||||||
<SharedLibrariesWrapper path={siteRoot + 'shared-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<FilesActivities path={siteRoot + 'dashboard'} />
|
||||||
<SharedWithOCMWrapper path={siteRoot + 'shared-with-ocm'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<MyFileActivities path={siteRoot + 'my-activities'} />
|
||||||
<OCMViaWebdavWrapper path={siteRoot + 'ocm-via-webdav'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<Group path={siteRoot + 'group/:groupID'} onGroupChanged={this.onGroupChanged} />
|
||||||
<MyLibraries path={siteRoot + 'my-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
<LinkedDevices path={siteRoot + 'linked-devices'} />
|
||||||
<MyLibDeleted path={siteRoot + 'my-libs/deleted/'} onSearchedClick={this.onSearchedClick} />
|
<ShareAdminLibraries path={siteRoot + 'share-admin-libs'} />
|
||||||
<LibContentView path={siteRoot + 'library/:repoID/*'} pathPrefix={this.state.pathPrefix} isSidePanelFolded={isSidePanelFolded} onMenuClick={this.onShowSidePanel} onTabNavClick={this.tabItemClick}/>
|
<ShareAdminFolders path={siteRoot + 'share-admin-folders'} />
|
||||||
<OCMRepoDir path={siteRoot + 'remote-library/:providerID/:repoID/*'} pathPrefix={this.state.pathPrefix} onMenuClick={this.onShowSidePanel} onTabNavClick={this.tabItemClick}/>
|
<SharedLibraries path={siteRoot + 'shared-libs'} />
|
||||||
<Group
|
<ShareWithOCM path={siteRoot + 'shared-with-ocm'} />
|
||||||
path={siteRoot + 'group/:groupID'}
|
<OCMViaWebdav path={siteRoot + 'ocm-via-webdav'} />
|
||||||
onShowSidePanel={this.onShowSidePanel}
|
<OCMRepoDir
|
||||||
onSearchedClick={this.onSearchedClick}
|
path={siteRoot + 'remote-library/:providerID/:repoID/*'}
|
||||||
onGroupChanged={this.onGroupChanged}
|
pathPrefix={this.state.pathPrefix}
|
||||||
|
onTabNavClick={this.tabItemClick}
|
||||||
|
/>
|
||||||
|
<LibContentView
|
||||||
|
path={siteRoot + 'library/:repoID/*'}
|
||||||
|
pathPrefix={this.state.pathPrefix}
|
||||||
|
isSidePanelFolded={isSidePanelFolded}
|
||||||
|
onTabNavClick={this.tabItemClick}
|
||||||
|
eventBus={this.eventBus}
|
||||||
/>
|
/>
|
||||||
<Wikis path={siteRoot + 'published'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick}/>
|
|
||||||
<PublicSharedView path={siteRoot + 'org/'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} onTabNavClick={this.tabItemClick}/>
|
|
||||||
<InvitationsViewWrapper path={siteRoot + 'invitations/'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />
|
|
||||||
</Router>
|
</Router>
|
||||||
</MainPanel>
|
</MainPanel>
|
||||||
<MediaQuery query="(max-width: 767.8px)">
|
<MediaQuery query="(max-width: 767.8px)">
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
export const EVENT_BUS_TYPE = {
|
export const EVENT_BUS_TYPE = {
|
||||||
|
// metadata
|
||||||
QUERY_COLLABORATORS: 'query-collaborators',
|
QUERY_COLLABORATORS: 'query-collaborators',
|
||||||
QUERY_COLLABORATOR: 'query-collaborator',
|
QUERY_COLLABORATOR: 'query-collaborator',
|
||||||
UPDATE_TABLE_ROWS: 'update-table-rows',
|
UPDATE_TABLE_ROWS: 'update-table-rows',
|
||||||
@@ -34,4 +35,7 @@ export const EVENT_BUS_TYPE = {
|
|||||||
|
|
||||||
// change
|
// change
|
||||||
VIEW_CHANGED: 'view_changed',
|
VIEW_CHANGED: 'view_changed',
|
||||||
|
|
||||||
|
// library
|
||||||
|
CURRENT_LIBRARY_CHANGED: 'current_library_changed',
|
||||||
};
|
};
|
5
frontend/src/components/header.css
Normal file
5
frontend/src/components/header.css
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.top-header {
|
||||||
|
background-color: #f8fafd;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
}
|
@@ -3,7 +3,11 @@ import PropTypes from 'prop-types';
|
|||||||
import Logo from './logo';
|
import Logo from './logo';
|
||||||
import CommonToolbar from './toolbar/common-toolbar';
|
import CommonToolbar from './toolbar/common-toolbar';
|
||||||
|
|
||||||
|
import './header.css';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
children: PropTypes.object,
|
||||||
|
eventBus: PropTypes.object.isRequired,
|
||||||
isSidePanelClosed: PropTypes.bool,
|
isSidePanelClosed: PropTypes.bool,
|
||||||
onCloseSidePanel: PropTypes.func,
|
onCloseSidePanel: PropTypes.func,
|
||||||
onShowSidePanel: PropTypes.func,
|
onShowSidePanel: PropTypes.func,
|
||||||
@@ -15,21 +19,23 @@ const propTypes = {
|
|||||||
class Header extends React.Component {
|
class Header extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { onShowSidePanel, onSearchedClick, showSearch } = this.props;
|
const { onShowSidePanel, onSearchedClick, showSearch, children } = this.props;
|
||||||
return (
|
return (
|
||||||
<div id="header" className="d-flex justify-content-between py-2 px-4">
|
<div id="header" className="top-header d-flex justify-content-between flex-shrink-0">
|
||||||
<div className={'flex-shrink-0 d-none d-md-flex'}>
|
<div className={'flex-shrink-0 d-none d-md-flex'}>
|
||||||
<Logo onCloseSidePanel={this.props.onCloseSidePanel} />
|
<Logo onCloseSidePanel={this.props.onCloseSidePanel} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0 d-flex flex-fill">
|
<div className={`flex-shrink-0 d-flex flex-fill ${children ? 'border-left-show' : ''}`}>
|
||||||
<div className="cur-view-toolbar">
|
<div className="cur-view-toolbar">
|
||||||
<span title="Side Nav Menu" onClick={onShowSidePanel} className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none">
|
<span title="Side Nav Menu" onClick={onShowSidePanel} className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none">
|
||||||
</span>
|
</span>
|
||||||
|
{children}
|
||||||
</div>
|
</div>
|
||||||
<CommonToolbar
|
<CommonToolbar
|
||||||
showSearch={showSearch}
|
showSearch={showSearch}
|
||||||
searchPlaceholder={this.props.searchPlaceholder}
|
searchPlaceholder={this.props.searchPlaceholder}
|
||||||
onSearchedClick={onSearchedClick}
|
onSearchedClick={onSearchedClick}
|
||||||
|
eventBus={this.props.eventBus}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,13 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from '../utils/constants';
|
import { siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from '../utils/constants';
|
||||||
import { Utils } from '../utils/utils';
|
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
onCloseSidePanel: PropTypes.func,
|
onCloseSidePanel: PropTypes.func,
|
||||||
showCloseSidePanelIcon: PropTypes.bool,
|
showCloseSidePanelIcon: PropTypes.bool,
|
||||||
positioned: PropTypes.bool,
|
|
||||||
showLogoOnlyInMobile: PropTypes.bool
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Logo extends React.Component {
|
class Logo extends React.Component {
|
||||||
@@ -17,14 +14,8 @@ class Logo extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { positioned, showLogoOnlyInMobile } = this.props;
|
|
||||||
|
|
||||||
if (showLogoOnlyInMobile && Utils.isDesktop()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`top-logo ${positioned ? 'd-none d-md-block positioned-top-logo' : ''}`}>
|
<div className='top-logo'>
|
||||||
<a href={siteRoot} id="logo">
|
<a href={siteRoot} id="logo">
|
||||||
<img src={logoPath.indexOf('image-view') != -1 ? logoPath : mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
|
<img src={logoPath.indexOf('image-view') != -1 ? logoPath : mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" />
|
||||||
</a>
|
</a>
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
import React, { Fragment } from 'react';
|
|
||||||
import GeneralToolBar from './toolbar/general-toolbar';
|
|
||||||
|
|
||||||
const MainContentWrapper = (WrapperedComponent) => {
|
|
||||||
return class Wrapper extends React.Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<GeneralToolBar {...this.props} />
|
|
||||||
<WrapperedComponent {...this.props} />
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MainContentWrapper;
|
|
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
import MediaQuery from 'react-responsive';
|
||||||
import Logo from './logo';
|
import Logo from './logo';
|
||||||
import MainSideNav from './main-side-nav';
|
import MainSideNav from './main-side-nav';
|
||||||
import { SIDE_PANEL_FOLDED_WIDTH } from '../constants';
|
import { SIDE_PANEL_FOLDED_WIDTH } from '../constants';
|
||||||
@@ -11,7 +12,6 @@ const propTypes = {
|
|||||||
onCloseSidePanel: PropTypes.func,
|
onCloseSidePanel: PropTypes.func,
|
||||||
tabItemClick: PropTypes.func,
|
tabItemClick: PropTypes.func,
|
||||||
children: PropTypes.object,
|
children: PropTypes.object,
|
||||||
showLogoOnlyInMobile: PropTypes.bool,
|
|
||||||
isSidePanelFolded: PropTypes.bool,
|
isSidePanelFolded: PropTypes.bool,
|
||||||
toggleFoldSideNav: PropTypes.func
|
toggleFoldSideNav: PropTypes.func
|
||||||
};
|
};
|
||||||
@@ -19,16 +19,15 @@ const propTypes = {
|
|||||||
class SidePanel extends React.Component {
|
class SidePanel extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children, isSidePanelFolded, showLogoOnlyInMobile = false } = this.props;
|
const { children, isSidePanelFolded } = this.props;
|
||||||
const style = isSidePanelFolded ? { flexBasis: SIDE_PANEL_FOLDED_WIDTH } : {};
|
const style = isSidePanelFolded ? { flexBasis: SIDE_PANEL_FOLDED_WIDTH } : {};
|
||||||
return (
|
return (
|
||||||
<div className={classnames('side-panel', { 'side-panel-folded': isSidePanelFolded, 'left-zero': !this.props.isSidePanelClosed })} style={style}>
|
<div className={classnames('side-panel', { 'side-panel-folded': isSidePanelFolded, 'left-zero': !this.props.isSidePanelClosed })} style={style}>
|
||||||
<div className={'side-panel-north'}>
|
<MediaQuery query="(max-width: 767.8px)">
|
||||||
<Logo
|
<div className='side-panel-north'>
|
||||||
onCloseSidePanel={this.props.onCloseSidePanel}
|
<Logo onCloseSidePanel={this.props.onCloseSidePanel} />
|
||||||
showLogoOnlyInMobile={showLogoOnlyInMobile}
|
</div>
|
||||||
/>
|
</MediaQuery>
|
||||||
</div>
|
|
||||||
<div className="side-panel-center">
|
<div className="side-panel-center">
|
||||||
{children ? children : (
|
{children ? children : (
|
||||||
<MainSideNav
|
<MainSideNav
|
||||||
|
@@ -7,6 +7,7 @@ import SearchByName from '../search/search-by-name';
|
|||||||
import Notification from '../common/notification';
|
import Notification from '../common/notification';
|
||||||
import Account from '../common/account';
|
import Account from '../common/account';
|
||||||
import Logout from '../common/logout';
|
import Logout from '../common/logout';
|
||||||
|
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
repoID: PropTypes.string,
|
repoID: PropTypes.string,
|
||||||
@@ -16,14 +17,41 @@ const propTypes = {
|
|||||||
onSearchedClick: PropTypes.func,
|
onSearchedClick: PropTypes.func,
|
||||||
searchPlaceholder: PropTypes.string,
|
searchPlaceholder: PropTypes.string,
|
||||||
currentRepoInfo: PropTypes.object,
|
currentRepoInfo: PropTypes.object,
|
||||||
|
eventBus: PropTypes.object,
|
||||||
isViewFile: PropTypes.bool,
|
isViewFile: PropTypes.bool,
|
||||||
showSearch: PropTypes.bool
|
showSearch: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommonToolbar extends React.Component {
|
class CommonToolbar extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
repoID: props.repoID,
|
||||||
|
repoName: props.repoName,
|
||||||
|
isLibView: props.isLibView,
|
||||||
|
path: props.path,
|
||||||
|
isViewFile: props.isViewFile,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.props.eventBus) {
|
||||||
|
this.unsubscribeLibChange = this.props.eventBus.subscribe(EVENT_BUS_TYPE.CURRENT_LIBRARY_CHANGED, this.onRepoChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unsubscribeLibChange && this.unsubscribeLibChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
onRepoChange = ({ repoID, repoName, isLibView, path, isViewFile }) => {
|
||||||
|
this.setState({ repoID, repoName, isLibView, path, isViewFile });
|
||||||
|
};
|
||||||
|
|
||||||
renderSearch = () => {
|
renderSearch = () => {
|
||||||
const { repoID, repoName, isLibView, searchPlaceholder, path, isViewFile } = this.props;
|
const { repoID, repoName, isLibView, path, isViewFile } = this.state;
|
||||||
|
const { searchPlaceholder } = this.props;
|
||||||
const placeholder = searchPlaceholder || gettext('Search files');
|
const placeholder = searchPlaceholder || gettext('Search files');
|
||||||
|
|
||||||
if (isPro) {
|
if (isPro) {
|
||||||
|
@@ -1,36 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import CommonToolbar from './common-toolbar';
|
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
searchPlaceholder: PropTypes.string,
|
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
class GeneralToolbar extends React.Component {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
// todo get repoID?
|
|
||||||
let { onShowSidePanel, onSearchedClick } = this.props;
|
|
||||||
return (
|
|
||||||
<div className="main-panel-north">
|
|
||||||
<div className="cur-view-toolbar">
|
|
||||||
<span
|
|
||||||
className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none"
|
|
||||||
title="Side Nav Menu"
|
|
||||||
onClick={onShowSidePanel}>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<CommonToolbar
|
|
||||||
searchPlaceholder={this.props.searchPlaceholder}
|
|
||||||
onSearchedClick={onSearchedClick}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GeneralToolbar.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default GeneralToolbar;
|
|
31
frontend/src/components/user-settings/setting-side-panel.js
Normal file
31
frontend/src/components/user-settings/setting-side-panel.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import Logo from '../logo';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import SideNav from './side-nav';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
isSidePanelClosed: PropTypes.bool,
|
||||||
|
curItemID: PropTypes.string.isRequired,
|
||||||
|
data: PropTypes.array.isRequired,
|
||||||
|
onCloseSidePanel: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
class SettingSidePanel extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={classnames('side-panel', { 'left-zero': !this.props.isSidePanelClosed })}>
|
||||||
|
<div className="side-panel-north">
|
||||||
|
<Logo onCloseSidePanel={this.props.onCloseSidePanel}/>
|
||||||
|
</div>
|
||||||
|
<div className="side-panel-center">
|
||||||
|
<SideNav data={this.props.data} curItemID={this.props.curItemID} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingSidePanel.propTypes = propTypes;
|
||||||
|
|
||||||
|
export default SettingSidePanel;
|
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import CommonToolbar from './common-toolbar';
|
import CommonToolbar from '../toolbar/common-toolbar';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
onShowSidePanel: PropTypes.func,
|
onShowSidePanel: PropTypes.func,
|
||||||
@@ -10,7 +10,7 @@ const propTypes = {
|
|||||||
showSearch: PropTypes.bool
|
showSearch: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
class TopToolbar extends React.Component {
|
class SettingTopToolbar extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { onShowSidePanel, onSearchedClick, children, showSearch } = this.props;
|
const { onShowSidePanel, onSearchedClick, children, showSearch } = this.props;
|
||||||
@@ -31,6 +31,6 @@ class TopToolbar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TopToolbar.propTypes = propTypes;
|
SettingTopToolbar.propTypes = propTypes;
|
||||||
|
|
||||||
export default TopToolbar;
|
export default SettingTopToolbar;
|
@@ -5,14 +5,6 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for top bottom layout*/
|
|
||||||
#header {
|
|
||||||
background: #fff;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0, 10%);
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for left right layout */
|
/* for left right layout */
|
||||||
#main {
|
#main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -37,13 +29,6 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.positioned-top-logo {
|
|
||||||
position: absolute;
|
|
||||||
top: .5rem;
|
|
||||||
left: 1rem;
|
|
||||||
z-index: 101;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-panel {
|
.main-panel {
|
||||||
flex: 1 0 78%;
|
flex: 1 0 78%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@@ -7,8 +7,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.top-header {
|
.top-header {
|
||||||
background: #f4f4f7;
|
background-color: #f8fafd;
|
||||||
border-bottom: 1px solid #e8e8e8;
|
border-bottom: 1px solid #eee;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.top-header {
|
.top-header {
|
||||||
background: #f4f4f7;
|
background-color: #f8fafd;
|
||||||
border-bottom: 1px solid #e8e8e8;
|
border-bottom: 1px solid #eee;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.top-header {
|
.top-header {
|
||||||
background: #f4f4f7;
|
background-color: #f8fafd;
|
||||||
border-bottom: 1px solid #e8e8e8;
|
border-bottom: 1px solid #eee;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
@@ -5,12 +5,12 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
z-index: 1;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container {
|
.search-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container.show {
|
.search-container.show {
|
||||||
@@ -298,7 +298,7 @@
|
|||||||
|
|
||||||
.search-container {
|
.search-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 2;
|
z-index: 4;
|
||||||
top: 5rem;
|
top: 5rem;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@@ -1,22 +1,26 @@
|
|||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-header {
|
.top-header {
|
||||||
background: #f4f4f7;
|
background-color: #f8fafd;
|
||||||
border-bottom: 1px solid #e8e8e8;
|
border-bottom: 1px solid #eee;
|
||||||
padding: 8px 16px 4px;
|
padding: 8px 16px 4px;
|
||||||
height: 53px;
|
height: 53px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shared-dir-view-main {
|
.shared-dir-view-main {
|
||||||
width: calc(100% - 40px);
|
width: calc(100% - 40px);
|
||||||
max-width: 950px;
|
max-width: 950px;
|
||||||
padding: 15px 0 40px;
|
padding: 15px 0 40px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.op-bar {
|
.op-bar {
|
||||||
padding: 9px 10px;
|
padding: 9px 10px;
|
||||||
background: #f2f2f2;
|
background: #f2f2f2;
|
||||||
@@ -34,18 +38,22 @@ body {
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-view-mode-btn.current-mode {
|
.sf-view-mode-btn.current-mode {
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shared-dir-op-btn {
|
.shared-dir-op-btn {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shared-dir-upload-btn {
|
.shared-dir-upload-btn {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-item .action-icon {
|
.grid-item .action-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
|
@@ -1,15 +1,18 @@
|
|||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-header {
|
.top-header {
|
||||||
background: #f4f4f7;
|
background-color: #f8fafd;
|
||||||
border-bottom: 1px solid #e8e8e8;
|
border-bottom: 1px solid #eee;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
max-width: 950px;
|
max-width: 950px;
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-header {
|
.top-header {
|
||||||
background: #f4f4f7;
|
background-color: #f8fafd;
|
||||||
border-bottom: 1px solid #e8e8e8;
|
border-bottom: 1px solid #eee;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -17,25 +19,30 @@ body {
|
|||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
margin: 2em auto;
|
margin: 2em auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shared-by .avatar {
|
.shared-by .avatar {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#upload-link-panel .warning-icon {
|
#upload-link-panel .warning-icon {
|
||||||
color: #f25041;
|
color: #f25041;
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#upload-link-drop-zone {
|
#upload-link-drop-zone {
|
||||||
background: rgba(255, 152, 0, 0.1);
|
background: rgba(255, 152, 0, 0.1);
|
||||||
border: 2px dashed #ff9800;
|
border: 2px dashed #ff9800;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 28px 0;
|
padding: 28px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#upload-link-drop-zone .upload-icon {
|
#upload-link-drop-zone .upload-icon {
|
||||||
color: rgba(240, 159, 63, 0.8);
|
color: rgba(240, 159, 63, 0.8);
|
||||||
font-size: 60px;
|
font-size: 60px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mh-2 {
|
.mh-2 {
|
||||||
min-height: 2rem;
|
min-height: 2rem;
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@ import GroupbyService from '../../services/groupby-service';
|
|||||||
import { isEsc } from '../../utils/hotkey';
|
import { isEsc } from '../../utils/hotkey';
|
||||||
import { getEventClassName } from '../../utils/utils';
|
import { getEventClassName } from '../../utils/utils';
|
||||||
import { generateDefaultGroupby, getDefaultCountType, getGroupbyColumns } from '../../../utils/groupby-utils';
|
import { generateDefaultGroupby, getDefaultCountType, getGroupbyColumns } from '../../../utils/groupby-utils';
|
||||||
import eventBus from '../../../utils/event-bus';
|
import eventBus from '../../../../../components/common/event-bus';
|
||||||
import { GROUPBY_ACTION_TYPE, GROUPBY_DATE_GRANULARITY_LIST, GROUPBY_GEOLOCATION_GRANULARITY_LIST } from '../../constants/groupby';
|
import { GROUPBY_ACTION_TYPE, GROUPBY_DATE_GRANULARITY_LIST, GROUPBY_GEOLOCATION_GRANULARITY_LIST } from '../../constants/groupby';
|
||||||
import { EVENT_BUS_TYPE } from '../../../constants';
|
import { EVENT_BUS_TYPE } from '../../../constants';
|
||||||
import { gettext } from '../../../utils';
|
import { gettext } from '../../../utils';
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { CellType } from '../_basic';
|
import { CellType } from '../_basic';
|
||||||
import { EVENT_BUS_TYPE } from './event-bus-type';
|
import { EVENT_BUS_TYPE } from '../../../components/common/event-bus-type';
|
||||||
import TRANSFER_TYPES from './TransferTypes';
|
import TRANSFER_TYPES from './TransferTypes';
|
||||||
|
|
||||||
export const CELL_NAVIGATION_MODE = {
|
export const CELL_NAVIGATION_MODE = {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import metadataAPI from '../api';
|
import metadataAPI from '../api';
|
||||||
import { UserService, LocalStorage } from './_basic';
|
import { UserService, LocalStorage } from './_basic';
|
||||||
import EventBus from './utils/event-bus';
|
import EventBus from '../../components/common/event-bus';
|
||||||
import { username } from '../../utils/constants';
|
import { username } from '../../utils/constants';
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
|
@@ -10,7 +10,6 @@ import ModalPortal from '../../components/modal-portal';
|
|||||||
import Group from '../../models/group';
|
import Group from '../../models/group';
|
||||||
import Repo from '../../models/repo';
|
import Repo from '../../models/repo';
|
||||||
import toaster from '../../components/toast';
|
import toaster from '../../components/toast';
|
||||||
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
|
||||||
import CreateRepoDialog from '../../components/dialog/create-repo-dialog';
|
import CreateRepoDialog from '../../components/dialog/create-repo-dialog';
|
||||||
import GroupMembersDialog from '../../components/dialog/group-members-dialog';
|
import GroupMembersDialog from '../../components/dialog/group-members-dialog';
|
||||||
import DismissGroupDialog from '../../components/dialog/dismiss-group-dialog';
|
import DismissGroupDialog from '../../components/dialog/dismiss-group-dialog';
|
||||||
@@ -26,8 +25,6 @@ import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-tool
|
|||||||
import '../../css/group-view.css';
|
import '../../css/group-view.css';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired,
|
|
||||||
onGroupChanged: PropTypes.func.isRequired,
|
onGroupChanged: PropTypes.func.isRequired,
|
||||||
groupID: PropTypes.string,
|
groupID: PropTypes.string,
|
||||||
};
|
};
|
||||||
@@ -430,12 +427,6 @@ class GroupView extends React.Component {
|
|||||||
const opList = this.getOpList();
|
const opList = this.getOpList();
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="main-panel-north border-left-show">
|
|
||||||
<div className="cur-view-toolbar">
|
|
||||||
<span className="sf2-icon-menu side-nav-toggle d-md-none" title="Side Nav Menu" onClick={this.props.onShowSidePanel}></span>
|
|
||||||
</div>
|
|
||||||
<CommonToolbar onSearchedClick={this.props.onSearchedClick} />
|
|
||||||
</div>
|
|
||||||
<div className="main-panel-center flex-row">
|
<div className="main-panel-center flex-row">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
|
@@ -300,11 +300,4 @@ Content.propTypes = {
|
|||||||
data: PropTypes.object.isRequired,
|
data: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const InvitationsViewPropTypes = {
|
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
InvitationsView.propTypes = InvitationsViewPropTypes;
|
|
||||||
|
|
||||||
export default InvitationsView;
|
export default InvitationsView;
|
||||||
|
@@ -29,7 +29,6 @@ class LibContentToolbar extends React.Component {
|
|||||||
repoName={this.props.repoName}
|
repoName={this.props.repoName}
|
||||||
currentRepoInfo={this.props.currentRepoInfo}
|
currentRepoInfo={this.props.currentRepoInfo}
|
||||||
onSearchedClick={this.props.onSearchedClick}
|
onSearchedClick={this.props.onSearchedClick}
|
||||||
searchPlaceholder={gettext('Search files')}
|
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@@ -16,17 +16,17 @@ import treeHelper from '../../components/tree-view/tree-helper';
|
|||||||
import toaster from '../../components/toast';
|
import toaster from '../../components/toast';
|
||||||
import ModalPortal from '../../components/modal-portal';
|
import ModalPortal from '../../components/modal-portal';
|
||||||
import LibDecryptDialog from '../../components/dialog/lib-decrypt-dialog';
|
import LibDecryptDialog from '../../components/dialog/lib-decrypt-dialog';
|
||||||
import LibContentToolbar from './lib-content-toolbar';
|
|
||||||
import LibContentContainer from './lib-content-container';
|
import LibContentContainer from './lib-content-container';
|
||||||
import FileUploader from '../../components/file-uploader/file-uploader';
|
import FileUploader from '../../components/file-uploader/file-uploader';
|
||||||
import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dirent-progress-dialog';
|
import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dirent-progress-dialog';
|
||||||
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
|
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
|
||||||
|
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
eventBus: PropTypes.object,
|
||||||
isSidePanelFolded: PropTypes.bool,
|
isSidePanelFolded: PropTypes.bool,
|
||||||
pathPrefix: PropTypes.array.isRequired,
|
pathPrefix: PropTypes.array.isRequired,
|
||||||
onTabNavClick: PropTypes.func.isRequired,
|
onTabNavClick: PropTypes.func.isRequired,
|
||||||
onMenuClick: PropTypes.func.isRequired,
|
|
||||||
repoID: PropTypes.string,
|
repoID: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -201,10 +201,24 @@ class LibContentView extends React.Component {
|
|||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.onpopstate = this.oldonpopstate;
|
window.onpopstate = this.oldonpopstate;
|
||||||
collabServer.unwatchRepo(this.props.repoID, this.onRepoUpdateEvent);
|
collabServer.unwatchRepo(this.props.repoID, this.onRepoUpdateEvent);
|
||||||
|
this.props.eventBus.dispatch(EVENT_BUS_TYPE.CURRENT_LIBRARY_CHANGED, {
|
||||||
|
repoID: '',
|
||||||
|
repoName: '',
|
||||||
|
path: '',
|
||||||
|
isViewFile: false,
|
||||||
|
isLibView: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
this.lastModifyTime = new Date();
|
this.lastModifyTime = new Date();
|
||||||
|
this.props.eventBus.dispatch(EVENT_BUS_TYPE.CURRENT_LIBRARY_CHANGED, {
|
||||||
|
repoID: this.props.repoID,
|
||||||
|
repoName: this.state.repoName,
|
||||||
|
path: this.state.path,
|
||||||
|
isViewFile: this.state.isViewFile,
|
||||||
|
isLibView: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onpopstate = (event) => {
|
onpopstate = (event) => {
|
||||||
@@ -2027,45 +2041,6 @@ class LibContentView extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="main-panel-north border-left-show">
|
|
||||||
<LibContentToolbar
|
|
||||||
isViewFile={this.state.isViewFile}
|
|
||||||
filePermission={this.state.filePermission}
|
|
||||||
fileTags={this.state.fileTags}
|
|
||||||
onFileTagChanged={this.onToolbarFileTagChanged}
|
|
||||||
onSideNavMenuClick={this.props.onMenuClick}
|
|
||||||
repoID={this.props.repoID}
|
|
||||||
path={this.state.path}
|
|
||||||
isDirentSelected={this.state.isDirentSelected}
|
|
||||||
selectedDirentList={this.state.selectedDirentList}
|
|
||||||
onItemsMove={this.onMoveItems}
|
|
||||||
onItemsCopy={this.onCopyItems}
|
|
||||||
onItemsDelete={this.onDeleteItems}
|
|
||||||
onItemRename={this.onMainPanelItemRename}
|
|
||||||
direntList={this.state.direntList}
|
|
||||||
repoName={this.state.repoName}
|
|
||||||
repoEncrypted={this.state.repoEncrypted}
|
|
||||||
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
|
|
||||||
userPerm={this.state.userPerm}
|
|
||||||
showShareBtn={showShareBtn}
|
|
||||||
enableDirPrivateShare={enableDirPrivateShare}
|
|
||||||
onAddFile={this.onAddFile}
|
|
||||||
onAddFolder={this.onAddFolder}
|
|
||||||
onUploadFile={this.onUploadFile}
|
|
||||||
onUploadFolder={this.onUploadFolder}
|
|
||||||
currentMode={this.state.currentMode}
|
|
||||||
switchViewMode={this.switchViewMode}
|
|
||||||
onSearchedClick={this.onSearchedClick}
|
|
||||||
isRepoOwner={isRepoOwner}
|
|
||||||
currentRepoInfo={this.state.currentRepoInfo}
|
|
||||||
updateDirent={this.updateDirent}
|
|
||||||
onDirentSelected={this.onDirentSelected}
|
|
||||||
showDirentDetail={this.showDirentDetail}
|
|
||||||
unSelectDirent={this.unSelectDirent}
|
|
||||||
onFilesTagChanged={this.onFileTagChanged}
|
|
||||||
repoTags={this.state.repoTags}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="main-panel-center flex-row">
|
<div className="main-panel-center flex-row">
|
||||||
<LibContentContainer
|
<LibContentContainer
|
||||||
isSidePanelFolded={this.props.isSidePanelFolded}
|
isSidePanelFolded={this.props.isSidePanelFolded}
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import cookie from 'react-cookies';
|
import cookie from 'react-cookies';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import { gettext, canAddRepo, canViewOrg } from '../../utils/constants';
|
import { gettext, canAddRepo, canViewOrg } from '../../utils/constants';
|
||||||
@@ -10,7 +9,6 @@ import Group from '../../models/group';
|
|||||||
import Loading from '../../components/loading';
|
import Loading from '../../components/loading';
|
||||||
import ViewModes from '../../components/view-modes';
|
import ViewModes from '../../components/view-modes';
|
||||||
import ReposSortMenu from '../../components/repos-sort-menu';
|
import ReposSortMenu from '../../components/repos-sort-menu';
|
||||||
import TopToolbar from '../../components/toolbar/top-toolbar';
|
|
||||||
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
||||||
import SortOptionsDialog from '../../components/dialog/sort-options';
|
import SortOptionsDialog from '../../components/dialog/sort-options';
|
||||||
import GuideForNewDialog from '../../components/dialog/guide-for-new-dialog';
|
import GuideForNewDialog from '../../components/dialog/guide-for-new-dialog';
|
||||||
@@ -22,11 +20,6 @@ import GroupItem from '../../pages/groups/group-item';
|
|||||||
|
|
||||||
import '../../css/files.css';
|
import '../../css/files.css';
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
class Libraries extends Component {
|
class Libraries extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -238,11 +231,7 @@ class Libraries extends Component {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<>
|
||||||
<TopToolbar
|
|
||||||
onShowSidePanel={this.props.onShowSidePanel}
|
|
||||||
onSearchedClick={this.props.onSearchedClick}
|
|
||||||
/>
|
|
||||||
<div className="main-panel-center flex-row">
|
<div className="main-panel-center flex-row">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
@@ -365,11 +354,9 @@ class Libraries extends Component {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Libraries.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default Libraries;
|
export default Libraries;
|
||||||
|
@@ -8,7 +8,6 @@ import { Utils } from '../../utils/utils';
|
|||||||
import toaster from '../../components/toast';
|
import toaster from '../../components/toast';
|
||||||
import Loading from '../../components/loading';
|
import Loading from '../../components/loading';
|
||||||
import EmptyTip from '../../components/empty-tip';
|
import EmptyTip from '../../components/empty-tip';
|
||||||
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
|
||||||
|
|
||||||
moment.locale(lang);
|
moment.locale(lang);
|
||||||
|
|
||||||
@@ -44,9 +43,6 @@ class MyLibsDeleted extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="main-panel-north">
|
|
||||||
<CommonToolbar onSearchedClick={this.props.onSearchedClick} />
|
|
||||||
</div>
|
|
||||||
<div className="main-panel-center">
|
<div className="main-panel-center">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
@@ -187,8 +183,4 @@ DeletedRepoItem.propTypes = {
|
|||||||
refreshDeletedRepoList: PropTypes.func.isRequired,
|
refreshDeletedRepoList: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
MyLibsDeleted.propTypes = {
|
|
||||||
onSearchedClick: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MyLibsDeleted;
|
export default MyLibsDeleted;
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import cookie from 'react-cookies';
|
import cookie from 'react-cookies';
|
||||||
import { navigate } from '@gatsbyjs/reach-router';
|
import { navigate } from '@gatsbyjs/reach-router';
|
||||||
import { DropdownToggle, Dropdown, DropdownMenu, DropdownItem } from 'reactstrap';
|
import { DropdownToggle, Dropdown, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||||
@@ -10,18 +9,12 @@ import toaster from '../../components/toast';
|
|||||||
import Repo from '../../models/repo';
|
import Repo from '../../models/repo';
|
||||||
import Loading from '../../components/loading';
|
import Loading from '../../components/loading';
|
||||||
import EmptyTip from '../../components/empty-tip';
|
import EmptyTip from '../../components/empty-tip';
|
||||||
import TopToolbar from '../../components/toolbar/top-toolbar';
|
|
||||||
import MylibRepoListView from './mylib-repo-list-view';
|
import MylibRepoListView from './mylib-repo-list-view';
|
||||||
import SortOptionsDialog from '../../components/dialog/sort-options';
|
import SortOptionsDialog from '../../components/dialog/sort-options';
|
||||||
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
||||||
import ModalPortal from '../../components/modal-portal';
|
import ModalPortal from '../../components/modal-portal';
|
||||||
import CreateRepoDialog from '../../components/dialog/create-repo-dialog';
|
import CreateRepoDialog from '../../components/dialog/create-repo-dialog';
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
class MyLibraries extends Component {
|
class MyLibraries extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -156,11 +149,6 @@ class MyLibraries extends Component {
|
|||||||
const { isDropdownMenuOpen } = this.state;
|
const { isDropdownMenuOpen } = this.state;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<TopToolbar
|
|
||||||
onShowSidePanel={this.props.onShowSidePanel}
|
|
||||||
onSearchedClick={this.props.onSearchedClick}
|
|
||||||
>
|
|
||||||
</TopToolbar>
|
|
||||||
<div className="main-panel-center flex-row">
|
<div className="main-panel-center flex-row">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
@@ -229,6 +217,4 @@ class MyLibraries extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyLibraries.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default MyLibraries;
|
export default MyLibraries;
|
||||||
|
@@ -14,7 +14,6 @@ import ShareLinkPermissionSelect from '../../components/dialog/share-link-permis
|
|||||||
import ShareAdminLink from '../../components/dialog/share-admin-link';
|
import ShareAdminLink from '../../components/dialog/share-admin-link';
|
||||||
import SortOptionsDialog from '../../components/dialog/sort-options';
|
import SortOptionsDialog from '../../components/dialog/sort-options';
|
||||||
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
||||||
import TopToolbar from '../../components/toolbar/top-toolbar';
|
|
||||||
import Selector from '../../components/single-selector';
|
import Selector from '../../components/single-selector';
|
||||||
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
||||||
|
|
||||||
@@ -363,11 +362,6 @@ class Item extends Component {
|
|||||||
|
|
||||||
Item.propTypes = itemPropTypes;
|
Item.propTypes = itemPropTypes;
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
const PER_PAGE = 25;
|
const PER_PAGE = 25;
|
||||||
|
|
||||||
class ShareAdminShareLinks extends Component {
|
class ShareAdminShareLinks extends Component {
|
||||||
@@ -540,11 +534,6 @@ class ShareAdminShareLinks extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<TopToolbar
|
|
||||||
onShowSidePanel={this.props.onShowSidePanel}
|
|
||||||
onSearchedClick={this.props.onSearchedClick}
|
|
||||||
>
|
|
||||||
</TopToolbar>
|
|
||||||
<div className="main-panel-center">
|
<div className="main-panel-center">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path share-upload-nav">
|
<div className="cur-view-path share-upload-nav">
|
||||||
@@ -600,6 +589,4 @@ class ShareAdminShareLinks extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareAdminShareLinks.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default ShareAdminShareLinks;
|
export default ShareAdminShareLinks;
|
||||||
|
@@ -12,7 +12,6 @@ import EmptyTip from '../../components/empty-tip';
|
|||||||
import UploadLink from '../../models/upload-link';
|
import UploadLink from '../../models/upload-link';
|
||||||
import ShareAdminLink from '../../components/dialog/share-admin-link';
|
import ShareAdminLink from '../../components/dialog/share-admin-link';
|
||||||
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
import CommonOperationConfirmationDialog from '../../components/dialog/common-operation-confirmation-dialog';
|
||||||
import TopToolbar from '../../components/toolbar/top-toolbar';
|
|
||||||
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
||||||
|
|
||||||
const contentPropTypes = {
|
const contentPropTypes = {
|
||||||
@@ -203,11 +202,6 @@ class Item extends Component {
|
|||||||
|
|
||||||
Item.propTypes = itemPropTypes;
|
Item.propTypes = itemPropTypes;
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShareAdminUploadLinks extends Component {
|
class ShareAdminUploadLinks extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -273,10 +267,6 @@ class ShareAdminUploadLinks extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<TopToolbar
|
|
||||||
onShowSidePanel={this.props.onShowSidePanel}
|
|
||||||
onSearchedClick={this.props.onSearchedClick}
|
|
||||||
/>
|
|
||||||
<div className="main-panel-center">
|
<div className="main-panel-center">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path share-upload-nav">
|
<div className="cur-view-path share-upload-nav">
|
||||||
@@ -318,6 +308,4 @@ class ShareAdminUploadLinks extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareAdminUploadLinks.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default ShareAdminUploadLinks;
|
export default ShareAdminUploadLinks;
|
||||||
|
@@ -1,30 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import Account from '../../components/common/account';
|
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
children: PropTypes.object
|
|
||||||
};
|
|
||||||
|
|
||||||
class MainPanelTopbar extends Component {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className={`main-panel-north ${this.props.children ? 'border-left-show' : ''}`}>
|
|
||||||
<div className="cur-view-toolbar">
|
|
||||||
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu"></span>
|
|
||||||
<div className="operation">
|
|
||||||
{this.props.children}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="common-toolbar">
|
|
||||||
<Account isAdminPanel={false} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MainPanelTopbar.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default MainPanelTopbar;
|
|
@@ -1,12 +1,10 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Button } from 'reactstrap';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import { siteRoot, gettext } from '../../utils/constants';
|
import { siteRoot } from '../../utils/constants';
|
||||||
import toaster from '../../components/toast';
|
import toaster from '../../components/toast';
|
||||||
import MainPanelTopbar from './remote-dir-topbar';
|
|
||||||
import DirPathBar from './remote-dir-path';
|
import DirPathBar from './remote-dir-path';
|
||||||
import DirContent from './remote-dir-content';
|
import DirContent from './remote-dir-content';
|
||||||
|
|
||||||
@@ -129,20 +127,15 @@ class DirView extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { loading, errorMsg,
|
const { loading, errorMsg, repoName, direntList, path } = this.state;
|
||||||
repoName, direntList, path, userPerm } = this.state;
|
|
||||||
const { repoID } = this.props;
|
const { repoID } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<MainPanelTopbar>
|
{/*
|
||||||
<Fragment>
|
<input className="d-none" type="file" onChange={this.onFileInputChange} ref={this.fileInput} />
|
||||||
<input className="d-none" type="file" onChange={this.onFileInputChange} ref={this.fileInput} />
|
{userPerm === 'rw' && <Button className="operation-item" onClick={this.openFileInput}>{gettext('Upload')}</Button>}
|
||||||
{userPerm === 'rw' &&
|
*/}
|
||||||
<Button className="operation-item" onClick={this.openFileInput}>{gettext('Upload')}</Button>
|
|
||||||
}
|
|
||||||
</Fragment>
|
|
||||||
</MainPanelTopbar>
|
|
||||||
<div className="main-panel-center flex-row">
|
<div className="main-panel-center flex-row">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path align-items-center">
|
<div className="cur-view-path align-items-center">
|
||||||
|
@@ -12,13 +12,10 @@ import SharedRepoListView from '../../components/shared-repo-list-view/shared-re
|
|||||||
import SortOptionsDialog from '../../components/dialog/sort-options';
|
import SortOptionsDialog from '../../components/dialog/sort-options';
|
||||||
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar';
|
||||||
import ModalPortal from '../../components/modal-portal';
|
import ModalPortal from '../../components/modal-portal';
|
||||||
import TopToolbar from '../../components/toolbar/top-toolbar';
|
|
||||||
import CreateRepoDialog from '../../components/dialog/create-repo-dialog';
|
import CreateRepoDialog from '../../components/dialog/create-repo-dialog';
|
||||||
import ShareRepoDialog from '../../components/dialog/share-repo-dialog';
|
import ShareRepoDialog from '../../components/dialog/share-repo-dialog';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
onShowSidePanel: PropTypes.func,
|
|
||||||
onSearchedClick: PropTypes.func,
|
|
||||||
currentViewMode: PropTypes.string,
|
currentViewMode: PropTypes.string,
|
||||||
inAllLibs: PropTypes.bool,
|
inAllLibs: PropTypes.bool,
|
||||||
repoList: PropTypes.array,
|
repoList: PropTypes.array,
|
||||||
@@ -222,11 +219,6 @@ class PublicSharedView extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<TopToolbar
|
|
||||||
onShowSidePanel={this.props.onShowSidePanel}
|
|
||||||
onSearchedClick={this.props.onSearchedClick}
|
|
||||||
>
|
|
||||||
</TopToolbar>
|
|
||||||
<div className="main-panel-center">
|
<div className="main-panel-center">
|
||||||
<div className="cur-view-container">
|
<div className="cur-view-container">
|
||||||
<div className="cur-view-path">
|
<div className="cur-view-path">
|
||||||
|
@@ -1,21 +1,14 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||||
import { gettext, canPublishRepo } from '../../utils/constants';
|
import { gettext, canPublishRepo } from '../../utils/constants';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import toaster from '../../components/toast';
|
import toaster from '../../components/toast';
|
||||||
import ModalPortal from '../../components/modal-portal';
|
import ModalPortal from '../../components/modal-portal';
|
||||||
import EmptyTip from '../../components/empty-tip';
|
import EmptyTip from '../../components/empty-tip';
|
||||||
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
|
||||||
import AddWikiDialog from '../../components/dialog/add-wiki-dialog';
|
import AddWikiDialog from '../../components/dialog/add-wiki-dialog';
|
||||||
import wikiAPI from '../../utils/wiki-api';
|
import wikiAPI from '../../utils/wiki-api';
|
||||||
import WikiCardView from '../../components/wiki-card-view/wiki-card-view';
|
import WikiCardView from '../../components/wiki-card-view/wiki-card-view';
|
||||||
|
|
||||||
const propTypes = {
|
|
||||||
onShowSidePanel: PropTypes.func.isRequired,
|
|
||||||
onSearchedClick: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
class Wikis extends Component {
|
class Wikis extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -177,12 +170,6 @@ class Wikis extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="main-panel-north border-left-show">
|
|
||||||
<div className="cur-view-toolbar">
|
|
||||||
<span className="sf2-icon-menu side-nav-toggle hidden-md-up d-md-none" title="Side Nav Menu" onClick={this.props.onShowSidePanel}></span>
|
|
||||||
</div>
|
|
||||||
<CommonToolbar onSearchedClick={this.props.onSearchedClick} />
|
|
||||||
</div>
|
|
||||||
{this.state.isShowAddDialog &&
|
{this.state.isShowAddDialog &&
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<AddWikiDialog
|
<AddWikiDialog
|
||||||
@@ -242,6 +229,4 @@ class Wikis extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Wikis.propTypes = propTypes;
|
|
||||||
|
|
||||||
export default Wikis;
|
export default Wikis;
|
||||||
|
@@ -6,10 +6,9 @@ import { Utils } from './utils/utils';
|
|||||||
import { isPro, isDBSqlite3, gettext, siteRoot } from './utils/constants';
|
import { isPro, isDBSqlite3, gettext, siteRoot } from './utils/constants';
|
||||||
import { seafileAPI } from './utils/seafile-api';
|
import { seafileAPI } from './utils/seafile-api';
|
||||||
import toaster from './components/toast';
|
import toaster from './components/toast';
|
||||||
import SidePanel from './components/side-panel';
|
|
||||||
import MainPanel from './components/main-panel';
|
import MainPanel from './components/main-panel';
|
||||||
import TopToolbar from './components/toolbar/top-toolbar';
|
import SettingSidePanel from './components/user-settings/setting-side-panel';
|
||||||
import SideNav from './components/user-settings/side-nav';
|
import SettingTopToolbar from './components/user-settings/setting-top-toolbar';
|
||||||
import UserAvatarForm from './components/user-settings/user-avatar-form';
|
import UserAvatarForm from './components/user-settings/user-avatar-form';
|
||||||
import UserBasicInfoForm from './components/user-settings/user-basic-info-form';
|
import UserBasicInfoForm from './components/user-settings/user-basic-info-form';
|
||||||
import WebAPIAuthToken from './components/user-settings/web-api-auth-token';
|
import WebAPIAuthToken from './components/user-settings/web-api-auth-token';
|
||||||
@@ -124,60 +123,52 @@ class Settings extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const { isSidePanelClosed } = this.state;
|
const { isSidePanelClosed } = this.state;
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<div id="main" className="h-100">
|
||||||
<div id="main" className="h-100">
|
<SettingSidePanel
|
||||||
<SidePanel
|
isSidePanelClosed={isSidePanelClosed}
|
||||||
isSidePanelClosed={isSidePanelClosed}
|
onCloseSidePanel={this.onCloseSidePanel}
|
||||||
onCloseSidePanel={this.onCloseSidePanel}
|
data={this.sideNavItems}
|
||||||
>
|
curItemID={this.state.curItemID}
|
||||||
<SideNav data={this.sideNavItems} curItemID={this.state.curItemID} />
|
/>
|
||||||
</SidePanel>
|
<MainPanel>
|
||||||
<MainPanel>
|
<SettingTopToolbar onShowSidePanel={this.onShowSidePanel} showSearch={false} />
|
||||||
<>
|
<div className="main-panel-center flex-row">
|
||||||
<TopToolbar
|
<div className="cur-view-container">
|
||||||
onShowSidePanel={this.onShowSidePanel}
|
<div className="cur-view-path">
|
||||||
showSearch={false}
|
<h3 className="sf-heading m-0">{gettext('Settings')}</h3>
|
||||||
>
|
|
||||||
</TopToolbar>
|
|
||||||
<div className="main-panel-center flex-row">
|
|
||||||
<div className="cur-view-container">
|
|
||||||
<div className="cur-view-path">
|
|
||||||
<h3 className="sf-heading m-0">{gettext('Settings')}</h3>
|
|
||||||
</div>
|
|
||||||
<div className="cur-view-content content position-relative" onScroll={this.handleContentScroll}>
|
|
||||||
<div id="user-basic-info" className="setting-item">
|
|
||||||
<h3 className="setting-item-heading">{gettext('Profile Setting')}</h3>
|
|
||||||
<UserAvatarForm />
|
|
||||||
{this.state.userInfo && <UserBasicInfoForm userInfo={this.state.userInfo} updateUserInfo={this.updateUserInfo} />}
|
|
||||||
</div>
|
|
||||||
{canUpdatePassword &&
|
|
||||||
<div id="update-user-passwd" className="setting-item">
|
|
||||||
<h3 className="setting-item-heading">{gettext('Password')}</h3>
|
|
||||||
<a href={`${siteRoot}accounts/password/change/`} className="btn btn-outline-primary">{passwordOperationText}</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{enableGetAuthToken && <WebAPIAuthToken />}
|
|
||||||
{enableWebdavSecret && <WebdavPassword />}
|
|
||||||
{enableAddressBook && this.state.userInfo &&
|
|
||||||
<ListInAddressBook userInfo={this.state.userInfo} updateUserInfo={this.updateUserInfo} />}
|
|
||||||
<LanguageSetting />
|
|
||||||
{(isPro || !isDBSqlite3) && <EmailNotice />}
|
|
||||||
{twoFactorAuthEnabled && <TwoFactorAuthentication />}
|
|
||||||
{enableWechatWork && <SocialLogin />}
|
|
||||||
{enableDingtalk && <SocialLoginDingtalk />}
|
|
||||||
{(enableADFS || (enableMultiADFS && isOrgContext)) && <SocialLoginSAML />}
|
|
||||||
<LinkedDevices />
|
|
||||||
{enableDeleteAccount && <DeleteAccount />}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
<div className="cur-view-content content position-relative" onScroll={this.handleContentScroll}>
|
||||||
</MainPanel>
|
<div id="user-basic-info" className="setting-item">
|
||||||
<MediaQuery query="(max-width: 767.8px)">
|
<h3 className="setting-item-heading">{gettext('Profile Setting')}</h3>
|
||||||
<Modal zIndex="1030" isOpen={!isSidePanelClosed} toggle={this.toggleSidePanel} contentClassName="d-none"></Modal>
|
<UserAvatarForm />
|
||||||
</MediaQuery>
|
{this.state.userInfo && <UserBasicInfoForm userInfo={this.state.userInfo} updateUserInfo={this.updateUserInfo} />}
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
{canUpdatePassword &&
|
||||||
|
<div id="update-user-passwd" className="setting-item">
|
||||||
|
<h3 className="setting-item-heading">{gettext('Password')}</h3>
|
||||||
|
<a href={`${siteRoot}accounts/password/change/`} className="btn btn-outline-primary">{passwordOperationText}</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{enableGetAuthToken && <WebAPIAuthToken />}
|
||||||
|
{enableWebdavSecret && <WebdavPassword />}
|
||||||
|
{enableAddressBook && this.state.userInfo &&
|
||||||
|
<ListInAddressBook userInfo={this.state.userInfo} updateUserInfo={this.updateUserInfo} />}
|
||||||
|
<LanguageSetting />
|
||||||
|
{(isPro || !isDBSqlite3) && <EmailNotice />}
|
||||||
|
{twoFactorAuthEnabled && <TwoFactorAuthentication />}
|
||||||
|
{enableWechatWork && <SocialLogin />}
|
||||||
|
{enableDingtalk && <SocialLoginDingtalk />}
|
||||||
|
{(enableADFS || (enableMultiADFS && isOrgContext)) && <SocialLoginSAML />}
|
||||||
|
<LinkedDevices />
|
||||||
|
{enableDeleteAccount && <DeleteAccount />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MainPanel>
|
||||||
|
<MediaQuery query="(max-width: 767.8px)">
|
||||||
|
<Modal zIndex="1030" isOpen={!isSidePanelClosed} toggle={this.toggleSidePanel} contentClassName="d-none"></Modal>
|
||||||
|
</MediaQuery>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1188,15 +1188,13 @@ a.sf-popover-item {
|
|||||||
}
|
}
|
||||||
/********** Container ***********/
|
/********** Container ***********/
|
||||||
#header {
|
#header {
|
||||||
background: #fff;
|
background-color: #f8fafd;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0, 10%);
|
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 49px;
|
height: 49px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
/*display:flex;*/
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -1399,9 +1397,9 @@ a.sf-popover-item {
|
|||||||
/*** separate pages ***/
|
/*** separate pages ***/
|
||||||
/* login */
|
/* login */
|
||||||
#lang {
|
#lang {
|
||||||
font-weight:normal;
|
font-weight: normal;
|
||||||
font-size:13px;
|
font-size: 13px;
|
||||||
margin-top:12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
#lang-context:hover {
|
#lang-context:hover {
|
||||||
text-decoration:none;
|
text-decoration:none;
|
||||||
|
Reference in New Issue
Block a user