Merge branch 'MDL-72603-master' of git://github.com/HuongNV13/moodle
This commit is contained in:
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("block_timeline/event_list",["jquery","core/notification","core/templates","core/paged_content_factory","core/str","core/user_date","block_timeline/calendar_events_repository"],function(a,b,c,d,e,f,g){var h=!1,i={EMPTY_MESSAGE:"[data-region=\"empty-message\"]",ROOT:"[data-region=\"event-list-container\"]",EVENT_LIST_CONTENT:"[data-region=\"event-list-content\"]",EVENT_LIST_LOADING_PLACEHOLDER:"[data-region=\"event-list-loading-placeholder\"]",TIMELINE_BLOCK:"[data-region=\"timeline\"]",TIMELINE_SEARCH:"[data-region=\"search-input\"]"},j={EVENT_LIST_CONTENT:"block_timeline/event-list-content"},k={ignoreControlWhileLoading:!0,controlPlacementBottom:!0,ariaLabels:{itemsperpagecomponents:"ariaeventlistpagelimit, block_timeline"}},l=function(a){a.find(i.EVENT_LIST_CONTENT).addClass("hidden");a.find(i.EMPTY_MESSAGE).removeClass("hidden")},m=function(a){a.find(i.EVENT_LIST_CONTENT).removeClass("hidden");a.find(i.EMPTY_MESSAGE).addClass("hidden")},n=function(a){a.find(i.EVENT_LIST_CONTENT).empty()},o=function(a){var b={},c={courseview:h,eventsbyday:[]};a.forEach(function(a){var c=a.timeusermidnight;if(b[c]){b[c].push(a)}else{b[c]=[a]}});Object.keys(b).forEach(function(a){var d=b[a];c.eventsbyday.push({dayTimestamp:a,events:d})});return c},p=function(a){var b=o(a),d=j.EVENT_LIST_CONTENT;return c.render(d,b)},q=function(a,b,c,d,e,f,h){var i=d!=void 0?a+d*86400:!1,j={starttime:a+c*86400,limit:b};if(e){j.aftereventid=e}if(i){j.endtime=i}if(h){j.searchvalue=h}if(f){j.courseid=f;return g.queryByCourse(j)}else{return g.queryByTime(j)}},r=function(a,b,c,d,e,g,h,i,j){var k=a.pageNumber,l=a.limit,m=k;while(!d.hasOwnProperty(m)){m--}var n=d[m],o=null;if(e&&e.hasOwnProperty(k)){o=e[k]}else{o=q(c,l+1,h,i,n,g,j)}return o.then(function(a){if(!a.events.length){b.allItemsLoaded(k);return[]}var d=document.querySelector("[data-filtername='overdue']"),e=d&&d.getAttribute("aria-current"),g=a.events.filter(function(a){if("open"==a.eventtype||"opensubmission"==a.eventtype){var b=f.getUserMidnightForTimestamp(a.timesort,c);return b>c}return!e||a.overdue}),h=g.length<=l;if(h){b.allItemsLoaded(k)}else{g.pop()}return g})},s=function(c,f,g,h,i,j,l,m,n,o){var q={1:0},s=!1,t=a.extend({},k,n);return e.get_string("ariaeventlistpagelimit","block_timeline",a.isArray(c)?c[0].value:c).then(function(a){t.ariaLabels.itemsperpage=a;t.ariaLabels.paginationnav=m;return a}).then(function(){return d.createWithLimit(c,function(c,d){var e=[];c.forEach(function(a){var c=a.pageNumber,h=r(a,d,g,q,f,i,j,l,o).then(function(a){if(a.length){s=!0;var b=a[a.length-1].id;q[c+1]=b;return p(a)}else{return a}}).catch(b.exception);e.push(h)});a.when.apply(a,e).then(function(){h.resolve(s)}).catch(function(){h.resolve(s)});return e},t)})};return{init:function init(d,e,f,g){var j=4<arguments.length&&arguments[4]!==void 0?arguments[4]:{};d=a(d);h=!!j.courseview;var k=a.Deferred(),o=d.find(i.EVENT_LIST_CONTENT),p=d.find(i.EVENT_LIST_LOADING_PLACEHOLDER),q=d.attr("data-course-id"),r=parseInt(d.attr("data-days-offset"),10),t=d.attr("data-days-limit"),u=parseInt(d.attr("data-midnight"),10),v=d.closest(i.TIMELINE_BLOCK).find(i.TIMELINE_SEARCH).val();n(d);m(d);p.removeClass("hidden");if(t!=void 0){t=parseInt(t,10)}return s(e,f,u,k,q,r,t,g,j,v).then(function(b,e){b=a(b);b.addClass("hidden");c.replaceNodeContents(o,b,e);k.then(function(a){b.removeClass("hidden");p.addClass("hidden");if(!a){l(d)}return a}).catch(function(){return!1});return b}).catch(b.exception)},rootSelector:i.ROOT}});
|
||||
define ("block_timeline/event_list",["jquery","core/notification","core/templates","core/str","core/user_date","block_timeline/calendar_events_repository"],function(a,b,c,d,e,f){var g=!1,h={EMPTY_MESSAGE:"[data-region=\"empty-message\"]",ROOT:"[data-region=\"event-list-container\"]",EVENT_LIST_CONTENT:"[data-region=\"event-list-content\"]",EVENT_LIST_WRAPPER:"[data-region=\"event-list-wrapper\"]",EVENT_LIST_LOADING_PLACEHOLDER:"[data-region=\"event-list-loading-placeholder\"]",TIMELINE_BLOCK:"[data-region=\"timeline\"]",TIMELINE_SEARCH:"[data-region=\"search-input\"]",MORE_ACTIVITIES_BUTTON:"[data-action=\"more-events\"]",MORE_ACTIVITIES_BUTTON_CONTAINER:"[data-region=\"more-events-button-container\"]"},i={EVENT_LIST_CONTENT:"block_timeline/event-list-content",MORE_ACTIVITIES_BUTTON:"block_timeline/event-list-loadmore",LOADING_ICON:"core/loading"},j=function(a){a.find(h.EVENT_LIST_CONTENT).addClass("hidden");a.find(h.EMPTY_MESSAGE).removeClass("hidden")},k=function(a){a.find(h.EVENT_LIST_CONTENT).removeClass("hidden");a.find(h.EMPTY_MESSAGE).addClass("hidden")},l=function(a){a.find(h.EVENT_LIST_CONTENT).empty()},m=function(a){var b={},c={courseview:g,eventsbyday:[]};a.forEach(function(a){var c=a.timeusermidnight;if(b[c]){b[c].push(a)}else{b[c]=[a]}});Object.keys(b).forEach(function(a){var d=b[a];c.eventsbyday.push({dayTimestamp:a,events:d})});return c},n=function(a){var b=m(a),d=i.EVENT_LIST_CONTENT;return c.render(d,b)},o=function(a,b,c,d,e,g,h){var i=d!=void 0?a+d*86400:!1,j={starttime:a+c*86400,limit:b};if(e){j.aftereventid=e}if(i){j.endtime=i}if(h){j.searchvalue=h}if(g){j.courseid=g;return f.queryByCourse(j)}else{return f.queryByTime(j)}},p=function(a,c,d,e,f,g,h,i,j){return q(a,d,e,f,g,h,i,j).then(function(a){if(a.calendarEvents.length){var b=a.calendarEvents.at(-1).id,d=a.calendarEvents.at(-1).timeusermidnight;c.resolve({hasContent:!0,lastId:b,lastTimeStamp:d,loadedAll:a.loadedAll});return n(a.calendarEvents,e)}else{c.resolve({hasContent:!1,lastId:0,lastTimeStamp:0,loadedAll:!0});return a.calendarEvents}}).catch(b.exception)},q=function(a,b,c,d,f,g,h,i){var j=o(c,b+1,g,h,d,f,i),k=[],l=!0;return j.then(function(d){if(!d.events.length){return{calendarEvents:k,loadedAll:l}}var f=document.querySelector("[data-filtername='overdue']"),g=f&&f.getAttribute("aria-current");k=d.events.filter(function(a){if("open"==a.eventtype||"opensubmission"==a.eventtype){var b=e.getUserMidnightForTimestamp(a.timesort,c);return b>c}return!g||a.overdue});l=k.length<=b;if(!l){k.pop()}if(k.length){var h=k.at(-1).id;t(a,h)}return{calendarEvents:k,loadedAll:l}})},r=function(d){var e=parseInt(d.attr("data-midnight"),10),f=d.attr("data-course-id"),g=parseInt(d.attr("data-days-offset"),10),j=d.attr("data-days-limit"),k=s(d),l=d.find(h.EVENT_LIST_WRAPPER),m=d.closest(h.TIMELINE_BLOCK).find(h.TIMELINE_SEARCH).val(),o=q(d,10,e,k,f,g,j,m);o.then(function(e){if(e.calendarEvents.length){var f=n(e.calendarEvents),g=u(d);f.then(function(b,f){b=a(b);b.find("[data-timestamp=\"".concat(g,"\"]")).remove();c.appendNodeContents(l,b.html(),f);if(!e.loadedAll){c.render(i.MORE_ACTIVITIES_BUTTON,{}).then(function(a){l.append(a);v(d,e.calendarEvents.at(-1).timeusermidnight);y(d);return a}).catch(function(){return!1})}return b}).catch(b.exception)}return e}).then(function(){return x(d)}).catch(b.exception)},s=function(a){return parseInt(a.attr("data-lazyload-offset"),10)},t=function(a,b){a.attr("data-lazyload-offset",b)},u=function(a){return parseInt(a.attr("data-timestamp"),10)},v=function(a,b){a.attr("data-timestamp",b)},w=function(a){var b=a.find(h.MORE_ACTIVITIES_BUTTON);b.prop("disabled",!0);c.render(i.LOADING_ICON,{}).then(function(a){b.append(a);return a}).catch(function(){return!1})},x=function(a){var b=a.find(h.MORE_ACTIVITIES_BUTTON_CONTAINER);b.remove()},y=function(a){var b=a.find(h.MORE_ACTIVITIES_BUTTON);b.on("click",function(){w(a);r(a)})};return{init:function init(d){var e=1<arguments.length&&arguments[1]!==void 0?arguments[1]:{};d=a(d);g=!!e.courseview;var f=a.Deferred(),m=d.find(h.EVENT_LIST_CONTENT),n=d.find(h.EVENT_LIST_LOADING_PLACEHOLDER),o=d.attr("data-course-id"),q=parseInt(d.attr("data-days-offset"),10),r=d.attr("data-days-limit"),s=parseInt(d.attr("data-midnight"),10),t=d.closest(h.TIMELINE_BLOCK).find(h.TIMELINE_SEARCH).val();l(d);k(d);n.removeClass("hidden");if(r!=void 0){r=parseInt(r,10)}return p(d,f,5,s,0,o,q,r,t).then(function(b,e){f.then(function(f){if(!f.hasContent){n.addClass("hidden");return j(d)}b=a(b);b.addClass("hidden");c.replaceNodeContents(m,b,e);b.removeClass("hidden");n.addClass("hidden");if(!f.loadedAll){c.render(i.MORE_ACTIVITIES_BUTTON,{}).then(function(a){m.append(a);v(d,f.lastTimeStamp);y(d);return a}).catch(function(){return!1})}return f}).catch(function(){return!1});return b}).catch(b.exception)},rootSelector:h.ROOT}});
|
||||
//# sourceMappingURL=event_list.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("block_timeline/view_courses",["jquery","core/notification","core/custom_interaction_events","core/str","core/templates","block_timeline/event_list","core_course/repository","block_timeline/calendar_events_repository"],function(a,b,c,d,e,f,g,h){var i={MORE_COURSES_BUTTON:"[data-action=\"more-courses\"]",MORE_COURSES_BUTTON_CONTAINER:"[data-region=\"more-courses-button-container\"]",NO_COURSES_EMPTY_MESSAGE:"[data-region=\"no-courses-empty-message\"]",COURSES_LIST:"[data-region=\"courses-list\"]",COURSE_ITEMS_LOADING_PLACEHOLDER:"[data-region=\"course-items-loading-placeholder\"]",COURSE_EVENTS_CONTAINER:"[data-region=\"course-events-container\"]",COURSE_NAME:"[data-region=\"course-name\"]",LOADING_ICON:".loading-icon",TIMELINE_BLOCK:"[data-region=\"timeline\"]",TIMELINE_SEARCH:"[data-region=\"search-input\"]"},j={COURSE_ITEMS:"block_timeline/course-items",LOADING_ICON:"core/loading"},k=5,l=86400,m={courseview:!0},n=function(a){a.find(i.COURSE_ITEMS_LOADING_PLACEHOLDER).addClass("hidden")},o=function(a){a.find(i.MORE_COURSES_BUTTON_CONTAINER).addClass("hidden")},p=function(a){a.find(i.MORE_COURSES_BUTTON_CONTAINER).removeClass("hidden")},q=function(a){var b=a.find(i.MORE_COURSES_BUTTON);b.prop("disabled",!0);e.render(j.LOADING_ICON,{}).then(function(a){b.append(a);return a}).catch(function(){return!1})},r=function(a){var b=a.find(i.MORE_COURSES_BUTTON);b.prop("disabled",!1);b.find(i.LOADING_ICON).remove()},s=function(a){a.find(i.NO_COURSES_EMPTY_MESSAGE).removeClass("hidden")},t=function(a,b){var c=a.find(i.COURSES_LIST);e.appendNodeContents(c,b,"")},u=function(a){return 0<a.find(i.COURSE_EVENTS_CONTAINER).length},v=function(a){return parseInt(a.attr("data-offset"),10)},w=function(a,b){a.attr("data-offset",b)},x=function(a){return parseInt(a.attr("data-limit"),10)},y=function(a){return parseInt(a.attr("data-days-offset"),10)},z=function(a){var b=a.attr("data-days-limit");return b!=void 0?parseInt(b,10):void 0},A=function(a){return parseInt(a.attr("data-midnight"),10)},B=function(a){var b=A(a),c=y(a);return b+c*l},C=function(a){var b=A(a),c=z(a);return c!=void 0?b+c*l:!1},D=function(a,b,c,d,e){var f={courseids:a,starttime:b,limit:c};if(d){f.endtime=d}if(e){f.searchvalue=e}return h.queryByCourses(f)},E=function(a){return a.data("last-event-load-time")},F=function(a,b){a.data("last-event-load-time",b)},G=function(a,b){return E(a)>b},H=function(a,b,c,d){var e=a.map(function(a){return a.id});return D(e,b,k+1,c,d)},I=function(a,b,c,d,f){return e.render(j.COURSE_ITEMS,{courses:a,midnight:c,hasdaysoffset:!0,hasdayslimit:f!=void 0,daysoffset:d,dayslimit:f,nodayslimit:f==void 0}).then(function(a){n(b);if(a){t(b,a)}else{if(!u(b)){s(b)}}return a}).then(function(c){if(a.length<2){o(b)}else{p(b)}return c}).catch(function(){n(b)})},J=function(c){var e=v(c),h=x(c);return g.getEnrolledCoursesByTimelineClassification("inprogress",h,e,"fullname asc").then(function(b){var e=Date.now(),g=b.courses,h=b.nextoffset,j=y(c),l=z(c),n=A(c),o=B(c),p=C(c),q=c.closest(i.TIMELINE_BLOCK).find(i.TIMELINE_SEARCH).val();w(c,h);var r=H(g,o,p,q),s=I(g,c,n,j,l);return a.when(r,s).then(function(b){if(G(c,e)){return b}g.forEach(function(e){var g=e.id,h=[],i=c.find("[data-region=\"course-events-container\"][data-course-id=\""+g+"\"]"),j=i.find(f.rootSelector),l=b.groupedbycourse.filter(function(a){return a.courseid==g});if(l.length){h=l[0].events}var n=a.Deferred().resolve({events:h}).promise();d.get_string("ariaeventlistpaginationnavcourses","block_timeline",e.fullnamedisplay).then(function(a){f.init(j,k,{1:n},a,m);return a}).catch(function(){f.init(j,k,{1:n},void 0,m)})});return b})}).catch(b.exception)},K=function(c){var e=Date.now(),g=B(c),h=C(c),j=c.find(i.COURSE_EVENTS_CONTAINER),l=j.map(function(){return a(this).attr("data-course-id")}).get(),n=c.closest(i.TIMELINE_BLOCK).find(i.TIMELINE_SEARCH).val();F(c,e);return D(l,g,k+1,h,n).then(function(b){if(G(c,e)){return b}j.each(function(c,e){e=a(e);var g=e.attr("data-course-id"),h=e.find(i.COURSE_NAME).text(),j=e.find(f.rootSelector),l=a.Deferred(),n=[],o=b.groupedbycourse.filter(function(a){return a.courseid==g});if(o.length){n=o[0].events}l.resolve({events:n});d.get_string("ariaeventlistpaginationnavcourses","block_timeline",h).then(function(a){f.init(j,k,{1:l.promise()},a,m);return a}).catch(function(){f.init(j,k,{1:l.promise()},void 0,m)})});return b}).catch(b.exception)},L=function(a){c.define(a,[c.events.activate]);a.on(c.events.activate,i.MORE_COURSES_BUTTON,function(b,c){q(a);J(a).then(function(){r(a)}).catch(function(){r(a)});if(c){c.originalEvent.preventDefault();c.originalEvent.stopPropagation()}b.stopPropagation()})},M=function(a){if(!a.attr("data-seen")){if(u(a)){K(a)}else{J(a)}a.attr("data-seen",!0)}};return{init:function init(b){b=a(b);F(b,Date.now());if(b.hasClass("active")){J(b);b.attr("data-seen",!0)}L(b)},reset:function reset(a){a.removeAttr("data-seen");if(a.hasClass("active")){M(a)}},shown:M}});
|
||||
define ("block_timeline/view_courses",["jquery","core/notification","core/custom_interaction_events","core/templates","block_timeline/event_list","core_course/repository","block_timeline/calendar_events_repository"],function(a,b,c,d,e,f,g){var h={MORE_COURSES_BUTTON:"[data-action=\"more-courses\"]",MORE_COURSES_BUTTON_CONTAINER:"[data-region=\"more-courses-button-container\"]",NO_COURSES_EMPTY_MESSAGE:"[data-region=\"no-courses-empty-message\"]",COURSES_LIST:"[data-region=\"courses-list\"]",COURSE_ITEMS_LOADING_PLACEHOLDER:"[data-region=\"course-items-loading-placeholder\"]",COURSE_EVENTS_CONTAINER:"[data-region=\"course-events-container\"]",COURSE_NAME:"[data-region=\"course-name\"]",LOADING_ICON:".loading-icon",TIMELINE_BLOCK:"[data-region=\"timeline\"]",TIMELINE_SEARCH:"[data-region=\"search-input\"]"},i={COURSE_ITEMS:"block_timeline/course-items",LOADING_ICON:"core/loading"},j=5,k=86400,l={courseview:!0},m=function(a){a.find(h.COURSE_ITEMS_LOADING_PLACEHOLDER).addClass("hidden")},n=function(a){a.find(h.MORE_COURSES_BUTTON_CONTAINER).addClass("hidden")},o=function(a){a.find(h.MORE_COURSES_BUTTON_CONTAINER).removeClass("hidden")},p=function(a){var b=a.find(h.MORE_COURSES_BUTTON);b.prop("disabled",!0);d.render(i.LOADING_ICON,{}).then(function(a){b.append(a);return a}).catch(function(){return!1})},q=function(a){var b=a.find(h.MORE_COURSES_BUTTON);b.prop("disabled",!1);b.find(h.LOADING_ICON).remove()},r=function(a){a.find(h.NO_COURSES_EMPTY_MESSAGE).removeClass("hidden")},s=function(a,b){var c=a.find(h.COURSES_LIST);d.appendNodeContents(c,b,"")},t=function(a){return 0<a.find(h.COURSE_EVENTS_CONTAINER).length},u=function(a){return parseInt(a.attr("data-offset"),10)},v=function(a,b){a.attr("data-offset",b)},w=function(a){return parseInt(a.attr("data-limit"),10)},x=function(a){return parseInt(a.attr("data-days-offset"),10)},y=function(a){var b=a.attr("data-days-limit");return b!=void 0?parseInt(b,10):void 0},z=function(a){return parseInt(a.attr("data-midnight"),10)},A=function(a){var b=z(a),c=x(a);return b+c*k},B=function(a){var b=z(a),c=y(a);return c!=void 0?b+c*k:!1},C=function(a,b,c,d,e){var f={courseids:a,starttime:b,limit:c};if(d){f.endtime=d}if(e){f.searchvalue=e}return g.queryByCourses(f)},D=function(a){return a.data("last-event-load-time")},E=function(a,b){a.data("last-event-load-time",b)},F=function(a,b){return D(a)>b},G=function(a,b,c,d){var e=a.map(function(a){return a.id});return C(e,b,j+1,c,d)},H=function(a,b,c,e,f){return d.render(i.COURSE_ITEMS,{courses:a,midnight:c,hasdaysoffset:!0,hasdayslimit:f!=void 0,daysoffset:e,dayslimit:f,nodayslimit:f==void 0}).then(function(a){m(b);if(a){s(b,a)}else{if(!t(b)){r(b)}}return a}).then(function(c){if(a.length<2){n(b)}else{o(b)}return c}).catch(function(){m(b)})},I=function(c){var d=u(c),g=w(c);return f.getEnrolledCoursesByTimelineClassification("inprogress",g,d,"fullname asc").then(function(b){var d=Date.now(),f=b.courses,g=b.nextoffset,i=x(c),j=y(c),k=z(c),m=A(c),n=B(c),o=c.closest(h.TIMELINE_BLOCK).find(h.TIMELINE_SEARCH).val();v(c,g);var p=G(f,m,n,o),q=H(f,c,k,i,j);return a.when(p,q).then(function(a){if(F(c,d)){return a}f.forEach(function(a){var b=a.id,d=c.find("[data-region=\"course-events-container\"][data-course-id=\""+b+"\"]"),f=d.find(e.rootSelector);e.init(f,l)});return a})}).catch(b.exception)},J=function(c){var d=Date.now(),f=A(c),g=B(c),i=c.find(h.COURSE_EVENTS_CONTAINER),k=i.map(function(){return a(this).attr("data-course-id")}).get(),m=c.closest(h.TIMELINE_BLOCK).find(h.TIMELINE_SEARCH).val();E(c,d);return C(k,f,j+1,g,m).then(function(b){if(F(c,d)){return b}i.each(function(b,c){c=a(c);var d=c.find(e.rootSelector);e.init(d,l)});return b}).catch(b.exception)},K=function(a){c.define(a,[c.events.activate]);a.on(c.events.activate,h.MORE_COURSES_BUTTON,function(b,c){p(a);I(a).then(function(){q(a)}).catch(function(){q(a)});if(c){c.originalEvent.preventDefault();c.originalEvent.stopPropagation()}b.stopPropagation()})},L=function(a){if(!a.attr("data-seen")){if(t(a)){J(a)}else{I(a)}a.attr("data-seen",!0)}};return{init:function init(b){b=a(b);E(b,Date.now());if(b.hasClass("active")){I(b);b.attr("data-seen",!0)}K(b)},reset:function reset(a){a.removeAttr("data-seen");if(a.hasClass("active")){L(a)}},shown:L}});
|
||||
//# sourceMappingURL=view_courses.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("block_timeline/view_dates",["jquery","core/str","block_timeline/event_list","core/pubsub","core/paged_content_events"],function(a,b,c,d,e){var f={EVENT_LIST_CONTAINER:"[data-region=\"event-list-container\"]"},g=[5,10,25],h=function(a){var b=parseInt(a.data("limit"),10),c=!1,d=g.map(function(a){if(b==a){c=!0}return{value:a,active:b==a}});if(!c){d[0].active=!0}return d},i=function(b,c){var f=c+e.SET_ITEMS_PER_PAGE_LIMIT;d.subscribe(f,function(c){a(b).data("limit",c)})},j=function(d){var e=d.find(f.EVENT_LIST_CONTAINER),g=a(e).attr("id")+"user_block_timeline"+Math.random();i(d,g);var j=h(d),k={persistentLimitKey:"block_timeline_user_limit_preference",eventNamespace:g};b.get_string("ariaeventlistpaginationnavdates","block_timeline").then(function(a){c.init(e,j,{},a,k);return a}).catch(function(){c.init(e,j,{},"",k)})};return{init:function init(b){b=a(b);if(b.hasClass("active")){j(b);b.attr("data-seen",!0)}},reset:function reset(a){a.removeAttr("data-seen");if(a.hasClass("active")){j(a);a.attr("data-seen",!0)}},shown:function shown(a){if(!a.attr("data-seen")){j(a);a.attr("data-seen",!0)}}}});
|
||||
define ("block_timeline/view_dates",["jquery","block_timeline/event_list","core/pubsub","core/paged_content_events"],function(a,b,c,d){var e={EVENT_LIST_CONTAINER:"[data-region=\"event-list-container\"]"},f=function(b,e){var f=e+d.SET_ITEMS_PER_PAGE_LIMIT;c.subscribe(f,function(c){a(b).data("limit",c)})},g=function(c){var d=c.find(e.EVENT_LIST_CONTAINER),g=a(d).attr("id")+"user_block_timeline"+Math.random();f(c,g);b.init(d,{persistentLimitKey:"block_timeline_user_limit_preference",eventNamespace:g})};return{init:function init(b){b=a(b);if(b.hasClass("active")){g(b);b.attr("data-seen",!0)}},reset:function reset(a){a.removeAttr("data-seen");if(a.hasClass("active")){g(a);a.attr("data-seen",!0)}},shown:function shown(a){if(!a.attr("data-seen")){g(a);a.attr("data-seen",!0)}}}});
|
||||
//# sourceMappingURL=view_dates.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -26,7 +26,6 @@ define(
|
||||
'jquery',
|
||||
'core/notification',
|
||||
'core/templates',
|
||||
'core/paged_content_factory',
|
||||
'core/str',
|
||||
'core/user_date',
|
||||
'block_timeline/calendar_events_repository'
|
||||
@@ -35,7 +34,6 @@ function(
|
||||
$,
|
||||
Notification,
|
||||
Templates,
|
||||
PagedContentFactory,
|
||||
Str,
|
||||
UserDate,
|
||||
CalendarEventsRepository
|
||||
@@ -48,24 +46,24 @@ function(
|
||||
EMPTY_MESSAGE: '[data-region="empty-message"]',
|
||||
ROOT: '[data-region="event-list-container"]',
|
||||
EVENT_LIST_CONTENT: '[data-region="event-list-content"]',
|
||||
EVENT_LIST_WRAPPER: '[data-region="event-list-wrapper"]',
|
||||
EVENT_LIST_LOADING_PLACEHOLDER: '[data-region="event-list-loading-placeholder"]',
|
||||
TIMELINE_BLOCK: '[data-region="timeline"]',
|
||||
TIMELINE_SEARCH: '[data-region="search-input"]'
|
||||
TIMELINE_SEARCH: '[data-region="search-input"]',
|
||||
MORE_ACTIVITIES_BUTTON: '[data-action="more-events"]',
|
||||
MORE_ACTIVITIES_BUTTON_CONTAINER: '[data-region="more-events-button-container"]'
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
EVENT_LIST_CONTENT: 'block_timeline/event-list-content'
|
||||
EVENT_LIST_CONTENT: 'block_timeline/event-list-content',
|
||||
MORE_ACTIVITIES_BUTTON: 'block_timeline/event-list-loadmore',
|
||||
LOADING_ICON: 'core/loading'
|
||||
};
|
||||
|
||||
// We want the paged content controls below the paged content area
|
||||
// and the controls should be ignored while data is loading.
|
||||
var DEFAULT_PAGED_CONTENT_CONFIG = {
|
||||
ignoreControlWhileLoading: true,
|
||||
controlPlacementBottom: true,
|
||||
ariaLabels: {
|
||||
itemsperpagecomponents: 'ariaeventlistpagelimit, block_timeline',
|
||||
}
|
||||
};
|
||||
/** @type {number} The total items will be shown on the first load. */
|
||||
const DEFAULT_LAZY_LOADING_ITEMS_FIRST_LOAD = 5;
|
||||
/** @type {number} The total items will be shown when click on the Show more activities button. */
|
||||
const DEFAULT_LAZY_LOADING_ITEMS_OTHER_LOAD = 10;
|
||||
|
||||
/**
|
||||
* Hide the content area and display the empty content message.
|
||||
@@ -211,219 +209,12 @@ function(
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a single page request from the paged content. Uses the given page data to request
|
||||
* the events from the server.
|
||||
* Create a lazy-loading region for the calendar events in the given root element.
|
||||
*
|
||||
* Checks the given preloadedPages before sending a request to the server to make sure we
|
||||
* don't load data unnecessarily.
|
||||
*
|
||||
* @param {object} pageData A single page data (see core/paged_content_pages for more info).
|
||||
* @param {object} actions Paged content actions (see core/paged_content_pages for more info).
|
||||
* @param {Number} midnight The user's midnight time in unix timestamp.
|
||||
* @param {object} lastIds The last event ID for each loaded page. Page number is key, id is value.
|
||||
* @param {object} preloadedPages An object of preloaded page data. Page number as key, data promise as value.
|
||||
* @param {int|undefined} courseId Course ID to restrict events to
|
||||
* @param {Number} daysOffset How many days (from midnight) to offset the results from
|
||||
* @param {int|undefined} daysLimit How many dates (from midnight) to limit the result to
|
||||
* @param {string|undefined} searchValue Search value
|
||||
* @return {object} jQuery promise resolved with calendar events.
|
||||
* @param {object} root The event list container element.
|
||||
* @param {object} additionalConfig Additional config options to pass to pagedContentFactory.
|
||||
*/
|
||||
var loadEventsFromPageData = function(
|
||||
pageData,
|
||||
actions,
|
||||
midnight,
|
||||
lastIds,
|
||||
preloadedPages,
|
||||
courseId,
|
||||
daysOffset,
|
||||
daysLimit,
|
||||
searchValue
|
||||
) {
|
||||
var pageNumber = pageData.pageNumber;
|
||||
var limit = pageData.limit;
|
||||
var lastPageNumber = pageNumber;
|
||||
|
||||
// This is here to protect us if, for some reason, the pages
|
||||
// are loaded out of order somehow and we don't have a reference
|
||||
// to the previous page. In that case, scan back to find the most
|
||||
// recent page we've seen.
|
||||
while (!lastIds.hasOwnProperty(lastPageNumber)) {
|
||||
lastPageNumber--;
|
||||
}
|
||||
// Use the last id of the most recent page.
|
||||
var lastId = lastIds[lastPageNumber];
|
||||
var eventsPromise = null;
|
||||
|
||||
if (preloadedPages && preloadedPages.hasOwnProperty(pageNumber)) {
|
||||
// This page has been preloaded so use that rather than load the values
|
||||
// again.
|
||||
eventsPromise = preloadedPages[pageNumber];
|
||||
} else {
|
||||
// Load one more than the given limit so that we can tell if there
|
||||
// is more content to load after this.
|
||||
eventsPromise = load(midnight, limit + 1, daysOffset, daysLimit, lastId, courseId, searchValue);
|
||||
}
|
||||
|
||||
return eventsPromise.then(function(result) {
|
||||
if (!result.events.length) {
|
||||
// If we didn't get any events back then tell the paged content
|
||||
// that we're done loading.
|
||||
actions.allItemsLoaded(pageNumber);
|
||||
return [];
|
||||
}
|
||||
|
||||
// Determine if the overdue filter is applied.
|
||||
const overdueFilter = document.querySelector("[data-filtername='overdue']");
|
||||
const filterByOverdue = (overdueFilter && overdueFilter.getAttribute('aria-current'));
|
||||
|
||||
var calendarEvents = result.events.filter(function(event) {
|
||||
if (event.eventtype == "open" || event.eventtype == "opensubmission") {
|
||||
var dayTimestamp = UserDate.getUserMidnightForTimestamp(event.timesort, midnight);
|
||||
return dayTimestamp > midnight;
|
||||
}
|
||||
|
||||
// When filtering by overdue, we fetch all events due today, in case any have elapsed already and are overdue.
|
||||
// This means if filtering by overdue, some events fetched might not be required (eg if due later today).
|
||||
return (!filterByOverdue || event.overdue);
|
||||
});
|
||||
// We expect to receive limit + 1 events back from the server.
|
||||
// Any less means there are no more events to load.
|
||||
var loadedAll = calendarEvents.length <= limit;
|
||||
|
||||
if (loadedAll) {
|
||||
// Tell the pagination that everything is loaded.
|
||||
actions.allItemsLoaded(pageNumber);
|
||||
} else {
|
||||
// Remove the last element from the array because it isn't
|
||||
// needed in this result set.
|
||||
calendarEvents.pop();
|
||||
}
|
||||
|
||||
return calendarEvents;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Use the paged content factory to create a paged content element for showing
|
||||
* the event list. We only provide a page limit to the factory because we don't
|
||||
* know exactly how many pages we'll need. This creates a paging bar with just
|
||||
* next/previous buttons.
|
||||
*
|
||||
* This function specifies the callback for loading the event data that the user
|
||||
* is requesting.
|
||||
*
|
||||
* @param {int|array} pageLimit A single limit or list of limits as options for the paged content
|
||||
* @param {object} preloadedPages An object of preloaded page data. Page number as key, data promise as value.
|
||||
* @param {Number} midnight The user's midnight time in unix timestamp.
|
||||
* @param {object} firstLoad A jQuery promise to be resolved after the first set of data is loaded.
|
||||
* @param {int|undefined} courseId Course ID to restrict events to
|
||||
* @param {Number} daysOffset How many days (from midnight) to offset the results from
|
||||
* @param {int|undefined} daysLimit How many dates (from midnight) to limit the result to
|
||||
* @param {string} paginationAriaLabel String to set as the aria label for the pagination bar.
|
||||
* @param {object} additionalConfig Additional config options to pass to pagedContentFactory
|
||||
* @param {string|undefined} searchValue Search value
|
||||
* @return {object} jQuery promise.
|
||||
*/
|
||||
var createPagedContent = function(
|
||||
pageLimit,
|
||||
preloadedPages,
|
||||
midnight,
|
||||
firstLoad,
|
||||
courseId,
|
||||
daysOffset,
|
||||
daysLimit,
|
||||
paginationAriaLabel,
|
||||
additionalConfig,
|
||||
searchValue
|
||||
) {
|
||||
// Remember the last event id we loaded on each page because we can't
|
||||
// use the offset value since the backend can skip events if the user doesn't
|
||||
// have the capability to see them. Instead we load the next page of events
|
||||
// based on the last seen event id.
|
||||
var lastIds = {'1': 0};
|
||||
var hasContent = false;
|
||||
var config = $.extend({}, DEFAULT_PAGED_CONTENT_CONFIG, additionalConfig);
|
||||
|
||||
return Str.get_string(
|
||||
'ariaeventlistpagelimit',
|
||||
'block_timeline',
|
||||
$.isArray(pageLimit) ? pageLimit[0].value : pageLimit
|
||||
)
|
||||
.then(function(string) {
|
||||
config.ariaLabels.itemsperpage = string;
|
||||
config.ariaLabels.paginationnav = paginationAriaLabel;
|
||||
return string;
|
||||
})
|
||||
.then(function() {
|
||||
return PagedContentFactory.createWithLimit(
|
||||
pageLimit,
|
||||
function(pagesData, actions) {
|
||||
var promises = [];
|
||||
|
||||
pagesData.forEach(function(pageData) {
|
||||
var pageNumber = pageData.pageNumber;
|
||||
// Load the page data.
|
||||
var pagePromise = loadEventsFromPageData(
|
||||
pageData,
|
||||
actions,
|
||||
midnight,
|
||||
lastIds,
|
||||
preloadedPages,
|
||||
courseId,
|
||||
daysOffset,
|
||||
daysLimit,
|
||||
searchValue
|
||||
).then(function(calendarEvents) {
|
||||
if (calendarEvents.length) {
|
||||
// Remember that we've loaded content.
|
||||
hasContent = true;
|
||||
// Remember the last id we've seen.
|
||||
var lastEventId = calendarEvents[calendarEvents.length - 1].id;
|
||||
// Record the id that the next page will need to start from.
|
||||
lastIds[pageNumber + 1] = lastEventId;
|
||||
// Get the HTML and JS for these calendar events.
|
||||
return render(calendarEvents);
|
||||
} else {
|
||||
return calendarEvents;
|
||||
}
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
|
||||
promises.push(pagePromise);
|
||||
});
|
||||
|
||||
$.when.apply($, promises).then(function() {
|
||||
// Tell the calling code that the first page has been loaded
|
||||
// and whether it contains any content.
|
||||
firstLoad.resolve(hasContent);
|
||||
return;
|
||||
})
|
||||
.catch(function() {
|
||||
firstLoad.resolve(hasContent);
|
||||
});
|
||||
|
||||
return promises;
|
||||
},
|
||||
config
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a paged content region for the calendar events in the given root element.
|
||||
* The content of the root element are replaced with a new paged content section
|
||||
* each time this function is called.
|
||||
*
|
||||
* This function will be called each time the offset or limit values are changed to
|
||||
* reload the event list region.
|
||||
*
|
||||
* @param {object} root The event list container element
|
||||
* @param {int|array} pageLimit A single limit or list of limits as options for the paged content
|
||||
* @param {object} preloadedPages An object of preloaded page data. Page number as key, data promise as value.
|
||||
* @param {string} paginationAriaLabel String to set as the aria label for the pagination bar.
|
||||
* @param {object} additionalConfig Additional config options to pass to pagedContentFactory
|
||||
*/
|
||||
var init = function(root, pageLimit, preloadedPages, paginationAriaLabel, additionalConfig = {}) {
|
||||
var init = function(root, additionalConfig = {}) {
|
||||
root = $(root);
|
||||
|
||||
courseview = !!additionalConfig.courseview;
|
||||
@@ -453,31 +244,42 @@ function(
|
||||
daysLimit = parseInt(daysLimit, 10);
|
||||
}
|
||||
|
||||
// Created the paged content element.
|
||||
return createPagedContent(pageLimit, preloadedPages, midnight, firstLoad, courseId, daysOffset, daysLimit,
|
||||
paginationAriaLabel, additionalConfig, searchValue)
|
||||
// Create the lazy loading content element.
|
||||
return createLazyLoadingContent(root, firstLoad,
|
||||
DEFAULT_LAZY_LOADING_ITEMS_FIRST_LOAD, midnight, 0, courseId, daysOffset, daysLimit, searchValue)
|
||||
.then(function(html, js) {
|
||||
html = $(html);
|
||||
// Hide the content for now.
|
||||
html.addClass('hidden');
|
||||
// Replace existing elements with the newly created paged content.
|
||||
// If we're reinitialising an existing event list this will replace
|
||||
// the old event list (including removing any event handlers).
|
||||
Templates.replaceNodeContents(eventListContent, html, js);
|
||||
firstLoad.then(function(data) {
|
||||
if (!data.hasContent) {
|
||||
loadingPlaceholder.addClass('hidden');
|
||||
// If we didn't get any data then show the empty data message.
|
||||
return hideContent(root);
|
||||
}
|
||||
|
||||
html = $(html);
|
||||
// Hide the content for now.
|
||||
html.addClass('hidden');
|
||||
// Replace existing elements with the newly created lazy-loading region.
|
||||
Templates.replaceNodeContents(eventListContent, html, js);
|
||||
|
||||
firstLoad.then(function(hasContent) {
|
||||
// Prevent changing page elements too much by only showing the content
|
||||
// once we've loaded some data for the first time. This allows our
|
||||
// fancy loading placeholder to shine.
|
||||
html.removeClass('hidden');
|
||||
loadingPlaceholder.addClass('hidden');
|
||||
|
||||
if (!hasContent) {
|
||||
// If we didn't get any data then show the empty data message.
|
||||
hideContent(root);
|
||||
if (!data.loadedAll) {
|
||||
Templates.render(TEMPLATES.MORE_ACTIVITIES_BUTTON, {}).then(function(html) {
|
||||
eventListContent.append(html);
|
||||
setLastTimestamp(root, data.lastTimeStamp);
|
||||
// Init the event handler.
|
||||
initEventListener(root);
|
||||
return html;
|
||||
}).catch(function() {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
return hasContent;
|
||||
return data;
|
||||
})
|
||||
.catch(function() {
|
||||
return false;
|
||||
@@ -488,6 +290,248 @@ function(
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a lazy-loading content element for showing the event list for the initial load.
|
||||
*
|
||||
* @param {object} root The event list container element.
|
||||
* @param {object} firstLoad A jQuery promise to be resolved after the first set of data is loaded.
|
||||
* @param {int} itemLimit Limit the number of items.
|
||||
* @param {Number} midnight The user's midnight time in unix timestamp.
|
||||
* @param {int} lastId The last event ID for each loaded page. Page number is key, id is value.
|
||||
* @param {int|undefined} courseId Course ID to restrict events to.
|
||||
* @param {Number} daysOffset How many days (from midnight) to offset the results from.
|
||||
* @param {int|undefined} daysLimit How many dates (from midnight) to limit the result to.
|
||||
* @param {string|undefined} searchValue Search value.
|
||||
* @return {object} jQuery promise resolved with calendar events.
|
||||
*/
|
||||
const createLazyLoadingContent = (root, firstLoad, itemLimit, midnight, lastId,
|
||||
courseId, daysOffset, daysLimit, searchValue) => {
|
||||
return loadEventsForLazyLoading(
|
||||
root,
|
||||
itemLimit,
|
||||
midnight,
|
||||
lastId,
|
||||
courseId,
|
||||
daysOffset,
|
||||
daysLimit,
|
||||
searchValue
|
||||
).then(data => {
|
||||
if (data.calendarEvents.length) {
|
||||
const lastEventId = data.calendarEvents.at(-1).id;
|
||||
const lastTimeStamp = data.calendarEvents.at(-1).timeusermidnight;
|
||||
firstLoad.resolve({
|
||||
hasContent: true,
|
||||
lastId: lastEventId,
|
||||
lastTimeStamp: lastTimeStamp,
|
||||
loadedAll: data.loadedAll
|
||||
});
|
||||
return render(data.calendarEvents, midnight);
|
||||
} else {
|
||||
firstLoad.resolve({
|
||||
hasContent: false,
|
||||
lastId: 0,
|
||||
lastTimeStamp: 0,
|
||||
loadedAll: true
|
||||
});
|
||||
return data.calendarEvents;
|
||||
}
|
||||
}).catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the request from the lazy-loading region.
|
||||
* Uses the given data like course id, offset... to request the events from the server.
|
||||
*
|
||||
* @param {object} root The event list container element.
|
||||
* @param {int} itemLimit Limit the number of items.
|
||||
* @param {Number} midnight The user's midnight time in unix timestamp.
|
||||
* @param {int} lastId The last event ID for each loaded page.
|
||||
* @param {int|undefined} courseId Course ID to restrict events to.
|
||||
* @param {Number} daysOffset How many days (from midnight) to offset the results from.
|
||||
* @param {int|undefined} daysLimit How many dates (from midnight) to limit the result to.
|
||||
* @param {string|undefined} searchValue Search value.
|
||||
* @return {object} jQuery promise resolved with calendar events.
|
||||
*/
|
||||
const loadEventsForLazyLoading = (root, itemLimit, midnight, lastId, courseId, daysOffset, daysLimit, searchValue) => {
|
||||
// Load one more than the given limit so that we can tell if there
|
||||
// is more content to load after this.
|
||||
const eventsPromise = load(midnight, itemLimit + 1, daysOffset, daysLimit, lastId, courseId, searchValue);
|
||||
let calendarEvents = [];
|
||||
let loadedAll = true;
|
||||
|
||||
return eventsPromise.then(result => {
|
||||
if (!result.events.length) {
|
||||
return {calendarEvents, loadedAll};
|
||||
}
|
||||
|
||||
// Determine if the overdue filter is applied.
|
||||
const overdueFilter = document.querySelector("[data-filtername='overdue']");
|
||||
const filterByOverdue = (overdueFilter && overdueFilter.getAttribute('aria-current'));
|
||||
|
||||
calendarEvents = result.events.filter(event => {
|
||||
if (event.eventtype == 'open' || event.eventtype == 'opensubmission') {
|
||||
const dayTimestamp = UserDate.getUserMidnightForTimestamp(event.timesort, midnight);
|
||||
return dayTimestamp > midnight;
|
||||
}
|
||||
// When filtering by overdue, we fetch all events due today, in case any have elapsed already and are overdue.
|
||||
// This means if filtering by overdue, some events fetched might not be required (eg if due later today).
|
||||
return (!filterByOverdue || event.overdue);
|
||||
});
|
||||
|
||||
loadedAll = calendarEvents.length <= itemLimit;
|
||||
|
||||
if (!loadedAll) {
|
||||
// Remove the last element from the array because it isn't
|
||||
// needed in this result set.
|
||||
calendarEvents.pop();
|
||||
}
|
||||
|
||||
if (calendarEvents.length) {
|
||||
const lastEventId = calendarEvents.at(-1).id;
|
||||
setOffset(root, lastEventId);
|
||||
}
|
||||
|
||||
return {calendarEvents, loadedAll};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Load new events and append to current list.
|
||||
*
|
||||
* @param {object} root The event list container element.
|
||||
*/
|
||||
const loadMoreEvents = root => {
|
||||
const midnight = parseInt(root.attr('data-midnight'), 10);
|
||||
const courseId = root.attr('data-course-id');
|
||||
const daysOffset = parseInt(root.attr('data-days-offset'), 10);
|
||||
const daysLimit = root.attr('data-days-limit');
|
||||
const lastId = getOffset(root);
|
||||
const eventListWrapper = root.find(SELECTORS.EVENT_LIST_WRAPPER);
|
||||
const searchValue = root.closest(SELECTORS.TIMELINE_BLOCK).find(SELECTORS.TIMELINE_SEARCH).val();
|
||||
const eventsPromise = loadEventsForLazyLoading(
|
||||
root,
|
||||
DEFAULT_LAZY_LOADING_ITEMS_OTHER_LOAD,
|
||||
midnight,
|
||||
lastId,
|
||||
courseId,
|
||||
daysOffset,
|
||||
daysLimit,
|
||||
searchValue
|
||||
);
|
||||
eventsPromise.then(data => {
|
||||
if (data.calendarEvents.length) {
|
||||
const renderPromise = render(data.calendarEvents);
|
||||
const lastTimestamp = getLastTimestamp(root);
|
||||
renderPromise.then((html, js) => {
|
||||
html = $(html);
|
||||
|
||||
// Remove the date heading if it has the same value as the previous one.
|
||||
html.find(`[data-timestamp="${lastTimestamp}"]`).remove();
|
||||
Templates.appendNodeContents(eventListWrapper, html.html(), js);
|
||||
|
||||
if (!data.loadedAll) {
|
||||
Templates.render(TEMPLATES.MORE_ACTIVITIES_BUTTON, {}).then(html => {
|
||||
eventListWrapper.append(html);
|
||||
setLastTimestamp(root, data.calendarEvents.at(-1).timeusermidnight);
|
||||
// Init the event handler.
|
||||
initEventListener(root);
|
||||
|
||||
return html;
|
||||
}).catch(() => {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
return html;
|
||||
}).catch(Notification.exception);
|
||||
}
|
||||
|
||||
return data;
|
||||
}).then(() => {
|
||||
return disableMoreActivitiesButtonLoading(root);
|
||||
}).catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the offset value for lazy loading fetching.
|
||||
*
|
||||
* @param {object} element The event list container element.
|
||||
* @return {Number} Offset value.
|
||||
*/
|
||||
const getOffset = element => {
|
||||
return parseInt(element.attr('data-lazyload-offset'), 10);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the offset value for lazy loading fetching.
|
||||
*
|
||||
* @param {object} element The event list container element.
|
||||
* @param {Number} offset Offset value.
|
||||
*/
|
||||
const setOffset = (element, offset) => {
|
||||
element.attr('data-lazyload-offset', offset);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the timestamp value for lazy loading fetching.
|
||||
*
|
||||
* @param {object} element The event list container element.
|
||||
* @return {Number} Timestamp value.
|
||||
*/
|
||||
const getLastTimestamp = element => {
|
||||
return parseInt(element.attr('data-timestamp'), 10);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the timestamp value for lazy loading fetching.
|
||||
*
|
||||
* @param {object} element The event list container element.
|
||||
* @param {Number} timestamp Timestamp value.
|
||||
*/
|
||||
const setLastTimestamp = (element, timestamp) => {
|
||||
element.attr('data-timestamp', timestamp);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the "Show more activities" button and remove and loading spinner.
|
||||
*
|
||||
* @param {object} root The event list container element.
|
||||
*/
|
||||
const enableMoreActivitiesButtonLoading = root => {
|
||||
const loadMoreButton = root.find(SELECTORS.MORE_ACTIVITIES_BUTTON);
|
||||
loadMoreButton.prop('disabled', true);
|
||||
Templates.render(TEMPLATES.LOADING_ICON, {}).then(html => {
|
||||
loadMoreButton.append(html);
|
||||
return html;
|
||||
}).catch(() => {
|
||||
// It's not important if this false so just do so silently.
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the "Show more activities" button and remove and loading spinner.
|
||||
*
|
||||
* @param {object} root The event list container element.
|
||||
*/
|
||||
const disableMoreActivitiesButtonLoading = root => {
|
||||
const loadMoreButtonContainer = root.find(SELECTORS.MORE_ACTIVITIES_BUTTON_CONTAINER);
|
||||
loadMoreButtonContainer.remove();
|
||||
};
|
||||
|
||||
/**
|
||||
* Event initialise.
|
||||
*
|
||||
* @param {object} root The event list container element.
|
||||
*/
|
||||
const initEventListener = root => {
|
||||
const loadMoreButton = root.find(SELECTORS.MORE_ACTIVITIES_BUTTON);
|
||||
loadMoreButton.on('click', () => {
|
||||
enableMoreActivitiesButtonLoading(root);
|
||||
loadMoreEvents(root);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: init,
|
||||
rootSelector: SELECTORS.ROOT,
|
||||
|
||||
@@ -25,7 +25,6 @@ define(
|
||||
'jquery',
|
||||
'core/notification',
|
||||
'core/custom_interaction_events',
|
||||
'core/str',
|
||||
'core/templates',
|
||||
'block_timeline/event_list',
|
||||
'core_course/repository',
|
||||
@@ -35,7 +34,6 @@ function(
|
||||
$,
|
||||
Notification,
|
||||
CustomEvents,
|
||||
Str,
|
||||
Templates,
|
||||
EventList,
|
||||
CourseRepository,
|
||||
@@ -424,33 +422,11 @@ function(
|
||||
// correct course event list.
|
||||
courses.forEach(function(course) {
|
||||
var courseId = course.id;
|
||||
var events = [];
|
||||
var containerSelector = '[data-region="course-events-container"][data-course-id="' + courseId + '"]';
|
||||
var courseEventsContainer = root.find(containerSelector);
|
||||
var eventListRoot = courseEventsContainer.find(EventList.rootSelector);
|
||||
var courseGroups = eventsByCourse.groupedbycourse.filter(function(group) {
|
||||
return group.courseid == courseId;
|
||||
});
|
||||
|
||||
if (courseGroups.length) {
|
||||
// Get the events for this course.
|
||||
events = courseGroups[0].events;
|
||||
}
|
||||
|
||||
// Create a preloaded page to pass to the event list because we've already
|
||||
// loaded the first page of events.
|
||||
var pageOnePreload = $.Deferred().resolve({events: events}).promise();
|
||||
// Initialise the event list pagination area for this course.
|
||||
Str.get_string('ariaeventlistpaginationnavcourses', 'block_timeline', course.fullnamedisplay)
|
||||
.then(function(string) {
|
||||
EventList.init(eventListRoot, COURSE_EVENT_LIMIT, {'1': pageOnePreload}, string, additionalConfig);
|
||||
return string;
|
||||
})
|
||||
.catch(function() {
|
||||
// An error is ok, just render with the default string.
|
||||
EventList.init(eventListRoot, COURSE_EVENT_LIMIT, {'1': pageOnePreload}, undefined,
|
||||
additionalConfig);
|
||||
});
|
||||
EventList.init(eventListRoot, additionalConfig);
|
||||
});
|
||||
|
||||
return eventsByCourse;
|
||||
@@ -488,35 +464,9 @@ function(
|
||||
|
||||
courseEventsContainers.each(function(index, container) {
|
||||
container = $(container);
|
||||
var courseId = container.attr('data-course-id');
|
||||
var courseName = container.find(SELECTORS.COURSE_NAME).text();
|
||||
var eventListContainer = container.find(EventList.rootSelector);
|
||||
var pageDeferred = $.Deferred();
|
||||
var events = [];
|
||||
var courseGroups = eventsByCourse.groupedbycourse.filter(function(group) {
|
||||
return group.courseid == courseId;
|
||||
});
|
||||
|
||||
if (courseGroups.length) {
|
||||
// Get the events just for this course.
|
||||
events = courseGroups[0].events;
|
||||
}
|
||||
|
||||
pageDeferred.resolve({events: events});
|
||||
|
||||
// Re-initialise the events list with the preloaded events we just got from
|
||||
// the server.
|
||||
Str.get_string('ariaeventlistpaginationnavcourses', 'block_timeline', courseName)
|
||||
.then(function(string) {
|
||||
EventList.init(eventListContainer, COURSE_EVENT_LIMIT, {'1': pageDeferred.promise()},
|
||||
string, additionalConfig);
|
||||
return string;
|
||||
})
|
||||
.catch(function() {
|
||||
// Ignore a failure to load the string. Just render with the default string.
|
||||
EventList.init(eventListContainer, COURSE_EVENT_LIMIT, {'1': pageDeferred.promise()},
|
||||
undefined, additionalConfig);
|
||||
});
|
||||
EventList.init(eventListContainer, additionalConfig);
|
||||
});
|
||||
|
||||
return eventsByCourse;
|
||||
|
||||
@@ -23,14 +23,12 @@
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/str',
|
||||
'block_timeline/event_list',
|
||||
'core/pubsub',
|
||||
'core/paged_content_events'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Str,
|
||||
EventList,
|
||||
PubSub,
|
||||
PagedContentEvents
|
||||
@@ -40,35 +38,6 @@ function(
|
||||
EVENT_LIST_CONTAINER: '[data-region="event-list-container"]',
|
||||
};
|
||||
|
||||
var DEFAULT_PAGE_LIMIT = [5, 10, 25];
|
||||
|
||||
/**
|
||||
* Generate a paged content array of limits taking into account user preferences
|
||||
*
|
||||
* @param {object} root The root element for the timeline dates view.
|
||||
* @return {array} Array of limit objects
|
||||
*/
|
||||
var getPagingLimits = function(root) {
|
||||
var limitPref = parseInt(root.data('limit'), 10);
|
||||
var isDefaultSet = false;
|
||||
var limits = DEFAULT_PAGE_LIMIT.map(function(value) {
|
||||
if (limitPref == value) {
|
||||
isDefaultSet = true;
|
||||
}
|
||||
|
||||
return {
|
||||
value: value,
|
||||
active: limitPref == value
|
||||
};
|
||||
});
|
||||
|
||||
if (!isDefaultSet) {
|
||||
limits[0].active = true;
|
||||
}
|
||||
|
||||
return limits;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the listeners for the timeline block
|
||||
*
|
||||
@@ -92,20 +61,11 @@ function(
|
||||
var namespace = $(eventListContainer).attr('id') + "user_block_timeline" + Math.random();
|
||||
registerEventListeners(root, namespace);
|
||||
|
||||
var limits = getPagingLimits(root);
|
||||
var config = {
|
||||
persistentLimitKey: "block_timeline_user_limit_preference",
|
||||
eventNamespace: namespace
|
||||
};
|
||||
Str.get_string('ariaeventlistpaginationnavdates', 'block_timeline')
|
||||
.then(function(string) {
|
||||
EventList.init(eventListContainer, limits, {}, string, config);
|
||||
return string;
|
||||
})
|
||||
.catch(function() {
|
||||
// Ignore if we can't load the string. Still init the event list.
|
||||
EventList.init(eventListContainer, limits, {}, "", config);
|
||||
});
|
||||
EventList.init(eventListContainer, config);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,14 +25,12 @@
|
||||
$string['ariadayfilter'] = 'Filter timeline by date';
|
||||
$string['ariadayfilteroption'] = '{$a} filter option';
|
||||
$string['ariaeventlistitem'] = '{$a->name} activity in {$a->course} is due on {$a->date}';
|
||||
$string['ariaeventlistpagelimit'] = 'Show {$a} activities per page';
|
||||
$string['ariaeventlistpaginationnavdates'] = 'Timeline activities pagination';
|
||||
$string['ariaeventlistpaginationnavcourses'] = 'Timeline activities for course {$a} pagination';
|
||||
$string['ariaviewselector'] = 'Sort timeline items';
|
||||
$string['ariaviewselectoroption'] = '{$a} sort option';
|
||||
$string['clearsearch'] = 'Clear search';
|
||||
$string['duedate'] = 'Due date';
|
||||
$string['morecourses'] = 'More courses';
|
||||
$string['moreactivities'] = 'Show more activities';
|
||||
$string['morecourses'] = 'Show more courses';
|
||||
$string['timeline:myaddinstance'] = 'Add a new timeline block to Dashboard';
|
||||
$string['nocoursesinprogress'] = 'No in-progress courses';
|
||||
$string['noevents'] = 'No activities require action';
|
||||
@@ -51,3 +49,8 @@ $string['viewcourse'] = 'View course';
|
||||
$string['privacy:metadata:timelinesortpreference'] = 'The user sort preference for the timeline block.';
|
||||
$string['privacy:metadata:timelinefilterpreference'] = 'The user day filter preference for the timeline block.';
|
||||
$string['privacy:metadata:timelinelimitpreference'] = 'The user page limit preference for the timeline block.';
|
||||
|
||||
// Deprecated since Moodle 4.0.
|
||||
$string['ariaeventlistpagelimit'] = 'Show {$a} activities per page';
|
||||
$string['ariaeventlistpaginationnavdates'] = 'Timeline activities pagination';
|
||||
$string['ariaeventlistpaginationnavcourses'] = 'Timeline activities for course {$a} pagination';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
ariaeventlistpagelimit,block_timeline
|
||||
ariaeventlistpaginationnavdates,block_timeline
|
||||
ariaeventlistpaginationnavcourses,block_timeline
|
||||
@@ -63,9 +63,9 @@
|
||||
]
|
||||
}
|
||||
}}
|
||||
<div class="pb-2">
|
||||
<div class="pb-2" data-region="event-list-wrapper">
|
||||
{{#eventsbyday}}
|
||||
<div class="mt-3">
|
||||
<div class="mt-3" data-region="event-list-content-date" data-timestamp="{{dayTimestamp}}">
|
||||
<h5 class="h6 d-inline {{^courseview}}font-weight-bold{{/courseview}}">{{#userdate}} {{dayTimestamp}}, {{#str}} strftimedaydate, core_langconfig {{/str}} {{/userdate}}</h5>
|
||||
</div>
|
||||
{{> block_timeline/event-list-items }}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template block_timeline/event-list-loadmore
|
||||
|
||||
This template renders a show more activities button.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
|
||||
}
|
||||
}}
|
||||
<div class="pt-1 pb-2" data-region="more-events-button-container">
|
||||
<button type="button" class="btn btn-secondary btn-sm" data-action="more-events">
|
||||
{{#str}} moreactivities, block_timeline {{/str}}
|
||||
</button>
|
||||
</div>
|
||||
@@ -30,8 +30,8 @@
|
||||
<div class="bg-pulse-grey mt-1" style="width: 100px; height: 30px; margin-left: auto; margin-right: auto"></div>
|
||||
</div>
|
||||
<ul class="list-group unstyled" data-region="courses-list"></ul>
|
||||
<div class="hidden text-xs-left text-left pt-3" data-region="more-courses-button-container">
|
||||
<button type="button" class="btn btn-secondary" data-action="more-courses">
|
||||
<div class="hidden text-xs-center text-center pt-3" data-region="more-courses-button-container">
|
||||
<button type="button" class="btn btn-primary" data-action="more-courses">
|
||||
{{#str}} morecourses, block_timeline {{/str}}
|
||||
<span class="hidden" data-region="loading-icon-container">
|
||||
{{> core/loading }}
|
||||
|
||||
@@ -44,7 +44,7 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
When I click on "Sort by courses" "link" in the "Timeline" "block"
|
||||
Then I should see "Course 1" in the "Timeline" "block"
|
||||
And I should see "Course 2" in the "Timeline" "block"
|
||||
And I should see "More courses" in the "Timeline" "block"
|
||||
And I should see "Show more courses" in the "Timeline" "block"
|
||||
And "Test choice 1" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Choice closes" in the "Timeline" "block"
|
||||
And "Test feedback 1" "link" should exist in the "Timeline" "block"
|
||||
@@ -64,7 +64,7 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
And I click on "All" "link" in the "Timeline" "block"
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by courses" "link" in the "Timeline" "block"
|
||||
When I click on "More courses" "button" in the "Timeline" "block"
|
||||
When I click on "Show more courses" "button" in the "Timeline" "block"
|
||||
Then I should see "Course 3" in the "Timeline" "block"
|
||||
And I should see "Course 2" in the "Timeline" "block"
|
||||
And I should see "Course 1" in the "Timeline" "block"
|
||||
@@ -78,7 +78,7 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
And "Test assign 2" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Assignment is due" in the "Timeline" "block"
|
||||
And I should see "Choice closes" in the "Timeline" "block"
|
||||
And I should not see "More courses" in the "Timeline" "block"
|
||||
And I should not see "Show more courses" in the "Timeline" "block"
|
||||
And I should not see "Course 4" in the "Timeline" "block"
|
||||
And "Test choice 2" "link" should not exist in the "Timeline" "block"
|
||||
And I should not see "Test feedback 4" in the "Timeline" "block"
|
||||
@@ -92,7 +92,7 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
When I reload the page
|
||||
Then I should see "Course 1" in the "Timeline" "block"
|
||||
And I should see "Course 2" in the "Timeline" "block"
|
||||
And I should see "More courses" in the "Timeline" "block"
|
||||
And I should see "Show more courses" in the "Timeline" "block"
|
||||
And "Test choice 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test feedback 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test feedback 5" "link" should exist in the "Timeline" "block"
|
||||
@@ -111,7 +111,7 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
And I click on "All" "link" in the "Timeline" "block"
|
||||
When I reload the page
|
||||
And I click on "More courses" "button" in the "Timeline" "block"
|
||||
And I click on "Show more courses" "button" in the "Timeline" "block"
|
||||
Then I should see "Course 3" in the "Timeline" "block"
|
||||
And I should see "Course 2" in the "Timeline" "block"
|
||||
And I should see "Course 1" in the "Timeline" "block"
|
||||
@@ -121,7 +121,7 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
And "Test feedback 2" "link" should exist in the "Timeline" "block"
|
||||
And "Test feedback 3" "link" should exist in the "Timeline" "block"
|
||||
And "Test assign 1" "link" should exist in the "Timeline" "block"
|
||||
And I should not see "More courses" in the "Timeline" "block"
|
||||
And I should not see "Show more courses" in the "Timeline" "block"
|
||||
And I should not see "Course 4" in the "Timeline" "block"
|
||||
And "Test choice 2" "link" should not exist in the "Timeline" "block"
|
||||
And "Test feedback 4" "link" should not exist in the "Timeline" "block"
|
||||
@@ -142,7 +142,7 @@ Feature: The timeline block allows users to see upcoming courses
|
||||
When I click on "All" "link" in the "Timeline" "block"
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by courses" "link" in the "Timeline" "block"
|
||||
And I click on "More courses" "button" in the "Timeline" "block"
|
||||
And I click on "Show more courses" "button" in the "Timeline" "block"
|
||||
Then "Test assign 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test feedback 2" "link" should exist in the "Timeline" "block"
|
||||
|
||||
|
||||
@@ -80,39 +80,15 @@ Feature: The timeline block allows users to see upcoming activities
|
||||
And I should see "Course 2 · Feedback closes" in the "Timeline" "block"
|
||||
And "Test choice 2" "link" should not exist in the "Timeline" "block"
|
||||
And "Test feedback 2" "link" should not exist in the "Timeline" "block"
|
||||
And I click on "[data-region='paging-bar'] [data-control='next'] [data-region='page-link']" "css_element" in the "Timeline" "block"
|
||||
And I click on "Show more activities" "button"
|
||||
And "Test feedback 2" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 1 · Feedback closes" in the "Timeline" "block"
|
||||
And "Test choice 3" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 3 · Choice closes" in the "Timeline" "block"
|
||||
And "Test feedback 3" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 3 · Feedback closes" in the "Timeline" "block"
|
||||
And I should not see "Test assign 1" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 1" in the "Timeline" "block"
|
||||
And I should not see "Test choice 1" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2" in the "Timeline" "block"
|
||||
|
||||
Scenario: All in date view no next
|
||||
Given I log in as "student1"
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
And I click on "All" "link" in the "Timeline" "block"
|
||||
And I click on "5" "button" in the "Timeline" "block"
|
||||
When I click on "25" "link" in the "Timeline" "block"
|
||||
Then "Test assign 1" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 1 · Assignment is due" in the "Timeline" "block"
|
||||
And "Test assign 2" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 2 · Assignment is due" in the "Timeline" "block"
|
||||
And "Test feedback 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test feedback 4" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 2 · Feedback closes" in the "Timeline" "block"
|
||||
And "Test choice 1" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 2 · Choice closes" in the "Timeline" "block"
|
||||
And "Test choice 3" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 3 · Choice closes" in the "Timeline" "block"
|
||||
And "Test feedback 3" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 3 · Feedback closes" in the "Timeline" "block"
|
||||
And "Test feedback 2" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 1 · Feedback closes" in the "Timeline" "block"
|
||||
And I should see "Test assign 1" in the "Timeline" "block"
|
||||
And I should see "Test feedback 1" in the "Timeline" "block"
|
||||
And I should see "Test choice 1" in the "Timeline" "block"
|
||||
And I should see "Test choice 3" in the "Timeline" "block"
|
||||
And I should see "Test feedback 3" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2" in the "Timeline" "block"
|
||||
|
||||
Scenario: Persistent All in date view
|
||||
@@ -132,17 +108,15 @@ Feature: The timeline block allows users to see upcoming activities
|
||||
And I should see "Course 2 · Feedback closes" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 2" in the "Timeline" "block"
|
||||
And I click on "[data-region='paging-bar'] [data-control='next']" "css_element" in the "Timeline" "block"
|
||||
And I click on "Show more activities" "button"
|
||||
And "Test feedback 2" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 1 · Feedback closes" in the "Timeline" "block"
|
||||
And "Test choice 3" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 3 · Choice closes" in the "Timeline" "block"
|
||||
And "Test feedback 3" "link" should exist in the "Timeline" "block"
|
||||
And I should see "Course 3 · Feedback closes" in the "Timeline" "block"
|
||||
And I should not see "Test assign 1" in the "Timeline" "block"
|
||||
And I should not see "Test feedback 1" in the "Timeline" "block"
|
||||
And I should not see "Test choice 1" in the "Timeline" "block"
|
||||
And I should see "Test assign 1" in the "Timeline" "block"
|
||||
And I should see "Test feedback 1" in the "Timeline" "block"
|
||||
And I should see "Test feedback 3" in the "Timeline" "block"
|
||||
And I should see "Test choice 1" in the "Timeline" "block"
|
||||
And I should not see "Test choice 2" in the "Timeline" "block"
|
||||
And I should see "Test choice 3" in the "Timeline" "block"
|
||||
|
||||
Scenario: Persistent Overdue in date view
|
||||
Given I log in as "student1"
|
||||
@@ -165,9 +139,6 @@ Feature: The timeline block allows users to see upcoming activities
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
And I click on "Overdue" "link" in the "Timeline" "block"
|
||||
And I reload the page
|
||||
# Expand to 25 results, to ensure we see the earliest and latest timeline items.
|
||||
And I click on "Show 5 activities per page" "button" in the "Timeline" "block"
|
||||
And I click on "25" "link"
|
||||
And "Test assign 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test feedback 2" "link" should not exist in the "Timeline" "block"
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
@@ -178,4 +149,5 @@ Feature: The timeline block allows users to see upcoming activities
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by dates" "link" in the "Timeline" "block"
|
||||
Then "Test assign 1" "link" should exist in the "Timeline" "block"
|
||||
And I click on "Show more activities" "button"
|
||||
And "Test feedback 2" "link" should exist in the "Timeline" "block"
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
@block @block_timeline @javascript
|
||||
Feature: The timeline block allows users to use the lazy loading to view more activities
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email | idnumber |
|
||||
| student1 | Student | 1 | student1@example.com | S1 |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | startdate | enddate |
|
||||
| Course 1 | C1 | 0 | ##yesterday## | ##last day of next month## |
|
||||
| Course 2 | C2 | 0 | ##yesterday## | ##last day of next month## |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
| student1 | C2 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | timeopen | timeclose |
|
||||
| choice | C1 | choice1 | Test choice 1 | Test choice description | ##yesterday## | ##tomorrow## |
|
||||
| choice | C1 | choice2 | Test choice 2 | Test choice description | ##yesterday## | ##+1 days## |
|
||||
| choice | C1 | choice3 | Test choice 3 | Test choice description | ##yesterday## | ##+2 days## |
|
||||
| choice | C1 | choice4 | Test choice 4 | Test choice description | ##yesterday## | ##+3 days## |
|
||||
| choice | C1 | choice5 | Test choice 5 | Test choice description | ##yesterday## | ##+4 days## |
|
||||
| choice | C1 | choice6 | Test choice 6 | Test choice description | ##yesterday## | ##+5 days## |
|
||||
| choice | C1 | choice7 | Test choice 7 | Test choice description | ##yesterday## | ##+6 days## |
|
||||
| choice | C1 | choice8 | Test choice 8 | Test choice description | ##yesterday## | ##+7 days## |
|
||||
| choice | C1 | choice9 | Test choice 9 | Test choice description | ##yesterday## | ##+8 days## |
|
||||
| choice | C1 | choice10 | Test choice 10 | Test choice description | ##yesterday## | ##+9 days## |
|
||||
| choice | C2 | choice10 | Test choice 11 | Test choice description | ##yesterday## | ##+9 days## |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | timeopen | duedate |
|
||||
| assign | C1 | assign1 | Test assign 1 | Test assign description | ##1 month ago## | ##yesterday## |
|
||||
|
||||
Scenario: Lazy loading for date view
|
||||
Given I log in as "student1"
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
When I click on "All" "link" in the "Timeline" "block"
|
||||
Then I should see "Test choice 1" in the "Timeline" "block"
|
||||
And "Test assign 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 2" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 3" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 4" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 5" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 6" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 7" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 8" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 9" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 10" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 11" "link" should not exist in the "Timeline" "block"
|
||||
And I click on "Show more activities" "button" in the "[data-region='view-dates']" "css_element"
|
||||
And "Test choice 5" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 6" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 7" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 8" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 9" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 10" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 11" "link" should exist in the "Timeline" "block"
|
||||
|
||||
Scenario: Lazy loading for course view
|
||||
Given I log in as "student1"
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
When I click on "Sort by courses" "link" in the "Timeline" "block"
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
And I click on "All" "link" in the "Timeline" "block"
|
||||
And "Test choice 1" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 2" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 3" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 4" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 5" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 11" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 6" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 7" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 8" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 9" "link" should not exist in the "Timeline" "block"
|
||||
And "Test choice 10" "link" should not exist in the "Timeline" "block"
|
||||
And I click on "Show more activities" "button" in the "[data-region='view-courses']" "css_element"
|
||||
And "Test choice 6" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 7" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 8" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 9" "link" should exist in the "Timeline" "block"
|
||||
And "Test choice 10" "link" should exist in the "Timeline" "block"
|
||||
|
||||
Scenario: The lazy loading button will not be shown if the number of events is smaller than 5
|
||||
Given I log in as "student1"
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by dates" "link" in the "Timeline" "block"
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
When I click on "Overdue" "link" in the "Timeline" "block"
|
||||
Then "Test assign 1" "link" should exist in the "Timeline" "block"
|
||||
And "Show more activities" "button" should not exist in the "[data-region='view-courses']" "css_element"
|
||||
@@ -1,64 +0,0 @@
|
||||
@block @block_timeline @javascript
|
||||
Feature: The timeline block allows user persistence of their page limits
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email | idnumber |
|
||||
| student1 | Student | 1 | student1@example.com | S1 |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | startdate | enddate |
|
||||
| Course 1 | C1 | 0 | ##1 month ago## | ##15 days ago## |
|
||||
| Course 2 | C2 | 0 | ##yesterday## | ##tomorrow## |
|
||||
| Course 3 | C3 | 0 | ##first day of next month## | ##last day of next month## |
|
||||
| Course 4 | C4 | 0 | ##first day of next month## | ##last day of next month## |
|
||||
| Course 5 | C5 | 0 | ##first day of next month## | ##last day of next month## |
|
||||
| Course 6 | C6 | 0 | ##first day of next month## | ##last day of next month## |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | timeopen | timeclose |
|
||||
| choice | C2 | choice1 | Test choice 1 | Test choice description | ##yesterday## | ##tomorrow## |
|
||||
| choice | C1 | choice2 | Test choice 2 | Test choice description | ##1 month ago## | ##15 days ago## |
|
||||
| choice | C3 | choice3 | Test choice 3 | Test choice description | ##first day of +5 months## | ##last day of +5 months## |
|
||||
| feedback | C2 | feedback1 | Test feedback 1 | Test feedback description | ##yesterday## | ##tomorrow## |
|
||||
| feedback | C1 | feedback2 | Test feedback 2 | Test feedback description | ##first day of +10 months## | ##last day of +10 months## |
|
||||
| feedback | C3 | feedback3 | Test feedback 3 | Test feedback description | ##first day of +5 months## | ##last day of +5 months## |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | timeopen | duedate |
|
||||
| assign | C1 | assign1 | Test assign 1 | Test assign description | ##1 month ago## | ##yesterday## |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | C1 | student |
|
||||
| student1 | C2 | student |
|
||||
| student1 | C3 | student |
|
||||
| student1 | C4 | student |
|
||||
| student1 | C5 | student |
|
||||
| student1 | C6 | student |
|
||||
|
||||
Scenario: Toggle the page limit 5 - 25
|
||||
Given I log in as "student1"
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
And I click on "All" "link" in the "Timeline" "block"
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by dates" "link" in the "Timeline" "block"
|
||||
When I click on "5" "button" in the "Timeline" "block"
|
||||
And I click on "25" "link"
|
||||
Then I should see "Test feedback 2" in the "Timeline" "block"
|
||||
And I reload the page
|
||||
Then I should see "Test feedback 2" in the "Timeline" "block"
|
||||
And I log out
|
||||
|
||||
Scenario: Toggle the page limit 25 - 5
|
||||
Given I log in as "student1"
|
||||
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
|
||||
And I click on "All" "link" in the "Timeline" "block"
|
||||
And I click on "Sort timeline items" "button" in the "Timeline" "block"
|
||||
And I click on "Sort by dates" "link" in the "Timeline" "block"
|
||||
When I click on "5" "button" in the "Timeline" "block"
|
||||
And I click on "25" "link"
|
||||
And I should see "Test feedback 2" in the "Timeline" "block"
|
||||
And I change window size to "large"
|
||||
And I click on "25" "button" in the "Timeline" "block"
|
||||
And I click on "5" "link" in the "[data-region='timeline'] [data-region='paging-control-limit-container'] .dropdown-menu" "css_element"
|
||||
Then I should not see "Test feedback 2" in the "Timeline" "block"
|
||||
And I reload the page
|
||||
And I should not see "Test feedback 2" in the "Timeline" "block"
|
||||
And I log out
|
||||
@@ -91,5 +91,5 @@ Feature: The timeline block allows users to search for upcoming activities
|
||||
And I should see "Test choice 4" in the "Timeline" "block"
|
||||
And I should see "Test choice 5" in the "Timeline" "block"
|
||||
And I should not see "Test choice 6" in the "Timeline" "block"
|
||||
And I click on "[data-control='next']" "css_element" in the "Timeline" "block"
|
||||
And I click on "Show more activities" "button"
|
||||
And I should see "Test choice 6" in the "Timeline" "block"
|
||||
|
||||
Reference in New Issue
Block a user