2020-12-14 14:50:37 +01:00
|
|
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
|
|
|
//
|
|
|
|
// 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, OnDestroy, ViewChild, ElementRef } from '@angular/core';
|
|
|
|
import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';
|
2021-01-21 15:24:45 +01:00
|
|
|
import { IonRefresher } from '@ionic/angular';
|
2020-12-14 14:50:37 +01:00
|
|
|
import { CoreEvents } from '@singletons/events';
|
|
|
|
import { CoreGroup, CoreGroups } from '@services/groups';
|
|
|
|
import { CoreSites } from '@services/sites';
|
|
|
|
import { CoreSync } from '@services/sync';
|
|
|
|
import { CoreDomUtils } from '@services/utils/dom';
|
|
|
|
import { CoreTimeUtils } from '@services/utils/time';
|
|
|
|
import { CoreUtils } from '@services/utils/utils';
|
|
|
|
import { CoreCategoryData, CoreCourses, CoreCourseSearchedData, CoreEnrolledCourseData } from '@features/courses/services/courses';
|
|
|
|
// @todo import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
|
|
|
import { CoreEditorRichTextEditorComponent } from '@features/editor/components/rich-text-editor/rich-text-editor.ts';
|
|
|
|
import {
|
|
|
|
AddonCalendarProvider,
|
|
|
|
AddonCalendarGetCalendarAccessInformationWSResponse,
|
|
|
|
AddonCalendarEvent,
|
|
|
|
AddonCalendarEventType,
|
|
|
|
AddonCalendar,
|
|
|
|
AddonCalendarSubmitCreateUpdateFormDataWSParams,
|
|
|
|
AddonCalendarUpdatedEventEvent,
|
|
|
|
} from '../../services/calendar';
|
|
|
|
import { AddonCalendarOffline } from '../../services/calendar-offline';
|
|
|
|
import { AddonCalendarEventTypeOption, AddonCalendarHelper } from '../../services/calendar-helper';
|
|
|
|
import { AddonCalendarSync, AddonCalendarSyncProvider } from '../../services/calendar-sync';
|
|
|
|
import { CoreSite } from '@classes/site';
|
|
|
|
import { Translate } from '@singletons';
|
|
|
|
import { CoreFilterHelper } from '@features/filter/services/filter-helper';
|
|
|
|
import { ActivatedRoute } from '@angular/router';
|
|
|
|
import { AddonCalendarOfflineEventDBRecord } from '../../services/database/calendar-offline';
|
|
|
|
import { CoreError } from '@classes/errors/error';
|
2021-01-21 15:24:45 +01:00
|
|
|
import { CoreNavigator } from '@services/navigator';
|
2020-12-14 14:50:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Page that displays a form to create/edit an event.
|
|
|
|
*/
|
|
|
|
@Component({
|
|
|
|
selector: 'page-addon-calendar-edit-event',
|
|
|
|
templateUrl: 'edit-event.html',
|
|
|
|
styleUrls: ['edit-event.scss'],
|
|
|
|
})
|
|
|
|
export class AddonCalendarEditEventPage implements OnInit, OnDestroy {
|
|
|
|
|
|
|
|
@ViewChild(CoreEditorRichTextEditorComponent) descriptionEditor!: CoreEditorRichTextEditorComponent;
|
|
|
|
@ViewChild('editEventForm') formElement!: ElementRef;
|
|
|
|
|
|
|
|
title = 'addon.calendar.newevent';
|
|
|
|
dateFormat: string;
|
|
|
|
component = AddonCalendarProvider.COMPONENT;
|
|
|
|
loaded = false;
|
|
|
|
hasOffline = false;
|
|
|
|
eventTypes: AddonCalendarEventTypeOption[] = [];
|
|
|
|
categories: CoreCategoryData[] = [];
|
|
|
|
courses: CoreCourseSearchedData[] | CoreEnrolledCourseData[] = [];
|
|
|
|
groups: CoreGroup[] = [];
|
|
|
|
loadingGroups = false;
|
|
|
|
courseGroupSet = false;
|
|
|
|
advanced = false;
|
|
|
|
errors: Record<string, string>;
|
|
|
|
error = false;
|
|
|
|
eventRepeatId?: number;
|
|
|
|
otherEventsCount = 0;
|
|
|
|
eventId?: number;
|
|
|
|
|
|
|
|
// Form variables.
|
|
|
|
form: FormGroup;
|
|
|
|
typeControl: FormControl;
|
|
|
|
groupControl: FormControl;
|
|
|
|
descriptionControl: FormControl;
|
|
|
|
|
|
|
|
protected courseId!: number;
|
|
|
|
protected originalData?: AddonCalendarOfflineEventDBRecord;
|
|
|
|
protected currentSite: CoreSite;
|
|
|
|
protected types: { [name: string]: boolean } = {}; // Object with the supported types.
|
|
|
|
protected showAll = false;
|
|
|
|
protected isDestroyed = false;
|
|
|
|
protected gotEventData = false;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
protected route: ActivatedRoute,
|
|
|
|
protected fb: FormBuilder,
|
|
|
|
) {
|
|
|
|
|
|
|
|
this.currentSite = CoreSites.instance.getCurrentSite()!;
|
|
|
|
this.errors = {
|
|
|
|
required: Translate.instance.instant('core.required'),
|
|
|
|
};
|
|
|
|
|
|
|
|
// Calculate format to use. ion-datetime doesn't support escaping characters ([]), so we remove them.
|
|
|
|
this.dateFormat = CoreTimeUtils.instance.convertPHPToMoment(Translate.instance.instant('core.strftimedatetimeshort'))
|
|
|
|
.replace(/[[\]]/g, '');
|
|
|
|
|
|
|
|
this.form = new FormGroup({});
|
|
|
|
|
|
|
|
// Initialize form variables.
|
|
|
|
this.typeControl = this.fb.control('', Validators.required);
|
|
|
|
this.groupControl = this.fb.control('');
|
|
|
|
this.descriptionControl = this.fb.control('');
|
|
|
|
this.form.addControl('name', this.fb.control('', Validators.required));
|
|
|
|
this.form.addControl('eventtype', this.typeControl);
|
|
|
|
this.form.addControl('categoryid', this.fb.control(''));
|
|
|
|
this.form.addControl('groupcourseid', this.fb.control(''));
|
|
|
|
this.form.addControl('groupid', this.groupControl);
|
|
|
|
this.form.addControl('description', this.descriptionControl);
|
|
|
|
this.form.addControl('location', this.fb.control(''));
|
|
|
|
this.form.addControl('duration', this.fb.control(0));
|
|
|
|
this.form.addControl('timedurationminutes', this.fb.control(''));
|
|
|
|
this.form.addControl('repeat', this.fb.control(false));
|
|
|
|
this.form.addControl('repeats', this.fb.control('1'));
|
|
|
|
this.form.addControl('repeateditall', this.fb.control(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Component being initialized.
|
|
|
|
*/
|
|
|
|
ngOnInit(): void {
|
|
|
|
this.eventId = this.route.snapshot.queryParams['eventId'];
|
|
|
|
this.courseId = parseInt(this.route.snapshot.queryParams['courseId'], 10) || 0;
|
|
|
|
this.title = this.eventId ? 'addon.calendar.editevent' : 'addon.calendar.newevent';
|
|
|
|
|
|
|
|
const timestamp = parseInt(this.route.snapshot.queryParams['timestamp'], 10);
|
|
|
|
const currentDate = CoreTimeUtils.instance.toDatetimeFormat(timestamp);
|
|
|
|
this.form.addControl('timestart', this.fb.control(currentDate, Validators.required));
|
|
|
|
this.form.addControl('timedurationuntil', this.fb.control(currentDate));
|
|
|
|
this.form.addControl('courseid', this.fb.control(this.courseId));
|
|
|
|
|
|
|
|
this.fetchData().finally(() => {
|
|
|
|
this.originalData = CoreUtils.instance.clone(this.form.value);
|
|
|
|
this.loaded = true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fetch the data needed to render the form.
|
|
|
|
*
|
|
|
|
* @param refresh Whether it's refreshing data.
|
|
|
|
* @return Promise resolved when done.
|
|
|
|
*/
|
|
|
|
protected async fetchData(): Promise<void> {
|
|
|
|
let accessInfo: AddonCalendarGetCalendarAccessInformationWSResponse;
|
|
|
|
|
|
|
|
this.error = false;
|
|
|
|
|
|
|
|
// Get access info.
|
|
|
|
try {
|
|
|
|
accessInfo = await AddonCalendar.instance.getAccessInformation(this.courseId);
|
|
|
|
this.types = await AddonCalendar.instance.getAllowedEventTypes(this.courseId);
|
|
|
|
|
|
|
|
const promises: Promise<void>[] = [];
|
|
|
|
const eventTypes = AddonCalendarHelper.instance.getEventTypeOptions(this.types);
|
|
|
|
|
|
|
|
if (!eventTypes.length) {
|
|
|
|
throw new CoreError(Translate.instance.instant('addon.calendar.nopermissiontoupdatecalendar'));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.eventId && !this.gotEventData) {
|
|
|
|
// Editing an event, get the event data. Wait for sync first.
|
|
|
|
promises.push(AddonCalendarSync.instance.waitForSync(AddonCalendarSyncProvider.SYNC_ID).then(async () => {
|
|
|
|
// Do not block if the scope is already destroyed.
|
|
|
|
if (!this.isDestroyed && this.eventId) {
|
|
|
|
CoreSync.instance.blockOperation(AddonCalendarProvider.COMPONENT, this.eventId);
|
|
|
|
}
|
|
|
|
|
|
|
|
let eventForm: AddonCalendarEvent | AddonCalendarOfflineEventDBRecord | undefined;
|
|
|
|
|
|
|
|
// Get the event offline data if there's any.
|
|
|
|
try {
|
|
|
|
eventForm = await AddonCalendarOffline.instance.getEvent(this.eventId!);
|
|
|
|
|
|
|
|
this.hasOffline = true;
|
|
|
|
} catch {
|
|
|
|
// No offline data.
|
|
|
|
this.hasOffline = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.eventId! > 0) {
|
|
|
|
// It's an online event. get its data from server.
|
|
|
|
const event = await AddonCalendar.instance.getEventById(this.eventId!);
|
|
|
|
|
|
|
|
if (!eventForm) {
|
|
|
|
eventForm = event; // Use offline data first.
|
|
|
|
}
|
|
|
|
|
|
|
|
this.eventRepeatId = event?.repeatid;
|
|
|
|
if (this.eventRepeatId) {
|
|
|
|
|
|
|
|
this.otherEventsCount = event.eventcount ? event.eventcount - 1 : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.gotEventData = true;
|
|
|
|
|
|
|
|
if (eventForm) {
|
|
|
|
// Load the data in the form.
|
|
|
|
return this.loadEventData(eventForm, this.hasOffline);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.types.category) {
|
|
|
|
// Get the categories.
|
|
|
|
promises.push(this.fetchCategories());
|
|
|
|
}
|
|
|
|
|
|
|
|
this.showAll = CoreUtils.instance.isTrueOrOne(this.currentSite.getStoredConfig('calendar_adminseesall')) &&
|
|
|
|
accessInfo.canmanageentries;
|
|
|
|
|
|
|
|
if (this.types.course || this.types.groups) {
|
|
|
|
promises.push(this.fetchCourses());
|
|
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
|
|
|
|
if (!this.typeControl.value) {
|
|
|
|
// Initialize event type value. If course is allowed, select it first.
|
|
|
|
if (this.types.course) {
|
|
|
|
this.typeControl.setValue(AddonCalendarEventType.COURSE);
|
|
|
|
} else {
|
|
|
|
this.typeControl.setValue(eventTypes[0].value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.eventTypes = eventTypes;
|
|
|
|
} catch (error) {
|
|
|
|
CoreDomUtils.instance.showErrorModalDefault(error, 'Error getting data.');
|
|
|
|
this.error = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected async fetchCategories(): Promise<void> {
|
|
|
|
this.categories = await CoreCourses.instance.getCategories(0, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected async fetchCourses(): Promise<void> {
|
|
|
|
// Get the courses.
|
|
|
|
let courses = await (this.showAll ? CoreCourses.instance.getCoursesByField() : CoreCourses.instance.getUserCourses());
|
|
|
|
|
|
|
|
if (courses.length < 0) {
|
|
|
|
this.courses = [];
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const courseFillterFullname = (course: CoreCourseSearchedData | CoreEnrolledCourseData): Promise<void> =>
|
|
|
|
CoreFilterHelper.instance.getFiltersAndFormatText(course.fullname, 'course', course.id)
|
|
|
|
.then((result) => {
|
|
|
|
course.fullname = result.text;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}).catch(() => {
|
|
|
|
// Ignore errors.
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (this.showAll) {
|
|
|
|
// Remove site home from the list of courses.
|
|
|
|
const siteHomeId = CoreSites.instance.getCurrentSiteHomeId();
|
|
|
|
|
|
|
|
if ('contacts' in courses[0]) {
|
|
|
|
courses = (courses as CoreCourseSearchedData[]).filter((course) => course.id != siteHomeId);
|
|
|
|
} else {
|
|
|
|
courses = (courses as CoreEnrolledCourseData[]).filter((course) => course.id != siteHomeId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Format the name of the courses.
|
|
|
|
if ('contacts' in courses[0]) {
|
|
|
|
await Promise.all((courses as CoreCourseSearchedData[]).map(courseFillterFullname));
|
|
|
|
} else {
|
|
|
|
await Promise.all((courses as CoreEnrolledCourseData[]).map(courseFillterFullname));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Sort courses by name.
|
|
|
|
this.courses = courses.sort((a, b) => {
|
|
|
|
const compareA = a.fullname.toLowerCase();
|
|
|
|
const compareB = b.fullname.toLowerCase();
|
|
|
|
|
|
|
|
return compareA.localeCompare(compareB);
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load an event data into the form.
|
|
|
|
*
|
|
|
|
* @param event Event data.
|
|
|
|
* @param isOffline Whether the data is from offline or not.
|
|
|
|
* @return Promise resolved when done.
|
|
|
|
*/
|
|
|
|
protected async loadEventData(
|
|
|
|
event: AddonCalendarEvent | AddonCalendarOfflineEventDBRecord,
|
|
|
|
isOffline: boolean,
|
|
|
|
): Promise<void> {
|
|
|
|
if (!event) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const offlineEvent = (event as AddonCalendarOfflineEventDBRecord);
|
|
|
|
const onlineEvent = (event as AddonCalendarEvent);
|
|
|
|
|
|
|
|
const courseId = isOffline ? offlineEvent.courseid : onlineEvent.course?.id;
|
|
|
|
|
|
|
|
this.form.controls.name.setValue(event.name);
|
|
|
|
this.form.controls.timestart.setValue(CoreTimeUtils.instance.toDatetimeFormat(event.timestart * 1000));
|
|
|
|
this.form.controls.eventtype.setValue(event.eventtype);
|
|
|
|
this.form.controls.categoryid.setValue(event.categoryid || '');
|
|
|
|
this.form.controls.courseid.setValue(courseId || '');
|
|
|
|
this.form.controls.groupcourseid.setValue(courseId || '');
|
|
|
|
this.form.controls.groupid.setValue(event.groupid || '');
|
|
|
|
this.form.controls.description.setValue(event.description);
|
|
|
|
this.form.controls.location.setValue(event.location);
|
|
|
|
|
|
|
|
if (isOffline) {
|
|
|
|
// It's an offline event, use the data as it is.
|
|
|
|
this.form.controls.duration.setValue(offlineEvent.duration);
|
|
|
|
this.form.controls.timedurationuntil.setValue(
|
|
|
|
CoreTimeUtils.instance.toDatetimeFormat(((offlineEvent.timedurationuntil || 0) * 1000) || Date.now()),
|
|
|
|
);
|
|
|
|
this.form.controls.timedurationminutes.setValue(offlineEvent.timedurationminutes || '');
|
|
|
|
this.form.controls.repeat.setValue(!!offlineEvent.repeat);
|
|
|
|
this.form.controls.repeats.setValue(offlineEvent.repeats || '1');
|
|
|
|
this.form.controls.repeateditall.setValue(offlineEvent.repeateditall || 1);
|
|
|
|
} else {
|
|
|
|
// Online event, we'll have to calculate the data.
|
|
|
|
|
|
|
|
if (onlineEvent.timeduration > 0) {
|
|
|
|
this.form.controls.duration.setValue(1);
|
|
|
|
this.form.controls.timedurationuntil.setValue(CoreTimeUtils.instance.toDatetimeFormat(
|
|
|
|
(onlineEvent.timestart + onlineEvent.timeduration) * 1000,
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
// No duration.
|
|
|
|
this.form.controls.duration.setValue(0);
|
|
|
|
this.form.controls.timedurationuntil.setValue(CoreTimeUtils.instance.toDatetimeFormat());
|
|
|
|
}
|
|
|
|
|
|
|
|
this.form.controls.timedurationminutes.setValue('');
|
|
|
|
this.form.controls.repeat.setValue(!!onlineEvent.repeatid);
|
|
|
|
this.form.controls.repeats.setValue(onlineEvent.eventcount || '1');
|
|
|
|
this.form.controls.repeateditall.setValue(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.eventtype == AddonCalendarEventType.GROUP && courseId) {
|
|
|
|
await this.loadGroups(courseId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pull to refresh.
|
|
|
|
*
|
|
|
|
* @param refresher Refresher.
|
|
|
|
*/
|
|
|
|
refreshData(refresher?: CustomEvent<IonRefresher>): void {
|
|
|
|
const promises = [
|
|
|
|
AddonCalendar.instance.invalidateAccessInformation(this.courseId),
|
|
|
|
AddonCalendar.instance.invalidateAllowedEventTypes(this.courseId),
|
|
|
|
];
|
|
|
|
|
|
|
|
if (this.types) {
|
|
|
|
if (this.types.category) {
|
|
|
|
promises.push(CoreCourses.instance.invalidateCategories(0, true));
|
|
|
|
}
|
|
|
|
if (this.types.course || this.types.groups) {
|
|
|
|
if (this.showAll) {
|
|
|
|
promises.push(CoreCourses.instance.invalidateCoursesByField());
|
|
|
|
} else {
|
|
|
|
promises.push(CoreCourses.instance.invalidateUserCourses());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Promise.all(promises).finally(() => {
|
|
|
|
this.fetchData().finally(() => {
|
|
|
|
refresher?.detail.complete();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A course was selected, get its groups.
|
|
|
|
*
|
|
|
|
* @param courseId Course ID.
|
|
|
|
*/
|
|
|
|
async groupCourseSelected(courseId: number): Promise<void> {
|
|
|
|
if (!courseId) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const modal = await CoreDomUtils.instance.showModalLoading();
|
|
|
|
|
|
|
|
try {
|
|
|
|
await this.loadGroups(courseId);
|
|
|
|
|
|
|
|
this.groupControl.setValue('');
|
|
|
|
} catch (error) {
|
|
|
|
CoreDomUtils.instance.showErrorModalDefault(error, 'Error getting data.');
|
|
|
|
}
|
|
|
|
|
|
|
|
modal.dismiss();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load groups of a certain course.
|
|
|
|
*
|
|
|
|
* @param courseId Course ID.
|
|
|
|
* @return Promise resolved when done.
|
|
|
|
*/
|
|
|
|
protected async loadGroups(courseId: number): Promise<void> {
|
|
|
|
this.loadingGroups = true;
|
|
|
|
|
|
|
|
try {
|
|
|
|
this.groups = await CoreGroups.instance.getUserGroupsInCourse(courseId);
|
|
|
|
this.courseGroupSet = true;
|
|
|
|
} finally {
|
|
|
|
this.loadingGroups = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show or hide advanced form fields.
|
|
|
|
*/
|
|
|
|
toggleAdvanced(): void {
|
|
|
|
this.advanced = !this.advanced;
|
|
|
|
}
|
|
|
|
|
|
|
|
selectDuration(duration: string): void {
|
|
|
|
this.form.controls.duration.setValue(duration);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create the event.
|
|
|
|
*/
|
|
|
|
async submit(): Promise<void> {
|
|
|
|
// Validate data.
|
|
|
|
const formData = this.form.value;
|
|
|
|
const timeStartDate = CoreTimeUtils.instance.convertToTimestamp(formData.timestart);
|
|
|
|
const timeUntilDate = CoreTimeUtils.instance.convertToTimestamp(formData.timedurationuntil);
|
|
|
|
const timeDurationMinutes = parseInt(formData.timedurationminutes || '', 10);
|
|
|
|
let error: string | undefined;
|
|
|
|
|
|
|
|
if (formData.eventtype == AddonCalendarEventType.COURSE && !formData.courseid) {
|
|
|
|
error = 'core.selectacourse';
|
|
|
|
} else if (formData.eventtype == AddonCalendarEventType.GROUP && !formData.groupcourseid) {
|
|
|
|
error = 'core.selectacourse';
|
|
|
|
} else if (formData.eventtype == AddonCalendarEventType.GROUP && !formData.groupid) {
|
|
|
|
error = 'core.selectagroup';
|
|
|
|
} else if (formData.eventtype == AddonCalendarEventType.CATEGORY && !formData.categoryid) {
|
|
|
|
error = 'core.selectacategory';
|
|
|
|
} else if (formData.duration == 1 && timeStartDate > timeUntilDate) {
|
|
|
|
error = 'addon.calendar.invalidtimedurationuntil';
|
|
|
|
} else if (formData.duration == 2 && (isNaN(timeDurationMinutes) || timeDurationMinutes < 1)) {
|
|
|
|
error = 'addon.calendar.invalidtimedurationminutes';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
// Show error and stop.
|
|
|
|
CoreDomUtils.instance.showErrorModal(Translate.instance.instant(error));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Format the data to send.
|
|
|
|
const data: AddonCalendarSubmitCreateUpdateFormDataWSParams = {
|
|
|
|
name: formData.name,
|
|
|
|
eventtype: formData.eventtype,
|
|
|
|
timestart: timeStartDate,
|
|
|
|
description: {
|
|
|
|
text: formData.description || '',
|
|
|
|
format: 1,
|
|
|
|
},
|
|
|
|
location: formData.location,
|
|
|
|
duration: formData.duration,
|
|
|
|
repeat: formData.repeat,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (formData.eventtype == AddonCalendarEventType.COURSE) {
|
|
|
|
data.courseid = formData.courseid;
|
|
|
|
} else if (formData.eventtype == AddonCalendarEventType.GROUP) {
|
|
|
|
data.groupcourseid = formData.groupcourseid;
|
|
|
|
data.groupid = formData.groupid;
|
|
|
|
} else if (formData.eventtype == AddonCalendarEventType.CATEGORY) {
|
|
|
|
data.categoryid = formData.categoryid;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (formData.duration == 1) {
|
|
|
|
data.timedurationuntil = timeUntilDate;
|
|
|
|
} else if (formData.duration == 2) {
|
|
|
|
data.timedurationminutes = formData.timedurationminutes;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (formData.repeat) {
|
|
|
|
data.repeats = Number(formData.repeats);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.eventRepeatId) {
|
|
|
|
data.repeatid = this.eventRepeatId;
|
|
|
|
data.repeateditall = formData.repeateditall;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send the data.
|
|
|
|
const modal = await CoreDomUtils.instance.showModalLoading('core.sending', true);
|
|
|
|
let event: AddonCalendarEvent | AddonCalendarOfflineEventDBRecord;
|
|
|
|
|
|
|
|
try {
|
|
|
|
const result = await AddonCalendar.instance.submitEvent(this.eventId, data);
|
|
|
|
event = result.event;
|
|
|
|
|
|
|
|
CoreDomUtils.instance.triggerFormSubmittedEvent(this.formElement, result.sent, this.currentSite.getId());
|
|
|
|
|
|
|
|
if (result.sent) {
|
|
|
|
// Event created or edited, invalidate right days & months.
|
|
|
|
const numberOfRepetitions = formData.repeat ? formData.repeats :
|
|
|
|
(data.repeateditall && this.otherEventsCount ? this.otherEventsCount + 1 : 1);
|
|
|
|
|
|
|
|
try {
|
|
|
|
await AddonCalendarHelper.instance.refreshAfterChangeEvent(result.event, numberOfRepetitions);
|
|
|
|
} catch {
|
|
|
|
// Ignore errors.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.returnToList(event);
|
|
|
|
} catch (error) {
|
|
|
|
CoreDomUtils.instance.showErrorModalDefault(error, 'Error sending data.');
|
|
|
|
}
|
|
|
|
|
|
|
|
modal.dismiss();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience function to update or return to event list depending on device.
|
|
|
|
*
|
|
|
|
* @param event Event.
|
|
|
|
*/
|
|
|
|
protected returnToList(event?: AddonCalendarEvent | AddonCalendarOfflineEventDBRecord): void {
|
|
|
|
// Unblock the sync because the view will be destroyed and the sync process could be triggered before ngOnDestroy.
|
|
|
|
this.unblockSync();
|
|
|
|
|
|
|
|
if (this.eventId && this.eventId > 0) {
|
|
|
|
// Editing an event.
|
|
|
|
CoreEvents.trigger<AddonCalendarUpdatedEventEvent>(
|
|
|
|
AddonCalendarProvider.EDIT_EVENT_EVENT,
|
|
|
|
{ eventId: this.eventId },
|
|
|
|
this.currentSite.getId(),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
if (event) {
|
|
|
|
CoreEvents.trigger<AddonCalendarUpdatedEventEvent>(
|
|
|
|
AddonCalendarProvider.NEW_EVENT_EVENT,
|
|
|
|
{ eventId: event.id! },
|
|
|
|
this.currentSite.getId(),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
CoreEvents.trigger(AddonCalendarProvider.NEW_EVENT_DISCARDED_EVENT, {}, this.currentSite.getId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if (this.svComponent && this.svComponent.isOn()) {
|
|
|
|
// Empty form.
|
|
|
|
this.hasOffline = false;
|
|
|
|
this.form.reset(this.originalData);
|
|
|
|
this.originalData = CoreUtils.instance.clone(this.form.value);
|
|
|
|
} else {*/
|
|
|
|
this.originalData = undefined; // Avoid asking for confirmation.
|
2021-01-21 15:24:45 +01:00
|
|
|
CoreNavigator.instance.back();
|
2020-12-14 14:50:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Discard an offline saved discussion.
|
|
|
|
*/
|
|
|
|
async discard(): Promise<void> {
|
|
|
|
try {
|
|
|
|
await CoreDomUtils.instance.showConfirm(Translate.instance.instant('core.areyousure'));
|
|
|
|
try {
|
|
|
|
await AddonCalendarOffline.instance.deleteEvent(this.eventId!);
|
|
|
|
|
|
|
|
CoreDomUtils.instance.triggerFormCancelledEvent(this.formElement, this.currentSite.getId());
|
|
|
|
|
|
|
|
this.returnToList();
|
|
|
|
} catch {
|
|
|
|
// Shouldn't happen.
|
|
|
|
CoreDomUtils.instance.showErrorModal('Error discarding event.');
|
|
|
|
}
|
|
|
|
} catch {
|
|
|
|
// Ignore errors
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if we can leave the page or not.
|
|
|
|
*
|
|
|
|
* @return Resolved if we can leave it, rejected if not.
|
|
|
|
*/
|
|
|
|
async ionViewCanLeave(): Promise<void> {
|
|
|
|
if (AddonCalendarHelper.instance.hasEventDataChanged(this.form.value, this.originalData)) {
|
|
|
|
// Show confirmation if some data has been modified.
|
|
|
|
await CoreDomUtils.instance.showConfirm(Translate.instance.instant('core.confirmcanceledit'));
|
|
|
|
}
|
|
|
|
|
|
|
|
CoreDomUtils.instance.triggerFormCancelledEvent(this.formElement, this.currentSite.getId());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unblock sync.
|
|
|
|
*/
|
|
|
|
protected unblockSync(): void {
|
|
|
|
if (this.eventId) {
|
|
|
|
CoreSync.instance.unblockOperation(AddonCalendarProvider.COMPONENT, this.eventId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Page destroyed.
|
|
|
|
*/
|
|
|
|
ngOnDestroy(): void {
|
|
|
|
this.unblockSync();
|
|
|
|
this.isDestroyed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|