forked from CIT/Vmeda.Online
		
	MOBILE-3021 calendar: Support monthly view
This commit is contained in:
		
							parent
							
								
									fa837532d4
								
							
						
					
					
						commit
						661709acb4
					
				@ -106,9 +106,13 @@
 | 
				
			|||||||
  "addon.calendar.eventname": "calendar",
 | 
					  "addon.calendar.eventname": "calendar",
 | 
				
			||||||
  "addon.calendar.eventstarttime": "calendar",
 | 
					  "addon.calendar.eventstarttime": "calendar",
 | 
				
			||||||
  "addon.calendar.eventtype": "calendar",
 | 
					  "addon.calendar.eventtype": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.fri": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.friday": "calendar",
 | 
				
			||||||
  "addon.calendar.gotoactivity": "calendar",
 | 
					  "addon.calendar.gotoactivity": "calendar",
 | 
				
			||||||
  "addon.calendar.invalidtimedurationminutes": "calendar",
 | 
					  "addon.calendar.invalidtimedurationminutes": "calendar",
 | 
				
			||||||
  "addon.calendar.invalidtimedurationuntil": "calendar",
 | 
					  "addon.calendar.invalidtimedurationuntil": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.mon": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.monday": "calendar",
 | 
				
			||||||
  "addon.calendar.newevent": "calendar",
 | 
					  "addon.calendar.newevent": "calendar",
 | 
				
			||||||
  "addon.calendar.noevents": "local_moodlemobileapp",
 | 
					  "addon.calendar.noevents": "local_moodlemobileapp",
 | 
				
			||||||
  "addon.calendar.nopermissiontoupdatecalendar": "error",
 | 
					  "addon.calendar.nopermissiontoupdatecalendar": "error",
 | 
				
			||||||
@ -118,7 +122,15 @@
 | 
				
			|||||||
  "addon.calendar.repeateditthis": "calendar",
 | 
					  "addon.calendar.repeateditthis": "calendar",
 | 
				
			||||||
  "addon.calendar.repeatevent": "calendar",
 | 
					  "addon.calendar.repeatevent": "calendar",
 | 
				
			||||||
  "addon.calendar.repeatweeksl": "calendar",
 | 
					  "addon.calendar.repeatweeksl": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.sat": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.saturday": "calendar",
 | 
				
			||||||
  "addon.calendar.setnewreminder": "local_moodlemobileapp",
 | 
					  "addon.calendar.setnewreminder": "local_moodlemobileapp",
 | 
				
			||||||
 | 
					  "addon.calendar.sun": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.sunday": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.thu": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.thursday": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.tue": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.tuesday": "calendar",
 | 
				
			||||||
  "addon.calendar.typecategory": "calendar",
 | 
					  "addon.calendar.typecategory": "calendar",
 | 
				
			||||||
  "addon.calendar.typeclose": "calendar",
 | 
					  "addon.calendar.typeclose": "calendar",
 | 
				
			||||||
  "addon.calendar.typecourse": "calendar",
 | 
					  "addon.calendar.typecourse": "calendar",
 | 
				
			||||||
@ -128,6 +140,8 @@
 | 
				
			|||||||
  "addon.calendar.typeopen": "calendar",
 | 
					  "addon.calendar.typeopen": "calendar",
 | 
				
			||||||
  "addon.calendar.typesite": "calendar",
 | 
					  "addon.calendar.typesite": "calendar",
 | 
				
			||||||
  "addon.calendar.typeuser": "calendar",
 | 
					  "addon.calendar.typeuser": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.wed": "calendar",
 | 
				
			||||||
 | 
					  "addon.calendar.wednesday": "calendar",
 | 
				
			||||||
  "addon.competency.activities": "tool_lp",
 | 
					  "addon.competency.activities": "tool_lp",
 | 
				
			||||||
  "addon.competency.competencies": "competency",
 | 
					  "addon.competency.competencies": "competency",
 | 
				
			||||||
  "addon.competency.competenciesmostoftennotproficientincourse": "tool_lp",
 | 
					  "addon.competency.competenciesmostoftennotproficientincourse": "tool_lp",
 | 
				
			||||||
@ -1657,6 +1671,7 @@
 | 
				
			|||||||
  "core.notingroup": "moodle",
 | 
					  "core.notingroup": "moodle",
 | 
				
			||||||
  "core.notsent": "local_moodlemobileapp",
 | 
					  "core.notsent": "local_moodlemobileapp",
 | 
				
			||||||
  "core.now": "moodle",
 | 
					  "core.now": "moodle",
 | 
				
			||||||
 | 
					  "core.nummore": "local_moodlemobileapp",
 | 
				
			||||||
  "core.numwords": "moodle",
 | 
					  "core.numwords": "moodle",
 | 
				
			||||||
  "core.offline": "message",
 | 
					  "core.offline": "message",
 | 
				
			||||||
  "core.ok": "moodle",
 | 
					  "core.ok": "moodle",
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					<core-loading [hideUntil]="loaded" class="core-loading-center">
 | 
				
			||||||
 | 
					    <!-- Period name and arrows to navigate. -->
 | 
				
			||||||
 | 
					    <ion-grid padding-top>
 | 
				
			||||||
 | 
					        <ion-row>
 | 
				
			||||||
 | 
					            <ion-col text-start *ngIf="canNavigate">
 | 
				
			||||||
 | 
					                <a ion-button icon-only clear (click)="loadPrevious()" [title]="'core.previous' | translate">
 | 
				
			||||||
 | 
					                    <ion-icon name="arrow-back" md="ios-arrow-back"></ion-icon>
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					            </ion-col>
 | 
				
			||||||
 | 
					            <ion-col text-center>
 | 
				
			||||||
 | 
					                <p>{{ periodName }}</p>
 | 
				
			||||||
 | 
					            </ion-col>
 | 
				
			||||||
 | 
					            <ion-col text-end *ngIf="canNavigate">
 | 
				
			||||||
 | 
					                <a ion-button icon-only clear (click)="loadNext()" [title]="'core.next' | translate">
 | 
				
			||||||
 | 
					                    <ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					            </ion-col>
 | 
				
			||||||
 | 
					        </ion-row>
 | 
				
			||||||
 | 
					    </ion-grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Calendar view. -->
 | 
				
			||||||
 | 
					    <ion-grid no-padding>
 | 
				
			||||||
 | 
					        <!-- List of days. -->
 | 
				
			||||||
 | 
					        <ion-row>
 | 
				
			||||||
 | 
					            <ion-col text-center *ngFor="let day of weekDays" class="addon-calendar-weekdays">
 | 
				
			||||||
 | 
					                <p>{{ day.shortname | translate }}</p>
 | 
				
			||||||
 | 
					            </ion-col>
 | 
				
			||||||
 | 
					        </ion-row>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- Weeks. -->
 | 
				
			||||||
 | 
					        <ion-row *ngFor="let week of weeks">
 | 
				
			||||||
 | 
					            <ion-col *ngFor="let value of week.prepadding" class="dayblank"></ion-col> <!-- Empty slots (first week). -->
 | 
				
			||||||
 | 
					            <ion-col text-center *ngFor="let day of week.days" [ngClass]='{"hasevents": day.hasevents, "today": day.istoday, "weekend": day.isweekend, "duration_finish": day.haslastdayofevent}' >
 | 
				
			||||||
 | 
					                <p>{{ day.mday }}</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <!-- In phone, display some dots to indicate the type of events. -->
 | 
				
			||||||
 | 
					                <p class="hidden-tablet"><span *ngFor="let type of day.calendareventtypes" class="calendar_event_type calendar_event_{{type}}"></span></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <!-- In tablet, display list of events. -->
 | 
				
			||||||
 | 
					                <div class="hidden-phone" class="addon-calendar-day-events">
 | 
				
			||||||
 | 
					                    <p *ngFor="let event of day.filteredEvents | slice:0:3">
 | 
				
			||||||
 | 
					                        <span class="calendar_event_type calendar_event_{{event.eventtype}}"></span>
 | 
				
			||||||
 | 
					                        {{event.name}}
 | 
				
			||||||
 | 
					                    </p>
 | 
				
			||||||
 | 
					                    <p *ngIf="day.filteredEvents.length > 3">{{ 'core.nummore' | translate:{$a: day.filteredEvents.length - 3} }}</p>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </ion-col>
 | 
				
			||||||
 | 
					            <ion-col *ngFor="let value of week.postpadding" class="dayblank"></ion-col> <!-- Empty slots (last week). -->
 | 
				
			||||||
 | 
					        </ion-row>
 | 
				
			||||||
 | 
					    </ion-grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</core-loading>
 | 
				
			||||||
							
								
								
									
										42
									
								
								src/addon/calendar/components/calendar/calendar.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/addon/calendar/components/calendar/calendar.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					$calendar-event-category-color: $purple !default; // Purple.
 | 
				
			||||||
 | 
					$calendar-event-course-color: $red !default; // Red.
 | 
				
			||||||
 | 
					$calendar-event-group-color: $yellow !default; // Yellow.
 | 
				
			||||||
 | 
					$calendar-event-user-color: $blue !default; // Blue.
 | 
				
			||||||
 | 
					$calendar-event-site-color: $green !default; // Green.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ion-app.app-root addon-calendar-calendar {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .addon-calendar-weekdays {
 | 
				
			||||||
 | 
					        opacity: 0.4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .addon-calendar-day-events {
 | 
				
			||||||
 | 
					        @include text-align('start');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .calendar_event_type {
 | 
				
			||||||
 | 
					        display: inline-block;
 | 
				
			||||||
 | 
					        width: 8px;
 | 
				
			||||||
 | 
					        height: 8px;
 | 
				
			||||||
 | 
					        border-radius: 50%;
 | 
				
			||||||
 | 
					        border: 1px solid white;
 | 
				
			||||||
 | 
					        @include margin-horizontal(1px, 1px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.calendar_event_category {
 | 
				
			||||||
 | 
					            background-color: $calendar-event-category-color;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        &.calendar_event_course {
 | 
				
			||||||
 | 
					            background-color: $calendar-event-course-color;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        &.calendar_event_group {
 | 
				
			||||||
 | 
					            background-color: $calendar-event-group-color;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        &.calendar_event_user {
 | 
				
			||||||
 | 
					            background-color: $calendar-event-user-color;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        &.calendar_event_site {
 | 
				
			||||||
 | 
					            background-color: $calendar-event-site-color;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										221
									
								
								src/addon/calendar/components/calendar/calendar.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								src/addon/calendar/components/calendar/calendar.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,221 @@
 | 
				
			|||||||
 | 
					// (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, OnDestroy, OnInit, Input, OnChanges, SimpleChange } from '@angular/core';
 | 
				
			||||||
 | 
					import { CoreEventsProvider } from '@providers/events';
 | 
				
			||||||
 | 
					import { CoreSitesProvider } from '@providers/sites';
 | 
				
			||||||
 | 
					import { CoreDomUtilsProvider } from '@providers/utils/dom';
 | 
				
			||||||
 | 
					import { CoreTimeUtilsProvider } from '@providers/utils/time';
 | 
				
			||||||
 | 
					import { CoreUtilsProvider } from '@providers/utils/utils';
 | 
				
			||||||
 | 
					import { AddonCalendarProvider } from '../../providers/calendar';
 | 
				
			||||||
 | 
					import { AddonCalendarHelperProvider } from '../../providers/helper';
 | 
				
			||||||
 | 
					import { CoreCoursesProvider } from '@core/courses/providers/courses';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Component that displays a calendar.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					    selector: 'addon-calendar-calendar',
 | 
				
			||||||
 | 
					    templateUrl: 'addon-calendar-calendar.html',
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class AddonCalendarCalendarComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			||||||
 | 
					    @Input() initialYear: number | string; // Initial year to load.
 | 
				
			||||||
 | 
					    @Input() initialMonth: number | string; // Initial month to load.
 | 
				
			||||||
 | 
					    @Input() courseId: number | string;
 | 
				
			||||||
 | 
					    @Input() categoryId: number | string; // Category ID the course belongs to.
 | 
				
			||||||
 | 
					    @Input() canNavigate?: string | boolean; // Whether to include arrows to change the month. Defaults to true.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    periodName: string;
 | 
				
			||||||
 | 
					    weekDays: any[];
 | 
				
			||||||
 | 
					    weeks: any[];
 | 
				
			||||||
 | 
					    loaded = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected year: number;
 | 
				
			||||||
 | 
					    protected month: number;
 | 
				
			||||||
 | 
					    protected categoriesRetrieved = false;
 | 
				
			||||||
 | 
					    protected categories = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(eventsProvider: CoreEventsProvider,
 | 
				
			||||||
 | 
					            sitesProvider: CoreSitesProvider,
 | 
				
			||||||
 | 
					            private calendarProvider: AddonCalendarProvider,
 | 
				
			||||||
 | 
					            private calendarHelper: AddonCalendarHelperProvider,
 | 
				
			||||||
 | 
					            private domUtils: CoreDomUtilsProvider,
 | 
				
			||||||
 | 
					            private timeUtils: CoreTimeUtilsProvider,
 | 
				
			||||||
 | 
					            private utils: CoreUtilsProvider,
 | 
				
			||||||
 | 
					            private coursesProvider: CoreCoursesProvider) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component loaded.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnInit(): void {
 | 
				
			||||||
 | 
					        const now = new Date();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.year = this.initialYear ? Number(this.initialYear) : now.getFullYear();
 | 
				
			||||||
 | 
					        this.month = this.initialYear ? Number(this.initialYear) : now.getMonth() + 1;
 | 
				
			||||||
 | 
					        this.canNavigate = typeof this.canNavigate == 'undefined' ? true : this.utils.isTrueOrOne(this.canNavigate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.fetchData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Detect changes on input properties.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnChanges(changes: {[name: string]: SimpleChange}): void {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((changes.courseId || changes.categoryId) && this.weeks) {
 | 
				
			||||||
 | 
					            const courseId = this.courseId ? Number(this.courseId) : undefined,
 | 
				
			||||||
 | 
					                categoryId = this.categoryId ? Number(this.categoryId) : undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.filterEvents(courseId, categoryId);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Fetch contacts.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {boolean} [refresh=false] True if we are refreshing contacts, false if we are loading more.
 | 
				
			||||||
 | 
					     * @return {Promise<any>} Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    fetchData(refresh: boolean = false): Promise<any> {
 | 
				
			||||||
 | 
					        const courseId = this.courseId ? Number(this.courseId) : undefined,
 | 
				
			||||||
 | 
					            categoryId = this.categoryId ? Number(this.categoryId) : undefined,
 | 
				
			||||||
 | 
					            promises = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        promises.push(this.loadCategories());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        promises.push(this.calendarProvider.getMonthlyEvents(this.year, this.month, courseId, categoryId).then((result) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Calculate the period name. We don't use the one in result because it's in server's language.
 | 
				
			||||||
 | 
					            this.periodName = this.timeUtils.userDate(new Date(this.year, this.month - 1).getTime(), 'core.strftimemonthyear');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.weekDays = this.calendarProvider.getWeekDays(result.daynames[0].dayno);
 | 
				
			||||||
 | 
					            this.weeks = result.weeks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.filterEvents(courseId, categoryId);
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Promise.all(promises).catch((error) => {
 | 
				
			||||||
 | 
					            this.domUtils.showErrorModalDefault(error, 'addon.calendar.errorloadevents', true);
 | 
				
			||||||
 | 
					        }).finally(() => {
 | 
				
			||||||
 | 
					            this.loaded = true;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Load categories to be able to filter events.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return {Promise<any>} Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected loadCategories(): Promise<any> {
 | 
				
			||||||
 | 
					        if (this.categoriesRetrieved) {
 | 
				
			||||||
 | 
					            // Already retrieved, stop.
 | 
				
			||||||
 | 
					            return Promise.resolve();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this.coursesProvider.getCategories(0, true).then((cats) => {
 | 
				
			||||||
 | 
					            this.categoriesRetrieved = true;
 | 
				
			||||||
 | 
					            this.categories = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Index categories by ID.
 | 
				
			||||||
 | 
					            cats.forEach((category) => {
 | 
				
			||||||
 | 
					                this.categories[category.id] = category;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }).catch(() => {
 | 
				
			||||||
 | 
					            // Ignore errors.
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Filter events to only display events belonging to a certain course.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {number} courseId Course ID.
 | 
				
			||||||
 | 
					     * @param {number} categoryId Category the course belongs to.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    filterEvents(courseId: number, categoryId: number): void {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.weeks.forEach((week) => {
 | 
				
			||||||
 | 
					            week.days.forEach((day) => {
 | 
				
			||||||
 | 
					                if (!courseId || courseId < 0) {
 | 
				
			||||||
 | 
					                    day.filteredEvents = day.events;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    day.filteredEvents = day.events.filter((event) => {
 | 
				
			||||||
 | 
					                        return this.calendarHelper.shouldDisplayEvent(event, courseId, categoryId, this.categories);
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Re-calculate some properties.
 | 
				
			||||||
 | 
					                this.calendarHelper.calculateDayData(day, day.filteredEvents);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Refresh events.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return {Promise<any>} Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    refreshData(): Promise<any> {
 | 
				
			||||||
 | 
					        const promises = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        promises.push(this.calendarProvider.invalidateMonthlyEvents(this.year, this.month));
 | 
				
			||||||
 | 
					        promises.push(this.coursesProvider.invalidateCategories(0, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.categoriesRetrieved = false; // Get categories again.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Promise.all(promises).then(() => {
 | 
				
			||||||
 | 
					            return this.fetchData(true);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Load next month.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    loadNext(): void {
 | 
				
			||||||
 | 
					        if (this.month === 12) {
 | 
				
			||||||
 | 
					            this.month = 1;
 | 
				
			||||||
 | 
					            this.year++;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            this.month++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.loaded = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.fetchData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Load previous month.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    loadPrevious(): void {
 | 
				
			||||||
 | 
					        if (this.month === 1) {
 | 
				
			||||||
 | 
					            this.month = 12;
 | 
				
			||||||
 | 
					            this.year--;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            this.month--;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.loaded = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.fetchData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Component destroyed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ngOnDestroy(): void {
 | 
				
			||||||
 | 
					        // @todo
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										40
									
								
								src/addon/calendar/components/components.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/addon/calendar/components/components.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					// (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 { CommonModule } from '@angular/common';
 | 
				
			||||||
 | 
					import { IonicModule } from 'ionic-angular';
 | 
				
			||||||
 | 
					import { TranslateModule } from '@ngx-translate/core';
 | 
				
			||||||
 | 
					import { CoreComponentsModule } from '@components/components.module';
 | 
				
			||||||
 | 
					import { CoreDirectivesModule } from '@directives/directives.module';
 | 
				
			||||||
 | 
					import { AddonCalendarCalendarComponent } from '../components/calendar/calendar';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@NgModule({
 | 
				
			||||||
 | 
					    declarations: [
 | 
				
			||||||
 | 
					        AddonCalendarCalendarComponent
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    imports: [
 | 
				
			||||||
 | 
					        CommonModule,
 | 
				
			||||||
 | 
					        IonicModule,
 | 
				
			||||||
 | 
					        TranslateModule.forChild(),
 | 
				
			||||||
 | 
					        CoreComponentsModule,
 | 
				
			||||||
 | 
					        CoreDirectivesModule
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    providers: [
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    exports: [
 | 
				
			||||||
 | 
					        AddonCalendarCalendarComponent
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class AddonCalendarComponentsModule {}
 | 
				
			||||||
@ -22,9 +22,13 @@
 | 
				
			|||||||
    "eventname": "Event title",
 | 
					    "eventname": "Event title",
 | 
				
			||||||
    "eventstarttime": "Start time",
 | 
					    "eventstarttime": "Start time",
 | 
				
			||||||
    "eventtype": "Event type",
 | 
					    "eventtype": "Event type",
 | 
				
			||||||
 | 
					    "fri": "Fri",
 | 
				
			||||||
 | 
					    "friday": "Friday",
 | 
				
			||||||
    "gotoactivity": "Go to activity",
 | 
					    "gotoactivity": "Go to activity",
 | 
				
			||||||
    "invalidtimedurationminutes": "The duration in minutes you have entered is invalid. Please enter the duration in minutes greater than 0 or select no duration.",
 | 
					    "invalidtimedurationminutes": "The duration in minutes you have entered is invalid. Please enter the duration in minutes greater than 0 or select no duration.",
 | 
				
			||||||
    "invalidtimedurationuntil": "The date and time you selected for duration until is before the start time of the event. Please correct this before proceeding.",
 | 
					    "invalidtimedurationuntil": "The date and time you selected for duration until is before the start time of the event. Please correct this before proceeding.",
 | 
				
			||||||
 | 
					    "mon": "Mon",
 | 
				
			||||||
 | 
					    "monday": "Monday",
 | 
				
			||||||
    "newevent": "New event",
 | 
					    "newevent": "New event",
 | 
				
			||||||
    "noevents": "There are no events",
 | 
					    "noevents": "There are no events",
 | 
				
			||||||
    "nopermissiontoupdatecalendar": "Sorry, but you do not have permission to update the calendar event",
 | 
					    "nopermissiontoupdatecalendar": "Sorry, but you do not have permission to update the calendar event",
 | 
				
			||||||
@ -34,7 +38,15 @@
 | 
				
			|||||||
    "repeateditthis": "Apply changes to this event only",
 | 
					    "repeateditthis": "Apply changes to this event only",
 | 
				
			||||||
    "repeatevent": "Repeat this event",
 | 
					    "repeatevent": "Repeat this event",
 | 
				
			||||||
    "repeatweeksl": "Repeat weekly, creating altogether",
 | 
					    "repeatweeksl": "Repeat weekly, creating altogether",
 | 
				
			||||||
 | 
					    "sat": "Sat",
 | 
				
			||||||
 | 
					    "saturday": "Saturday",
 | 
				
			||||||
    "setnewreminder": "Set a new reminder",
 | 
					    "setnewreminder": "Set a new reminder",
 | 
				
			||||||
 | 
					    "sun": "Sun",
 | 
				
			||||||
 | 
					    "sunday": "Sunday",
 | 
				
			||||||
 | 
					    "thu": "Thu",
 | 
				
			||||||
 | 
					    "thursday": "Thursday",
 | 
				
			||||||
 | 
					    "tue": "Tue",
 | 
				
			||||||
 | 
					    "tuesday": "Tuesday",
 | 
				
			||||||
    "typeclose": "Close event",
 | 
					    "typeclose": "Close event",
 | 
				
			||||||
    "typecourse": "Course event",
 | 
					    "typecourse": "Course event",
 | 
				
			||||||
    "typecategory": "Category event",
 | 
					    "typecategory": "Category event",
 | 
				
			||||||
@ -43,5 +55,7 @@
 | 
				
			|||||||
    "typegroup": "Group event",
 | 
					    "typegroup": "Group event",
 | 
				
			||||||
    "typeopen": "Open event",
 | 
					    "typeopen": "Open event",
 | 
				
			||||||
    "typesite": "Site event",
 | 
					    "typesite": "Site event",
 | 
				
			||||||
    "typeuser": "User event"
 | 
					    "typeuser": "User event",
 | 
				
			||||||
 | 
					    "wed": "Wed",
 | 
				
			||||||
 | 
					    "wednesday": "Wednesday"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -15,9 +15,8 @@
 | 
				
			|||||||
    <ion-refresher [enabled]="loaded" (ionRefresh)="doRefresh($event)">
 | 
					    <ion-refresher [enabled]="loaded" (ionRefresh)="doRefresh($event)">
 | 
				
			||||||
        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
					        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
				
			||||||
    </ion-refresher>
 | 
					    </ion-refresher>
 | 
				
			||||||
    <core-loading [hideUntil]="loaded">
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </core-loading>
 | 
					    <addon-calendar-calendar [courseId]="courseId" [categoryId]="categoryId"></addon-calendar-calendar>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Create a calendar event. -->
 | 
					    <!-- Create a calendar event. -->
 | 
				
			||||||
    <ion-fab core-fab bottom end *ngIf="canCreate">
 | 
					    <ion-fab core-fab bottom end *ngIf="canCreate">
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,7 @@ import { TranslateModule } from '@ngx-translate/core';
 | 
				
			|||||||
import { CoreComponentsModule } from '@components/components.module';
 | 
					import { CoreComponentsModule } from '@components/components.module';
 | 
				
			||||||
import { CoreDirectivesModule } from '@directives/directives.module';
 | 
					import { CoreDirectivesModule } from '@directives/directives.module';
 | 
				
			||||||
import { CorePipesModule } from '@pipes/pipes.module';
 | 
					import { CorePipesModule } from '@pipes/pipes.module';
 | 
				
			||||||
 | 
					import { AddonCalendarComponentsModule } from '../../components/components.module';
 | 
				
			||||||
import { AddonCalendarIndexPage } from './index';
 | 
					import { AddonCalendarIndexPage } from './index';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@NgModule({
 | 
					@NgModule({
 | 
				
			||||||
@ -28,6 +29,7 @@ import { AddonCalendarIndexPage } from './index';
 | 
				
			|||||||
        CoreComponentsModule,
 | 
					        CoreComponentsModule,
 | 
				
			||||||
        CoreDirectivesModule,
 | 
					        CoreDirectivesModule,
 | 
				
			||||||
        CorePipesModule,
 | 
					        CorePipesModule,
 | 
				
			||||||
 | 
					        AddonCalendarComponentsModule,
 | 
				
			||||||
        IonicPageModule.forChild(AddonCalendarIndexPage),
 | 
					        IonicPageModule.forChild(AddonCalendarIndexPage),
 | 
				
			||||||
        TranslateModule.forChild()
 | 
					        TranslateModule.forChild()
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
				
			|||||||
@ -8,12 +8,20 @@
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// Unless required by applicable law or agreed to in writing, software
 | 
					// Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
					// distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					// WITHOUT WARRANTIES OR CONDITIONS OFx ANY KIND, either express or implied.
 | 
				
			||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { Component, OnInit } from '@angular/core';
 | 
					import { Component, OnInit, ViewChild } from '@angular/core';
 | 
				
			||||||
import { IonicPage } from 'ionic-angular';
 | 
					import { IonicPage, NavParams, NavController, PopoverController } from 'ionic-angular';
 | 
				
			||||||
 | 
					import { CoreLocalNotificationsProvider } from '@providers/local-notifications';
 | 
				
			||||||
 | 
					import { CoreDomUtilsProvider } from '@providers/utils/dom';
 | 
				
			||||||
 | 
					import { AddonCalendarProvider } from '../../providers/calendar';
 | 
				
			||||||
 | 
					import { AddonCalendarHelperProvider } from '../../providers/helper';
 | 
				
			||||||
 | 
					import { AddonCalendarCalendarComponent } from '../../components/calendar/calendar';
 | 
				
			||||||
 | 
					import { CoreCoursesProvider } from '@core/courses/providers/courses';
 | 
				
			||||||
 | 
					import { CoreCoursePickerMenuPopoverComponent } from '@components/course-picker-menu/course-picker-menu-popover';
 | 
				
			||||||
 | 
					import { TranslateService } from '@ngx-translate/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Page that displays the calendar events.
 | 
					 * Page that displays the calendar events.
 | 
				
			||||||
@ -24,15 +32,154 @@ import { IonicPage } from 'ionic-angular';
 | 
				
			|||||||
    templateUrl: 'index.html',
 | 
					    templateUrl: 'index.html',
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class AddonCalendarIndexPage implements OnInit {
 | 
					export class AddonCalendarIndexPage implements OnInit {
 | 
				
			||||||
 | 
					    @ViewChild(AddonCalendarCalendarComponent) calendarComponent: AddonCalendarCalendarComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor() {
 | 
					    protected allCourses = {
 | 
				
			||||||
        // @todo
 | 
					        id: -1,
 | 
				
			||||||
 | 
					        fullname: this.translate.instant('core.fulllistofcourses'),
 | 
				
			||||||
 | 
					        category: -1
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    courseId: number;
 | 
				
			||||||
 | 
					    categoryId: number;
 | 
				
			||||||
 | 
					    canCreate = false;
 | 
				
			||||||
 | 
					    courses: any[];
 | 
				
			||||||
 | 
					    notificationsEnabled = false;
 | 
				
			||||||
 | 
					    loaded = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(localNotificationsProvider: CoreLocalNotificationsProvider,
 | 
				
			||||||
 | 
					            navParams: NavParams,
 | 
				
			||||||
 | 
					            private navCtrl: NavController,
 | 
				
			||||||
 | 
					            private domUtils: CoreDomUtilsProvider,
 | 
				
			||||||
 | 
					            private calendarProvider: AddonCalendarProvider,
 | 
				
			||||||
 | 
					            private calendarHelper: AddonCalendarHelperProvider,
 | 
				
			||||||
 | 
					            private translate: TranslateService,
 | 
				
			||||||
 | 
					            private coursesProvider: CoreCoursesProvider,
 | 
				
			||||||
 | 
					            private popoverCtrl: PopoverController) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.courseId = navParams.get('courseId');
 | 
				
			||||||
 | 
					        this.notificationsEnabled = localNotificationsProvider.isAvailable();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * View loaded.
 | 
					     * View loaded.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    ngOnInit(): void {
 | 
					    ngOnInit(): void {
 | 
				
			||||||
        // @todo
 | 
					        this.fetchData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Fetch all the data required for the view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return {Promise<any>} Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    fetchData(): Promise<any> {
 | 
				
			||||||
 | 
					        const promises = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Load courses for the popover.
 | 
				
			||||||
 | 
					        promises.push(this.coursesProvider.getUserCourses(false).then((courses) => {
 | 
				
			||||||
 | 
					            // Add "All courses".
 | 
				
			||||||
 | 
					            courses.unshift(this.allCourses);
 | 
				
			||||||
 | 
					            this.courses = courses;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (this.courseId) {
 | 
				
			||||||
 | 
					                // Search the course to get the category.
 | 
				
			||||||
 | 
					                const course = this.courses.find((course) => {
 | 
				
			||||||
 | 
					                    return course.id == this.courseId;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (course) {
 | 
				
			||||||
 | 
					                    this.categoryId = course.category;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check if user can create events.
 | 
				
			||||||
 | 
					        promises.push(this.calendarHelper.canEditEvents(this.courseId).then((canEdit) => {
 | 
				
			||||||
 | 
					            this.canCreate = canEdit;
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Promise.all(promises).catch((error) => {
 | 
				
			||||||
 | 
					            this.domUtils.showErrorModalDefault(error, 'addon.calendar.errorloadevents', true);
 | 
				
			||||||
 | 
					        }).finally(() => {
 | 
				
			||||||
 | 
					            this.loaded = true;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Refresh the data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {any} [refresher] Refresher.
 | 
				
			||||||
 | 
					     * @return {Promise<any>} Promise resolved when done.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    doRefresh(refresher?: any): void {
 | 
				
			||||||
 | 
					        if (!this.loaded) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const promises = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        promises.push(this.calendarProvider.invalidateAllowedEventTypes().then(() => {
 | 
				
			||||||
 | 
					            return this.fetchData();
 | 
				
			||||||
 | 
					        }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Refresh the sub-component.
 | 
				
			||||||
 | 
					        promises.push(this.calendarComponent.refreshData());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Promise.all(promises).finally(() => {
 | 
				
			||||||
 | 
					            refresher && refresher.complete();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Show the context menu.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {MouseEvent} event Event.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    openCourseFilter(event: MouseEvent): void {
 | 
				
			||||||
 | 
					        const popover = this.popoverCtrl.create(CoreCoursePickerMenuPopoverComponent, {
 | 
				
			||||||
 | 
					            courses: this.courses,
 | 
				
			||||||
 | 
					            courseId: this.courseId
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        popover.onDidDismiss((course) => {
 | 
				
			||||||
 | 
					            if (course) {
 | 
				
			||||||
 | 
					                this.courseId = course.id > 0 ? course.id : undefined;
 | 
				
			||||||
 | 
					                this.categoryId = course.id > 0 ? course.category : undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Course viewed has changed, check if the user can create events for this course calendar.
 | 
				
			||||||
 | 
					                this.calendarHelper.canEditEvents(this.courseId).then((canEdit) => {
 | 
				
			||||||
 | 
					                    this.canCreate = canEdit;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        popover.present({
 | 
				
			||||||
 | 
					            ev: event
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Open page to create/edit an event.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {number} [eventId] Event ID to edit.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    openEdit(eventId?: number): void {
 | 
				
			||||||
 | 
					        const params: any = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (eventId) {
 | 
				
			||||||
 | 
					            params.eventId = eventId;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.courseId) {
 | 
				
			||||||
 | 
					            params.courseId = this.courseId;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.navCtrl.push('AddonCalendarEditEventPage', params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Open calendar events settings.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    openSettings(): void {
 | 
				
			||||||
 | 
					        this.navCtrl.push('AddonCalendarSettingsPage');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -423,50 +423,10 @@ export class AddonCalendarListPage implements OnDestroy {
 | 
				
			|||||||
            return this.events;
 | 
					            return this.events;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return this.events.filter(this.shouldDisplayEvent.bind(this));
 | 
					        return this.events.filter((event) => {
 | 
				
			||||||
    }
 | 
					            return this.calendarHelper.shouldDisplayEvent(event, this.filter.course.id, this.filter.course.category,
 | 
				
			||||||
 | 
					                    this.categories);
 | 
				
			||||||
    /**
 | 
					        });
 | 
				
			||||||
     * Check if an event should be displayed based on the filter.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param {any} event Event object.
 | 
					 | 
				
			||||||
     * @return {boolean} Whether it should be displayed.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected shouldDisplayEvent(event: any): boolean {
 | 
					 | 
				
			||||||
        if (event.eventtype == 'user' || event.eventtype == 'site') {
 | 
					 | 
				
			||||||
            // User or site event, display it.
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (event.eventtype == 'category') {
 | 
					 | 
				
			||||||
            if (!event.categoryid || !Object.keys(this.categories).length) {
 | 
					 | 
				
			||||||
                // We can't tell if the course belongs to the category, display them all.
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (event.categoryid == this.filter.course.category) {
 | 
					 | 
				
			||||||
                // The event is in the same category as the course, display it.
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Check parent categories.
 | 
					 | 
				
			||||||
            let category = this.categories[this.filter.course.category];
 | 
					 | 
				
			||||||
            while (category) {
 | 
					 | 
				
			||||||
                if (!category.parent) {
 | 
					 | 
				
			||||||
                    // Category doesn't have parent, stop.
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (event.categoryid == category.parent) {
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                category = this.categories[category.parent];
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Show the event if it is from site home or if it matches the selected course.
 | 
					 | 
				
			||||||
        return event.courseid === this.siteHomeId || event.courseid == this.filter.course.id;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -51,6 +51,37 @@ export class AddonCalendarProvider {
 | 
				
			|||||||
    static TYPE_USER = 'user';
 | 
					    static TYPE_USER = 'user';
 | 
				
			||||||
    protected ROOT_CACHE_KEY = 'mmaCalendar:';
 | 
					    protected ROOT_CACHE_KEY = 'mmaCalendar:';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected weekDays = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            shortname: 'addon.calendar.sun',
 | 
				
			||||||
 | 
					            fullname: 'addon.calendar.sunday'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            shortname: 'addon.calendar.mon',
 | 
				
			||||||
 | 
					            fullname: 'addon.calendar.monday'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            shortname: 'addon.calendar.tue',
 | 
				
			||||||
 | 
					            fullname: 'addon.calendar.tuesday'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            shortname: 'addon.calendar.wed',
 | 
				
			||||||
 | 
					            fullname: 'addon.calendar.wednesday'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            shortname: 'addon.calendar.thu',
 | 
				
			||||||
 | 
					            fullname: 'addon.calendar.thursday'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            shortname: 'addon.calendar.fri',
 | 
				
			||||||
 | 
					            fullname: 'addon.calendar.friday'
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            shortname: 'addon.calendar.sat',
 | 
				
			||||||
 | 
					            fullname: 'addon.calendar.saturday'
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Variables for database.
 | 
					    // Variables for database.
 | 
				
			||||||
    static EVENTS_TABLE = 'addon_calendar_events_2';
 | 
					    static EVENTS_TABLE = 'addon_calendar_events_2';
 | 
				
			||||||
    static REMINDERS_TABLE = 'addon_calendar_reminders';
 | 
					    static REMINDERS_TABLE = 'addon_calendar_reminders';
 | 
				
			||||||
@ -875,6 +906,18 @@ export class AddonCalendarProvider {
 | 
				
			|||||||
        return this.getUpcomingEventsPrefixCacheKey() + (courseId ? courseId : '') + ':' + (categoryId ? categoryId : '');
 | 
					        return this.getUpcomingEventsPrefixCacheKey() + (courseId ? courseId : '') + ':' + (categoryId ? categoryId : '');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the week days, already ordered according to a specified starting day.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {number} [startingDay=0] Starting day. 0=Sunday, 1=Monday, ...
 | 
				
			||||||
 | 
					     * @return {any[]} Week days.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    getWeekDays(startingDay?: number): any[] {
 | 
				
			||||||
 | 
					        startingDay = startingDay || 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this.weekDays.slice(startingDay).concat(this.weekDays.slice(0, startingDay));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Invalidates access information.
 | 
					     * Invalidates access information.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import { Injectable } from '@angular/core';
 | 
					import { Injectable } from '@angular/core';
 | 
				
			||||||
import { CoreLoggerProvider } from '@providers/logger';
 | 
					import { CoreLoggerProvider } from '@providers/logger';
 | 
				
			||||||
 | 
					import { CoreSitesProvider } from '@providers/sites';
 | 
				
			||||||
import { CoreCourseProvider } from '@core/course/providers/course';
 | 
					import { CoreCourseProvider } from '@core/course/providers/course';
 | 
				
			||||||
import { AddonCalendarProvider } from './calendar';
 | 
					import { AddonCalendarProvider } from './calendar';
 | 
				
			||||||
import { CoreConstants } from '@core/constants';
 | 
					import { CoreConstants } from '@core/constants';
 | 
				
			||||||
@ -33,11 +34,35 @@ export class AddonCalendarHelperProvider {
 | 
				
			|||||||
        category: 'fa-cubes'
 | 
					        category: 'fa-cubes'
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(logger: CoreLoggerProvider, private courseProvider: CoreCourseProvider,
 | 
					    constructor(logger: CoreLoggerProvider,
 | 
				
			||||||
 | 
					            private courseProvider: CoreCourseProvider,
 | 
				
			||||||
 | 
					            private sitesProvider: CoreSitesProvider,
 | 
				
			||||||
            private calendarProvider: AddonCalendarProvider) {
 | 
					            private calendarProvider: AddonCalendarProvider) {
 | 
				
			||||||
        this.logger = logger.getInstance('AddonCalendarHelperProvider');
 | 
					        this.logger = logger.getInstance('AddonCalendarHelperProvider');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Calculate some day data based on a list of events for that day.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {any} day Day.
 | 
				
			||||||
 | 
					     * @param {any[]} events Events.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    calculateDayData(day: any, events: any[]): void {
 | 
				
			||||||
 | 
					        day.hasevents = events.length > 0;
 | 
				
			||||||
 | 
					        day.haslastdayofevent = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const types = {};
 | 
				
			||||||
 | 
					        events.forEach((event) => {
 | 
				
			||||||
 | 
					            types[event.eventtype] = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (event.islastday) {
 | 
				
			||||||
 | 
					                day.haslastdayofevent = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        day.calendareventtypes = Object.keys(types);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Check if current user can create/edit events.
 | 
					     * Check if current user can create/edit events.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -155,4 +180,51 @@ export class AddonCalendarHelperProvider {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if an event should be displayed based on the filter.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param {any} event Event object.
 | 
				
			||||||
 | 
					     * @param {number} courseId Course ID to filter.
 | 
				
			||||||
 | 
					     * @param {number} categoryId Category ID the course belongs to.
 | 
				
			||||||
 | 
					     * @param {any} categories Categories indexed by ID.
 | 
				
			||||||
 | 
					     * @return {boolean} Whether it should be displayed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    shouldDisplayEvent(event: any, courseId: number, categoryId: number, categories: any): boolean {
 | 
				
			||||||
 | 
					        if (event.eventtype == 'user' || event.eventtype == 'site') {
 | 
				
			||||||
 | 
					            // User or site event, display it.
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (event.eventtype == 'category') {
 | 
				
			||||||
 | 
					            if (!event.categoryid || !Object.keys(categories).length) {
 | 
				
			||||||
 | 
					                // We can't tell if the course belongs to the category, display them all.
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (event.categoryid == categoryId) {
 | 
				
			||||||
 | 
					                // The event is in the same category as the course, display it.
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Check parent categories.
 | 
				
			||||||
 | 
					            let category = categories[categoryId];
 | 
				
			||||||
 | 
					            while (category) {
 | 
				
			||||||
 | 
					                if (!category.parent) {
 | 
				
			||||||
 | 
					                    // Category doesn't have parent, stop.
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (event.categoryid == category.parent) {
 | 
				
			||||||
 | 
					                    return true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                category = categories[category.parent];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Show the event if it is from site home or if it matches the selected course.
 | 
				
			||||||
 | 
					        return event.courseid === this.sitesProvider.getSiteHomeId() || event.courseid == courseId;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -106,9 +106,13 @@
 | 
				
			|||||||
    "addon.calendar.eventname": "Event title",
 | 
					    "addon.calendar.eventname": "Event title",
 | 
				
			||||||
    "addon.calendar.eventstarttime": "Start time",
 | 
					    "addon.calendar.eventstarttime": "Start time",
 | 
				
			||||||
    "addon.calendar.eventtype": "Event type",
 | 
					    "addon.calendar.eventtype": "Event type",
 | 
				
			||||||
 | 
					    "addon.calendar.fri": "Fri",
 | 
				
			||||||
 | 
					    "addon.calendar.friday": "Friday",
 | 
				
			||||||
    "addon.calendar.gotoactivity": "Go to activity",
 | 
					    "addon.calendar.gotoactivity": "Go to activity",
 | 
				
			||||||
    "addon.calendar.invalidtimedurationminutes": "The duration in minutes you have entered is invalid. Please enter the duration in minutes greater than 0 or select no duration.",
 | 
					    "addon.calendar.invalidtimedurationminutes": "The duration in minutes you have entered is invalid. Please enter the duration in minutes greater than 0 or select no duration.",
 | 
				
			||||||
    "addon.calendar.invalidtimedurationuntil": "The date and time you selected for duration until is before the start time of the event. Please correct this before proceeding.",
 | 
					    "addon.calendar.invalidtimedurationuntil": "The date and time you selected for duration until is before the start time of the event. Please correct this before proceeding.",
 | 
				
			||||||
 | 
					    "addon.calendar.mon": "Mon",
 | 
				
			||||||
 | 
					    "addon.calendar.monday": "Monday",
 | 
				
			||||||
    "addon.calendar.newevent": "New event",
 | 
					    "addon.calendar.newevent": "New event",
 | 
				
			||||||
    "addon.calendar.noevents": "There are no events",
 | 
					    "addon.calendar.noevents": "There are no events",
 | 
				
			||||||
    "addon.calendar.nopermissiontoupdatecalendar": "Sorry, but you do not have permission to update the calendar event",
 | 
					    "addon.calendar.nopermissiontoupdatecalendar": "Sorry, but you do not have permission to update the calendar event",
 | 
				
			||||||
@ -118,7 +122,15 @@
 | 
				
			|||||||
    "addon.calendar.repeateditthis": "Apply changes to this event only",
 | 
					    "addon.calendar.repeateditthis": "Apply changes to this event only",
 | 
				
			||||||
    "addon.calendar.repeatevent": "Repeat this event",
 | 
					    "addon.calendar.repeatevent": "Repeat this event",
 | 
				
			||||||
    "addon.calendar.repeatweeksl": "Repeat weekly, creating altogether",
 | 
					    "addon.calendar.repeatweeksl": "Repeat weekly, creating altogether",
 | 
				
			||||||
 | 
					    "addon.calendar.sat": "Sat",
 | 
				
			||||||
 | 
					    "addon.calendar.saturday": "Saturday",
 | 
				
			||||||
    "addon.calendar.setnewreminder": "Set a new reminder",
 | 
					    "addon.calendar.setnewreminder": "Set a new reminder",
 | 
				
			||||||
 | 
					    "addon.calendar.sun": "Sun",
 | 
				
			||||||
 | 
					    "addon.calendar.sunday": "Sunday",
 | 
				
			||||||
 | 
					    "addon.calendar.thu": "Thu",
 | 
				
			||||||
 | 
					    "addon.calendar.thursday": "Thursday",
 | 
				
			||||||
 | 
					    "addon.calendar.tue": "Tue",
 | 
				
			||||||
 | 
					    "addon.calendar.tuesday": "Tuesday",
 | 
				
			||||||
    "addon.calendar.typecategory": "Category event",
 | 
					    "addon.calendar.typecategory": "Category event",
 | 
				
			||||||
    "addon.calendar.typeclose": "Close event",
 | 
					    "addon.calendar.typeclose": "Close event",
 | 
				
			||||||
    "addon.calendar.typecourse": "Course event",
 | 
					    "addon.calendar.typecourse": "Course event",
 | 
				
			||||||
@ -128,6 +140,8 @@
 | 
				
			|||||||
    "addon.calendar.typeopen": "Open event",
 | 
					    "addon.calendar.typeopen": "Open event",
 | 
				
			||||||
    "addon.calendar.typesite": "Site event",
 | 
					    "addon.calendar.typesite": "Site event",
 | 
				
			||||||
    "addon.calendar.typeuser": "User event",
 | 
					    "addon.calendar.typeuser": "User event",
 | 
				
			||||||
 | 
					    "addon.calendar.wed": "Wed",
 | 
				
			||||||
 | 
					    "addon.calendar.wednesday": "Wednesday",
 | 
				
			||||||
    "addon.competency.activities": "Activities",
 | 
					    "addon.competency.activities": "Activities",
 | 
				
			||||||
    "addon.competency.competencies": "Competencies",
 | 
					    "addon.competency.competencies": "Competencies",
 | 
				
			||||||
    "addon.competency.competenciesmostoftennotproficientincourse": "Competencies most often not proficient in this course",
 | 
					    "addon.competency.competenciesmostoftennotproficientincourse": "Competencies most often not proficient in this course",
 | 
				
			||||||
@ -1658,6 +1672,7 @@
 | 
				
			|||||||
    "core.notingroup": "Sorry, but you need to be part of a group to see this page.",
 | 
					    "core.notingroup": "Sorry, but you need to be part of a group to see this page.",
 | 
				
			||||||
    "core.notsent": "Not sent",
 | 
					    "core.notsent": "Not sent",
 | 
				
			||||||
    "core.now": "now",
 | 
					    "core.now": "now",
 | 
				
			||||||
 | 
					    "core.nummore": "{{$a}} more",
 | 
				
			||||||
    "core.numwords": "{{$a}} words",
 | 
					    "core.numwords": "{{$a}} words",
 | 
				
			||||||
    "core.offline": "Offline",
 | 
					    "core.offline": "Offline",
 | 
				
			||||||
    "core.ok": "OK",
 | 
					    "core.ok": "OK",
 | 
				
			||||||
 | 
				
			|||||||
@ -184,6 +184,7 @@
 | 
				
			|||||||
    "notingroup": "Sorry, but you need to be part of a group to see this page.",
 | 
					    "notingroup": "Sorry, but you need to be part of a group to see this page.",
 | 
				
			||||||
    "notsent": "Not sent",
 | 
					    "notsent": "Not sent",
 | 
				
			||||||
    "now": "now",
 | 
					    "now": "now",
 | 
				
			||||||
 | 
					    "nummore": "{{$a}} more",
 | 
				
			||||||
    "numwords": "{{$a}} words",
 | 
					    "numwords": "{{$a}} words",
 | 
				
			||||||
    "offline": "Offline",
 | 
					    "offline": "Offline",
 | 
				
			||||||
    "ok": "OK",
 | 
					    "ok": "OK",
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,7 @@ $green:           #5e8100; // Accent.
 | 
				
			|||||||
$red:             #cb3d4d;
 | 
					$red:             #cb3d4d;
 | 
				
			||||||
$orange:          #f98012; // Accent (never text).
 | 
					$orange:          #f98012; // Accent (never text).
 | 
				
			||||||
$yellow:          #fbad1a; // Accent (never text).
 | 
					$yellow:          #fbad1a; // Accent (never text).
 | 
				
			||||||
 | 
					$purple:          #8e24aa; // Accent (never text).
 | 
				
			||||||
$core-color:      $orange;
 | 
					$core-color:      $orange;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Branded apps customization
 | 
					// Branded apps customization
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user