diff --git a/src/addon/calendar/calendar.module.ts b/src/addon/calendar/calendar.module.ts
index c8f9cef82..66ab9f237 100644
--- a/src/addon/calendar/calendar.module.ts
+++ b/src/addon/calendar/calendar.module.ts
@@ -70,7 +70,13 @@ export class AddonCalendarModule {
return;
}
- loginHelper.redirect('AddonCalendarListPage', {eventId: data.eventid}, data.siteId);
+ // Check which page we should load.
+ calendarProvider.canViewMonth(data.siteId).then((canView) => {
+ const pageName = canView ? 'AddonCalendarIndexPage' : 'AddonCalendarListPage';
+
+ loginHelper.redirect(pageName, {eventId: data.eventid}, data.siteId);
+ });
+
});
});
}
diff --git a/src/addon/calendar/pages/index/index.html b/src/addon/calendar/pages/index/index.html
new file mode 100644
index 000000000..122436442
--- /dev/null
+++ b/src/addon/calendar/pages/index/index.html
@@ -0,0 +1,28 @@
+
+
+ {{ 'addon.calendar.calendarevents' | translate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/addon/calendar/pages/index/index.module.ts b/src/addon/calendar/pages/index/index.module.ts
new file mode 100644
index 000000000..0c3486dd9
--- /dev/null
+++ b/src/addon/calendar/pages/index/index.module.ts
@@ -0,0 +1,35 @@
+// (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 { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '@components/components.module';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { CorePipesModule } from '@pipes/pipes.module';
+import { AddonCalendarIndexPage } from './index';
+
+@NgModule({
+ declarations: [
+ AddonCalendarIndexPage,
+ ],
+ imports: [
+ CoreComponentsModule,
+ CoreDirectivesModule,
+ CorePipesModule,
+ IonicPageModule.forChild(AddonCalendarIndexPage),
+ TranslateModule.forChild()
+ ],
+})
+export class AddonCalendarIndexPageModule {}
diff --git a/src/addon/calendar/pages/index/index.ts b/src/addon/calendar/pages/index/index.ts
new file mode 100644
index 000000000..3c1be5ed2
--- /dev/null
+++ b/src/addon/calendar/pages/index/index.ts
@@ -0,0 +1,38 @@
+// (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 { Component, OnInit } from '@angular/core';
+import { IonicPage } from 'ionic-angular';
+
+/**
+ * Page that displays the calendar events.
+ */
+@IonicPage({ segment: 'addon-calendar-index' })
+@Component({
+ selector: 'page-addon-calendar-index',
+ templateUrl: 'index.html',
+})
+export class AddonCalendarIndexPage implements OnInit {
+
+ constructor() {
+ // @todo
+ }
+
+ /**
+ * View loaded.
+ */
+ ngOnInit(): void {
+ // @todo
+ }
+}
diff --git a/src/addon/calendar/providers/calendar.ts b/src/addon/calendar/providers/calendar.ts
index 9e34520a1..fdc4905d3 100644
--- a/src/addon/calendar/providers/calendar.ts
+++ b/src/addon/calendar/providers/calendar.ts
@@ -237,6 +237,8 @@ export class AddonCalendarProvider {
canDeleteEvents(siteId?: string): Promise {
return this.sitesProvider.getSite(siteId).then((site) => {
return this.canDeleteEventsInSite(site);
+ }).catch(() => {
+ return false;
});
}
@@ -263,6 +265,8 @@ export class AddonCalendarProvider {
canEditEvents(siteId?: string): Promise {
return this.sitesProvider.getSite(siteId).then((site) => {
return this.canEditEventsInSite(site);
+ }).catch(() => {
+ return false;
});
}
@@ -280,6 +284,34 @@ export class AddonCalendarProvider {
return site.isVersionGreaterEqualThan('3.7.1');
}
+ /**
+ * Check if a certain site allows viewing events in monthly view.
+ *
+ * @param {string} [siteId] Site Id. If not defined, use current site.
+ * @return {Promise} Promise resolved with true if monthly view is supported.
+ * @since 3.4
+ */
+ canViewMonth(siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return this.canViewMonthInSite(site);
+ }).catch(() => {
+ return false;
+ });
+ }
+
+ /**
+ * Check if a certain site allows viewing events in monthly view.
+ *
+ * @param {CoreSite} [site] Site. If not defined, use current site.
+ * @return {boolean} Whether monthly view is supported.
+ * @since 3.4
+ */
+ canViewMonthInSite(site?: CoreSite): boolean {
+ site = site || this.sitesProvider.getCurrentSite();
+
+ return site.wsAvailable('core_calendar_get_calendar_monthly_view');
+ }
+
/**
* Removes expired events from local DB.
*
@@ -723,6 +755,126 @@ export class AddonCalendarProvider {
return this.getEventsListPrefixCacheKey() + daysToStart + ':' + daysInterval;
}
+ /**
+ * Get monthly calendar events.
+ *
+ * @param {number} year Year to get.
+ * @param {number} month Month to get.
+ * @param {number} [courseId] Course to get.
+ * @param {number} [categoryId] Category to get.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved with the response.
+ */
+ getMonthlyEvents(year: number, month: number, courseId?: number, categoryId?: number, siteId?: string): Promise {
+
+ return this.sitesProvider.getSite(siteId).then((site) => {
+
+ const data: any = {
+ year: year,
+ month: month,
+ mini: 1 // Set mini to 1 to prevent returning the course selector HTML.
+ };
+
+ if (courseId) {
+ data.courseid = courseId;
+ }
+ if (categoryId) {
+ data.categoryid = categoryId;
+ }
+
+ const preSets = {
+ cacheKey: this.getMonthlyEventsCacheKey(year, month, courseId, categoryId),
+ updateFrequency: CoreSite.FREQUENCY_SOMETIMES
+ };
+
+ return site.read('core_calendar_get_calendar_monthly_view', data, preSets);
+ });
+ }
+
+ /**
+ * Get prefix cache key for monthly events WS calls.
+ *
+ * @return {string} Prefix Cache key.
+ */
+ protected getMonthlyEventsPrefixCacheKey(): string {
+ return this.ROOT_CACHE_KEY + 'monthly:';
+ }
+
+ /**
+ * Get prefix cache key for a certain month for monthly events WS calls.
+ *
+ * @param {number} year Year to get.
+ * @param {number} month Month to get.
+ * @return {string} Prefix Cache key.
+ */
+ protected getMonthlyEventsMonthPrefixCacheKey(year: number, month: number): string {
+ return this.getMonthlyEventsPrefixCacheKey() + year + ':' + month + ':';
+ }
+
+ /**
+ * Get cache key for monthly events WS calls.
+ *
+ * @param {number} year Year to get.
+ * @param {number} month Month to get.
+ * @param {number} [courseId] Course to get.
+ * @param {number} [categoryId] Category to get.
+ * @return {string} Cache key.
+ */
+ protected getMonthlyEventsCacheKey(year: number, month: number, courseId?: number, categoryId?: number): string {
+ return this.getMonthlyEventsMonthPrefixCacheKey(year, month) + (courseId ? courseId : '') + ':' +
+ (categoryId ? categoryId : '');
+ }
+
+ /**
+ * Get upcoming calendar events.
+ *
+ * @param {number} [courseId] Course to get.
+ * @param {number} [categoryId] Category to get.
+ * @param {string} [siteId] Site ID. If not defined, current site.
+ * @return {Promise} Promise resolved with the response.
+ */
+ getUpcomingEvents(courseId?: number, categoryId?: number, siteId?: string): Promise {
+
+ return this.sitesProvider.getSite(siteId).then((site) => {
+
+ const data: any = {};
+
+ if (courseId) {
+ data.courseid = courseId;
+ }
+ if (categoryId) {
+ data.categoryid = categoryId;
+ }
+
+ const preSets = {
+ cacheKey: this.getUpcomingEventsCacheKey(courseId, categoryId),
+ updateFrequency: CoreSite.FREQUENCY_SOMETIMES
+ };
+
+ return site.read('core_calendar_get_calendar_upcoming_view', data, preSets);
+ });
+ }
+
+ /**
+ * Get prefix cache key for upcoming events WS calls.
+ *
+ * @return {string} Prefix Cache key.
+ */
+ protected getUpcomingEventsPrefixCacheKey(): string {
+ return this.ROOT_CACHE_KEY + 'upcoming:';
+ }
+
+ /**
+ * Get cache key for upcoming events WS calls.
+ *
+ * @param {number} [courseId] Course to get.
+ * @param {number} [categoryId] Category to get.
+ * @return {string} Cache key.
+ */
+ protected getUpcomingEventsCacheKey(courseId?: number, categoryId?: number): string {
+ return this.getUpcomingEventsPrefixCacheKey() + (courseId ? courseId : '') + ':' + (categoryId ? categoryId : '');
+ }
+
/**
* Invalidates access information.
*
@@ -782,6 +934,56 @@ export class AddonCalendarProvider {
});
}
+ /**
+ * Invalidates monthly events for all months.
+ *
+ * @param {string} [siteId] Site Id. If not defined, use current site.
+ * @return {Promise} Promise resolved when the data is invalidated.
+ */
+ invalidateAllMonthlyEvents(siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return site.invalidateWsCacheForKeyStartingWith(this.getMonthlyEventsPrefixCacheKey());
+ });
+ }
+
+ /**
+ * Invalidates monthly events for a certain months.
+ *
+ * @param {number} year Year.
+ * @param {number} month Month.
+ * @return {Promise} Promise resolved when the data is invalidated.
+ */
+ invalidateMonthlyEvents(year: number, month: number, siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return site.invalidateWsCacheForKeyStartingWith(this.getMonthlyEventsMonthPrefixCacheKey(year, month));
+ });
+ }
+
+ /**
+ * Invalidates upcoming events for all courses and categories.
+ *
+ * @param {string} [siteId] Site Id. If not defined, use current site.
+ * @return {Promise} Promise resolved when the data is invalidated.
+ */
+ invalidateAllUpcomingEvents(siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return site.invalidateWsCacheForKeyStartingWith(this.getUpcomingEventsPrefixCacheKey());
+ });
+ }
+
+ /**
+ * Invalidates upcoming events for a certain course or category.
+ *
+ * @param {number} [courseId] Course ID.
+ * @param {number} [categoryId] Category ID.
+ * @return {Promise} Promise resolved when the data is invalidated.
+ */
+ invalidateUpcomingEvents(courseId?: number, categoryId?: number, siteId?: string): Promise {
+ return this.sitesProvider.getSite(siteId).then((site) => {
+ return site.invalidateWsCacheForKeyStartingWith(this.getUpcomingEventsCacheKey(courseId, categoryId));
+ });
+ }
+
/**
* Check if Calendar is disabled in a certain site.
*
diff --git a/src/addon/calendar/providers/mainmenu-handler.ts b/src/addon/calendar/providers/mainmenu-handler.ts
index 2769f0e0b..0568eeb01 100644
--- a/src/addon/calendar/providers/mainmenu-handler.ts
+++ b/src/addon/calendar/providers/mainmenu-handler.ts
@@ -44,7 +44,7 @@ export class AddonCalendarMainMenuHandler implements CoreMainMenuHandler {
return {
icon: 'calendar',
title: 'addon.calendar.calendar',
- page: 'AddonCalendarListPage',
+ page: this.calendarProvider.canViewMonthInSite() ? 'AddonCalendarIndexPage' : 'AddonCalendarListPage',
class: 'addon-calendar-handler'
};
}