show spinner and enable assignment muting

fixes CNVS-22027

test plan
  - mute an assignment
  - ensure menu item displays 'Mute Assignment'
  - ensure the 'muted assignment' icon shows up
    next to the assignment name
  - click the menu again
  - ensure the menu item displays 'Unmute Assignment'
  - click unmute and verify the mute assignment
    icon has been removed.

  - verify a spinner displays as the gradebook
    is loading

Change-Id: I80b4701ceb6905c9e0c48a9b5ddc6fc9975a7124
Reviewed-on: https://gerrit.instructure.com/63177
Reviewed-by: Spencer Olson <solson@instructure.com>
Tested-by: Jenkins
QA-Review: Jason Carter <jcarter@instructure.com>
Product-Review: Dylan Ross <dross@instructure.com>
This commit is contained in:
Dylan Ross 2015-08-28 16:05:11 -06:00
parent 51552fa9ec
commit fa98c30c00
8 changed files with 181 additions and 18 deletions

View File

@ -9,7 +9,10 @@ define [
], (I18n, $, mute_dialog_template) ->
class AssignmentMuter
constructor: (@$link, @assignment, @url, @setter) ->
constructor: (@$link, @assignment, @url, @setter, @options) ->
if @options?.openDialogInstantly
if @assignment.muted then @confirmUnmute() else @showDialog()
else
@$link = $(@$link)
@updateLink()
@$link.click (event) =>
@ -37,7 +40,7 @@ define [
@setter @assignment, 'muted', serverResponse.assignment.muted
else
@assignment.muted = serverResponse.assignment.muted
@updateLink()
@updateLink() unless @options?.openDialogInstantly
@$dialog.dialog('close')
$.publish('assignment_muting_toggled', [@assignment])

View File

@ -4,7 +4,8 @@ define([
], function (Reflux, $) {
var AssignmentGroupsActions = Reflux.createActions({
load: { asyncResult: true },
replaceAssignmentGroups: { asyncResult: false }
replaceAssignmentGroups: { asyncResult: false },
replaceAssignment: {asyncResult: false}
});
AssignmentGroupsActions.load.listen(function() {

View File

@ -70,10 +70,14 @@ define([
label = this.props.label;
if (assignment) {
var paddingAdjustment = GradebookConstants.DEFAULT_LAYOUTS.headers.paddingAdjustment;
var paddingAdjustment = GradebookConstants.DEFAULT_LAYOUTS.headers.paddingAdjustment,
className = "assignment-name" + ((assignment.muted) ? ' muted' : '');
return (
<div className='gradebook-label' style={{width: this.props.width - paddingAdjustment}}>
<a title={label} href={assignment.html_url}>
<a className={className}
title={label}
href={assignment.html_url}>
{ this.shouldDisplayAssignmentWarning() && <i ref="icon" title={this.getTitle()} className="icon-warning"></i> }
{label}
</a>

View File

@ -5,8 +5,9 @@ define([
'i18n!gradebook',
'jsx/gradebook/grid/components/dropdown_components/headerDropdownOption',
'jsx/gradebook/grid/constants',
'jsx/gradebook/grid/components/dropdown_components/setDefaultGradeOption'
], function (React, _, I18n, HeaderDropdownOption, GradebookConstants, SetDefaultGradeOption) {
'jsx/gradebook/grid/components/dropdown_components/setDefaultGradeOption',
'jsx/gradebook/grid/components/dropdown_components/muteAssignmentOption'
], function (React, _, I18n, HeaderDropdownOption, GradebookConstants, SetDefaultGradeOption, MuteAssignmentOption) {
var AssignmentHeaderDropdownOptions = React.createClass({
@ -46,9 +47,6 @@ define([
dropdownOptions.splice(1, 0, speedGraderOption);
}
muteAssignmentOption = { title: I18n.t('Mute Assignment'), action: 'toggleMuting' };
if (assignment.muted) muteAssignmentOption.title = I18n.t('Unmute Assignment');
dropdownOptions.push(muteAssignmentOption);
return dropdownOptions;
},
@ -83,6 +81,10 @@ define([
}
})
}
<MuteAssignmentOption
key={'muteAssignment-' + assignment.id}
assignment={assignment}/>
</ul>
);
}

View File

@ -0,0 +1,62 @@
/** @jsx React.DOM */
define([
'react',
'jquery',
'bower/reflux/dist/reflux',
'underscore',
'i18n!gradebook',
'jsx/gradebook/grid/components/dropdown_components/headerDropdownOption',
'compiled/AssignmentMuter',
'jsx/gradebook/grid/constants',
'jsx/gradebook/grid/actions/assignmentGroupsActions'
], function (
React,
$,
Reflux,
_,
I18n,
HeaderDropdownOption,
AssignmentMuter,
GradebookConstants,
AssignmentGroupsActions
) {
const MUTE = I18n.t('Mute Assignment'),
UNMUTE = I18n.t('Unmute Assignment'),
MUTING_EVENT = 'assignment_muting_toggled';
var MuteAssignmentOption = React.createClass({
propTypes: {
assignment: React.PropTypes.object.isRequired
},
openDialog() {
var assignment = this.props.assignment,
contextUrl = GradebookConstants.context_url,
options = {openDialogInstantly: true},
id = assignment.id,
url = contextUrl + "/assignments/" + id + "/mute";
new AssignmentMuter(null, assignment, url, null, options);
$.subscribe(MUTING_EVENT, (assignment) => {
AssignmentGroupsActions.replaceAssignment(assignment);
$.unsubscribe(MUTING_EVENT);
});
},
render() {
var title = (this.props.assignment.muted) ? UNMUTE : MUTE;
return(
<HeaderDropdownOption
handleClick={this.openDialog}
key={'muteAssignment' + this.props.assignment.id}
title={title}/>
);
}
});
return MuteAssignmentOption;
});

View File

@ -21,7 +21,8 @@ define([
'../actions/submissionsActions',
'../stores/keyboardNavigationStore',
'../actions/keyboardNavigationActions',
'../helpers/columnArranger'
'../helpers/columnArranger',
'vendor/spin'
], function (
React,
FixedDataTable,
@ -44,12 +45,14 @@ define([
SubmissionsActions,
KeyboardNavigationStore,
KeyboardNavigationActions,
ColumnArranger
ColumnArranger,
Spinner
){
var Table = FixedDataTable.Table,
Column = FixedDataTable.Column,
isColumnResizing = false;
isColumnResizing = false,
spinner;
var Gradebook = React.createClass({
mixins: [
@ -215,6 +218,15 @@ define([
|| this.state.submissions.error;
},
renderSpinner() {
spinner = new Spinner();
$(spinner.spin().el).css({
opacity: 0.5,
top: '55px',
left: '50%'
}).addClass('use-css-transitions-for-show-hide').appendTo('#main');
},
renderNotesColumn() {
if (!this.state.toolbarOptions.hideNotesColumn) {
return this.renderColumn(I18n.t('Notes'), GradebookConstants.NOTES_COLUMN_ID);
@ -242,6 +254,9 @@ define([
}
else if (this.state.submissions.data && this.state.assignmentGroups.data
&& this.state.studentEnrollments.data) {
$(spinner.el).remove();
return (
<div id="react-gradebook-canvas"
onKeyDown={this.handleKeyDown}
@ -260,7 +275,11 @@ define([
</div>
);
} else {
return (<h2>{I18n.t('Gradebook loading...replace this with a spinner?')}</h2>);
if (!spinner) {
this.renderSpinner();
}
return <div/>;
}
}
});

View File

@ -44,6 +44,16 @@ define([
});
},
onReplaceAssignment(updatedAssignment) {
var assignmentGroups = this.assignmentGroups.data,
assignments = _.flatten(_.pluck(assignmentGroups, 'assignments')),
assignment = _.find(assignments, assignment => updatedAssignment.id === assignment.id);
assignment.muted = updatedAssignment.muted;
this.assignmentGroups.data = assignmentGroups;
this.trigger(this.assignmentGroups);
},
formatAssignmentGroups(groups) {
return _.map(groups, (group) => {
group.assignments = _.map(

View File

@ -0,0 +1,62 @@
define [
'jsx/gradebook/grid/components/dropdown_components/muteAssignmentOption',
'compiled/gradebook2/SetDefaultGradeDialog'
'jquery'
], (SetDefaultGradeOption, SetDefaultGradeDialog, $) ->
wrapper = document.getElementById('fixtures')
defaultProps = ->
assignment: { id: '1', muted: false }
renderComponent = (props) ->
props = props || defaultProps()
componentFactory = React.createFactory(SetDefaultGradeOption)
React.render(componentFactory(props), wrapper)
module 'MuteAssignmentOption',
setup: ->
$('.ui-dialog').remove()
@component = renderComponent()
teardown: ->
$('.ui-dialog').remove()
React.unmountComponentAtNode wrapper
test 'mounts properly', ->
ok renderComponent().isMounted()
test 'displays "Mute Assignment" when assignment is unmuted', ->
component = renderComponent()
text = component.getDOMNode().children[0].innerHTML
deepEqual(text, 'Mute Assignment')
test 'displays "Unmute Assignment" when assignment is muted', ->
props = {assignment: {id: '1', muted: true}}
component = renderComponent(props)
text = component.getDOMNode().children[0].innerHTML
deepEqual(text, 'Unmute Assignment')
test 'displays dialog on click', ->
component = renderComponent()
equal($('.ui-dialog').size(), 0)
component.openDialog()
equal($('.ui-dialog').size(), 1)
test 'mute dialog displays when assignment is unmuted', ->
component = renderComponent()
component.openDialog()
title = $('.ui-dialog-title')[0].innerHTML
equal(title, 'Mute Assignment')
test 'unmute dialog displays when assignment is muted', ->
props = {assignment: {id: '1', muted: true}}
component = renderComponent(props)
component.openDialog()
title = $('.ui-dialog-title')[0].innerHTML
equal(title, 'Unmute Assignment')
test '$subscribe to assignment_muting_toggled event after dialog is opened', ->
subscribeStub = @stub($, 'subscribe')
component = renderComponent()
component.openDialog()
ok subscribeStub.calledWith('assignment_muting_toggled')