diff --git a/app/coffeescripts/calendar/CommonEvent.CalendarEvent.coffee b/app/coffeescripts/calendar/CommonEvent.CalendarEvent.coffee
index ebf1adda5c2..6756d6eb090 100644
--- a/app/coffeescripts/calendar/CommonEvent.CalendarEvent.coffee
+++ b/app/coffeescripts/calendar/CommonEvent.CalendarEvent.coffee
@@ -4,9 +4,10 @@ define [
'compiled/util/fcUtil'
'compiled/util/semanticDateRange'
'compiled/calendar/CommonEvent'
+ 'compiled/util/natcompare'
'jquery.instructure_date_and_time'
'jquery.instructure_misc_helpers'
-], (I18n, $, fcUtil, semanticDateRange, CommonEvent) ->
+], (I18n, $, fcUtil, semanticDateRange, CommonEvent, natcompare) ->
deleteConfirmation = I18n.t('prompts.delete_event', "Are you sure you want to delete this event?")
@@ -15,6 +16,7 @@ define [
super data, contextInfo, actualContextInfo
@eventType = 'calendar_event'
@appointmentGroupEventStatus = @calculateAppointmentGroupEventStatus()
+ @reservedUsers = @getListOfReservedPeople(5).join('; ')
@deleteConfirmation = deleteConfirmation
@deleteURL = contextInfo.calendar_event_url
@@ -94,12 +96,29 @@ define [
calculateAppointmentGroupEventStatus: ->
status = I18n.t 'Available'
-
if @calendarEvent.available_slots > 0
status = I18n.t('%{availableSlots} Available', {availableSlots: @calendarEvent.available_slots})
+ if @calendarEvent.available_slots > 0 && @calendarEvent.child_events?.length
+ status = I18n.t('%{availableSlots} more available', {availableSlots: @calendarEvent.available_slots})
if @calendarEvent.available_slots == 0
status = I18n.t('Filled')
- if @calendarEvent.reserved == true || (@calendarEvent.appointment_group_url && @calendarEvent.parent_event_id)
+ if @consideredReserved()
status = I18n.t('Reserved')
status
+
+ # Returns an array of sortable user names that have reserved this slot optionally
+ # limited to a certain number. The list is returned sorted naturally. If there
+ # are more than the limit 'and more...' will be appended.
+ getListOfReservedPeople: (limit) ->
+ return [] unless @calendarEvent.child_events?.length
+ names = @calendarEvent.child_events?.map((child_event) -> child_event.user?.sortable_name)
+ sorted = names.sort((a, b) => natcompare.strings(a, b))
+ if (limit)
+ sorted = sorted.slice(0, limit)
+ if @calendarEvent.child_events?.length > limit
+ sorted.push(I18n.t('and more...'))
+ sorted
+
+ # True if the slot should be considered reserved
+ consideredReserved: -> @calendarEvent.reserved == true || (@calendarEvent.appointment_group_url && @calendarEvent.parent_event_id)
diff --git a/app/views/jst/calendar/agendaView.handlebars b/app/views/jst/calendar/agendaView.handlebars
index dc740710e48..0a670bf2acb 100644
--- a/app/views/jst/calendar/agendaView.handlebars
+++ b/app/views/jst/calendar/agendaView.handlebars
@@ -18,7 +18,11 @@
{{readableType}},
{{#if ../../meta.better_scheduler}}
- {{#truncate title 60}}{{/truncate}} - {{appointmentGroupEventStatus}}
+ {{#if can_edit}}
+ {{#truncate title 60}}{{/truncate}} - {{appointmentGroupEventStatus}} {{#if reservedUsers }} - {{reservedUsers}} {{/if}}
+ {{else}}
+ {{#truncate title 60}}{{/truncate}} - {{appointmentGroupEventStatus}}
+ {{/if}}
{{else}}
{{#ifAll ../../../meta.displayAppointmentEvents isAppointmentGroupEvent}}
{{appointmentGroupEventStatus}}
diff --git a/spec/javascripts/jsx/calendar/CommonEvent.CalendarEventSpec.jsx b/spec/javascripts/jsx/calendar/CommonEvent.CalendarEventSpec.jsx
index 5cac4a404db..ae34b078c75 100644
--- a/spec/javascripts/jsx/calendar/CommonEvent.CalendarEventSpec.jsx
+++ b/spec/javascripts/jsx/calendar/CommonEvent.CalendarEventSpec.jsx
@@ -4,22 +4,64 @@ define([
let calendarEvent;
+ const getFakeChildEvents = () => {
+ return [
+ { user: {sortable_name: 'Stark, Tony'}},
+ { user: {sortable_name: 'Parker, Peter'}},
+ { user: {sortable_name: 'Rogers, Steve'}}
+ ];
+ }
+
module('CommonEvent.CalendarEvent', {
setup () {
- const data = {}
- const contexts = ['course_1']
- calendarEvent = new CalendarEvent(data, contexts)
+ const data = {
+ child_events: []
+ };
+ const contexts = ['course_1'];
+ calendarEvent = new CalendarEvent(data, contexts);
},
teardown () {
calendarEvent = null;
}
});
- test('calculateAppointmentGroupEventStatus returns number of available slots string when more than 0', () => {
+ test('Constructor sets reservedUsers from child_events limited to 5 and joined by "; "', () => {
+ const data = {
+ child_events: getFakeChildEvents().concat([
+ { user: {sortable_name: 'Banner, Bruce'}},
+ { user: {sortable_name: 'Lang, Scott'}}
+ ])
+ };
+ calendarEvent = new CalendarEvent(data, ['course_1']);
+ const expected = "Banner, Bruce; Lang, Scott; Parker, Peter; Rogers, Steve; Stark, Tony";
+ equal(calendarEvent.reservedUsers, expected);
+ });
+
+ test('Constructor sets reservedUsers from child_events limited to 5 and joined by "; " with "and more..." if more than 5', () => {
+ const data = {
+ child_events: getFakeChildEvents().concat([
+ { user: {sortable_name: 'Banner, Bruce'}},
+ { user: {sortable_name: 'Lang, Scott'}},
+ { user: {sortable_name: 'Barton, Clint'}}
+
+ ])
+ };
+ calendarEvent = new CalendarEvent(data, ['course_1']);
+ const expected = "Banner, Bruce; Barton, Clint; Lang, Scott; Parker, Peter; Rogers, Steve; and more...";
+ equal(calendarEvent.reservedUsers, expected);
+ });
+
+ test('calculateAppointmentGroupEventStatus returns number of available slots string when more than 0 and none are reserved', () => {
calendarEvent.calendarEvent.available_slots = 20;
equal(calendarEvent.calculateAppointmentGroupEventStatus(), '20 Available');
});
+ test('calculateAppointmentGroupEventStatus returns "X more available" when there are some reserved and some open', () => {
+ calendarEvent.calendarEvent.child_events = getFakeChildEvents();
+ calendarEvent.calendarEvent.available_slots = 17;
+ equal(calendarEvent.calculateAppointmentGroupEventStatus(), '17 more available');
+ })
+
test('calculateAppointmentGroupEventStatus gives "Filled" string when 0 available_slots', () => {
calendarEvent.calendarEvent.available_slots = 0;
equal(calendarEvent.calculateAppointmentGroupEventStatus(), 'Filled');
@@ -37,5 +79,17 @@ define([
equal(calendarEvent.calculateAppointmentGroupEventStatus(), 'Reserved');
});
+ test('consideredReserved returns true when reserve should be shown', () => {
+ calendarEvent.calendarEvent.reserved = true;
+ ok(calendarEvent.consideredReserved(), 'true when reserved');
+
+ calendarEvent.calendarEvent.reserved = false;
+ calendarEvent.calendarEvent.appointment_group_url = 1;
+ calendarEvent.calendarEvent.parent_event_id = 30;
+ ok(calendarEvent.consideredReserved(), 'true with appointment_group_url and parent_event_id');
+ });
+
+
+
})