fix sorting on agenda view
the results of the events and assignments api request were not being properly merged into a sorted list. fixes CNVS-9037 test plan: - create a bunch of days that contain only events. - interleave a bunch of days that contain only assignments. - verify that the agenda view is sorted correctly. - verify that "load more" works properly. Change-Id: I7f5c203149bb854496e64af053170b50361b7a96 Reviewed-on: https://gerrit.instructure.com/25641 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Braden Anderson <banderson@instructure.com> Product-Review: Marc LeGendre <marc@instructure.com> QA-Review: Marc LeGendre <marc@instructure.com>
This commit is contained in:
parent
76a40a005b
commit
22fcb45b3d
|
@ -7,14 +7,6 @@ define [
|
|||
'vendor/jquery.ba-tinypubsub'
|
||||
], (I18n, _, Backbone, CalendarEventCollection, template) ->
|
||||
|
||||
|
||||
# Public: Helper function translate a model date string into a date object.
|
||||
#
|
||||
# m - A model instance.
|
||||
# prop - The name of the date property (default: 'start_at').
|
||||
toDate = _.compose(((d) -> new Date(d)),
|
||||
((m, prop = 'start_at') -> if m.get then m.get(prop) else m[prop]))
|
||||
|
||||
class AgendaView extends Backbone.View
|
||||
|
||||
PER_PAGE: 50
|
||||
|
@ -74,23 +66,31 @@ define [
|
|||
@eventCollection.canFetch('next') or
|
||||
@assignmentCollection.canFetch('next')
|
||||
|
||||
# Public: Helper function to translate a model date into a timestamp.
|
||||
# Public: Helper function translate a model date string into a date object.
|
||||
#
|
||||
# m - A model instance.
|
||||
#
|
||||
# Returns a Date object.
|
||||
toDate: (m) -> new Date(m.get('start_at'))
|
||||
|
||||
# Internal: Helper function to translate a model date into a timestamp.
|
||||
#
|
||||
# m - A model instance.
|
||||
# prop - The name of the date property (default: 'start_at').
|
||||
#
|
||||
# Returns a timestamp integer.
|
||||
toTime: _.compose(((d) -> d.getTime()), toDate)
|
||||
toTime: (m) => @toDate(m).getTime()
|
||||
|
||||
# Public: Helper function to translate a model date into a fudged date.
|
||||
# Internal: Helper function to translate a model date into a fudged date.
|
||||
#
|
||||
# m - A model instance.
|
||||
# m - A model instance or hash.
|
||||
# prop - The name of the date property (default: 'start_at').
|
||||
#
|
||||
# Returns a fudged date.
|
||||
toFudgedDate: _.compose(((d) -> $.fudgeDateForProfileTimezone(d)), toDate)
|
||||
toFudgedDate: (m, prop = 'start_at') =>
|
||||
d = if m.get then m.get(prop) else m[prop]
|
||||
$.fudgeDateForProfileTimezone(new Date(d))
|
||||
|
||||
# Public: Given two collections, determine the latest shared date.
|
||||
# Internal: Given two collections, determine the latest shared date.
|
||||
#
|
||||
# c1 - Collection object.
|
||||
# c2 - Collection object.
|
||||
|
@ -108,37 +108,87 @@ define [
|
|||
else
|
||||
null
|
||||
|
||||
# Public: Translate a list of event models to a hash.
|
||||
# Internal: Change a flat array of objects into a sturctured array of
|
||||
# objects based on the given iterator function. Similar to _.groupBy,
|
||||
# except the result is an Array instead of a Hash and this function
|
||||
# assumes the list is already sorted by the given iterator.
|
||||
#
|
||||
# list - An array of model objects.
|
||||
# limit - A timestamp to stop returning events after (default: null).
|
||||
# list - The sorted list of values to box.
|
||||
# iterator - A function that returns the value to box by. The iterator
|
||||
# is passed the value from the list.
|
||||
#
|
||||
# Returns a hash.
|
||||
eventListToHash: (list, limit = null) =>
|
||||
_.reduce(list, (result, event) =>
|
||||
return result if limit and limit < @toTime(event)
|
||||
# Returns a new boxed array with elemens from the given list.
|
||||
sortedBoxBy: (list, iterator) ->
|
||||
_.reduce(list, (result, currentElt) ->
|
||||
return [[currentElt]] if _.isEmpty(result)
|
||||
|
||||
previousBox = _.last(result)
|
||||
previousElt = _.last(previousBox)
|
||||
if iterator(currentElt) == iterator(previousElt)
|
||||
previousBox.push(currentElt)
|
||||
else
|
||||
result.push([currentElt])
|
||||
|
||||
result
|
||||
, [])
|
||||
|
||||
# Internal: Do necessary changes on each event model in the list
|
||||
#
|
||||
# list - the list of the events to prepare
|
||||
#
|
||||
# Returns nothing.
|
||||
prepareEvents: (list) ->
|
||||
prepare = (event) ->
|
||||
event.set('start_at', @toFudgedDate(event))
|
||||
day = I18n.l('#date.formats.short_with_weekday', toDate(event))
|
||||
if assignment = event.get('assignment')
|
||||
assignment.due_at = @toFudgedDate(assignment, 'due_at')
|
||||
result[day] or= []
|
||||
result[day].push(event.toJSON())
|
||||
result
|
||||
, {})
|
||||
|
||||
# Public: Format a hash of event data to an object ready to be sent to the template.
|
||||
#
|
||||
# result - A hash of event data from AgendaView#toJSON.
|
||||
#
|
||||
# Returns an object.
|
||||
formatResult: (events) =>
|
||||
result = {days: [], meta: {}}
|
||||
result.days.push(date: key, events: events[key]) for key of events
|
||||
result.meta.hasMore = @hasMore()
|
||||
result
|
||||
_.each(list, prepare, this)
|
||||
|
||||
# Internal: returns the 'start_at' of the event formatted for the template
|
||||
#
|
||||
# event - the event to format
|
||||
#
|
||||
# Returns the formatted String
|
||||
formattedDayString: (event) =>
|
||||
I18n.l('#date.formats.short_with_weekday', @toDate(event))
|
||||
|
||||
# Internal: change a box of events into an output hash for toJSON
|
||||
#
|
||||
# events - a box of events (all the events occur on the same day)
|
||||
#
|
||||
# Returns an Object with 'date' and 'events' keys.
|
||||
eventBoxToHash: (events) =>
|
||||
date: @formattedDayString(_.first(events))
|
||||
events: _.map(events, (e) -> e.toJSON())
|
||||
|
||||
# Internal: Format a hash of event data to an object ready to be sent to the template.
|
||||
#
|
||||
# boxedEvents - A boxed list of events
|
||||
#
|
||||
# Returns an object in the format specified by toJSON.
|
||||
formatResult: (boxedEvents) ->
|
||||
days: _.map(boxedEvents, @eventBoxToHash)
|
||||
meta:
|
||||
hasMore: @hasMore()
|
||||
|
||||
# Public: Creates the json for the template.
|
||||
#
|
||||
# Returns an Object:
|
||||
# {
|
||||
# days: [
|
||||
# [date: 'some date', events: [event1.toJSON(), event2.toJSON()],
|
||||
# [date: ...]
|
||||
# ],
|
||||
# meta: {
|
||||
# hasMore: true/false
|
||||
# }
|
||||
# }
|
||||
toJSON: ->
|
||||
limit = @limitOf(@eventCollection, @assignmentCollection)
|
||||
list = _.union(@eventCollection.models, @assignmentCollection.models)
|
||||
_.compose(@formatResult, @eventListToHash)(list, limit)
|
||||
limit = @limitOf(@eventCollection, @assignmentCollection)
|
||||
list = _.union(@eventCollection.models, @assignmentCollection.models)
|
||||
list = _.filter(list, (e) => @toTime(e) < limit) if limit
|
||||
list = _.sortBy(list, @toTime)
|
||||
@prepareEvents(list)
|
||||
list = @sortedBoxBy(list, @formattedDayString)
|
||||
@formatResult(list)
|
||||
|
|
|
@ -34,7 +34,24 @@ require [
|
|||
ok @container.find('.ig-row').length == 18
|
||||
|
||||
# should bin results by day
|
||||
ok @container.find('.agenda-date').length == 9
|
||||
dates = @container.find('.agenda-date')
|
||||
ok dates.length == 10
|
||||
|
||||
# the bins should be sorted properly
|
||||
textDates = _.map(dates, (d) -> d.innerText)
|
||||
console.log(textDates)
|
||||
ok _.isEqual(textDates, [
|
||||
"Mon, Oct 7"
|
||||
"Tue, Oct 8"
|
||||
"Wed, Oct 9"
|
||||
"Thu, Oct 10"
|
||||
"Fri, Oct 11"
|
||||
"Sat, Oct 12"
|
||||
"Mon, Oct 14"
|
||||
"Wed, Oct 16"
|
||||
"Fri, Oct 18"
|
||||
"Fri, Nov 1"
|
||||
])
|
||||
|
||||
# should not show "load more" if there are no more pages
|
||||
ok !@container.find('.agenda-load-btn').length
|
||||
|
|
|
@ -3,7 +3,7 @@ define [], () ->
|
|||
[
|
||||
{
|
||||
"all_day": true,
|
||||
"all_day_date": "2013-10-11",
|
||||
"all_day_date": "2013-10-12",
|
||||
"created_at": "2013-10-07T22:46:01Z",
|
||||
"title": "Book report",
|
||||
"updated_at": "2013-10-07T22:46:01Z",
|
||||
|
@ -14,7 +14,7 @@ define [], () ->
|
|||
"assignment_group_id": "2",
|
||||
"automatic_peer_reviews": false,
|
||||
"description": null,
|
||||
"due_at": "2013-10-12T05:59:59Z",
|
||||
"due_at": "2013-10-13T05:59:59Z",
|
||||
"grade_group_students_individually": null,
|
||||
"grading_standard_id": null,
|
||||
"grading_type": "points",
|
||||
|
@ -36,8 +36,8 @@ define [], () ->
|
|||
"locked_for_user": false
|
||||
},
|
||||
"context_code": "course_2",
|
||||
"end_at": "2013-10-12T05:59:59Z",
|
||||
"start_at": "2013-10-12T05:59:59Z",
|
||||
"end_at": "2013-10-13T05:59:59Z",
|
||||
"start_at": "2013-10-13T05:59:59Z",
|
||||
"url": "http://canvas.dev/api/v1/calendar_events/assignment_6",
|
||||
"html_url": "http://canvas.dev/courses/2/assignments/6"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue