Skip to content
Snippets Groups Projects
Unverified Commit 1c712615 authored by Benjamin Wheeler's avatar Benjamin Wheeler Committed by GitHub
Browse files

Merge pull request #3364 from benjiwheeler/capabilities

use can__ boolean properties to explicitly set user capabilities
parents a9f1e2ee 38fa3b5e
No related branches found
No related tags found
No related merge requests found
...@@ -61,6 +61,11 @@ const GUIComponent = props => { ...@@ -61,6 +61,11 @@ const GUIComponent = props => {
backpackOptions, backpackOptions,
blocksTabVisible, blocksTabVisible,
cardsVisible, cardsVisible,
canCreateNew,
canRemix,
canSave,
canSaveAsCopy,
canShare,
children, children,
costumeLibraryVisible, costumeLibraryVisible,
costumesTabVisible, costumesTabVisible,
...@@ -164,6 +169,11 @@ const GUIComponent = props => { ...@@ -164,6 +169,11 @@ const GUIComponent = props => {
) : null} ) : null}
<MenuBar <MenuBar
accountNavOpen={accountNavOpen} accountNavOpen={accountNavOpen}
canCreateNew={canCreateNew}
canRemix={canRemix}
canSave={canSave}
canSaveAsCopy={canSaveAsCopy}
canShare={canShare}
className={styles.menuBarPosition} className={styles.menuBarPosition}
enableCommunity={enableCommunity} enableCommunity={enableCommunity}
renderLogin={renderLogin} renderLogin={renderLogin}
...@@ -305,6 +315,11 @@ GUIComponent.propTypes = { ...@@ -305,6 +315,11 @@ GUIComponent.propTypes = {
}), }),
basePath: PropTypes.string, basePath: PropTypes.string,
blocksTabVisible: PropTypes.bool, blocksTabVisible: PropTypes.bool,
canCreateNew: PropTypes.bool,
canRemix: PropTypes.bool,
canSave: PropTypes.bool,
canSaveAsCopy: PropTypes.bool,
canShare: PropTypes.bool,
cardsVisible: PropTypes.bool, cardsVisible: PropTypes.bool,
children: PropTypes.node, children: PropTypes.node,
costumeLibraryVisible: PropTypes.bool, costumeLibraryVisible: PropTypes.bool,
...@@ -344,6 +359,11 @@ GUIComponent.defaultProps = { ...@@ -344,6 +359,11 @@ GUIComponent.defaultProps = {
visible: false visible: false
}, },
basePath: './', basePath: './',
canCreateNew: true,
canRemix: false,
canSave: false,
canSaveAsCopy: false,
canShare: false,
stageSizeMode: STAGE_SIZE_MODES.large stageSizeMode: STAGE_SIZE_MODES.large
}; };
......
...@@ -145,12 +145,11 @@ class MenuBar extends React.Component { ...@@ -145,12 +145,11 @@ class MenuBar extends React.Component {
} }
} }
handleClickNew () { handleClickNew () {
const canSave = this.props.canUpdateProject; // logged in
// if canSave===true, it's safe to replace current project, since we will auto-save first // if canSave===true, it's safe to replace current project, since we will auto-save first
const readyToReplaceProject = const readyToReplaceProject =
canSave || confirm('Replace contents of the current project?'); // eslint-disable-line no-alert this.props.canSave || confirm('Replace contents of the current project?'); // eslint-disable-line no-alert
if (readyToReplaceProject) { if (readyToReplaceProject) {
this.props.onClickNew(canSave); this.props.onClickNew(this.props.canSave);
} }
} }
handleClickSave () { handleClickSave () {
...@@ -210,6 +209,13 @@ class MenuBar extends React.Component { ...@@ -210,6 +209,13 @@ class MenuBar extends React.Component {
id="gui.menuBar.saveNow" id="gui.menuBar.saveNow"
/> />
); );
const saveAsCopyMessage = (
<FormattedMessage
defaultMessage="Save as a copy"
description="Menu bar item for saving as a copy"
id="gui.menuBar.saveAsCopy"
/>
);
const newProjectMessage = ( const newProjectMessage = (
<FormattedMessage <FormattedMessage
defaultMessage="New" defaultMessage="New"
...@@ -285,24 +291,23 @@ class MenuBar extends React.Component { ...@@ -285,24 +291,23 @@ class MenuBar extends React.Component {
place={this.props.isRtl ? 'left' : 'right'} place={this.props.isRtl ? 'left' : 'right'}
onRequestClose={this.props.onRequestCloseFile} onRequestClose={this.props.onRequestCloseFile}
> >
{/* for now, only enable New when there is no session */} {this.props.canCreateNew ? (
{this.props.sessionExists ? (
<MenuItemTooltip
id="new"
isRtl={this.props.isRtl}
>
<MenuItem>{newProjectMessage}</MenuItem>
</MenuItemTooltip>
) : (
<MenuItem <MenuItem
isRtl={this.props.isRtl} isRtl={this.props.isRtl}
onClick={this.handleClickNew} onClick={this.handleClickNew}
> >
{newProjectMessage} {newProjectMessage}
</MenuItem> </MenuItem>
) : (
<MenuItemTooltip
id="new"
isRtl={this.props.isRtl}
>
<MenuItem>{newProjectMessage}</MenuItem>
</MenuItemTooltip>
)} )}
<MenuSection> <MenuSection>
{this.props.canUpdateProject ? ( {this.props.canSave ? (
<MenuItem onClick={this.handleClickSave}> <MenuItem onClick={this.handleClickSave}>
{saveNowMessage} {saveNowMessage}
</MenuItem> </MenuItem>
...@@ -314,18 +319,18 @@ class MenuBar extends React.Component { ...@@ -314,18 +319,18 @@ class MenuBar extends React.Component {
<MenuItem>{saveNowMessage}</MenuItem> <MenuItem>{saveNowMessage}</MenuItem>
</MenuItemTooltip> </MenuItemTooltip>
)} )}
<MenuItemTooltip {this.props.canSaveAsCopy ? (
id="copy" <MenuItem onClick={this.handleClickSaveAsCopy}>
isRtl={this.props.isRtl} {saveAsCopyMessage}
>
<MenuItem>
<FormattedMessage
defaultMessage="Save as a copy"
description="Menu bar item for saving as a copy"
id="gui.menuBar.saveAsCopy"
/>
</MenuItem> </MenuItem>
</MenuItemTooltip> ) : (
<MenuItemTooltip
id="copy"
isRtl={this.props.isRtl}
>
<MenuItem>{saveAsCopyMessage}</MenuItem>
</MenuItemTooltip>
)}
</MenuSection> </MenuSection>
<MenuSection> <MenuSection>
<SBFileUploader> <SBFileUploader>
...@@ -432,7 +437,7 @@ class MenuBar extends React.Component { ...@@ -432,7 +437,7 @@ class MenuBar extends React.Component {
</MenuBarItemTooltip> </MenuBarItemTooltip>
</div> </div>
<div className={classNames(styles.menuBarItem)}> <div className={classNames(styles.menuBarItem)}>
{this.props.onShare ? shareButton : ( {this.props.canShare ? shareButton : (
<MenuBarItemTooltip id="share-button"> <MenuBarItemTooltip id="share-button">
{shareButton} {shareButton}
</MenuBarItemTooltip> </MenuBarItemTooltip>
...@@ -615,7 +620,11 @@ class MenuBar extends React.Component { ...@@ -615,7 +620,11 @@ class MenuBar extends React.Component {
MenuBar.propTypes = { MenuBar.propTypes = {
accountMenuOpen: PropTypes.bool, accountMenuOpen: PropTypes.bool,
canUpdateProject: PropTypes.bool, canCreateNew: PropTypes.bool,
canRemix: PropTypes.bool,
canSave: PropTypes.bool,
canSaveAsCopy: PropTypes.bool,
canShare: PropTypes.bool,
className: PropTypes.string, className: PropTypes.string,
editMenuOpen: PropTypes.bool, editMenuOpen: PropTypes.bool,
enableCommunity: PropTypes.bool, enableCommunity: PropTypes.bool,
...@@ -651,12 +660,15 @@ MenuBar.propTypes = { ...@@ -651,12 +660,15 @@ MenuBar.propTypes = {
username: PropTypes.string username: PropTypes.string
}; };
MenuBar.defaultProps = {
onShare: () => {}
};
const mapStateToProps = state => { const mapStateToProps = state => {
const loadingState = state.scratchGui.projectState.loadingState; const loadingState = state.scratchGui.projectState.loadingState;
const user = state.session && state.session.session && state.session.session.user; const user = state.session && state.session.session && state.session.session.user;
return { return {
accountMenuOpen: accountMenuOpen(state), accountMenuOpen: accountMenuOpen(state),
canUpdateProject: typeof user !== 'undefined',
fileMenuOpen: fileMenuOpen(state), fileMenuOpen: fileMenuOpen(state),
editMenuOpen: editMenuOpen(state), editMenuOpen: editMenuOpen(state),
isRtl: state.locales.isRtl, isRtl: state.locales.isRtl,
......
...@@ -37,5 +37,9 @@ export default appTarget => { ...@@ -37,5 +37,9 @@ export default appTarget => {
window.onbeforeunload = () => true; window.onbeforeunload = () => true;
} }
ReactDOM.render(<WrappedGui backpackOptions={backpackOptions} />, appTarget); ReactDOM.render(
<WrappedGui
backpackOptions={backpackOptions}
/>,
appTarget);
}; };
import path from 'path';
import SeleniumHelper from '../helpers/selenium-helper';
const {
clickXpath,
findByXpath,
getDriver,
loadUri
} = new SeleniumHelper();
const uri = path.resolve(__dirname, '../../build/index.html');
let driver;
describe('Menu bar settings', () => {
beforeAll(() => {
driver = getDriver();
});
afterAll(async () => {
await driver.quit();
});
test('File->New should be enabled', async () => {
await loadUri(uri);
await clickXpath('//button[@title="Try It"]');
await clickXpath(
'//div[contains(@class, "menu-bar_menu-bar-item") and ' +
'contains(@class, "menu-bar_hoverable")][span[text()="File"]]'
);
await findByXpath('//*[li[span[text()="New"]] and not(@data-tip="tooltip")]');
});
test('File->Save now should NOT be enabled', async () => {
await loadUri(uri);
await clickXpath('//button[@title="Try It"]');
await clickXpath(
'//div[contains(@class, "menu-bar_menu-bar-item") and ' +
'contains(@class, "menu-bar_hoverable")][span[text()="File"]]'
);
await findByXpath('//*[li[span[text()="Save now"]] and @data-tip="tooltip"]');
});
test('File->Save as a copy should NOT be enabled', async () => {
await loadUri(uri);
await clickXpath('//button[@title="Try It"]');
await clickXpath(
'//div[contains(@class, "menu-bar_menu-bar-item") and ' +
'contains(@class, "menu-bar_hoverable")][span[text()="File"]]'
);
await findByXpath('//*[li[span[text()="Save as a copy"]] and @data-tip="tooltip"]');
});
test('Share button should NOT be enabled', async () => {
await loadUri(uri);
await clickXpath('//button[@title="Try It"]');
await findByXpath('//div[span[div[span[text()="Share"]]] and @data-tip="tooltip"]');
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment