Skip to content

Commit

Permalink
add moduleSequenceFooter to a2 student page
Browse files Browse the repository at this point in the history
this also fixes some RTL bugs from our inline styling

demo: https://instructure.slack.com/files/U0296D4BU/FQJSMRXHR/screencast_showing_modulesequencefooter_in_a2_student_view.mov

Test Plan:
* as a teacher create a course with a module that has a few items
  (discussions, pages, lit tools, assignments, quizzes, etc) before
  and a few items after a given assignment
* now as a student go navigate to the first of those items
* use the “next” an “previous” buttons down in the moduleSequenceFooter
  to go back and forward through the items in the module
* when you get to this assignment the “prev” and “next” buttons should
  show up just like on all the page types
* clicking the “previous” and “next” buttons should work
* the “submit” button to submit your assignment should no longer float
  on the bottom of the page so it doesn’t interfere with the
  moduleSequenceFooter “previous” and “next” buttons

Test RTL:
* either set your language to arabic or hebrew or turn on the
  “force RTL even for non-RTL” feature flag
* verify that the buttons on the bottom of the screen flip to the
  opposite side of the screen

fixes: KNO-161
flag=assignments_2_student

Change-Id: I5f9e070f1b69aeadf4d3e1faca0d60fae7097b46
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/218440
Tested-by: Service Cloud Jenkins <[email protected]>
Tested-by: Jenkins
QA-Review: Matthew Lemon <[email protected]>
Product-Review: Ryan Shaw <[email protected]>
Reviewed-by: Matthew Lemon <[email protected]>
  • Loading branch information
ryankshaw committed Nov 26, 2019
1 parent 275ef5d commit 3d0d134
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {IconDocumentLine, IconTextLine, IconTrashLine} from '@instructure/ui-ico
import LoadingIndicator from '../../../shared/LoadingIndicator'
import {ScreenReaderContent} from '@instructure/ui-a11y'
import {View} from '@instructure/ui-layout'
import {direction} from '../../../../shared/helpers/rtlHelper'

export default class TextEntry extends React.Component {
static propTypes = {
Expand Down Expand Up @@ -198,14 +199,8 @@ export default class TextEntry extends React.Component {
}

renderButtons() {
const buttonAlign = {
margin: '15px 0 0 0',
position: 'absolute',
right: '35px'
}

return (
<div style={buttonAlign}>
<div style={{textAlign: direction('right')}}>
<Button
data-testid="cancel-text-entry"
margin="0 xx-small 0 0"
Expand Down
5 changes: 5 additions & 0 deletions app/jsx/assignments_2/student/components/ContentTabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ function LoggedInContentTabs(props) {
setSelectedTabIndex(index)
}

const noRightLeftPadding = 'small none' // to make "submit" button edge line up with moduleSequenceFooter "next" button edge

return (
<div data-testid="assignment-2-student-content-tabs">
{props.submission.state === 'graded' || props.submission.state === 'submitted'
Expand All @@ -136,6 +138,7 @@ function LoggedInContentTabs(props) {
>
<Tabs.Panel
key="attempt-tab"
padding={noRightLeftPadding}
renderTitle={I18n.t('Attempt %{attempt}', {attempt: getCurrentAttempt(props.submission)})}
selected={selectedTabIndex === 0}
>
Expand All @@ -147,6 +150,7 @@ function LoggedInContentTabs(props) {
</Tabs.Panel>
<Tabs.Panel
key="comments-tab"
padding={noRightLeftPadding}
selected={selectedTabIndex === 1}
renderTitle={
<span>
Expand All @@ -166,6 +170,7 @@ function LoggedInContentTabs(props) {
{props.assignment.rubric && (
<Tabs.Panel
key="rubrics-tab"
padding={noRightLeftPadding}
renderTitle={I18n.t('Rubric')}
selected={selectedTabIndex === 2}
>
Expand Down
109 changes: 38 additions & 71 deletions app/jsx/assignments_2/student/components/SubmissionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import React, {Component} from 'react'
import {STUDENT_VIEW_QUERY, SUBMISSION_HISTORIES_QUERY} from '../graphqlData/Queries'
import StudentViewContext from './Context'
import {Submission} from '../graphqlData/Submission'
import theme from '@instructure/canvas-theme'
import {direction} from '../../../shared/helpers/rtlHelper'

export default class SubmissionManager extends Component {
static propTypes = {
Expand All @@ -56,7 +56,7 @@ export default class SubmissionManager extends Component {
})
}

getActiveSubmissionTypeFromProps = () => {
getActiveSubmissionTypeFromProps() {
if (this.props.assignment.submissionTypes.length > 1) {
return this.props.submission?.submissionDraft?.activeSubmissionType || null
} else {
Expand Down Expand Up @@ -135,8 +135,8 @@ export default class SubmissionManager extends Component {
})
}

submitToGraphql = async (submitMutation, submitVars) => {
await submitMutation({
submitToGraphql(submitMutation, submitVars) {
return submitMutation({
variables: {
assignmentLid: this.props.assignment._id,
submissionID: this.props.submission.id,
Expand All @@ -145,7 +145,7 @@ export default class SubmissionManager extends Component {
})
}

submitAssignment = async submitMutation => {
async submitAssignment(submitMutation) {
if (this.state.submittingAssignment || this.state.activeSubmissionType === null) {
return
}
Expand Down Expand Up @@ -228,7 +228,7 @@ export default class SubmissionManager extends Component {
)
}

handleDraftComplete = success => {
handleDraftComplete(success) {
this.updateUploadingFiles(false)

if (success) {
Expand All @@ -238,20 +238,20 @@ export default class SubmissionManager extends Component {
}
}

handleSubmitConfirmation = submitMutation => {
handleSubmitConfirmation(submitMutation) {
this.submitAssignment(submitMutation)
this.setState({openSubmitModal: false})
}

handleSubmitButton = submitMutation => {
handleSubmitButton(submitMutation) {
if (multipleTypesDrafted(this.props.submission)) {
this.setState({openSubmitModal: true})
} else {
this.handleSubmitConfirmation(submitMutation)
}
}

renderAttemptTab = () => {
renderAttemptTab() {
return (
<Mutation
mutation={CREATE_SUBMISSION_DRAFT}
Expand All @@ -276,7 +276,7 @@ export default class SubmissionManager extends Component {
)
}

renderSubmitConfirmation = submitMutation => {
renderSubmitConfirmation(submitMutation) {
return (
<Modal
data-testid="submission-confirmation-modal"
Expand Down Expand Up @@ -320,68 +320,35 @@ export default class SubmissionManager extends Component {
)
}

renderSubmitButton = () => {
const outerFooterStyle = {
position: 'fixed',
bottom: '0',
left: '0',
right: '0',
maxWidth: '1366px',
margin: '0 0 0 84px',
zIndex: '5'
}

// TODO: Delete this once the better global footers are implemented. This
// is some pretty ghetto stuff to handle the fixed buttom bars (for
// masquarading and beta instances) that would otherwise hide the
// submit button.
let paddingOffset = 0
if (document.getElementById('masquerade_bar')) {
paddingOffset += 52
}
if (document.getElementById('element_toggler_0')) {
paddingOffset += 63
}

const innerFooterStyle = {
backgroundColor: theme.variables.colors.white,
borderColor: theme.variables.colors.borderMedium,
borderTop: `1px solid ${theme.variables.colors.borderMedium}`,
textAlign: 'right',
margin: `0 ${theme.variables.spacing.medium}`,
paddingBottom: `${paddingOffset}px`
}

renderSubmitButton() {
return (
<div style={outerFooterStyle}>
<div style={innerFooterStyle}>
<Mutation
mutation={CREATE_SUBMISSION}
onCompleted={data =>
data.createSubmission.errors
? this.context.setOnFailure(I18n.t('Error sending submission'))
: this.context.setOnSuccess(I18n.t('Submission sent'))
}
onError={() => this.context.setOnFailure(I18n.t('Error sending submission'))}
update={this.clearSubmissionHistoriesCache}
>
{submitMutation => (
<>
<Button
id="submit-button"
data-testid="submit-button"
disabled={this.state.submittingAssignment}
variant="primary"
margin="xx-small 0"
onClick={() => this.handleSubmitButton(submitMutation)}
>
{I18n.t('Submit')}
</Button>
{this.state.openSubmitModal && this.renderSubmitConfirmation(submitMutation)}
</>
)}
</Mutation>
</div>
<div style={{textAlign: direction('right')}}>
<Mutation
mutation={CREATE_SUBMISSION}
onCompleted={data =>
data.createSubmission.errors
? this.context.setOnFailure(I18n.t('Error sending submission'))
: this.context.setOnSuccess(I18n.t('Submission sent'))
}
onError={() => this.context.setOnFailure(I18n.t('Error sending submission'))}
update={this.clearSubmissionHistoriesCache}
>
{submitMutation => (
<>
<Button
id="submit-button"
data-testid="submit-button"
disabled={this.state.submittingAssignment}
variant="primary"
margin="xx-small 0"
onClick={() => this.handleSubmitButton(submitMutation)}
>
{I18n.t('Submit')}
</Button>
{this.state.openSubmitModal && this.renderSubmitConfirmation(submitMutation)}
</>
)}
</Mutation>
</div>
)
}
Expand Down
18 changes: 16 additions & 2 deletions app/jsx/bundles/assignments_2_show_student.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@
*/

import renderAssignmentsApp from '../assignments_2/studentIndex'
import $ from 'jquery'

const elt = document.getElementById('content')
renderAssignmentsApp(ENV, elt)
$(() => {
renderAssignmentsApp(ENV, $('<div/>').appendTo('#content')[0])
})

import('compiled/jquery/ModuleSequenceFooter').then(() => {
$(() => {
$('<div id="module_sequence_footer" style="margin-top: 30px" />')
.appendTo('#content')
.moduleSequenceFooter({
assetType: 'Assignment',
assetID: ENV.ASSIGNMENT_ID,
courseID: ENV.COURSE_ID
})
})
})
2 changes: 1 addition & 1 deletion app/jsx/shared/helpers/rtlHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const flipped = {
* works exactly like our sass helper named the same thing
* @param {String} "left" or "right"
* @param {ElementToCheck}, will use the <html> element by default
* @returns {String} 'ltr' or 'rtl' (or `undefined` if no DOM is present)
* @returns {String} 'left' or 'right' (or `undefined` if no DOM is present)
*/
export function direction(leftOrRight, element) {
if (leftOrRight !== 'left' && leftOrRight !== 'right')
Expand Down
20 changes: 20 additions & 0 deletions spec/selenium/assignments_v2/student_assignment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@
end
end

context "moduleSequenceFooter" do
before do
@assignment = @course.assignments.create!(submission_types: 'online_upload')

# add items to module
@module = @course.context_modules.create!(:name => "My Module")
@item_before = @module.add_item :type => 'assignment', :id => @course.assignments.create!(:title => 'assignment BEFORE this one').id
@module.add_item :type => 'assignment', :id => @assignment.id
@item_after = @module.add_item :type => 'assignment', :id => @course.assignments.create!(:title => 'assignment AFTER this one').id

user_session(@student)
StudentAssignmentPageV2.visit(@course, @assignment)
end

it "shows the module sequence footer" do
expect(f('.module-sequence-footer-button--previous')).to have_attribute("href", "/courses/#{@course.id}/modules/items/#{@item_before.id}")
expect(f('.module-sequence-footer-button--next a')).to have_attribute("href", "/courses/#{@course.id}/modules/items/#{@item_after.id}")
end
end

context 'media assignments' do
before(:once) do
@assignment = @course.assignments.create!(
Expand Down

0 comments on commit 3d0d134

Please sign in to comment.