Fix some invalid imports
These are all things that were improperly importing either: * a “default” object when there was only named exports * a named export when there is only a default export They work now because we tell babel to transpile es modules down to commonJS in the “env” preset in babelrc but we want to eventually not do that and these will need to be fixed before then Test plan: * no functionality should actually change in the code generated by Webpack * this build should pass * but so should the build for the commit that follows this that sets the `“modules”: false` option for babel-preset-env in .babelrc Change-Id: Ic6f49fb94ee0d0592ca5e34ef7ed0a5633c40d80 Reviewed-on: https://gerrit.instructure.com/167054 Tested-by: Jenkins Reviewed-by: Steven Burnett <sburnett@instructure.com> QA-Review: Ryan Shaw <ryan@instructure.com> Product-Review: Ryan Shaw <ryan@instructure.com>
This commit is contained in:
parent
3fddcf98e2
commit
52437a1137
|
@ -26,7 +26,7 @@ import 'jquery.instructure_misc_plugins' // ifExists, showIf
|
||||||
import 'jquery.loadingImg'
|
import 'jquery.loadingImg'
|
||||||
import 'vendor/jquery.scrollTo'
|
import 'vendor/jquery.scrollTo'
|
||||||
import 'jqueryui/datepicker'
|
import 'jqueryui/datepicker'
|
||||||
import * as mathml from 'mathml'
|
import {isMathJaxLoaded, reloadElement, loadMathJax, isMathMLOnPage} from 'mathml'
|
||||||
|
|
||||||
let specialDatesAreHidden = false
|
let specialDatesAreHidden = false
|
||||||
|
|
||||||
|
@ -313,11 +313,11 @@ const bindToEditSyllabus = function () {
|
||||||
$course_syllabus.loadingImage('remove').html(data.course.syllabus_body)
|
$course_syllabus.loadingImage('remove').html(data.course.syllabus_body)
|
||||||
$course_syllabus.data('syllabus_body', data.course.syllabus_body)
|
$course_syllabus.data('syllabus_body', data.course.syllabus_body)
|
||||||
$course_syllabus_details.hide()
|
$course_syllabus_details.hide()
|
||||||
if (mathml.isMathMLOnPage()) {
|
if (isMathMLOnPage()) {
|
||||||
if (mathml.isMathJaxLoaded()) {
|
if (isMathJaxLoaded()) {
|
||||||
mathml.reloadElement('content')
|
reloadElement('content')
|
||||||
} else {
|
} else {
|
||||||
mathml.loadMathJax('MML_HTMLorMML.js')
|
loadMathJax('MML_HTMLorMML.js')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright (C) 2012 - present Instructure, Inc.
|
|
||||||
#
|
|
||||||
# This file is part of Canvas.
|
|
||||||
#
|
|
||||||
# Canvas is free software: you can redistribute it and/or modify it under
|
|
||||||
# the terms of the GNU Affero General Public License as published by the Free
|
|
||||||
# Software Foundation, version 3 of the License.
|
|
||||||
#
|
|
||||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License along
|
|
||||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
define [
|
|
||||||
'../models/Folder'
|
|
||||||
], (Folder) ->
|
|
||||||
|
|
||||||
# `FoldersCollection` is actually defined inside of '../models/Folder'
|
|
||||||
# because RequireJS sucks at figuring out circular dependencies.
|
|
||||||
# I did exactly what http://requirejs.org/docs/api.html#circular said but the
|
|
||||||
# load order was still completely arbitrary. By defining them in the same file
|
|
||||||
# we control the load order exactly and things work--consistently.
|
|
||||||
return Folder.FoldersCollection
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 - present Instructure, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of Canvas.
|
||||||
|
//
|
||||||
|
// Canvas is free software: you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
// Software Foundation, version 3 of the License.
|
||||||
|
//
|
||||||
|
// Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
// details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License along
|
||||||
|
// with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Folder from '../models/Folder'
|
||||||
|
|
||||||
|
// `FoldersCollection` is actually defined inside of '../models/Folder'
|
||||||
|
// because RequireJS sucks at figuring out circular dependencies.
|
||||||
|
// I did exactly what http://requirejs.org/docs/api.html#circular said but the
|
||||||
|
// load order was still completely arbitrary. By defining them in the same file
|
||||||
|
// we control the load order exactly and things work--consistently.
|
||||||
|
export default Folder.FoldersCollection
|
|
@ -22,7 +22,7 @@ import ajax from 'ic-ajax'
|
||||||
import startApp from '../start_app'
|
import startApp from '../start_app'
|
||||||
import Ember from 'ember'
|
import Ember from 'ember'
|
||||||
import fixtures from '../shared_ajax_fixtures'
|
import fixtures from '../shared_ajax_fixtures'
|
||||||
import GradeCalculatorSpecHelper from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
|
import {createCourseGradesWithGradingPeriods} from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
|
||||||
import SRGBController from '../../controllers/screenreader_gradebook_controller'
|
import SRGBController from '../../controllers/screenreader_gradebook_controller'
|
||||||
import userSettings from '../../../../userSettings'
|
import userSettings from '../../../../userSettings'
|
||||||
import CourseGradeCalculator from 'jsx/gradebook/CourseGradeCalculator'
|
import CourseGradeCalculator from 'jsx/gradebook/CourseGradeCalculator'
|
||||||
|
@ -713,7 +713,7 @@ QUnit.module 'ScreenReader Gradebook', (suiteHooks) ->
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
weighted: true
|
weighted: true
|
||||||
exampleGrades = GradeCalculatorSpecHelper.createCourseGradesWithGradingPeriods()
|
exampleGrades = createCourseGradesWithGradingPeriods()
|
||||||
initializeApp()
|
initializeApp()
|
||||||
asyncHelper.waitForRequests().then ->
|
asyncHelper.waitForRequests().then ->
|
||||||
sinon.stub(CourseGradeCalculator, 'calculate').returns(exampleGrades)
|
sinon.stub(CourseGradeCalculator, 'calculate').returns(exampleGrades)
|
||||||
|
|
|
@ -1,201 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright (C) 2012 - present Instructure, Inc.
|
|
||||||
#
|
|
||||||
# This file is part of Canvas.
|
|
||||||
#
|
|
||||||
# Canvas is free software: you can redistribute it and/or modify it under
|
|
||||||
# the terms of the GNU Affero General Public License as published by the Free
|
|
||||||
# Software Foundation, version 3 of the License.
|
|
||||||
#
|
|
||||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License along
|
|
||||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
define [
|
|
||||||
'require'
|
|
||||||
'../models/FilesystemObject'
|
|
||||||
'vendor/backbone-identity-map'
|
|
||||||
'../collections/PaginatedCollection'
|
|
||||||
'../collections/FilesCollection'
|
|
||||||
'../util/natcompare'
|
|
||||||
'jsx/shared/helpers/urlHelper'
|
|
||||||
], (require, FilesystemObject, identityMapMixin, PaginatedCollection, FilesCollection, natcompare, urlHelper) ->
|
|
||||||
|
|
||||||
|
|
||||||
Folder = identityMapMixin class __Folder extends FilesystemObject
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
'name' : ''
|
|
||||||
|
|
||||||
initialize: (options) ->
|
|
||||||
@contentTypes ||= options?.contentTypes
|
|
||||||
@useVerifiers ||= options?.useVerifiers
|
|
||||||
@setUpFilesAndFoldersIfNeeded()
|
|
||||||
@on 'change:sort change:order', @setQueryStringParams
|
|
||||||
super
|
|
||||||
|
|
||||||
url: ->
|
|
||||||
if @isNew()
|
|
||||||
super
|
|
||||||
else
|
|
||||||
"/api/v1/folders/#{@id}"
|
|
||||||
|
|
||||||
parse: (response) ->
|
|
||||||
json = super
|
|
||||||
@contentTypes ||= response.contentTypes
|
|
||||||
@useVerifiers ||= response.useVerifiers
|
|
||||||
@setUpFilesAndFoldersIfNeeded()
|
|
||||||
|
|
||||||
@folders.url = response.folders_url
|
|
||||||
@files.url = response.files_url
|
|
||||||
|
|
||||||
json
|
|
||||||
|
|
||||||
setUpFilesAndFoldersIfNeeded: ->
|
|
||||||
unless @folders
|
|
||||||
@folders = new FoldersCollection [], parentFolder: this
|
|
||||||
unless @files
|
|
||||||
@files = new FilesCollection [], parentFolder: this
|
|
||||||
|
|
||||||
getSubtrees: ->
|
|
||||||
@folders
|
|
||||||
|
|
||||||
getItems: ->
|
|
||||||
@files
|
|
||||||
|
|
||||||
expand: (force=false, options={}) ->
|
|
||||||
@isExpanded = true
|
|
||||||
@trigger 'expanded'
|
|
||||||
return $.when() if @expandDfd || force
|
|
||||||
@isExpanding = true
|
|
||||||
@trigger 'beginexpanding'
|
|
||||||
@expandDfd = $.Deferred().done =>
|
|
||||||
@isExpanding = false
|
|
||||||
@trigger 'endexpanding'
|
|
||||||
|
|
||||||
selfHasntBeenFetched = @folders.url is @folders.constructor::url or @files.url is @files.constructor::url
|
|
||||||
fetchDfd = @fetch() if selfHasntBeenFetched || force
|
|
||||||
$.when(fetchDfd).done =>
|
|
||||||
foldersDfd = @folders.fetch() unless @get('folders_count') is 0
|
|
||||||
filesDfd = @files.fetch() if (@get('files_count') isnt 0) and !options.onlyShowSubtrees
|
|
||||||
$.when(foldersDfd, filesDfd).done(@expandDfd.resolve)
|
|
||||||
|
|
||||||
collapse: ->
|
|
||||||
@isExpanded = false
|
|
||||||
@trigger 'collapsed'
|
|
||||||
|
|
||||||
toggle: (options) ->
|
|
||||||
if @isExpanded
|
|
||||||
@collapse()
|
|
||||||
else
|
|
||||||
@expand(false, options)
|
|
||||||
|
|
||||||
previewUrl: ->
|
|
||||||
if @get('context_type') in ['Course', 'Group']
|
|
||||||
"/#{ @get('context_type').toLowerCase() + 's' }/#{ @get('context_id') }/files/{{id}}/preview"
|
|
||||||
|
|
||||||
isEmpty: ->
|
|
||||||
!!(@files.loadedAll and (@files.length is 0)) and (@folders.loadedAll and (@folders.length is 0))
|
|
||||||
|
|
||||||
# `full_name` will be something like "course files/some folder/another".
|
|
||||||
# For routing in the react app in the browser, we want something that will take that "course files"
|
|
||||||
# out. because urls will end up being /courses/2/files/folder/some folder/another
|
|
||||||
EVERYTHING_BEFORE_THE_FIRST_SLASH = /^[^\/]+\/?/
|
|
||||||
filesEnv = null
|
|
||||||
urlPath: ->
|
|
||||||
relativePath = (@get('full_name') or '').replace(EVERYTHING_BEFORE_THE_FIRST_SLASH, '')
|
|
||||||
relativePath = urlHelper.encodeSpecialChars(relativePath)
|
|
||||||
relativePath = relativePath.split('/').map((component) ->
|
|
||||||
encodeURIComponent(component)
|
|
||||||
).join('/')
|
|
||||||
|
|
||||||
filesEnv ||= require('../react_files/modules/filesEnv') # circular dep
|
|
||||||
|
|
||||||
# when we are viewing all files we need to pad the context_asset_string on the front of the url
|
|
||||||
# so it would be something like /files/folder/users_1/some/sub/folder
|
|
||||||
if filesEnv.showingAllContexts
|
|
||||||
assetString = "#{@get('context_type')?.toLowerCase()}s_#{@get('context_id')}"
|
|
||||||
relativePath = assetString + '/' + relativePath
|
|
||||||
|
|
||||||
relativePath
|
|
||||||
|
|
||||||
@resolvePath = (contextType, contextId, folderPath) ->
|
|
||||||
folderPath = urlHelper.decodeSpecialChars(folderPath)
|
|
||||||
|
|
||||||
url = "/api/v1/#{contextType}/#{contextId}/folders/by_path#{folderPath}"
|
|
||||||
$.getJSON(url).pipe (folders) ->
|
|
||||||
folders.map (folderAttrs) ->
|
|
||||||
new Folder(folderAttrs, {parse: true})
|
|
||||||
|
|
||||||
getSortProp = (model, sortProp) ->
|
|
||||||
# if we are sorting by name use 'display_name' for files and 'name' for folders.
|
|
||||||
if sortProp is 'name' and not (model instanceof Folder)
|
|
||||||
model.get('display_name')
|
|
||||||
else if sortProp is 'user'
|
|
||||||
model.get('user')?.display_name || ''
|
|
||||||
else if sortProp is 'usage_rights'
|
|
||||||
model.get('usage_rights')?.license_name || ''
|
|
||||||
else
|
|
||||||
model.get(sortProp)
|
|
||||||
|
|
||||||
##
|
|
||||||
# Special sorter for handling sorting with special properties
|
|
||||||
# It's been enhanced to sort naturally when certain sortProps
|
|
||||||
# are used.
|
|
||||||
childrenSorter: (sortProp='name', sortOrder='asc', a, b) ->
|
|
||||||
# Only use natural mode for instances we expect strings in.
|
|
||||||
naturalMode = sortProp in ['name', 'user', 'usage_rights']
|
|
||||||
|
|
||||||
# Get actual values for the properties we are sorting by.
|
|
||||||
a = getSortProp(a, sortProp)
|
|
||||||
b = getSortProp(b, sortProp)
|
|
||||||
|
|
||||||
if naturalMode
|
|
||||||
res = natcompare.strings(a, b)
|
|
||||||
else
|
|
||||||
res = if a is b
|
|
||||||
0
|
|
||||||
else if a > b or a is undefined
|
|
||||||
1
|
|
||||||
else if a < b or b is undefined
|
|
||||||
-1
|
|
||||||
else
|
|
||||||
throw new Error("wat? error sorting")
|
|
||||||
|
|
||||||
res = 0 - res if sortOrder is 'desc'
|
|
||||||
res
|
|
||||||
|
|
||||||
children: ({sort, order}) ->
|
|
||||||
(@folders.toArray().concat @files.toArray()).sort(@childrenSorter.bind(null, sort, order))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# FoldersCollection is defined inside of this file, and not where it
|
|
||||||
# should be, because RequireJS sucks at figuring out circular dependencies.
|
|
||||||
# '../collections/FoldersCollection' just grabs this and re-exports it.
|
|
||||||
Folder.FoldersCollection = class FoldersCollection extends PaginatedCollection
|
|
||||||
@optionProperty 'parentFolder'
|
|
||||||
|
|
||||||
model: Folder
|
|
||||||
|
|
||||||
parse: (response) ->
|
|
||||||
if response
|
|
||||||
response.forEach (folder) =>
|
|
||||||
folder.contentTypes = @parentFolder.contentTypes
|
|
||||||
folder.useVerifiers = @parentFolder.useVerifiers
|
|
||||||
super
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Folder
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 - present Instructure, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of Canvas.
|
||||||
|
//
|
||||||
|
// Canvas is free software: you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Affero General Public License as published by the Free
|
||||||
|
// Software Foundation, version 3 of the License.
|
||||||
|
//
|
||||||
|
// Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||||
|
// details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License along
|
||||||
|
// with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import FilesystemObject from '../models/FilesystemObject'
|
||||||
|
import identityMapMixin from 'vendor/backbone-identity-map'
|
||||||
|
import PaginatedCollection from '../collections/PaginatedCollection'
|
||||||
|
import FilesCollection from '../collections/FilesCollection'
|
||||||
|
import natcompare from '../util/natcompare'
|
||||||
|
import urlHelper from 'jsx/shared/helpers/urlHelper'
|
||||||
|
|
||||||
|
// `full_name` will be something like "course files/some folder/another".
|
||||||
|
// For routing in the react app in the browser, we want something that will take that "course files"
|
||||||
|
// out. because urls will end up being /courses/2/files/folder/some folder/another
|
||||||
|
const EVERYTHING_BEFORE_THE_FIRST_SLASH = /^[^\/]+\/?/
|
||||||
|
let filesEnv = null
|
||||||
|
|
||||||
|
function getSortProp(model, sortProp) {
|
||||||
|
// if we are sorting by name use 'display_name' for files and 'name' for folders.
|
||||||
|
if (sortProp === 'name' && !(model instanceof Folder)) {
|
||||||
|
return model.get('display_name')
|
||||||
|
} else if (sortProp === 'user') {
|
||||||
|
return __guard__(model.get('user'), x => x.display_name) || ''
|
||||||
|
} else if (sortProp === 'usage_rights') {
|
||||||
|
return __guard__(model.get('usage_rights'), x1 => x1.license_name) || ''
|
||||||
|
} else {
|
||||||
|
return model.get(sortProp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class __Folder extends FilesystemObject {
|
||||||
|
initialize(options) {
|
||||||
|
if (!this.contentTypes) this.contentTypes = options != null ? options.contentTypes : undefined
|
||||||
|
if (!this.useVerifiers) this.useVerifiers = options != null ? options.useVerifiers : undefined
|
||||||
|
this.setUpFilesAndFoldersIfNeeded()
|
||||||
|
this.on('change:sort change:order', this.setQueryStringParams)
|
||||||
|
return super.initialize(...arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
url() {
|
||||||
|
if (this.isNew()) {
|
||||||
|
return super.url(...arguments)
|
||||||
|
} else {
|
||||||
|
return `/api/v1/folders/${this.id}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(response) {
|
||||||
|
const json = super.parse(...arguments)
|
||||||
|
if (!this.contentTypes) this.contentTypes = response.contentTypes
|
||||||
|
if (!this.useVerifiers) this.useVerifiers = response.useVerifiers
|
||||||
|
this.setUpFilesAndFoldersIfNeeded()
|
||||||
|
|
||||||
|
this.folders.url = response.folders_url
|
||||||
|
this.files.url = response.files_url
|
||||||
|
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpFilesAndFoldersIfNeeded() {
|
||||||
|
if (!this.folders) {
|
||||||
|
this.folders = new FoldersCollection([], {parentFolder: this})
|
||||||
|
}
|
||||||
|
if (!this.files) {
|
||||||
|
return (this.files = new FilesCollection([], {parentFolder: this}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubtrees() {
|
||||||
|
return this.folders
|
||||||
|
}
|
||||||
|
|
||||||
|
getItems() {
|
||||||
|
return this.files
|
||||||
|
}
|
||||||
|
|
||||||
|
expand(force = false, options = {}) {
|
||||||
|
let fetchDfd
|
||||||
|
this.isExpanded = true
|
||||||
|
this.trigger('expanded')
|
||||||
|
if (this.expandDfd || force) {
|
||||||
|
return $.when()
|
||||||
|
}
|
||||||
|
this.isExpanding = true
|
||||||
|
this.trigger('beginexpanding')
|
||||||
|
this.expandDfd = $.Deferred().done(() => {
|
||||||
|
this.isExpanding = false
|
||||||
|
return this.trigger('endexpanding')
|
||||||
|
})
|
||||||
|
|
||||||
|
const selfHasntBeenFetched =
|
||||||
|
this.folders.url === this.folders.constructor.prototype.url ||
|
||||||
|
this.files.url === this.files.constructor.prototype.url
|
||||||
|
if (selfHasntBeenFetched || force) {
|
||||||
|
fetchDfd = this.fetch()
|
||||||
|
}
|
||||||
|
return $.when(fetchDfd).done(() => {
|
||||||
|
let filesDfd, foldersDfd
|
||||||
|
if (this.get('folders_count') !== 0) {
|
||||||
|
foldersDfd = this.folders.fetch()
|
||||||
|
}
|
||||||
|
if (this.get('files_count') !== 0 && !options.onlyShowSubtrees) {
|
||||||
|
filesDfd = this.files.fetch()
|
||||||
|
}
|
||||||
|
return $.when(foldersDfd, filesDfd).done(this.expandDfd.resolve)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse() {
|
||||||
|
this.isExpanded = false
|
||||||
|
return this.trigger('collapsed')
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(options) {
|
||||||
|
if (this.isExpanded) {
|
||||||
|
return this.collapse()
|
||||||
|
} else {
|
||||||
|
return this.expand(false, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previewUrl() {
|
||||||
|
let needle
|
||||||
|
if (((needle = this.get('context_type')), ['Course', 'Group'].includes(needle))) {
|
||||||
|
return `/${`${this.get('context_type').toLowerCase()}s`}/${this.get(
|
||||||
|
'context_id'
|
||||||
|
)}/files/{{id}}/preview`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty() {
|
||||||
|
return (
|
||||||
|
!!(this.files.loadedAll && this.files.length === 0) &&
|
||||||
|
(this.folders.loadedAll && this.folders.length === 0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
urlPath() {
|
||||||
|
let relativePath = (this.get('full_name') || '').replace(EVERYTHING_BEFORE_THE_FIRST_SLASH, '')
|
||||||
|
relativePath = urlHelper.encodeSpecialChars(relativePath)
|
||||||
|
relativePath = relativePath
|
||||||
|
.split('/')
|
||||||
|
.map(component => encodeURIComponent(component))
|
||||||
|
.join('/')
|
||||||
|
|
||||||
|
if (!filesEnv) filesEnv = require('../react_files/modules/filesEnv') // circular dep
|
||||||
|
|
||||||
|
// when we are viewing all files we need to pad the context_asset_string on the front of the url
|
||||||
|
// so it would be something like /files/folder/users_1/some/sub/folder
|
||||||
|
if (filesEnv.showingAllContexts) {
|
||||||
|
const assetString = `${__guard__(this.get('context_type'), x => x.toLowerCase())}s_${this.get(
|
||||||
|
'context_id'
|
||||||
|
)}`
|
||||||
|
relativePath = `${assetString}/${relativePath}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return relativePath
|
||||||
|
}
|
||||||
|
|
||||||
|
// #
|
||||||
|
// Special sorter for handling sorting with special properties
|
||||||
|
// It's been enhanced to sort naturally when certain sortProps
|
||||||
|
// are used.
|
||||||
|
childrenSorter(sortProp = 'name', sortOrder = 'asc', a, b) {
|
||||||
|
// Only use natural mode for instances we expect strings in.
|
||||||
|
let res
|
||||||
|
const naturalMode = ['name', 'user', 'usage_rights'].includes(sortProp)
|
||||||
|
|
||||||
|
// Get actual values for the properties we are sorting by.
|
||||||
|
a = getSortProp(a, sortProp)
|
||||||
|
b = getSortProp(b, sortProp)
|
||||||
|
|
||||||
|
if (naturalMode) {
|
||||||
|
res = natcompare.strings(a, b)
|
||||||
|
} else {
|
||||||
|
res = (() => {
|
||||||
|
if (a === b) {
|
||||||
|
return 0
|
||||||
|
} else if (a > b || a === undefined) {
|
||||||
|
return 1
|
||||||
|
} else if (a < b || b === undefined) {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
throw new Error('wat? error sorting')
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sortOrder === 'desc') {
|
||||||
|
res = 0 - res
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
children({sort, order}) {
|
||||||
|
return this.folders
|
||||||
|
.toArray()
|
||||||
|
.concat(this.files.toArray())
|
||||||
|
.sort(this.childrenSorter.bind(null, sort, order))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__Folder.resolvePath = function(contextType, contextId, folderPath) {
|
||||||
|
folderPath = urlHelper.decodeSpecialChars(folderPath)
|
||||||
|
|
||||||
|
const url = `/api/v1/${contextType}/${contextId}/folders/by_path${folderPath}`
|
||||||
|
return $.getJSON(url).pipe(folders =>
|
||||||
|
folders.map(folderAttrs => new Folder(folderAttrs, {parse: true}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
__Folder.prototype.defaults = {name: ''}
|
||||||
|
|
||||||
|
const Folder = identityMapMixin(__Folder)
|
||||||
|
export default Folder
|
||||||
|
|
||||||
|
class FoldersCollection extends PaginatedCollection {
|
||||||
|
static initClass() {
|
||||||
|
this.optionProperty('parentFolder')
|
||||||
|
this.prototype.model = Folder
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(response) {
|
||||||
|
if (response) {
|
||||||
|
response.forEach(folder => {
|
||||||
|
folder.contentTypes = this.parentFolder.contentTypes
|
||||||
|
return (folder.useVerifiers = this.parentFolder.useVerifiers)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return super.parse(...arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FoldersCollection.initClass()
|
||||||
|
|
||||||
|
// FoldersCollection is defined inside of this file, and not where it
|
||||||
|
// should be, because RequireJS sucks at figuring out circular dependencies.
|
||||||
|
// '../collections/FoldersCollection' just grabs this and re-exports it.
|
||||||
|
Folder.FoldersCollection = FoldersCollection
|
||||||
|
|
||||||
|
function __guard__(value, transform) {
|
||||||
|
return typeof value !== 'undefined' && value !== null ? transform(value) : undefined
|
||||||
|
}
|
|
@ -25,9 +25,9 @@ import IconBlueprintLine from '@instructure/ui-icons/lib/Line/IconBlueprint'
|
||||||
import IconPlusLine from '@instructure/ui-icons/lib/Line/IconPlus'
|
import IconPlusLine from '@instructure/ui-icons/lib/Line/IconPlus'
|
||||||
import IconSettingsLine from '@instructure/ui-icons/lib/Line/IconSettings'
|
import IconSettingsLine from '@instructure/ui-icons/lib/Line/IconSettings'
|
||||||
import IconStatsLine from '@instructure/ui-icons/lib/Line/IconStats'
|
import IconStatsLine from '@instructure/ui-icons/lib/Line/IconStats'
|
||||||
import {get} from 'axios'
|
import axios from 'axios'
|
||||||
import {uniqBy} from 'lodash'
|
import {uniqBy} from 'lodash'
|
||||||
import {flashMessage} from 'compiled/jquery.rails_flash_notifications'
|
import $ from 'compiled/jquery.rails_flash_notifications'
|
||||||
import I18n from 'i18n!account_course_user_search'
|
import I18n from 'i18n!account_course_user_search'
|
||||||
import UserLink from './UserLink'
|
import UserLink from './UserLink'
|
||||||
import AddPeopleApp from '../../add_people/add_people_app'
|
import AddPeopleApp from '../../add_people/add_people_app'
|
||||||
|
@ -65,7 +65,7 @@ export default class CoursesListRow extends React.Component {
|
||||||
|
|
||||||
getSections = () =>
|
getSections = () =>
|
||||||
this.promiseToGetSections ||
|
this.promiseToGetSections ||
|
||||||
(this.promiseToGetSections = get(
|
(this.promiseToGetSections = axios.get(
|
||||||
`/api/v1/courses/${this.props.id}/sections?per_page=100`
|
`/api/v1/courses/${this.props.id}/sections?per_page=100`
|
||||||
)).then(resp => resp.data)
|
)).then(resp => resp.data)
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ export default class CoursesListRow extends React.Component {
|
||||||
|
|
||||||
handleNewEnrollments = newEnrollments => {
|
handleNewEnrollments = newEnrollments => {
|
||||||
if (newEnrollments && newEnrollments.length) {
|
if (newEnrollments && newEnrollments.length) {
|
||||||
flashMessage({
|
$.flashMessage({
|
||||||
html: I18n.t(
|
html: I18n.t(
|
||||||
{
|
{
|
||||||
one: '%{user_name} successfully enrolled into *%{course_name}*.',
|
one: '%{user_name} successfully enrolled into *%{course_name}*.',
|
||||||
|
|
|
@ -20,7 +20,7 @@ import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import DashboardCardBox from '../dashboard_card/DashboardCardBox'
|
import DashboardCardBox from '../dashboard_card/DashboardCardBox'
|
||||||
import getDroppableDashboardCardBox from '../dashboard_card/getDroppableDashboardCardBox'
|
import getDroppableDashboardCardBox from '../dashboard_card/getDroppableDashboardCardBox'
|
||||||
import {get} from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
let promiseToGetDashboardCards
|
let promiseToGetDashboardCards
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ export default function loadCardDashboard () {
|
||||||
if (cachedCards) render(JSON.parse(cachedCards))
|
if (cachedCards) render(JSON.parse(cachedCards))
|
||||||
|
|
||||||
if (!promiseToGetDashboardCards) {
|
if (!promiseToGetDashboardCards) {
|
||||||
promiseToGetDashboardCards = get('/dashboard/dashboard_cards').then(({data}) => data)
|
promiseToGetDashboardCards = axios.get('/dashboard/dashboard_cards').then(({data}) => data)
|
||||||
promiseToGetDashboardCards.then((dashboardCards) =>
|
promiseToGetDashboardCards.then((dashboardCards) =>
|
||||||
sessionStorage.setItem(sessionStorageKey, JSON.stringify(dashboardCards))
|
sessionStorage.setItem(sessionStorageKey, JSON.stringify(dashboardCards))
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,7 +22,6 @@ import GettingStartedCollaborations from '../collaborations/GettingStartedCollab
|
||||||
import CollaborationsNavigation from '../collaborations/CollaborationsNavigation'
|
import CollaborationsNavigation from '../collaborations/CollaborationsNavigation'
|
||||||
import CollaborationsList from './CollaborationsList'
|
import CollaborationsList from './CollaborationsList'
|
||||||
import LoadingSpinner from './LoadingSpinner'
|
import LoadingSpinner from './LoadingSpinner'
|
||||||
import { dispatch } from './store/store'
|
|
||||||
|
|
||||||
class CollaborationsApp extends React.Component {
|
class CollaborationsApp extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import ReactDOM from 'react-dom'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Collaboration from './Collaboration'
|
import Collaboration from './Collaboration'
|
||||||
import LoadMore from '../shared/load-more'
|
import LoadMore from '../shared/load-more'
|
||||||
import { dispatch } from './store/store'
|
import store from './store/store'
|
||||||
|
|
||||||
class CollaborationsList extends React.Component {
|
class CollaborationsList extends React.Component {
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import { dispatch } from './store/store'
|
||||||
|
|
||||||
loadMoreCollaborations () {
|
loadMoreCollaborations () {
|
||||||
ReactDOM.findDOMNode(this.refs[`collaboration-${this.props.collaborationsState.list.length - 1}`]).focus();
|
ReactDOM.findDOMNode(this.refs[`collaboration-${this.props.collaborationsState.list.length - 1}`]).focus();
|
||||||
dispatch(this.props.getCollaborations(this.props.collaborationsState.nextPage));
|
store.dispatch(this.props.getCollaborations(this.props.collaborationsState.nextPage));
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -19,12 +19,12 @@
|
||||||
import 'jquery.instructure_date_and_time'
|
import 'jquery.instructure_date_and_time'
|
||||||
import parseLinkHeader from '../../shared/parseLinkHeader';
|
import parseLinkHeader from '../../shared/parseLinkHeader';
|
||||||
|
|
||||||
const FETCH_HISTORY_START = 'FETCH_HISTORY_START';
|
export const FETCH_HISTORY_START = 'FETCH_HISTORY_START';
|
||||||
const FETCH_HISTORY_SUCCESS = 'FETCH_HISTORY_SUCCESS';
|
export const FETCH_HISTORY_SUCCESS = 'FETCH_HISTORY_SUCCESS';
|
||||||
const FETCH_HISTORY_FAILURE = 'FETCH_HISTORY_FAILURE';
|
export const FETCH_HISTORY_FAILURE = 'FETCH_HISTORY_FAILURE';
|
||||||
const FETCH_HISTORY_NEXT_PAGE_START = 'FETCH_HISTORY_NEXT_PAGE_START';
|
export const FETCH_HISTORY_NEXT_PAGE_START = 'FETCH_HISTORY_NEXT_PAGE_START';
|
||||||
const FETCH_HISTORY_NEXT_PAGE_SUCCESS = 'FETCH_HISTORY_NEXT_PAGE_SUCCESS';
|
export const FETCH_HISTORY_NEXT_PAGE_SUCCESS = 'FETCH_HISTORY_NEXT_PAGE_SUCCESS';
|
||||||
const FETCH_HISTORY_NEXT_PAGE_FAILURE = 'FETCH_HISTORY_NEXT_PAGE_FAILURE';
|
export const FETCH_HISTORY_NEXT_PAGE_FAILURE = 'FETCH_HISTORY_NEXT_PAGE_FAILURE';
|
||||||
|
|
||||||
function indexById (collection = []) {
|
function indexById (collection = []) {
|
||||||
return collection.reduce((acc, item) => {
|
return collection.reduce((acc, item) => {
|
||||||
|
@ -78,13 +78,13 @@ function formatHistoryItems (data) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHistoryStart () {
|
export function fetchHistoryStart () {
|
||||||
return {
|
return {
|
||||||
type: FETCH_HISTORY_START
|
type: FETCH_HISTORY_START
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHistorySuccess ({ events, linked: { assignments, users }}, { link }) {
|
export function fetchHistorySuccess ({ events, linked: { assignments, users }}, { link }) {
|
||||||
return {
|
return {
|
||||||
type: FETCH_HISTORY_SUCCESS,
|
type: FETCH_HISTORY_SUCCESS,
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -94,19 +94,19 @@ function fetchHistorySuccess ({ events, linked: { assignments, users }}, { link
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHistoryFailure () {
|
export function fetchHistoryFailure () {
|
||||||
return {
|
return {
|
||||||
type: FETCH_HISTORY_FAILURE
|
type: FETCH_HISTORY_FAILURE
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHistoryNextPageStart () {
|
export function fetchHistoryNextPageStart () {
|
||||||
return {
|
return {
|
||||||
type: FETCH_HISTORY_NEXT_PAGE_START
|
type: FETCH_HISTORY_NEXT_PAGE_START
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHistoryNextPageSuccess ({ events, linked: { assignments, users }}, { link }) {
|
export function fetchHistoryNextPageSuccess ({ events, linked: { assignments, users }}, { link }) {
|
||||||
return {
|
return {
|
||||||
type: FETCH_HISTORY_NEXT_PAGE_SUCCESS,
|
type: FETCH_HISTORY_NEXT_PAGE_SUCCESS,
|
||||||
payload: {
|
payload: {
|
||||||
|
@ -116,23 +116,8 @@ function fetchHistoryNextPageSuccess ({ events, linked: { assignments, users }},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchHistoryNextPageFailure () {
|
export function fetchHistoryNextPageFailure () {
|
||||||
return {
|
return {
|
||||||
type: FETCH_HISTORY_NEXT_PAGE_FAILURE
|
type: FETCH_HISTORY_NEXT_PAGE_FAILURE
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
|
||||||
FETCH_HISTORY_START,
|
|
||||||
FETCH_HISTORY_SUCCESS,
|
|
||||||
FETCH_HISTORY_FAILURE,
|
|
||||||
FETCH_HISTORY_NEXT_PAGE_START,
|
|
||||||
FETCH_HISTORY_NEXT_PAGE_SUCCESS,
|
|
||||||
FETCH_HISTORY_NEXT_PAGE_FAILURE,
|
|
||||||
fetchHistoryStart,
|
|
||||||
fetchHistorySuccess,
|
|
||||||
fetchHistoryFailure,
|
|
||||||
fetchHistoryNextPageStart,
|
|
||||||
fetchHistoryNextPageSuccess,
|
|
||||||
fetchHistoryNextPageFailure,
|
|
||||||
};
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import AssignmentApi from '../../gradebook-history/api/AssignmentApi';
|
import AssignmentApi from '../../gradebook-history/api/AssignmentApi';
|
||||||
import HistoryActions from '../../gradebook-history/actions/HistoryActions';
|
import * as HistoryActions from '../../gradebook-history/actions/HistoryActions';
|
||||||
import HistoryApi from '../../gradebook-history/api/HistoryApi';
|
import HistoryApi from '../../gradebook-history/api/HistoryApi';
|
||||||
import UserApi from '../../gradebook-history/api/UserApi';
|
import UserApi from '../../gradebook-history/api/UserApi';
|
||||||
import environment from '../../gradebook-history/environment';
|
import environment from '../../gradebook-history/environment';
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import HistoryActions from '../../gradebook-history/actions/HistoryActions';
|
import * as HistoryActions from '../../gradebook-history/actions/HistoryActions';
|
||||||
import HistoryApi from '../../gradebook-history/api/HistoryApi';
|
import HistoryApi from '../../gradebook-history/api/HistoryApi';
|
||||||
|
|
||||||
function getHistoryNextPage (url) {
|
export function getHistoryNextPage (url) {
|
||||||
return function (dispatch) {
|
return function (dispatch) {
|
||||||
dispatch(HistoryActions.fetchHistoryNextPageStart());
|
dispatch(HistoryActions.fetchHistoryNextPageStart());
|
||||||
|
|
||||||
|
@ -31,8 +31,4 @@ function getHistoryNextPage (url) {
|
||||||
dispatch(HistoryActions.fetchHistoryNextPageFailure());
|
dispatch(HistoryActions.fetchHistoryNextPageFailure());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
|
||||||
getHistoryNextPage
|
|
||||||
};
|
|
|
@ -17,15 +17,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import { bool, func, shape, string } from 'prop-types'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
import I18n from 'i18n!modules'
|
import I18n from 'i18n!modules'
|
||||||
import PostGradesDialog from '../../gradezilla/SISGradePassback/PostGradesDialog'
|
import PostGradesDialog from '../../gradezilla/SISGradePassback/PostGradesDialog'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
|
||||||
const { bool, func, shape, string } = PropTypes
|
|
||||||
|
|
||||||
// The PostGradesApp mounts a single "Sync Grades" button, which pops up
|
// The PostGradesApp mounts a single "Sync Grades" button, which pops up
|
||||||
// the PostGradesDialog when clicked.
|
// the PostGradesDialog when clicked.
|
||||||
class PostGradesApp extends React.Component {
|
class PostGradesApp extends React.Component {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Grid } from 'vendor/slickgrid';
|
import slickgrid from 'vendor/slickgrid';
|
||||||
import 'jqueryui/sortable';
|
import 'jqueryui/sortable';
|
||||||
import CellEditorFactory from './editors/CellEditorFactory'
|
import CellEditorFactory from './editors/CellEditorFactory'
|
||||||
import CellFormatterFactory from './formatters/CellFormatterFactory'
|
import CellFormatterFactory from './formatters/CellFormatterFactory'
|
||||||
|
@ -53,7 +53,7 @@ export default class GradebookGrid {
|
||||||
this.gridData.columns.definitions[columnId]
|
this.gridData.columns.definitions[columnId]
|
||||||
));
|
));
|
||||||
|
|
||||||
this.grid = new Grid(this.options.$container, this.gridData.rows, columns, options);
|
this.grid = new slickgrid.Grid(this.options.$container, this.gridData.rows, columns, options);
|
||||||
|
|
||||||
const gridSupportOptions = {
|
const gridSupportOptions = {
|
||||||
activeBorderColor: this.options.activeBorderColor,
|
activeBorderColor: this.options.activeBorderColor,
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { camelize, underscore } from 'convert_case';
|
import { camelize, underscore } from 'convert_case';
|
||||||
|
|
||||||
const DEFAULT_LATE_POLICY_DATA = Object.freeze({
|
export const DEFAULT_LATE_POLICY_DATA = Object.freeze({
|
||||||
lateSubmissionDeductionEnabled: false,
|
lateSubmissionDeductionEnabled: false,
|
||||||
lateSubmissionDeduction: 0,
|
lateSubmissionDeduction: 0,
|
||||||
lateSubmissionInterval: 'day',
|
lateSubmissionInterval: 'day',
|
||||||
|
@ -35,7 +35,7 @@ function camelizeLatePolicyResponseData (latePolicyResponseData) {
|
||||||
return { latePolicy: camelizedData };
|
return { latePolicy: camelizedData };
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchLatePolicy (courseId) {
|
export function fetchLatePolicy (courseId) {
|
||||||
const url = `/api/v1/courses/${courseId}/late_policy`;
|
const url = `/api/v1/courses/${courseId}/late_policy`;
|
||||||
return axios.get(url)
|
return axios.get(url)
|
||||||
.then(response => (
|
.then(response => (
|
||||||
|
@ -52,7 +52,7 @@ function fetchLatePolicy (courseId) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLatePolicy (courseId, latePolicyData) {
|
export function createLatePolicy (courseId, latePolicyData) {
|
||||||
const url = `/api/v1/courses/${courseId}/late_policy`;
|
const url = `/api/v1/courses/${courseId}/late_policy`;
|
||||||
const data = { late_policy: underscore(latePolicyData) };
|
const data = { late_policy: underscore(latePolicyData) };
|
||||||
return axios.post(url, data).then(response => (
|
return axios.post(url, data).then(response => (
|
||||||
|
@ -60,7 +60,7 @@ function createLatePolicy (courseId, latePolicyData) {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLatePolicy (courseId, latePolicyData) {
|
export function updateLatePolicy (courseId, latePolicyData) {
|
||||||
const url = `/api/v1/courses/${courseId}/late_policy`;
|
const url = `/api/v1/courses/${courseId}/late_policy`;
|
||||||
const data = { late_policy: underscore(latePolicyData) };
|
const data = { late_policy: underscore(latePolicyData) };
|
||||||
return axios.patch(url, data);
|
return axios.patch(url, data);
|
||||||
|
|
|
@ -24,7 +24,7 @@ import Button from '@instructure/ui-buttons/lib/components/Button'
|
||||||
import Menu, { MenuItem, MenuItemSeparator } from '@instructure/ui-menu/lib/components/Menu'
|
import Menu, { MenuItem, MenuItemSeparator } from '@instructure/ui-menu/lib/components/Menu'
|
||||||
import Text from '@instructure/ui-elements/lib/components/Text'
|
import Text from '@instructure/ui-elements/lib/components/Text'
|
||||||
import GradebookExportManager from '../../../gradezilla/shared/GradebookExportManager'
|
import GradebookExportManager from '../../../gradezilla/shared/GradebookExportManager'
|
||||||
import { AppLaunch } from '../../../gradezilla/SISGradePassback/PostGradesApp'
|
import PostGradesApp from '../../../gradezilla/SISGradePassback/PostGradesApp'
|
||||||
import tz from 'timezone'
|
import tz from 'timezone'
|
||||||
import DateHelper from '../../../shared/helpers/dateHelper'
|
import DateHelper from '../../../shared/helpers/dateHelper'
|
||||||
import I18n from 'i18n!gradebook'
|
import I18n from 'i18n!gradebook'
|
||||||
|
@ -195,7 +195,7 @@ const { arrayOf, bool, func, object, shape, string } = PropTypes;
|
||||||
|
|
||||||
launchPostGrades () {
|
launchPostGrades () {
|
||||||
const { store, returnFocusTo } = this.props.postGradesFeature;
|
const { store, returnFocusTo } = this.props.postGradesFeature;
|
||||||
setTimeout(() => AppLaunch(store, returnFocusTo), 10);
|
setTimeout(() => PostGradesApp.AppLaunch(store, returnFocusTo), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPostGradesTools () {
|
renderPostGradesTools () {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
import Color from 'tinycolor2';
|
import Color from 'tinycolor2';
|
||||||
|
|
||||||
const defaultColors = {
|
export const defaultColors = {
|
||||||
salmon: '#FFE8E5',
|
salmon: '#FFE8E5',
|
||||||
orange: '#FEF0E5',
|
orange: '#FEF0E5',
|
||||||
yellow: '#FEF7E5',
|
yellow: '#FEF7E5',
|
||||||
|
@ -39,19 +39,13 @@ const defaultStatusColors = {
|
||||||
resubmitted: defaultColors.green
|
resubmitted: defaultColors.green
|
||||||
};
|
};
|
||||||
|
|
||||||
function statusColors (userColors = {}) {
|
export function statusColors (userColors = {}) {
|
||||||
return {
|
return {
|
||||||
...defaultStatusColors,
|
...defaultStatusColors,
|
||||||
...userColors
|
...userColors
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function darken (color, percent) {
|
export function darken (color, percent) {
|
||||||
return Color(color).darken(percent);
|
return Color(color).darken(percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
|
||||||
defaultColors,
|
|
||||||
statusColors,
|
|
||||||
darken
|
|
||||||
};
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
import I18n from 'i18n!gradebook';
|
import I18n from 'i18n!gradebook';
|
||||||
|
|
||||||
const statuses = [
|
export const statuses = [
|
||||||
'late',
|
'late',
|
||||||
'missing',
|
'missing',
|
||||||
'resubmitted',
|
'resubmitted',
|
||||||
|
@ -26,7 +26,7 @@ const statuses = [
|
||||||
'excused'
|
'excused'
|
||||||
];
|
];
|
||||||
|
|
||||||
const statusesTitleMap = {
|
export const statusesTitleMap = {
|
||||||
late: I18n.t('Late'),
|
late: I18n.t('Late'),
|
||||||
missing: I18n.t('Missing'),
|
missing: I18n.t('Missing'),
|
||||||
resubmitted: I18n.t('Resubmitted'),
|
resubmitted: I18n.t('Resubmitted'),
|
||||||
|
@ -34,8 +34,3 @@ const statusesTitleMap = {
|
||||||
excused: I18n.t('Excused')
|
excused: I18n.t('Excused')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
statuses,
|
|
||||||
statusesTitleMap
|
|
||||||
};
|
|
||||||
|
|
|
@ -18,38 +18,38 @@
|
||||||
|
|
||||||
import GRADEBOOK_TRANSLATIONS from 'compiled/gradebook/GradebookTranslations'
|
import GRADEBOOK_TRANSLATIONS from 'compiled/gradebook/GradebookTranslations'
|
||||||
|
|
||||||
const MULTIPLIER = 1.5;
|
const MULTIPLIER = 1.5
|
||||||
|
|
||||||
const isNegativePoints = function(score) {
|
function isNegativePoints (score) {
|
||||||
return score < 0;
|
return score < 0
|
||||||
};
|
}
|
||||||
|
|
||||||
const isUnusuallyHigh = function(score, pointsPossible) {
|
export function isUnusuallyHigh(score, pointsPossible) {
|
||||||
if (pointsPossible === 0 || pointsPossible == null) { return false; }
|
if (pointsPossible === 0 || pointsPossible == null) {
|
||||||
const outlierBoundary = pointsPossible * MULTIPLIER;
|
return false
|
||||||
return score >= outlierBoundary;
|
}
|
||||||
};
|
const outlierBoundary = pointsPossible * MULTIPLIER
|
||||||
|
return score >= outlierBoundary
|
||||||
|
}
|
||||||
|
|
||||||
class OutlierScoreHelper {
|
export default class OutlierScoreHelper {
|
||||||
constructor(score, pointsPossible) {
|
constructor(score, pointsPossible) {
|
||||||
this.score = score;
|
this.score = score
|
||||||
this.pointsPossible = pointsPossible;
|
this.pointsPossible = pointsPossible
|
||||||
|
}
|
||||||
|
|
||||||
|
hasWarning() {
|
||||||
|
// mutually exclusive
|
||||||
|
return isNegativePoints(this.score) || isUnusuallyHigh(this.score, this.pointsPossible)
|
||||||
|
}
|
||||||
|
|
||||||
|
warningMessage() {
|
||||||
|
if (isNegativePoints(this.score)) {
|
||||||
|
return GRADEBOOK_TRANSLATIONS.submission_negative_points_warning
|
||||||
|
} else if (isUnusuallyHigh(this.score, this.pointsPossible)) {
|
||||||
|
return GRADEBOOK_TRANSLATIONS.submission_too_many_points_warning
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
hasWarning() {
|
}
|
||||||
// mutually exclusive
|
|
||||||
return isNegativePoints(this.score) || isUnusuallyHigh(this.score, this.pointsPossible);
|
|
||||||
}
|
|
||||||
|
|
||||||
warningMessage() {
|
|
||||||
if (isNegativePoints(this.score)) {
|
|
||||||
return GRADEBOOK_TRANSLATIONS.submission_negative_points_warning;
|
|
||||||
} else if (isUnusuallyHigh(this.score, this.pointsPossible)) {
|
|
||||||
return GRADEBOOK_TRANSLATIONS.submission_too_many_points_warning;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export { OutlierScoreHelper as default, isUnusuallyHigh }
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import CloseButton from '@instructure/ui-buttons/lib/components/CloseButton'
|
||||||
import IconGroup from '@instructure/ui-icons/lib/Line/IconGroup'
|
import IconGroup from '@instructure/ui-icons/lib/Line/IconGroup'
|
||||||
import Spinner from '@instructure/ui-elements/lib/components/Spinner'
|
import Spinner from '@instructure/ui-elements/lib/components/Spinner'
|
||||||
import PresentationContent from '@instructure/ui-a11y/lib/components/PresentationContent'
|
import PresentationContent from '@instructure/ui-a11y/lib/components/PresentationContent'
|
||||||
import {post} from 'axios'
|
import axios from 'axios'
|
||||||
import {string} from 'prop-types'
|
import {string} from 'prop-types'
|
||||||
|
|
||||||
export default class GeneratePairingCode extends Component {
|
export default class GeneratePairingCode extends Component {
|
||||||
|
@ -50,7 +50,7 @@ export default class GeneratePairingCode extends Component {
|
||||||
|
|
||||||
generatePairingCode = () => {
|
generatePairingCode = () => {
|
||||||
this.setState({ gettingPairingCode: true, pairingCodeError: false })
|
this.setState({ gettingPairingCode: true, pairingCodeError: false })
|
||||||
post(`/api/v1/users/${this.props.userId}/observer_pairing_codes`)
|
axios.post(`/api/v1/users/${this.props.userId}/observer_pairing_codes`)
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
gettingPairingCode: false,
|
gettingPairingCode: false,
|
||||||
|
|
|
@ -168,6 +168,8 @@ module.exports = {
|
||||||
],
|
],
|
||||||
exclude: [
|
exclude: [
|
||||||
path.resolve(__dirname, '../public/javascripts/translations'),
|
path.resolve(__dirname, '../public/javascripts/translations'),
|
||||||
|
path.resolve(__dirname, '../public/javascripts/react-dnd-test-backend'),
|
||||||
|
path.resolve(__dirname, '../public/javascripts/lodash.underscore'),
|
||||||
/bower\//,
|
/bower\//,
|
||||||
],
|
],
|
||||||
loaders: happify('babel', [
|
loaders: happify('babel', [
|
||||||
|
|
|
@ -21,12 +21,12 @@
|
||||||
// back a Backbone with all of our instructure specific patches to it.
|
// back a Backbone with all of our instructure specific patches to it.
|
||||||
|
|
||||||
// Get the unpatched Backbone
|
// Get the unpatched Backbone
|
||||||
import Backbone from 'node_modules-version-of-backbone'
|
const Backbone = require('node_modules-version-of-backbone')
|
||||||
|
|
||||||
// Apply all of our patches
|
// Apply all of our patches
|
||||||
import 'compiled/backbone-ext/Backbone.syncWithMultipart'
|
require('compiled/backbone-ext/Backbone.syncWithMultipart')
|
||||||
import 'compiled/backbone-ext/Model'
|
require('compiled/backbone-ext/Model')
|
||||||
import 'compiled/backbone-ext/View'
|
require('compiled/backbone-ext/View')
|
||||||
import 'compiled/backbone-ext/Collection'
|
require('compiled/backbone-ext/Collection')
|
||||||
|
|
||||||
export default Backbone
|
module.exports = Backbone
|
||||||
|
|
|
@ -22,7 +22,7 @@ import PublishCloud from 'jsx/shared/PublishCloud'
|
||||||
import ModuleDuplicationSpinner from 'jsx/modules/components/ModuleDuplicationSpinner'
|
import ModuleDuplicationSpinner from 'jsx/modules/components/ModuleDuplicationSpinner'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import * as MoveItem from 'jsx/move_item'
|
import {reorderElements, renderTray} from 'jsx/move_item'
|
||||||
import PublishableModuleItem from 'compiled/models/PublishableModuleItem'
|
import PublishableModuleItem from 'compiled/models/PublishableModuleItem'
|
||||||
import PublishIconView from 'compiled/views/PublishIconView'
|
import PublishIconView from 'compiled/views/PublishIconView'
|
||||||
import LockIconView from 'compiled/views/LockIconView'
|
import LockIconView from 'compiled/views/LockIconView'
|
||||||
|
@ -1275,13 +1275,13 @@ function scrollTo ($thing, time = 500) {
|
||||||
$container[0].appendChild(item)
|
$container[0].appendChild(item)
|
||||||
|
|
||||||
const order = data.context_module.content_tags.map(item => item.content_tag.id)
|
const order = data.context_module.content_tags.map(item => item.content_tag.id)
|
||||||
MoveItem.reorderElements(order, $container[0], id => `#context_module_item_${id}`)
|
reorderElements(order, $container[0], id => `#context_module_item_${id}`)
|
||||||
$container.sortable('enable').sortable('refresh')
|
$container.sortable('enable').sortable('refresh')
|
||||||
},
|
},
|
||||||
focusOnExit: () => currentItem.querySelector('.al-trigger'),
|
focusOnExit: () => currentItem.querySelector('.al-trigger'),
|
||||||
}
|
}
|
||||||
|
|
||||||
MoveItem.renderTray(moveTrayProps, document.getElementById('not_right_side'))
|
renderTray(moveTrayProps, document.getElementById('not_right_side'))
|
||||||
})
|
})
|
||||||
|
|
||||||
$('.move_module_link').on('click keyclick', function (event) {
|
$('.move_module_link').on('click keyclick', function (event) {
|
||||||
|
|
|
@ -197,7 +197,7 @@ import YouTubeApi from './youtube_api'
|
||||||
var $editor = $box.data('editor');
|
var $editor = $box.data('editor');
|
||||||
var $target = $(event.target);
|
var $target = $(event.target);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
RceCommandShim.send($editor, 'insert_code', buttonToImg($target));
|
send($editor, 'insert_code', buttonToImg($target));
|
||||||
$box.dialog('close');
|
$box.dialog('close');
|
||||||
});
|
});
|
||||||
// http://img.youtube.com/vi/BOegH4uYe-c/3.jpg
|
// http://img.youtube.com/vi/BOegH4uYe-c/3.jpg
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
|
|
||||||
////
|
////
|
||||||
// if you want underscore in your code. require 'underscore' (this file)
|
// if you want underscore in your code. require 'underscore' (this file)
|
||||||
|
const _ = require('vendor/lodash.underscore')
|
||||||
import _ from 'vendor/lodash.underscore'
|
|
||||||
|
|
||||||
// grab the global '_' variable, make it not global and return it
|
// grab the global '_' variable, make it not global and return it
|
||||||
export default _.noConflict();
|
module.exports = _.noConflict();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
import h from '../../str/htmlEscape'
|
import h from '../../str/htmlEscape'
|
||||||
import returnValOfUnpatchedDialog from 'jqueryui/dialog-unpatched'
|
import 'jqueryui/dialog-unpatched'
|
||||||
|
|
||||||
// have UI dialogs default to modal:true
|
// have UI dialogs default to modal:true
|
||||||
$.ui.dialog.prototype.options.modal = true
|
$.ui.dialog.prototype.options.modal = true
|
||||||
|
@ -41,5 +41,3 @@ import returnValOfUnpatchedDialog from 'jqueryui/dialog-unpatched'
|
||||||
return setOption.call(this, key, value);
|
return setOption.call(this, key, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default returnValOfUnpatchedDialog;
|
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
import returnValueOfUnpatchedDraggable from 'jqueryui/draggable-unpatched'
|
import 'jqueryui/draggable-unpatched'
|
||||||
import 'jquery-ui-touch-punch'
|
import 'jquery-ui-touch-punch'
|
||||||
|
|
||||||
export default returnValueOfUnpatchedDraggable
|
|
||||||
|
|
|
@ -1,36 +1,38 @@
|
||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
import returnValueOfUnpatchedWidget from 'jqueryui/widget-unpatched'
|
import 'jqueryui/widget-unpatched'
|
||||||
|
|
||||||
// This function is the same as $.widget.extend
|
// This function is the same as $.widget.extend
|
||||||
// except for this additional check on the target:
|
// except for this additional check on the target:
|
||||||
// && $.isPlainObject(target[key])
|
// && $.isPlainObject(target[key])
|
||||||
//
|
//
|
||||||
// The change is because it was merging strings and objects
|
// The change is because it was merging strings and objects
|
||||||
// which caused problems. Here's an example of what it was doing:
|
// which caused problems. Here's an example of what it was doing:
|
||||||
// $.widget.extend({}, {handle: 'e,s,se'}, {handle: {s: 'div.ui-resizable-s'}})
|
// $.widget.extend({}, {handle: 'e,s,se'}, {handle: {s: 'div.ui-resizable-s'}})
|
||||||
// => {0: 'e',
|
// => {0: 'e',
|
||||||
// 1: ',',
|
// 1: ',',
|
||||||
// 2: 's',
|
// 2: 's',
|
||||||
// 3: ',',
|
// 3: ',',
|
||||||
// 4: 's',
|
// 4: 's',
|
||||||
// 5: 'e',
|
// 5: 'e',
|
||||||
// s: 'div.ui-resizable-s'}
|
// s: 'div.ui-resizable-s'}
|
||||||
$.widget.extend = function( target ) {
|
$.widget.extend = function(target) {
|
||||||
var input = Array.prototype.slice.call( arguments, 1 ),
|
var input = Array.prototype.slice.call(arguments, 1),
|
||||||
inputIndex = 0,
|
inputIndex = 0,
|
||||||
inputLength = input.length,
|
inputLength = input.length,
|
||||||
key,
|
key,
|
||||||
value;
|
value
|
||||||
for ( ; inputIndex < inputLength; inputIndex++ ) {
|
for (; inputIndex < inputLength; inputIndex++) {
|
||||||
for ( key in input[ inputIndex ] ) {
|
for (key in input[inputIndex]) {
|
||||||
value = input[ inputIndex ][ key ];
|
value = input[inputIndex][key]
|
||||||
if (input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
|
if (input[inputIndex].hasOwnProperty(key) && value !== undefined) {
|
||||||
target[ key ] = $.isPlainObject( value ) && $.isPlainObject(target[key]) ? $.widget.extend( {}, target[ key ], value ) : value;
|
target[key] =
|
||||||
}
|
$.isPlainObject(value) && $.isPlainObject(target[key])
|
||||||
|
? $.widget.extend({}, target[key], value)
|
||||||
|
: value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return target;
|
}
|
||||||
};
|
return target
|
||||||
|
}
|
||||||
export default returnValueOfUnpatchedWidget;
|
|
||||||
|
|
||||||
|
export default $
|
||||||
|
|
|
@ -21,7 +21,7 @@ import UnassignedGroupUserCollection from 'compiled/collections/UnassignedGroupU
|
||||||
import GroupCategory from 'compiled/models/GroupCategory'
|
import GroupCategory from 'compiled/models/GroupCategory'
|
||||||
import GroupUser from 'compiled/models/GroupUser'
|
import GroupUser from 'compiled/models/GroupUser'
|
||||||
import Group from 'compiled/models/Group'
|
import Group from 'compiled/models/Group'
|
||||||
import {Collection} from 'Backbone'
|
import Backbone from 'Backbone'
|
||||||
|
|
||||||
let source = null
|
let source = null
|
||||||
let target = null
|
let target = null
|
||||||
|
@ -32,7 +32,7 @@ QUnit.module('GroupUserCollection', {
|
||||||
setup() {
|
setup() {
|
||||||
group = new Group({id: 1})
|
group = new Group({id: 1})
|
||||||
const category = new GroupCategory()
|
const category = new GroupCategory()
|
||||||
category._groups = new Collection([group])
|
category._groups = new Backbone.Collection([group])
|
||||||
users = [
|
users = [
|
||||||
new GroupUser({
|
new GroupUser({
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import GradeCalculatorSpecHelper from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
|
import {createCourseGradesWithGradingPeriods as createExampleGrades} from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
|
||||||
import Gradebook from 'compiled/gradebook/Gradebook'
|
import Gradebook from 'compiled/gradebook/Gradebook'
|
||||||
import DataLoader from 'jsx/gradebook/DataLoader'
|
import DataLoader from 'jsx/gradebook/DataLoader'
|
||||||
import _ from 'underscore'
|
import _ from 'underscore'
|
||||||
|
@ -43,8 +43,6 @@ const exampleGradebookOptions = {
|
||||||
sections: []
|
sections: []
|
||||||
}
|
}
|
||||||
|
|
||||||
const createExampleGrades = GradeCalculatorSpecHelper.createCourseGradesWithGradingPeriods
|
|
||||||
|
|
||||||
QUnit.module('Gradebook')
|
QUnit.module('Gradebook')
|
||||||
|
|
||||||
test('normalizes the grading period set from the env', function() {
|
test('normalizes the grading period set from the env', function() {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
export default {
|
||||||
setup(options = {}) {
|
setup(options = {}) {
|
||||||
if (!window.ENV) window.ENV = {}
|
if (!window.ENV) window.ENV = {}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
import environment from 'jsx/gradebook-history/environment';
|
import environment from 'jsx/gradebook-history/environment';
|
||||||
import GradebookHistoryStore from 'jsx/gradebook-history/store/GradebookHistoryStore';
|
import GradebookHistoryStore from 'jsx/gradebook-history/store/GradebookHistoryStore';
|
||||||
import HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
|
import * as HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
|
||||||
import HistoryApi from 'jsx/gradebook-history/api/HistoryApi';
|
import HistoryApi from 'jsx/gradebook-history/api/HistoryApi';
|
||||||
import SearchFormActions, {
|
import SearchFormActions, {
|
||||||
CLEAR_RECORDS,
|
CLEAR_RECORDS,
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
|
|
||||||
import Fixtures from '../../gradebook-history/Fixtures';
|
import Fixtures from '../../gradebook-history/Fixtures';
|
||||||
import GradebookHistoryStore from 'jsx/gradebook-history/store/GradebookHistoryStore';
|
import GradebookHistoryStore from 'jsx/gradebook-history/store/GradebookHistoryStore';
|
||||||
import HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
|
import * as HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
|
||||||
import HistoryApi from 'jsx/gradebook-history/api/HistoryApi';
|
import HistoryApi from 'jsx/gradebook-history/api/HistoryApi';
|
||||||
import SearchResultsActions from 'jsx/gradebook-history/actions/SearchResultsActions';
|
import * as SearchResultsActions from 'jsx/gradebook-history/actions/SearchResultsActions';
|
||||||
|
|
||||||
QUnit.module('SearchResultsActionsSpec getHistoryNextPage', {
|
QUnit.module('SearchResultsActionsSpec getHistoryNextPage', {
|
||||||
setup () {
|
setup () {
|
||||||
|
|
|
@ -16,61 +16,57 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const GradeCalculatorSpecHelper = {
|
export function createCourseGradesWithGradingPeriods() {
|
||||||
createCourseGradesWithGradingPeriods() {
|
return {
|
||||||
return {
|
assignmentGroups: {
|
||||||
assignmentGroups: {
|
301: {
|
||||||
301: {
|
assignmentGroupId: 301,
|
||||||
assignmentGroupId: 301,
|
assignmentGroupWeight: 40,
|
||||||
assignmentGroupWeight: 40,
|
current: {score: 5, possible: 10, submissions: []},
|
||||||
current: {score: 5, possible: 10, submissions: []},
|
final: {score: 5, possible: 20, submissions: []}
|
||||||
final: {score: 5, possible: 20, submissions: []}
|
|
||||||
},
|
|
||||||
|
|
||||||
302: {
|
|
||||||
assignmentGroupId: 302,
|
|
||||||
assignmentGroupWeight: 60,
|
|
||||||
current: {score: 12, possible: 15, submissions: []},
|
|
||||||
final: {score: 12, possible: 25, submissions: []}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
gradingPeriods: {
|
302: {
|
||||||
701: {
|
assignmentGroupId: 302,
|
||||||
gradingPeriodId: 701,
|
assignmentGroupWeight: 60,
|
||||||
gradingPeriodWeight: 25,
|
current: {score: 12, possible: 15, submissions: []},
|
||||||
assignmentGroups: {
|
final: {score: 12, possible: 25, submissions: []}
|
||||||
301: {
|
}
|
||||||
assignmentGroupId: 301,
|
},
|
||||||
assignmentGroupWeight: 40,
|
|
||||||
current: {score: 5, possible: 10, submissions: []},
|
|
||||||
final: {score: 5, possible: 20, submissions: []}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
current: {score: 5, possible: 10, submissions: []},
|
|
||||||
final: {score: 5, possible: 20, submissions: []}
|
|
||||||
},
|
|
||||||
|
|
||||||
702: {
|
gradingPeriods: {
|
||||||
gradingPeriodId: 702,
|
701: {
|
||||||
gradingPeriodWeight: 75,
|
gradingPeriodId: 701,
|
||||||
assignmentGroups: {
|
gradingPeriodWeight: 25,
|
||||||
302: {
|
assignmentGroups: {
|
||||||
assignmentGroupId: 302,
|
301: {
|
||||||
assignmentGroupWeight: 60,
|
assignmentGroupId: 301,
|
||||||
current: {score: 12, possible: 15, submissions: []},
|
assignmentGroupWeight: 40,
|
||||||
final: {score: 12, possible: 25, submissions: []}
|
current: {score: 5, possible: 10, submissions: []},
|
||||||
}
|
final: {score: 5, possible: 20, submissions: []}
|
||||||
},
|
}
|
||||||
current: {score: 12, possible: 15, submissions: []},
|
},
|
||||||
final: {score: 12, possible: 25, submissions: []}
|
current: {score: 5, possible: 10, submissions: []},
|
||||||
}
|
final: {score: 5, possible: 20, submissions: []}
|
||||||
},
|
},
|
||||||
|
|
||||||
current: {score: 17, possible: 25, submissions: []},
|
702: {
|
||||||
final: {score: 17, possible: 45, submissions: []}
|
gradingPeriodId: 702,
|
||||||
}
|
gradingPeriodWeight: 75,
|
||||||
|
assignmentGroups: {
|
||||||
|
302: {
|
||||||
|
assignmentGroupId: 302,
|
||||||
|
assignmentGroupWeight: 60,
|
||||||
|
current: {score: 12, possible: 15, submissions: []},
|
||||||
|
final: {score: 12, possible: 25, submissions: []}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
current: {score: 12, possible: 15, submissions: []},
|
||||||
|
final: {score: 12, possible: 25, submissions: []}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
current: {score: 17, possible: 25, submissions: []},
|
||||||
|
final: {score: 17, possible: 45, submissions: []}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GradeCalculatorSpecHelper
|
|
||||||
|
|
|
@ -17,10 +17,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { Editors, Grid } from 'vendor/slickgrid';
|
import slickgrid from 'vendor/slickgrid';
|
||||||
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
||||||
import SlickGridSpecHelper from './SlickGridSpecHelper'
|
import SlickGridSpecHelper from './SlickGridSpecHelper'
|
||||||
|
|
||||||
|
const { Editors, Grid } = slickgrid
|
||||||
|
|
||||||
function createColumns () {
|
function createColumns () {
|
||||||
return [1, 2, 3, 4].map(id => (
|
return [1, 2, 3, 4].map(id => (
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,9 +16,11 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Editors, Grid } from 'vendor/slickgrid';
|
import slickgrid from 'vendor/slickgrid';
|
||||||
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
||||||
|
|
||||||
|
const { Editors, Grid } = slickgrid
|
||||||
|
|
||||||
function createColumns () {
|
function createColumns () {
|
||||||
return [1, 2, 3, 4].map(id => (
|
return [1, 2, 3, 4].map(id => (
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,9 +17,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'jquery.keycodes'; // used by some SlickGrid editors
|
import 'jquery.keycodes'; // used by some SlickGrid editors
|
||||||
import { Grid, Editors } from 'vendor/slickgrid';
|
import slickgrid from 'vendor/slickgrid';
|
||||||
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
||||||
|
|
||||||
|
const { Grid, Editors } = slickgrid
|
||||||
|
|
||||||
const keyMap = {
|
const keyMap = {
|
||||||
Tab: { which: 9, shiftKey: false },
|
Tab: { which: 9, shiftKey: false },
|
||||||
ShiftTab: { which: 9, shiftKey: true },
|
ShiftTab: { which: 9, shiftKey: true },
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'jquery.keycodes'; // used by some SlickGrid editors
|
import 'jquery.keycodes'; // used by some SlickGrid editors
|
||||||
import { Editors, GlobalEditorLock, Grid } from 'vendor/slickgrid';
|
import slickgrid from 'vendor/slickgrid';
|
||||||
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
||||||
|
|
||||||
|
const { Editors, GlobalEditorLock, Grid } = slickgrid
|
||||||
const $fixtures = document.getElementById('fixtures');
|
const $fixtures = document.getElementById('fixtures');
|
||||||
|
|
||||||
function createColumns () {
|
function createColumns () {
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Editors, Grid } from 'vendor/slickgrid';
|
import slickgrid from 'vendor/slickgrid';
|
||||||
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
|
||||||
|
|
||||||
|
const { Editors, Grid } = slickgrid
|
||||||
const $fixtures = document.getElementById('fixtures');
|
const $fixtures = document.getElementById('fixtures');
|
||||||
|
|
||||||
function createColumns () {
|
function createColumns () {
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
|
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { createGradebook, setFixtureHtml } from '../../GradebookSpecHelper';
|
import { createGradebook, setFixtureHtml } from '../../GradebookSpecHelper';
|
||||||
import AssignmentColumnHeaderRenderer
|
import AssignmentColumnHeaderRenderer from 'jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer'
|
||||||
from 'jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer'
|
|
||||||
|
|
||||||
QUnit.module('AssignmentColumnHeaderRenderer', function (suiteHooks) {
|
QUnit.module('AssignmentColumnHeaderRenderer', function (suiteHooks) {
|
||||||
let $container;
|
let $container;
|
||||||
|
|
|
@ -24,7 +24,7 @@ import fakeENV from 'helpers/fakeENV'
|
||||||
import numberHelper from 'jsx/shared/helpers/numberHelper'
|
import numberHelper from 'jsx/shared/helpers/numberHelper'
|
||||||
import CourseGradeCalculator from 'jsx/gradebook/CourseGradeCalculator'
|
import CourseGradeCalculator from 'jsx/gradebook/CourseGradeCalculator'
|
||||||
import GradeSummary from 'jsx/grading/GradeSummary'
|
import GradeSummary from 'jsx/grading/GradeSummary'
|
||||||
import GradeCalculatorSpecHelper from '../gradebook/GradeCalculatorSpecHelper'
|
import {createCourseGradesWithGradingPeriods} from '../gradebook/GradeCalculatorSpecHelper'
|
||||||
|
|
||||||
const $fixtures = $('#fixtures')
|
const $fixtures = $('#fixtures')
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ QUnit.module('GradeSummary.calculateGrades', {
|
||||||
}
|
}
|
||||||
ENV.effective_due_dates = {201: {101: {grading_period_id: '701'}}}
|
ENV.effective_due_dates = {201: {101: {grading_period_id: '701'}}}
|
||||||
ENV.student_id = '101'
|
ENV.student_id = '101'
|
||||||
exampleGrades = GradeCalculatorSpecHelper.createCourseGradesWithGradingPeriods()
|
exampleGrades = createCourseGradesWithGradingPeriods()
|
||||||
sandbox.stub(CourseGradeCalculator, 'calculate').returns(exampleGrades)
|
sandbox.stub(CourseGradeCalculator, 'calculate').returns(exampleGrades)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {encodeSpecialChars, decodeSpecialChars} from 'jsx/shared/helpers/urlHelper'
|
import urlHelper from 'jsx/shared/helpers/urlHelper'
|
||||||
|
|
||||||
QUnit.module('Url Helper')
|
QUnit.module('Url Helper')
|
||||||
|
|
||||||
test('encodes % properly', () => {
|
test('encodes % properly', () => {
|
||||||
equal(encodeSpecialChars('/some/path%thing'), '/some/path%thing')
|
equal(urlHelper.encodeSpecialChars('/some/path%thing'), '/some/path%thing')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('decodes the encoded % properly', () => {
|
test('decodes the encoded % properly', () => {
|
||||||
equal(decodeSpecialChars('/some/path%26%2337%3Bthing'), '/some/path%25thing')
|
equal(urlHelper.decodeSpecialChars('/some/path%26%2337%3Bthing'), '/some/path%25thing')
|
||||||
})
|
})
|
||||||
|
|
|
@ -27,7 +27,9 @@ import fakeENV from 'helpers/fakeENV';
|
||||||
import natcompare from 'compiled/util/natcompare';
|
import natcompare from 'compiled/util/natcompare';
|
||||||
import numberHelper from 'jsx/shared/helpers/numberHelper';
|
import numberHelper from 'jsx/shared/helpers/numberHelper';
|
||||||
import userSettings from 'compiled/userSettings';
|
import userSettings from 'compiled/userSettings';
|
||||||
import {unescape} from 'str/htmlEscape';
|
import htmlEscape from 'str/htmlEscape';
|
||||||
|
|
||||||
|
const {unescape} = htmlEscape;
|
||||||
|
|
||||||
import 'jquery.ajaxJSON';
|
import 'jquery.ajaxJSON';
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import htmlEscape, {unescape} from 'str/htmlEscape'
|
import htmlEscape from 'str/htmlEscape'
|
||||||
|
|
||||||
|
const {unescape} = htmlEscape
|
||||||
|
|
||||||
QUnit.module('htmlEscape', () => {
|
QUnit.module('htmlEscape', () => {
|
||||||
QUnit.module('.htmlEscape()', () => {
|
QUnit.module('.htmlEscape()', () => {
|
||||||
|
|
Loading…
Reference in New Issue