setup blueprint course sidebar
refs MC-145 test plan: - navigate to a blueprint course - note the blue line / bar and button on the right side - click the button - a tray sidebar should open from the right side of the screen - click the close button on the tray - note that the tray closes - note that the sidebar shows up on every page in a blueprint course - note that the sidebar does not show up in non-blueprint course pages or any other pages throughout canvas Change-Id: I4dcadb82e32bf2af01b25ed3b6167ecffc594dd8 Reviewed-on: https://gerrit.instructure.com/107373 Reviewed-by: Ed Schiebel <eschiebel@instructure.com> Tested-by: Jenkins QA-Review: Heath Hales <hhales@instructure.com> Product-Review: Felix Milea-Ciobanu <fmileaciobanu@instructure.com>
This commit is contained in:
parent
62c2cb5dfc
commit
0d7898fe11
|
@ -269,6 +269,11 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
helper_method :set_master_course_js_env_data
|
||||
|
||||
def should_load_master_course_sidebar?
|
||||
@context && @context.is_a?(Course) && MasterCourses::MasterTemplate.is_master_course?(@context) && @context.grants_right?(@current_user, :manage)
|
||||
end
|
||||
helper_method :should_load_master_course_sidebar?
|
||||
|
||||
def editing_restricted?(content, edit_type=:any)
|
||||
return false unless master_courses? && content.respond_to?(:editing_restricted?)
|
||||
content.editing_restricted?(edit_type)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import App from 'jsx/course_blueprint_settings/sidebar'
|
||||
|
||||
const wrapper = document.getElementById('wrapper')
|
||||
const root = document.createElement('div')
|
||||
root.className = 'bcs__root'
|
||||
wrapper.appendChild(root)
|
||||
|
||||
const app = new App(root)
|
||||
app.render()
|
|
@ -0,0 +1,60 @@
|
|||
import I18n from 'i18n!blueprint_course_sidebar'
|
||||
import React, { Component } from 'react'
|
||||
import Tray from 'instructure-ui/lib/components/Tray'
|
||||
import Button from 'instructure-ui/lib/components/Button'
|
||||
import Typography from 'instructure-ui/lib/components/Typography'
|
||||
import Heading from 'instructure-ui/lib/components/Heading'
|
||||
import IconCopyLine from 'instructure-icons/react/Line/IconCopyLine'
|
||||
import IconXSolid from 'instructure-icons/react/Solid/IconXSolid'
|
||||
|
||||
export default class BlueprintCourseSidebar extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
isOpen: false,
|
||||
}
|
||||
}
|
||||
|
||||
handleOpen = () => {
|
||||
this.setState({ isOpen: true })
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({ isOpen: false })
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className="bcs__wrapper">
|
||||
<div className="bcs__trigger">
|
||||
<Button variant="icon" onClick={this.handleOpen}>
|
||||
<Typography color="primary-inverse" size="large">
|
||||
<IconCopyLine title={I18n.t('Open sidebar')} />
|
||||
</Typography>
|
||||
</Button>
|
||||
</div>
|
||||
<Tray
|
||||
label={I18n.t('Blueprint Settings')}
|
||||
isDismissable={false}
|
||||
isOpen={this.state.isOpen}
|
||||
placement="right"
|
||||
>
|
||||
<div className="bcs__content">
|
||||
<header className="bcs__header">
|
||||
<Heading color="primary-inverse" level="h3">
|
||||
<div className="bcs__close-wrapper">
|
||||
<Button variant="icon" onClick={this.handleClose} ref={(c) => { this.closeBtn = c }}>
|
||||
<Typography color="primary-inverse" size="small">
|
||||
<IconXSolid title={I18n.t('Close sidebar')} />
|
||||
</Typography>
|
||||
</Button>
|
||||
</div>
|
||||
<IconCopyLine /> {I18n.t('Blueprint')}
|
||||
</Heading>
|
||||
</header>
|
||||
</div>
|
||||
</Tray>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import Sidebar from './components/BlueprintCourseSidebar'
|
||||
|
||||
export default class BlueprintCourseSidebar {
|
||||
|
||||
constructor (root) {
|
||||
this.root = root
|
||||
}
|
||||
|
||||
render () {
|
||||
ReactDOM.render(
|
||||
<Sidebar />,
|
||||
this.root)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
@import "base/environment";
|
||||
|
||||
.bcs__trigger {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 10px 3px;
|
||||
border-bottom-left-radius: 5px;
|
||||
background-color: $ic-brand-primary;
|
||||
box-shadow: -1px 1px 2px 0 rgba(0,0,0,.2);
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 58px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 8px;
|
||||
background-color: $ic-brand-primary;
|
||||
box-shadow: -1px 0 1px 0 rgba(0,0,0,.2)
|
||||
}
|
||||
}
|
||||
|
||||
.bcs__content {
|
||||
width: 270px;
|
||||
}
|
||||
|
||||
.bcs__header {
|
||||
background: $ic-brand-primary;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 1.2em 0;
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .2)
|
||||
}
|
||||
|
||||
.bcs__close-wrapper {
|
||||
position: absolute;
|
||||
top: 0.5em;
|
||||
left: 0.5em;
|
||||
}
|
|
@ -56,6 +56,10 @@
|
|||
|
||||
content_for :head, include_common_stylesheets
|
||||
|
||||
if should_load_master_course_sidebar?
|
||||
js_bundle :blueprint_course_sidebar
|
||||
css_bundle :blueprint_course_sidebar
|
||||
end
|
||||
-%>
|
||||
<%= render :partial => "layouts/head" %>
|
||||
<body class="<%= (@body_classes).uniq.join(" ") %>">
|
||||
|
@ -198,7 +202,6 @@
|
|||
<div class="NewUserTutorialTray__Container"></div>
|
||||
<% end %>
|
||||
<%= render :partial => 'layouts/foot', :locals => { :include_common_bundle => true } %>
|
||||
|
||||
</div> <!-- #application -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import React from 'react'
|
||||
import * as enzyme from 'enzyme'
|
||||
import BlueprintCourseSidebar from 'jsx/course_blueprint_settings/components/BlueprintCourseSidebar'
|
||||
|
||||
QUnit.module('BlueprintCourseSidebar component')
|
||||
|
||||
const defaultProps = () => ({
|
||||
|
||||
})
|
||||
|
||||
test('renders the BlueprintCourseSidebar component', () => {
|
||||
const tree = enzyme.shallow(<BlueprintCourseSidebar {...defaultProps()} />)
|
||||
const node = tree.find('.bcs__wrapper')
|
||||
ok(node.exists())
|
||||
})
|
||||
|
||||
test('clicking open button sets isOpen to true', () => {
|
||||
const props = defaultProps()
|
||||
const tree = enzyme.mount(<BlueprintCourseSidebar {...props} />)
|
||||
|
||||
const button = tree.find('.bcs__trigger button')
|
||||
button.at(0).simulate('click')
|
||||
|
||||
const instance = tree.instance()
|
||||
equal(instance.state.isOpen, true)
|
||||
})
|
||||
|
||||
test('clicking close button sets isOpen to false', () => {
|
||||
const props = defaultProps()
|
||||
const tree = enzyme.mount(<BlueprintCourseSidebar {...props} />)
|
||||
|
||||
const instance = tree.instance()
|
||||
instance.setState({ isOpen: true })
|
||||
|
||||
const closeBtn = instance.closeBtn
|
||||
const btnWrapper = new enzyme.ReactWrapper(closeBtn, closeBtn)
|
||||
btnWrapper.at(0).simulate('click')
|
||||
|
||||
equal(instance.state.isOpen, false)
|
||||
})
|
Loading…
Reference in New Issue