Commit 726a2005 authored by Ray Schamp's avatar Ray Schamp

Basic project admin panel support

Just in case we don't do anything else, this "proxies" the old admin panel to the new project page.

Requires https://github.com/LLK/scratchr2/pull/5219 to work.
parent 4a57d361
const bindAll = require('lodash.bindall');
const classNames = require('classnames');
const connect = require('react-redux').connect;
const PropTypes = require('prop-types');
const React = require('react');
const Button = require('../forms/button.jsx');
require('./adminpanel.scss');
class AdminPanel extends React.Component {
......@@ -23,64 +22,37 @@ class AdminPanel extends React.Component {
}
render () {
if (!this.props.isAdmin) return false;
if (this.state.showPanel) {
return (
<div
className="visible"
id="admin-panel"
>
return (
<div
className={classNames(
'admin-panel', this.props.className, {
hidden: !this.state.showPanel
}
)}
>
{this.state.showPanel ? (
<React.Fragment>
<span
className="toggle"
onClick={this.handleToggleVisibility}
>
x
</span>
<div className="admin-header">
<h3>Admin Panel</h3>
</div>
<div className="admin-content">
{this.props.children}
</div>
</React.Fragment>
) : (
<span
className="toggle"
onClick={this.handleToggleVisibility}
>
x
&gt;
</span>
<div className="admin-header">
<h3>Admin Panel</h3>
</div>
<div className="admin-content">
<dl>
{this.props.children}
<dt>Page Cache</dt>
<dd>
<ul className="cache-list">
<li>
<form
action="/scratch_admin/page/clear-anon-cache/"
method="post"
>
<input
name="path"
type="hidden"
value="/"
/>
<div className="button-row">
<span>For anonymous users:</span>
<Button type="submit">
<span>Clear</span>
</Button>
</div>
</form>
</li>
</ul>
</dd>
</dl>
</div>
</div>
);
}
return (
<div
className="hidden"
id="admin-panel"
>
<span
className="toggle"
onClick={this.handleToggleVisibility}
>
&gt;
</span>
)}
</div>
);
}
......@@ -88,6 +60,7 @@ class AdminPanel extends React.Component {
AdminPanel.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
isAdmin: PropTypes.bool
};
......
@import "../../colors";
#admin-panel {
.admin-panel {
position: fixed;
top: 0;
left: 0;
......@@ -8,17 +8,12 @@
border: 1px solid $ui-gray;
box-shadow: 0 2px 5px $box-shadow-gray;
background-color: $ui-gray;
width: 230px;
padding: 1rem;
height: 100%;
overflow: scroll;
text-shadow: none;
&.visible {
width: 20%;
min-width: 180px;
max-width: 230px;
}
&.hidden {
width: 10px;
}
......@@ -28,33 +23,6 @@
cursor: pointer;
}
.admin-content {
dl {
list-style: none;
dt {
margin: 2rem 0 1rem 0;
border-bottom: 1px solid $ui-dark-gray;
font-size: large;
font-weight: 700;
}
dd {
margin-left: 0;
}
}
ul {
padding: 0;
li {
margin: 0;
list-style: none;
}
}
}
.button-row {
display: flex;
font-size: small;
......
......@@ -11,6 +11,7 @@ const classNames = require('classnames');
const GUI = require('scratch-gui').default;
const IntlGUI = injectIntl(GUI);
const AdminPanel = require('../../components/adminpanel/adminpanel.jsx');
const decorateText = require('../../lib/decorate-text.jsx');
const FlexRow = require('../../components/flex-row/flex-row.jsx');
const Button = require('../../components/forms/button.jsx');
......@@ -45,6 +46,7 @@ const onKeyPress = e => {
const PreviewPresentation = ({
addToStudioOpen,
adminModalOpen,
assetHost,
backpackHost,
canAddToStudio,
......@@ -160,6 +162,18 @@ const PreviewPresentation = ({
return (
<div className="preview">
<AdminPanel
className={classNames('project-admin-panel', {
'modal-open': adminModalOpen
})}
>
<iframe
className={classNames('admin-iframe', {
'modal-open': adminModalOpen
})}
src={`/scratch2/${projectId}`}
/>
</AdminPanel>
{ projectInfo && projectInfo.author && projectInfo.author.id && (
<React.Fragment>
{banner}
......
......@@ -35,6 +35,21 @@ $stage-width: 480px;
}
}
.admin-iframe {
position: absolute;
width: 252px;
height: 100%;
z-index: 100;
top: 0;
left: 0;
}
.admin-iframe.modal-open,
.project-admin-panel.modal-open {
width: 100%
}
.project-title {
font-size: 1.75rem;
font-weight: 500;
......
......@@ -45,6 +45,7 @@ class Preview extends React.Component {
'handleFavoriteToggle',
'handleLoadMore',
'handleLoveToggle',
'handleMessage',
'handlePopState',
'handleReportClick',
'handleReportClose',
......@@ -79,6 +80,7 @@ class Preview extends React.Component {
this.state = {
addToStudioOpen: false,
adminModalOpen: false,
extensions: [],
favoriteCount: 0,
justShared: false,
......@@ -91,10 +93,12 @@ class Preview extends React.Component {
reportOpen: false,
singleCommentId: singleCommentId
};
this.addEventListeners();
/* In the beginning, if user is on mobile and landscape, go to fullscreen */
this.setScreenFromOrientation();
}
componentDidMount () {
this.addEventListeners();
}
componentDidUpdate (prevProps, prevState) {
if (this.state.projectId > 0 &&
((this.props.sessionStatus !== prevProps.sessionStatus &&
......@@ -138,10 +142,12 @@ class Preview extends React.Component {
addEventListeners () {
window.addEventListener('popstate', this.handlePopState);
window.addEventListener('orientationchange', this.setScreenFromOrientation);
window.addEventListener('message', this.handleMessage);
}
removeEventListeners () {
window.removeEventListener('popstate', this.handlePopState);
window.removeEventListener('orientationchange', this.setScreenFromOrientation);
window.removeEventListener('message', this.handleMessage);
}
fetchCommunityData () {
if (this.props.userPresent) {
......@@ -257,6 +263,18 @@ class Preview extends React.Component {
handleDeleteComment (id, topLevelCommentId) {
this.props.handleDeleteComment(this.state.projectId, id, topLevelCommentId, this.props.user.token);
}
handleMessage (messageEvent) {
if (messageEvent.data === 'showDialog') {
this.setState({
adminModalOpen: true
});
}
if (messageEvent.data === 'hideDialog') {
this.setState({
adminModalOpen: false
});
}
}
handleReportComment (id, topLevelCommentId) {
this.props.handleReportComment(this.state.projectId, id, topLevelCommentId, this.props.user.token);
}
......@@ -463,6 +481,7 @@ class Preview extends React.Component {
<Page>
<PreviewPresentation
addToStudioOpen={this.state.addToStudioOpen}
adminModalOpen={this.state.adminModalOpen}
assetHost={this.props.assetHost}
backpackHost={this.props.backpackHost}
canAddToStudio={this.props.canAddToStudio}
......
......@@ -529,41 +529,66 @@ class SplashPresentation extends React.Component { // eslint-disable-line react/
>
{featured}
{this.props.isAdmin ? [
<AdminPanel key="admin-panel">
<dt>Tools</dt>
<dd>
<ul>
<li>
<a href="/scratch_admin/tickets">Ticket Queue</a>
</li>
<li>
<a href="/scratch_admin/ip-search/">IP Search</a>
</li>
<li>
<a href="/scratch_admin/email-search/">Email Search</a>
</li>
</ul>
</dd>
<dt>Homepage Cache</dt>
<dd>
<ul className="cache-list">
<li>
<div className="button-row">
<span>Refresh row data:</span>
<Button
className={this.props.refreshCacheStatus.status}
disabled={this.props.refreshCacheStatus.disabled}
onClick={this.props.onRefreshHomepageCache}
{this.props.isAdmin && (
<AdminPanel className="splash-admin-panel">
<dl>
<dt>Tools</dt>
<dd>
<ul>
<li>
<a href="/scratch_admin/tickets">Ticket Queue</a>
</li>
<li>
<a href="/scratch_admin/ip-search/">IP Search</a>
</li>
<li>
<a href="/scratch_admin/email-search/">Email Search</a>
</li>
</ul>
</dd>
<dt>Homepage Cache</dt>
<dd>
<ul className="cache-list">
<li>
<div className="button-row">
<span>Refresh row data:</span>
<Button
className={this.props.refreshCacheStatus.status}
disabled={this.props.refreshCacheStatus.disabled}
onClick={this.props.onRefreshHomepageCache}
>
<span>{this.props.refreshCacheStatus.content}</span>
</Button>
</div>
</li>
</ul>
</dd>
<dt>Page Cache</dt>
<dd>
<ul className="cache-list">
<li>
<form
action="/scratch_admin/page/clear-anon-cache/"
method="post"
>
<span>{this.props.refreshCacheStatus.content}</span>
</Button>
</div>
</li>
</ul>
</dd>
<input
name="path"
type="hidden"
value="/"
/>
<div className="button-row">
<span>For anonymous users:</span>
<Button type="submit">
<span>Clear</span>
</Button>
</div>
</form>
</li>
</ul>
</dd>
</dl>
</AdminPanel>
] : []}
)}
</div>
</div>
);
......
......@@ -47,6 +47,33 @@
}
}
.splash-admin-panel {
dl {
list-style: none;
dt {
margin: 2rem 0 1rem 0;
border-bottom: 1px solid $ui-dark-gray;
font-size: large;
font-weight: 700;
}
dd {
margin-left: 0;
}
}
ul {
padding: 0;
li {
margin: 0;
list-style: none;
}
}
}
.modal-content.mod-confirmation {
width: 31.25rem;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment