render calendar events as paginated data is fetched
fixes PFS-3691 note that the event source caching does not update as pages are fetched so switching between calendar pages while pages are fetching clears any already loaded events and effectively reverts to unpaginated rendering. the changes to fullcalendar are unfortunate but if they are removed (in an upgrade, for example) then the calendar will revert to unpaginated rendering. also, the api is unchanged for anyone who does not want to use paginated rendering. test plan - have enough calendar events to have multiple pages of them. default page size is 50, but you can set per_page in the render_events_for_user Api.paginate call to lower that for testing - view the calendar - ensure that events are rendered as the pages are fetched. you can add a sleep statement to the calendar_events_api index action to make page loads more obvious for testing. - regression test calendar Change-Id: I758dfc0eda7f3ec93bcf1b9401b1024e8a8c6303 Reviewed-on: https://gerrit.instructure.com/74029 Reviewed-by: Kacey Roberts <kroberts@instructure.com> Reviewed-by: Felix Milea-Ciobanu <fmileaciobanu@instructure.com> Tested-by: Jenkins QA-Review: Heath Hales <hhales@instructure.com> Product-Review: Allison Weiss <allison@instructure.com>
This commit is contained in:
parent
dabd3407e1
commit
1415d7bc7d
|
@ -173,7 +173,7 @@ define [
|
|||
@gotoDate(fcUtil.now())
|
||||
|
||||
# FullCalendar callbacks
|
||||
getEvents: (start, end, timezone, cb) =>
|
||||
getEvents: (start, end, timezone, donecb, datacb) =>
|
||||
@dataSource.getEvents start, end, @visibleContextList, (events) =>
|
||||
if @displayAppointmentEvents
|
||||
@dataSource.getEventsForAppointmentGroup @displayAppointmentEvents, (aEvents) =>
|
||||
|
@ -185,9 +185,14 @@ define [
|
|||
event.removeClass('current-appointment-group')
|
||||
for event in aEvents
|
||||
event.addClass('current-appointment-group')
|
||||
cb(calendarEventFilter(@displayAppointmentEvents, events.concat(aEvents)))
|
||||
donecb(calendarEventFilter(@displayAppointmentEvents, events.concat(aEvents)))
|
||||
else
|
||||
cb(calendarEventFilter(@displayAppointmentEvents, events))
|
||||
if (datacb?)
|
||||
donecb([])
|
||||
else
|
||||
donecb(calendarEventFilter(@displayAppointmentEvents, events))
|
||||
, datacb? && (events) =>
|
||||
datacb(calendarEventFilter(@displayAppointmentEvents, events))
|
||||
|
||||
# Close all event details popup on the page and have them cleaned up.
|
||||
closeEventPopups: ->
|
||||
|
|
|
@ -220,7 +220,7 @@ define [
|
|||
params = { include: [ 'reserved_times', 'participant_count', 'appointments', 'child_events' ]}
|
||||
@startFetch [[ group.url, params ]], dataCB, (() => cb @cache.appointmentGroups[group.id].appointmentEvents)
|
||||
|
||||
getEvents: (start, end, contexts, cb, options = {}) =>
|
||||
getEvents: (start, end, contexts, donecb, datacb, options = {}) =>
|
||||
if @inFlightRequest['default']
|
||||
@pendingRequests.push([@getEvents, arguments, 'default'])
|
||||
return
|
||||
|
@ -267,20 +267,25 @@ define [
|
|||
# Yay, this request can be satisfied by the cache
|
||||
list = @getEventsFromCache(start, end, contexts)
|
||||
list.requestID = options.requestID
|
||||
cb list
|
||||
datacb list if datacb?
|
||||
donecb list
|
||||
@processNextRequest()
|
||||
return
|
||||
|
||||
requestResults = {}
|
||||
dataCB = (data, url, params) =>
|
||||
return unless data
|
||||
newEvents = []
|
||||
key = 'type_'+params.type
|
||||
requestResult = requestResults[key] or {events: []}
|
||||
requestResult.next = data.next
|
||||
for e in data
|
||||
event = commonEventFactory(e, @contexts)
|
||||
if event && event.object.workflow_state != 'deleted'
|
||||
newEvents.push(event)
|
||||
requestResult.events.push(event)
|
||||
newEvents.requestID = options.requestID
|
||||
datacb newEvents if datacb?
|
||||
requestResults[key] = requestResult
|
||||
|
||||
doneCB = () =>
|
||||
|
@ -324,7 +329,7 @@ define [
|
|||
list = @getEventsFromCache(start, end, contexts)
|
||||
list.nextPageDate = nextPageDate
|
||||
list.requestID = options.requestID
|
||||
cb list
|
||||
donecb list
|
||||
|
||||
@startFetch [
|
||||
[ '/api/v1/calendar_events', params ]
|
||||
|
|
|
@ -34,7 +34,7 @@ define [
|
|||
"CommonEvent/eventSaved" : @eventSaved
|
||||
)
|
||||
|
||||
getEvents: (start, end, timezone, cb) =>
|
||||
getEvents: (start, end, timezone, donecb, datacb) =>
|
||||
# Since we have caching (lazyFetching) turned off, we can rely on this
|
||||
# getting called every time we switch views, *before* the events are rendered.
|
||||
# That makes this a great place to clear out the previous classes.
|
||||
|
@ -42,7 +42,7 @@ define [
|
|||
@calendar.find(".fc-widget-content td")
|
||||
.removeClass("event slot-available")
|
||||
.removeAttr('title')
|
||||
@mainCalendar.getEvents start, end, timezone, cb
|
||||
@mainCalendar.getEvents start, end, timezone, donecb, datacb
|
||||
|
||||
dayClick: (date) =>
|
||||
@mainCalendar.gotoDate(date)
|
||||
|
|
|
@ -62,7 +62,7 @@ define [
|
|||
_fetch: (start, callback) ->
|
||||
end = fcUtil.clone(start).year(3000)
|
||||
@lastRequestID = $.guid++
|
||||
@dataSource.getEvents start, end, @contexts, callback, {singlePage: true, requestID: @lastRequestID}
|
||||
@dataSource.getEvents start, end, @contexts, callback, undefined, {singlePage: true, requestID: @lastRequestID}
|
||||
|
||||
refetch: =>
|
||||
return unless @startDate
|
||||
|
|
|
@ -9366,11 +9366,17 @@ function EventManager(options) { // assumed to be a calendar
|
|||
reportEvents(cache);
|
||||
}
|
||||
}
|
||||
}, function(eventInputs) {
|
||||
if (fetchID == currentFetchID) {
|
||||
for (i = 0; i < eventInputs.length; i++) {
|
||||
renderEvent(eventInputs[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function _fetchEventSource(source, callback) {
|
||||
function _fetchEventSource(source, callback, dataCallback) {
|
||||
var i;
|
||||
var fetchers = fc.sourceFetchers;
|
||||
var res;
|
||||
|
@ -9408,7 +9414,8 @@ function EventManager(options) { // assumed to be a calendar
|
|||
function(events) {
|
||||
callback(events);
|
||||
t.popLoading();
|
||||
}
|
||||
},
|
||||
dataCallback
|
||||
);
|
||||
}
|
||||
else if ($.isArray(events)) {
|
||||
|
|
|
@ -151,3 +151,14 @@ define [
|
|||
equal list.length, 2
|
||||
ok ['calendar_event_1', 'assignment_3'].indexOf(list[0].id) >= 0
|
||||
ok ['calendar_event_1', 'assignment_3'].indexOf(list[1].id) >= 0
|
||||
|
||||
test 'pagination: calls data callback with each page of data if set', ->
|
||||
@server.addCalendarEvent('course_1', '1', fcUtil.unwrap(@date1).toISOString())
|
||||
@server.addAssignment('course_2', '3', fcUtil.unwrap(@date3).toISOString())
|
||||
pages = 0
|
||||
@source.getEvents @date1, @date4, @contexts, (list) ->
|
||||
equal list.length, 2
|
||||
equal pages, 2
|
||||
, (list) ->
|
||||
pages += 1
|
||||
equal list.length, 1
|
||||
|
|
Loading…
Reference in New Issue