mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-17 15:53:28 +00:00
conflict fixed
This commit is contained in:
10
frontend/src/components/common/logout.js
Normal file
10
frontend/src/components/common/logout.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import { siteRoot, gettext } from '../../utils/constants';
|
||||
|
||||
export default function Logout() {
|
||||
return (
|
||||
<a className="logout-icon" href={`${siteRoot}accounts/logout/`} title={gettext('Log out')}>
|
||||
<i className="sf3-font sf3-font-logout" style={{fontSize: '24px'}}></i>
|
||||
</a>
|
||||
);
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Modal, ModalBody } from 'reactstrap';
|
||||
import { gettext, lang, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle, seafileVersion } from '../../utils/constants';
|
||||
import { gettext, lang, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle, seafileVersion, extraAboutDialogLinks } from '../../utils/constants';
|
||||
|
||||
const propTypes = {
|
||||
onCloseAboutDialog: PropTypes.func.isRequired,
|
||||
@@ -13,6 +13,16 @@ class AboutDialog extends React.Component {
|
||||
this.props.onCloseAboutDialog();
|
||||
}
|
||||
|
||||
renderExternalAboutLinks = () => {
|
||||
if (extraAboutDialogLinks && (typeof extraAboutDialogLinks) === 'object') {
|
||||
let keys = Object.keys(extraAboutDialogLinks);
|
||||
return keys.map((key, index) => {
|
||||
return <a key={index} className="d-block" href={extraAboutDialogLinks[key]}>{key}</a>;
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
let href = lang === lang == 'zh-cn' ? 'http://seafile.com/about/' : 'http://seafile.com/en/about/';
|
||||
|
||||
@@ -23,6 +33,7 @@ class AboutDialog extends React.Component {
|
||||
<div className="about-content">
|
||||
<p><img src={mediaUrl + logoPath} height={logoHeight} width={logoWidth} title={siteTitle} alt="logo" /></p>
|
||||
<p>{gettext('Server Version: ')}{seafileVersion}<br />© 2019 {gettext('Seafile')}</p>
|
||||
<p>{this.renderExternalAboutLinks()}</p>
|
||||
<p><a href={href} target="_blank">{gettext('About Us')}</a></p>
|
||||
</div>
|
||||
</ModalBody>
|
||||
|
@@ -23,7 +23,7 @@ class CopyMoveDirentProgressDialog extends React.Component {
|
||||
textAlign: 'left',
|
||||
};
|
||||
return (
|
||||
<Modal isOpen={true} toggle={this.props.toggleDialog}>
|
||||
<Modal isOpen={true}>
|
||||
<ModalHeader toggle={this.props.toggleDialog}>{title}</ModalHeader>
|
||||
<ModalBody style={{minHeight: '80px'}}>
|
||||
<div className="progress" style={{height: '40px'}}>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Modal, ModalHeader, ModalBody, TabContent, TabPane, Nav, NavItem, NavLink } from 'reactstrap';
|
||||
import { gettext, username, canGenerateShareLink, canGenerateUploadLink, canInvitePeople } from '../../utils/constants';
|
||||
import { Modal, ModalHeader, ModalBody, TabContent, TabPane, Nav, NavItem, NavLink } from 'reactstrap';
|
||||
import { gettext, username, canGenerateShareLink, canGenerateUploadLink, canInvitePeople, extraShareDialogNote } from '../../utils/constants';
|
||||
import ShareToUser from './share-to-user';
|
||||
import ShareToGroup from './share-to-group';
|
||||
import ShareToInvitePeople from './share-to-invite-people';
|
||||
@@ -226,13 +226,28 @@ class ShareDialog extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderExternalShareMessage = () => {
|
||||
if (extraShareDialogNote && (typeof extraShareDialogNote) === 'object') {
|
||||
return (
|
||||
<div className="external-share-message mt-2">
|
||||
<h6>{extraShareDialogNote.title}</h6>
|
||||
<div style={{fontSize: '14px', color: '#666'}}>{extraShareDialogNote.content}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { itemType, itemName, repoEncrypted } = this.props;
|
||||
const enableShareLink = !repoEncrypted && canGenerateShareLink;
|
||||
return (
|
||||
<div>
|
||||
<Modal isOpen={true} style={{ maxWidth: '720px' }} className="share-dialog" toggle={this.props.toggleDialog}>
|
||||
<ModalHeader toggle={this.props.toggleDialog}>{gettext('Share')} <span className="op-target" title={itemName}>{itemName}</span></ModalHeader>
|
||||
<Modal isOpen={true} style={{maxWidth: '720px'}} className="share-dialog" toggle={this.props.toggleDialog}>
|
||||
<ModalHeader toggle={this.props.toggleDialog}>
|
||||
{gettext('Share')} <span className="op-target" title={itemName}>{itemName}</span>
|
||||
{this.renderExternalShareMessage()}
|
||||
</ModalHeader>
|
||||
<ModalBody className="share-dialog-content">
|
||||
{(itemType === 'library' || itemType === 'dir') && this.renderDirContent()}
|
||||
{(itemType === 'file' && enableShareLink) && this.renderFileContent()}
|
||||
|
@@ -279,8 +279,8 @@ class ShareToGroup extends React.Component {
|
||||
let sharedItemGroupID = sharedItem.group_info.id;
|
||||
if (groupID === sharedItemGroupID) {
|
||||
sharedItem.permission = permission;
|
||||
sharedItem.is_admin = permission === 'admin' ? true : false;
|
||||
}
|
||||
sharedItem.is_admin = permission === 'admin' ? true : false;
|
||||
return sharedItem;
|
||||
});
|
||||
this.setState({sharedItems: sharedItems});
|
||||
|
@@ -263,8 +263,8 @@ class ShareToUser extends React.Component {
|
||||
let sharedItemUsername = sharedItem.user_info.name;
|
||||
if (username === sharedItemUsername) {
|
||||
sharedItem.permission = permission;
|
||||
sharedItem.is_admin = permission === 'admin' ? true : false;
|
||||
}
|
||||
sharedItem.is_admin = permission === 'admin' ? true : false;
|
||||
return sharedItem;
|
||||
});
|
||||
this.setState({sharedItems: sharedItems});
|
||||
|
@@ -94,29 +94,52 @@ class Search extends Component {
|
||||
|
||||
sendRequest(queryData, cancelToken) {
|
||||
var _this = this;
|
||||
let isPublic = this.props.isPublic;
|
||||
|
||||
seafileAPI.searchFiles(queryData, cancelToken).then(res => {
|
||||
if (!res.data.total) {
|
||||
if (isPublic) {
|
||||
seafileAPI.searchFilesInPublishedRepo(queryData.search_repo, queryData.q).then(res => {
|
||||
if (!res.data.total) {
|
||||
_this.setState({
|
||||
resultItems: [],
|
||||
isResultGetted: true
|
||||
});
|
||||
_this.source = null;
|
||||
return;
|
||||
}
|
||||
|
||||
let items = _this.formatResultItems(res.data.results);
|
||||
_this.setState({
|
||||
resultItems: [],
|
||||
resultItems: items,
|
||||
isResultGetted: true
|
||||
});
|
||||
_this.source = null;
|
||||
return;
|
||||
}
|
||||
|
||||
let items = _this.formatResultItems(res.data.results);
|
||||
_this.setState({
|
||||
total: res.data.total,
|
||||
resultItems: items,
|
||||
isResultGetted: true
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
_this.source = null;
|
||||
}).catch(res => {
|
||||
/* eslint-disable */
|
||||
} else {
|
||||
editorUtilities.searchFiles(queryData,cancelToken).then(res => {
|
||||
if (!res.data.total) {
|
||||
_this.setState({
|
||||
resultItems: [],
|
||||
isResultGetted: true
|
||||
});
|
||||
_this.source = null;
|
||||
return;
|
||||
}
|
||||
|
||||
let items = _this.formatResultItems(res.data.results);
|
||||
_this.setState({
|
||||
resultItems: items,
|
||||
isResultGetted: true
|
||||
});
|
||||
_this.source = null;
|
||||
}).catch(res => {
|
||||
/* eslint-disable */
|
||||
console.log(res);
|
||||
/* eslint-enable */
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cancelRequest() {
|
||||
|
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { gettext } from '../../utils/constants';
|
||||
|
||||
const { err, trafficOverLimit, zipped, filePath } = window.shared.pageOptions;
|
||||
const { err, trafficOverLimit, zipped, filePath, canDownload } = window.shared.pageOptions;
|
||||
|
||||
const propTypes = {
|
||||
errorMsg: PropTypes.string
|
||||
@@ -16,11 +16,14 @@ class SharedFileViewTip extends React.Component {
|
||||
} else {
|
||||
errorMsg = <p className="error">{err || this.props.errorMsg}</p>;
|
||||
}
|
||||
|
||||
let isShowDownloadBtn = canDownload && !trafficOverLimit;
|
||||
|
||||
return (
|
||||
<div className="shared-file-view-body">
|
||||
<div className="file-view-tip">
|
||||
<div className={`file-view-tip ${!isShowDownloadBtn ? 'pt-7' : ''}`}>
|
||||
{errorMsg}
|
||||
{!trafficOverLimit &&
|
||||
{isShowDownloadBtn &&
|
||||
<a href={`?${zipped ? 'p=' + encodeURIComponent(filePath) + '&' : ''}dl=1`} className="btn btn-secondary">{gettext('Download')}</a>
|
||||
}
|
||||
</div>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { gettext, siteRoot } from '../utils/constants';
|
||||
import React, { Fragment } from 'react';
|
||||
import { gettext, siteRoot, sideNavFooterCustomHtml, extraAppBottomLinks } from '../utils/constants';
|
||||
import ModalPortal from './modal-portal';
|
||||
import AboutDialog from './dialog/about-dialog';
|
||||
|
||||
@@ -16,21 +16,38 @@ class SideNavFooter extends React.Component {
|
||||
this.setState({isAboutDialogShow: !this.state.isAboutDialogShow});
|
||||
}
|
||||
|
||||
renderExternalAppLinks = () => {
|
||||
if (extraAppBottomLinks && (typeof extraAppBottomLinks) === 'object') {
|
||||
let keys = Object.keys(extraAppBottomLinks);
|
||||
return keys.map((key, index) => {
|
||||
return <a key={index} className="item" href={extraAppBottomLinks[key]}>{key}</a>;
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (sideNavFooterCustomHtml) {
|
||||
return (<div className='side-nav-footer' dangerouslySetInnerHTML={{__html: sideNavFooterCustomHtml}}></div>);
|
||||
}
|
||||
return (
|
||||
<div className="side-nav-footer">
|
||||
<a href={siteRoot + 'help/'} target="_blank" rel="noopener noreferrer" className="item">{gettext('Help')}</a>
|
||||
<a className="item cursor-pointer" onClick={this.onAboutDialogToggle}>{gettext('About')}</a>
|
||||
<a href={siteRoot + 'download_client_program/'} className="item last-item">
|
||||
<span aria-hidden="true" className="sf2-icon-monitor vam"></span>{' '}
|
||||
<span className="vam">{gettext('Clients')}</span>
|
||||
</a>
|
||||
{this.state.isAboutDialogShow &&
|
||||
<Fragment>
|
||||
<div className="side-nav-footer flex-wrap">
|
||||
<a href={siteRoot + 'help/'} target="_blank" rel="noopener noreferrer" className="item">{gettext('Help')}</a>
|
||||
<a className="item cursor-pointer" onClick={this.onAboutDialogToggle}>{gettext('About')}</a>
|
||||
{this.renderExternalAppLinks()}
|
||||
<a href={siteRoot + 'download_client_program/'} className={`item ${extraAppBottomLinks ? '' : 'last-item'}`}>
|
||||
<span aria-hidden="true" className="sf2-icon-monitor vam"></span>{' '}
|
||||
<span className="vam">{gettext('Clients')}</span>
|
||||
</a>
|
||||
</div>
|
||||
{this.state.isAboutDialogShow && (
|
||||
<ModalPortal>
|
||||
<AboutDialog onCloseAboutDialog={this.onAboutDialogToggle} />
|
||||
</ModalPortal>
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isPro, gettext } from '../../utils/constants';
|
||||
import { isPro, gettext, showLogoutIcon } from '../../utils/constants';
|
||||
import Search from '../search/search';
|
||||
import Notification from '../common/notification';
|
||||
import Account from '../common/account';
|
||||
import Logout from '../common/logout';
|
||||
|
||||
const propTypes = {
|
||||
repoID: PropTypes.string,
|
||||
@@ -25,6 +26,7 @@ class CommonToolbar extends React.Component {
|
||||
)}
|
||||
<Notification />
|
||||
<Account />
|
||||
{showLogoutIcon && (<Logout />)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -83,6 +83,17 @@
|
||||
.common-toolbar > div{
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
.common-toolbar .logout-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-left: 8px;
|
||||
text-decoration: none;
|
||||
color: #ccc;
|
||||
}
|
||||
/* end common-toolbar */
|
||||
|
||||
/* begin path toolbar */
|
||||
|
@@ -78,6 +78,29 @@ class EditorUtilities {
|
||||
return url;
|
||||
}
|
||||
|
||||
uploadImage = (imageFile) => {
|
||||
return (
|
||||
seafileAPI.getFileServerUploadLink(repoID, dirPath).then((res) => {
|
||||
let uploadLinkComponent = res.data;
|
||||
const uploadLink = uploadLinkComponent + '?ret-json=1';
|
||||
const name = getImageFileNameWithTimestamp();
|
||||
const blob = imageFile.slice(0, -1, 'image/png');
|
||||
const newFile = new File([blob], name, {type: 'image/png'});
|
||||
const formData = new FormData();
|
||||
formData.append('parent_dir', '/');
|
||||
formData.append('relative_path', 'images/auto-upload');
|
||||
formData.append('file', newFile);
|
||||
return {uploadLink, formData};
|
||||
}).then(({ uploadLink, formData}) => {
|
||||
return seafileAPI.uploadImage(uploadLink, formData);
|
||||
}).then ((res) => {
|
||||
let resArr = res.data[0];
|
||||
let filename = resArr.name;
|
||||
return this._getImageURL(filename);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
uploadLocalImage = (imageFile) => {
|
||||
return (
|
||||
seafileAPI.getFileServerUploadLink(repoID, dirPath).then((res) => {
|
||||
|
@@ -77,6 +77,7 @@ class LibContentView extends React.Component {
|
||||
isSessionExpired: false,
|
||||
isCopyMoveProgressDialogShow: false,
|
||||
asyncCopyMoveTaskId: '',
|
||||
asyncOperationType: 'move',
|
||||
asyncOperationProgress: 0,
|
||||
asyncOperatedFilesLength: 0,
|
||||
};
|
||||
@@ -632,18 +633,18 @@ class LibContentView extends React.Component {
|
||||
// toolbar operations
|
||||
onMoveItems = (destRepo, destDirentPath) => {
|
||||
let repoID = this.props.repoID;
|
||||
let direntPaths = this.getSelectedDirentPaths();
|
||||
let dirNames = this.getSelectedDirentNames();
|
||||
|
||||
let selectedDirentList = this.state.selectedDirentList;
|
||||
if (repoID !== destRepo.repo_id) {
|
||||
this.setState({
|
||||
asyncOperatedFilesLength: dirNames.length,
|
||||
this.setState(() => ({
|
||||
asyncOperatedFilesLength: selectedDirentList.length,
|
||||
asyncOperationProgress: 0,
|
||||
asyncOperationType: 'move',
|
||||
isCopyMoveProgressDialogShow: true
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
let dirNames = this.getSelectedDirentNames();
|
||||
let direntPaths = this.getSelectedDirentPaths();
|
||||
seafileAPI.moveDir(repoID, destRepo.repo_id, destDirentPath, this.state.path, dirNames).then(res => {
|
||||
if (repoID !== destRepo.repo_id) {
|
||||
this.setState({
|
||||
@@ -682,17 +683,18 @@ class LibContentView extends React.Component {
|
||||
|
||||
onCopyItems = (destRepo, destDirentPath) => {
|
||||
let repoID = this.props.repoID;
|
||||
let dirNames = this.getSelectedDirentNames();
|
||||
|
||||
let selectedDirentList = this.state.selectedDirentList;
|
||||
|
||||
if (repoID !== destRepo.repo_id) {
|
||||
this.setState({
|
||||
asyncOperatedFilesLength: dirNames.length,
|
||||
asyncOperatedFilesLength: selectedDirentList.length,
|
||||
asyncOperationProgress: 0,
|
||||
asyncOperationType: 'copy',
|
||||
isCopyMoveProgressDialogShow: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
let dirNames = this.getSelectedDirentNames();
|
||||
seafileAPI.copyDir(repoID, destRepo.repo_id, destDirentPath, this.state.path, dirNames).then(res => {
|
||||
if (repoID !== destRepo.repo_id) {
|
||||
this.setState({
|
||||
@@ -1715,7 +1717,7 @@ class LibContentView extends React.Component {
|
||||
}
|
||||
|
||||
let enableDirPrivateShare = false;
|
||||
let { currentRepoInfo, userPerm } = this.state;
|
||||
let { currentRepoInfo, userPerm, isCopyMoveProgressDialogShow } = this.state;
|
||||
let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, userPerm);
|
||||
let isRepoOwner = currentRepoInfo.owner_email === username;
|
||||
let isVirtual = currentRepoInfo.is_virtual;
|
||||
@@ -1860,7 +1862,7 @@ class LibContentView extends React.Component {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{this.state.isCopyMoveProgressDialogShow && (
|
||||
{isCopyMoveProgressDialogShow && (
|
||||
<CopyMoveDirentProgressDialog
|
||||
type={this.state.asyncOperationType}
|
||||
asyncOperatedFilesLength={this.state.asyncOperatedFilesLength}
|
||||
|
@@ -1,12 +1,11 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { gettext, repoID, slug, siteRoot, username } from '../../utils/constants';
|
||||
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||
import { gettext, repoID, slug, siteRoot, username, isPro } from '../../utils/constants';
|
||||
import WikiMarkdownViewer from '../../components/wiki-markdown-viewer';
|
||||
import WikiDirListView from '../../components/wiki-dir-list-view/wiki-dir-list-view';
|
||||
import Loading from '../../components/loading';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import Search from '../../components/search/wiki-search';
|
||||
import Search from '../../components/search/search';
|
||||
import Notification from '../../components/common/notification';
|
||||
import Account from '../../components/common/account';
|
||||
|
||||
@@ -78,6 +77,8 @@ class MainPanel extends Component {
|
||||
|
||||
|
||||
render() {
|
||||
let { onSearchedClick, permission } = this.props;
|
||||
let searchPlaceholder = gettext('Search files in this library');
|
||||
const errMessage = (<div className="message err-tip">{gettext('Folder does not exist.')}</div>);
|
||||
|
||||
const isViewingFile = this.props.pathExist && !this.props.isDataLoading && this.props.isViewFile;
|
||||
@@ -90,11 +91,9 @@ class MainPanel extends Component {
|
||||
<span className="sf2-icon-menu hidden-md-up d-md-none side-nav-toggle" title="Side Nav Menu" onClick={this.onMenuClick}></span>
|
||||
</div>
|
||||
<div className="common-toolbar">
|
||||
<Search
|
||||
repoID={repoID}
|
||||
onSearchedClick={this.props.onSearchedClick}
|
||||
placeholder={gettext('Search')}
|
||||
/>
|
||||
{isPro && (
|
||||
<Search isPublic={true} repoID={repoID} onSearchedClick={onSearchedClick} placeholder={searchPlaceholder}/>
|
||||
)}
|
||||
</div>
|
||||
</Fragment>
|
||||
}
|
||||
@@ -109,12 +108,10 @@ class MainPanel extends Component {
|
||||
)}
|
||||
</div>
|
||||
<div className="common-toolbar">
|
||||
<Search
|
||||
repoID={repoID}
|
||||
onSearchedClick={this.props.onSearchedClick}
|
||||
placeholder={gettext('Search')}
|
||||
/>
|
||||
<Notification />
|
||||
{isPro && (
|
||||
<Search isPublic={true} repoID={repoID} onSearchedClick={onSearchedClick} placeholder={searchPlaceholder}/>
|
||||
)}
|
||||
<Notification />
|
||||
<Account />
|
||||
</div>
|
||||
</Fragment>
|
||||
|
@@ -50,9 +50,10 @@ class FileContent extends React.Component {
|
||||
return;
|
||||
}
|
||||
// get image path
|
||||
let index = imageUrl.indexOf('/file');
|
||||
let index2 = imageUrl.indexOf('?');
|
||||
const imagePath = imageUrl.substring(index + 5, index2);
|
||||
let imagePath = imageUrl.substring(serviceURL.length);
|
||||
let index = imagePath.indexOf('/file');
|
||||
let index2 = imagePath.indexOf('?');
|
||||
imagePath = imagePath.substring(index + 5, index2);
|
||||
// change image url
|
||||
innerNode.data.src = serviceURL + '/view-image-via-share-link/?token=' + sharedToken + '&path=' + imagePath;
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@ export const enableRepoSnapshotLabel = window.app.pageOptions.enableRepoSnapshot
|
||||
export const shareLinkPasswordMinLength = window.app.pageOptions.shareLinkPasswordMinLength;
|
||||
export const shareLinkExpireDaysMin = window.app.pageOptions.shareLinkExpireDaysMin;
|
||||
export const shareLinkExpireDaysMax = window.app.pageOptions.shareLinkExpireDaysMax;
|
||||
export const sideNavFooterCustomHtml = window.app.pageOptions.sideNavFooterCustomHtml;
|
||||
export const shareLinkExpireDaysDefault = window.app.pageOptions.shareLinkExpireDaysDefault;
|
||||
export const maxFileName = window.app.pageOptions.maxFileName;
|
||||
export const canPublishRepo = window.app.pageOptions.canPublishRepo;
|
||||
@@ -66,6 +67,10 @@ export const curNoteID = window.app.pageOptions.curNoteID;
|
||||
|
||||
// dtable
|
||||
export const workspaceID = window.app.pageOptions.workspaceID;
|
||||
export const showLogoutIcon = window.app.pageOptions.showLogoutIcon;
|
||||
export const extraShareDialogNote = window.app.pageOptions.extraShareDialogNote;
|
||||
export const extraAppBottomLinks = window.app.pageOptions.extraAppBottomLinks;
|
||||
export const extraAboutDialogLinks = window.app.pageOptions.extraAboutDialogLinks;
|
||||
|
||||
// wiki
|
||||
export const slug = window.wiki ? window.wiki.config.slug : '';
|
||||
|
Reference in New Issue
Block a user