274 lines
10 KiB
TypeScript
Raw Normal View History

// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreSitesProvider } from '@providers/sites';
import { CoreSite } from '@classes/site';
import * as moment from 'moment';
/**
* Service that provides some features regarding course overview.
*/
@Injectable()
export class CoreCoursesMyOverviewProvider {
2018-01-29 10:05:20 +01:00
static EVENTS_LIMIT = 20;
static EVENTS_LIMIT_PER_COURSE = 10;
protected ROOT_CACHE_KEY = 'myoverview:';
2018-01-29 10:05:20 +01:00
constructor(private sitesProvider: CoreSitesProvider) { }
/**
* Get calendar action events for the given course.
*
* @param {number} courseId Only events in this course.
* @param {number} [afterEventId] The last seen event id.
* @param {string} [siteId] Site ID. If not defined, use current site.
* @return {Promise<{events: any[], canLoadMore: number}>} Promise resolved when the info is retrieved.
*/
2018-01-29 10:05:20 +01:00
getActionEventsByCourse(courseId: number, afterEventId?: number, siteId?: string):
Promise<{ events: any[], canLoadMore: number }> {
return this.sitesProvider.getSite(siteId).then((site) => {
2018-01-29 10:05:20 +01:00
const time = moment().subtract(14, 'days').unix(), // Check two weeks ago.
data: any = {
timesortfrom: time,
courseid: courseId,
limitnum: CoreCoursesMyOverviewProvider.EVENTS_LIMIT_PER_COURSE
},
preSets = {
cacheKey: this.getActionEventsByCourseCacheKey(courseId)
};
if (afterEventId) {
data.aftereventid = afterEventId;
}
2018-01-29 10:05:20 +01:00
return site.read('core_calendar_get_action_events_by_course', data, preSets).then((courseEvents): any => {
if (courseEvents && courseEvents.events) {
return this.treatCourseEvents(courseEvents, time);
}
2018-01-29 10:05:20 +01:00
return Promise.reject(null);
});
});
}
/**
* Get cache key for get calendar action events for the given course value WS call.
*
* @param {number} courseId Only events in this course.
* @return {string} Cache key.
*/
2018-01-29 10:05:20 +01:00
protected getActionEventsByCourseCacheKey(courseId: number): string {
return this.getActionEventsByCoursesCacheKey() + ':' + courseId;
}
/**
* Get calendar action events for a given list of courses.
*
* @param {number[]} courseIds Course IDs.
* @param {string} [siteId] Site ID. If not defined, use current site.
* @return {Promise<{[s: string]: {events: any[], canLoadMore: number}}>} Promise resolved when the info is retrieved.
*/
2018-01-29 10:05:20 +01:00
getActionEventsByCourses(courseIds: number[], siteId?: string): Promise<{ [s: string]:
{ events: any[], canLoadMore: number } }> {
return this.sitesProvider.getSite(siteId).then((site) => {
2018-01-29 10:05:20 +01:00
const time = moment().subtract(14, 'days').unix(), // Check two weeks ago.
data = {
timesortfrom: time,
courseids: courseIds,
limitnum: CoreCoursesMyOverviewProvider.EVENTS_LIMIT_PER_COURSE
},
preSets = {
cacheKey: this.getActionEventsByCoursesCacheKey()
};
2018-01-29 10:05:20 +01:00
return site.read('core_calendar_get_action_events_by_courses', data, preSets).then((events): any => {
if (events && events.groupedbycourse) {
2018-01-29 10:05:20 +01:00
const courseEvents = {};
events.groupedbycourse.forEach((course) => {
courseEvents[course.courseid] = this.treatCourseEvents(course, time);
});
return courseEvents;
}
return Promise.reject(null);
});
});
}
/**
* Get cache key for get calendar action events for a given list of courses value WS call.
*
* @return {string} Cache key.
*/
2018-01-29 10:05:20 +01:00
protected getActionEventsByCoursesCacheKey(): string {
return this.ROOT_CACHE_KEY + 'bycourse';
}
/**
* Get calendar action events based on the timesort value.
*
* @param {number} [afterEventId] The last seen event id.
* @param {string} [siteId] Site ID. If not defined, use current site.
* @return {Promise<{events: any[], canLoadMore: number}>} Promise resolved when the info is retrieved.
*/
2018-01-29 10:05:20 +01:00
getActionEventsByTimesort(afterEventId: number, siteId?: string): Promise<{ events: any[], canLoadMore: number }> {
return this.sitesProvider.getSite(siteId).then((site) => {
2018-01-29 10:05:20 +01:00
const time = moment().subtract(14, 'days').unix(), // Check two weeks ago.
data: any = {
timesortfrom: time,
limitnum: CoreCoursesMyOverviewProvider.EVENTS_LIMIT
},
preSets = {
cacheKey: this.getActionEventsByTimesortCacheKey(afterEventId, data.limitnum),
getCacheUsingCacheKey: true,
uniqueCacheKey: true
};
if (afterEventId) {
data.aftereventid = afterEventId;
}
2018-01-29 10:05:20 +01:00
return site.read('core_calendar_get_action_events_by_timesort', data, preSets).then((events): any => {
if (events && events.events) {
2018-01-29 10:05:20 +01:00
const canLoadMore = events.events.length >= data.limitnum ? events.lastid : undefined;
// Filter events by time in case it uses cache.
events = events.events.filter((element) => {
return element.timesort >= time;
});
return {
events: events,
canLoadMore: canLoadMore
};
}
2018-01-29 10:05:20 +01:00
return Promise.reject(null);
});
});
}
/**
* Get prefix cache key for calendar action events based on the timesort value WS calls.
*
* @return {string} Cache key.
*/
2018-01-29 10:05:20 +01:00
protected getActionEventsByTimesortPrefixCacheKey(): string {
return this.ROOT_CACHE_KEY + 'bytimesort:';
}
/**
* Get cache key for get calendar action events based on the timesort value WS call.
*
* @param {number} [afterEventId] The last seen event id.
* @param {number} [limit] Limit num of the call.
* @return {string} Cache key.
*/
2018-01-29 10:05:20 +01:00
protected getActionEventsByTimesortCacheKey(afterEventId?: number, limit?: number): string {
afterEventId = afterEventId || 0;
limit = limit || 0;
2018-01-29 10:05:20 +01:00
return this.getActionEventsByTimesortPrefixCacheKey() + afterEventId + ':' + limit;
}
/**
* Invalidates get calendar action events for a given list of courses WS call.
*
* @param {string} [siteId] Site ID to invalidate. If not defined, use current site.
* @return {Promise<any>} Promise resolved when the data is invalidated.
*/
2018-01-29 10:05:20 +01:00
invalidateActionEventsByCourses(siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.invalidateWsCacheForKeyStartingWith(this.getActionEventsByCoursesCacheKey());
});
}
/**
* Invalidates get calendar action events based on the timesort value WS call.
*
* @param {string} [siteId] Site ID to invalidate. If not defined, use current site.
* @return {Promise<any>} Promise resolved when the data is invalidated.
*/
2018-01-29 10:05:20 +01:00
invalidateActionEventsByTimesort(siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.invalidateWsCacheForKeyStartingWith(this.getActionEventsByTimesortPrefixCacheKey());
});
}
/**
* Returns whether or not My Overview is available for a certain site.
*
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<boolean>} Promise resolved with true if available, resolved with false or rejected otherwise.
*/
2018-01-29 10:05:20 +01:00
isAvailable(siteId?: string): Promise<boolean> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.wsAvailable('core_calendar_get_action_events_by_courses');
});
}
/**
* Check if My Overview is disabled in a certain site.
*
* @param {CoreSite} [site] Site. If not defined, use current site.
* @return {boolean} Whether it's disabled.
*/
2018-01-29 10:05:20 +01:00
isDisabledInSite(site?: CoreSite): boolean {
site = site || this.sitesProvider.getCurrentSite();
2018-01-29 10:05:20 +01:00
return site.isFeatureDisabled('CoreMainMenuDelegate_CoreCourses');
}
/**
* Check if My Overview is available and not disabled.
*
* @return {Promise<boolean>} Promise resolved with true if enabled, resolved with false otherwise.
*/
2018-01-29 10:05:20 +01:00
isEnabled(): Promise<boolean> {
if (!this.isDisabledInSite()) {
return this.isAvailable().catch(() => {
return false;
});
}
2018-01-29 10:05:20 +01:00
return Promise.resolve(false);
}
/**
* Handles course events, filtering and treating if more can be loaded.
*
* @param {any} course Object containing response course events info.
* @param {number} timeFrom Current time to filter events from.
* @return {{events: any[], canLoadMore: number}} Object with course events and last loaded event id if more can be loaded.
*/
2018-01-29 10:05:20 +01:00
protected treatCourseEvents(course: any, timeFrom: number): { events: any[], canLoadMore: number } {
const canLoadMore: number =
course.events.length >= CoreCoursesMyOverviewProvider.EVENTS_LIMIT_PER_COURSE ? course.lastid : undefined;
// Filter events by time in case it uses cache.
course.events = course.events.filter((element) => {
return element.timesort >= timeFrom;
});
return {
events: course.events,
canLoadMore: canLoadMore
};
}
}