MOBILE-3909 calendar: Fix non-null assertion eslint warnings

main
Dani Palou 2021-11-11 10:02:53 +01:00
parent 47c913f434
commit 56596ad30e
30 changed files with 139 additions and 114 deletions

View File

@ -94,7 +94,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
this.obsDefaultTimeChange = CoreEvents.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, () => { this.obsDefaultTimeChange = CoreEvents.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, () => {
this.weeks.forEach((week) => { this.weeks.forEach((week) => {
week.days.forEach((day) => { week.days.forEach((day) => {
AddonCalendar.scheduleEventsNotifications(day.eventsFormated!); AddonCalendar.scheduleEventsNotifications(day.eventsFormated || []);
}); });
}); });
}, this.currentSiteId); }, this.currentSiteId);
@ -150,7 +150,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
if (this.weeks) { if (this.weeks) {
// Check if there's any change in the filter object. // Check if there's any change in the filter object.
const changes = this.differ.diff(this.filter!); const changes = this.differ.diff(this.filter || {});
if (changes) { if (changes) {
this.filterEvents(); this.filterEvents();
} }
@ -173,8 +173,8 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
this.offlineEvents = AddonCalendarHelper.classifyIntoMonths(events); this.offlineEvents = AddonCalendarHelper.classifyIntoMonths(events);
// Get the IDs of events edited in offline. // Get the IDs of events edited in offline.
const filtered = events.filter((event) => event.id! > 0); const filtered = events.filter((event) => event.id > 0);
this.offlineEditedEventsIds = filtered.map((event) => event.id!); this.offlineEditedEventsIds = filtered.map((event) => event.id);
return; return;
})); }));
@ -261,7 +261,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
isPast = day.ispast; isPast = day.ispast;
if (day.istoday) { if (day.istoday) {
day.eventsFormated!.forEach((event) => { day.eventsFormated?.forEach((event) => {
event.ispast = this.isEventPast(event); event.ispast = this.isEventPast(event);
}); });
} }
@ -306,8 +306,8 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
this.weeks.forEach((week) => { this.weeks.forEach((week) => {
week.days.forEach((day) => { week.days.forEach((day) => {
day.filteredEvents = AddonCalendarHelper.getFilteredEvents( day.filteredEvents = AddonCalendarHelper.getFilteredEvents(
day.eventsFormated!, day.eventsFormated || [],
this.filter!, this.filter,
this.categories, this.categories,
); );
@ -466,14 +466,14 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
week.days.forEach((day) => { week.days.forEach((day) => {
// Schedule notifications for the events retrieved (only future events will be scheduled). // Schedule notifications for the events retrieved (only future events will be scheduled).
AddonCalendar.scheduleEventsNotifications(day.eventsFormated!); AddonCalendar.scheduleEventsNotifications(day.eventsFormated || []);
if (monthOfflineEvents || this.deletedEvents.length) { if (monthOfflineEvents || this.deletedEvents.length) {
// There is offline data, merge it. // There is offline data, merge it.
if (this.deletedEvents.length) { if (this.deletedEvents.length) {
// Mark as deleted the events that were deleted in offline. // Mark as deleted the events that were deleted in offline.
day.eventsFormated!.forEach((event) => { day.eventsFormated?.forEach((event) => {
event.deleted = this.deletedEvents.indexOf(event.id) != -1; event.deleted = this.deletedEvents.indexOf(event.id) != -1;
}); });
} }
@ -483,10 +483,10 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
day.events = day.events.filter((event) => this.offlineEditedEventsIds.indexOf(event.id) == -1); day.events = day.events.filter((event) => this.offlineEditedEventsIds.indexOf(event.id) == -1);
} }
if (monthOfflineEvents && monthOfflineEvents[day.mday]) { if (monthOfflineEvents && monthOfflineEvents[day.mday] && day.eventsFormated) {
// Add the offline events (either new or edited). // Add the offline events (either new or edited).
day.eventsFormated = day.eventsFormated =
AddonCalendarHelper.sortEvents(day.eventsFormated!.concat(monthOfflineEvents[day.mday])); AddonCalendarHelper.sortEvents(day.eventsFormated.concat(monthOfflineEvents[day.mday]));
} }
} }
}); });
@ -505,7 +505,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
this.weeks.forEach((week) => { this.weeks.forEach((week) => {
week.days.forEach((day) => { week.days.forEach((day) => {
const event = day.eventsFormated!.find((event) => event.id == eventId); const event = day.eventsFormated?.find((event) => event.id == eventId);
if (event) { if (event) {
event.deleted = false; event.deleted = false;
@ -521,7 +521,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
* @return True if it's in the past. * @return True if it's in the past.
*/ */
protected isEventPast(event: { timestart: number; timeduration: number}): boolean { protected isEventPast(event: { timestart: number; timeduration: number}): boolean {
return (event.timestart + event.timeduration) < this.currentTime!; return (event.timestart + event.timeduration) < (this.currentTime || CoreTimeUtils.timestamp());
} }
/** /**

View File

@ -106,7 +106,7 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On
*/ */
ngDoCheck(): void { ngDoCheck(): void {
// Check if there's any change in the filter object. // Check if there's any change in the filter object.
const changes = this.differ.diff(this.filter!); const changes = this.differ.diff(this.filter || {});
if (changes) { if (changes) {
this.filterEvents(); this.filterEvents();
} }
@ -183,7 +183,7 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On
// Re-calculate the formatted time so it uses the device date. // Re-calculate the formatted time so it uses the device date.
const promises = this.events.map((event) => const promises = this.events.map((event) =>
AddonCalendar.formatEventTime(event, this.timeFormat!).then((time) => { AddonCalendar.formatEventTime(event, this.timeFormat).then((time) => {
event.formattedtime = time; event.formattedtime = time;
return; return;
@ -221,7 +221,7 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On
* Filter events based on the filter popover. * Filter events based on the filter popover.
*/ */
protected filterEvents(): void { protected filterEvents(): void {
this.filteredEvents = AddonCalendarHelper.getFilteredEvents(this.events, this.filter!, this.categories); this.filteredEvents = AddonCalendarHelper.getFilteredEvents(this.events, this.filter, this.categories);
} }
/** /**

View File

@ -286,7 +286,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
this.offlineEvents = AddonCalendarHelper.classifyIntoMonths(offlineEvents); this.offlineEvents = AddonCalendarHelper.classifyIntoMonths(offlineEvents);
// Get the IDs of events edited in offline. // Get the IDs of events edited in offline.
this.offlineEditedEventsIds = offlineEvents.filter((event) => event.id! > 0).map((event) => event.id!); this.offlineEditedEventsIds = offlineEvents.filter((event) => event.id > 0).map((event) => event.id);
return; return;
})); }));
@ -361,7 +361,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
const promises = this.events.map((event) => { const promises = this.events.map((event) => {
event.ispast = this.isPastDay || (this.isCurrentDay && this.isEventPast(event)); event.ispast = this.isPastDay || (this.isCurrentDay && this.isEventPast(event));
return AddonCalendar.formatEventTime(event, this.timeFormat!, true, dayTime).then((time) => { return AddonCalendar.formatEventTime(event, this.timeFormat, true, dayTime).then((time) => {
event.formattedtime = time; event.formattedtime = time;
return; return;

View File

@ -171,17 +171,19 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
if (this.eventId && !this.gotEventData) { if (this.eventId && !this.gotEventData) {
// Editing an event, get the event data. Wait for sync first. // Editing an event, get the event data. Wait for sync first.
const eventId = this.eventId;
promises.push(AddonCalendarSync.waitForSync(AddonCalendarSyncProvider.SYNC_ID).then(async () => { promises.push(AddonCalendarSync.waitForSync(AddonCalendarSyncProvider.SYNC_ID).then(async () => {
// Do not block if the scope is already destroyed. // Do not block if the scope is already destroyed.
if (!this.isDestroyed && this.eventId) { if (!this.isDestroyed && this.eventId) {
CoreSync.blockOperation(AddonCalendarProvider.COMPONENT, this.eventId); CoreSync.blockOperation(AddonCalendarProvider.COMPONENT, eventId);
} }
let eventForm: AddonCalendarEvent | AddonCalendarOfflineEventDBRecord | undefined; let eventForm: AddonCalendarEvent | AddonCalendarOfflineEventDBRecord | undefined;
// Get the event offline data if there's any. // Get the event offline data if there's any.
try { try {
eventForm = await AddonCalendarOffline.getEvent(this.eventId!); eventForm = await AddonCalendarOffline.getEvent(eventId);
this.hasOffline = true; this.hasOffline = true;
} catch { } catch {
@ -189,9 +191,9 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
this.hasOffline = false; this.hasOffline = false;
} }
if (this.eventId! > 0) { if (eventId > 0) {
// It's an online event. get its data from server. // It's an online event. get its data from server.
const event = await AddonCalendar.getEventById(this.eventId!); const event = await AddonCalendar.getEventById(eventId);
if (!eventForm) { if (!eventForm) {
eventForm = event; // Use offline data first. eventForm = event; // Use offline data first.
@ -562,7 +564,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
if (event) { if (event) {
CoreEvents.trigger( CoreEvents.trigger(
AddonCalendarProvider.NEW_EVENT_EVENT, AddonCalendarProvider.NEW_EVENT_EVENT,
{ eventId: event.id! }, { eventId: event.id },
this.currentSite.getId(), this.currentSite.getId(),
); );
} else { } else {
@ -578,10 +580,15 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
* Discard an offline saved discussion. * Discard an offline saved discussion.
*/ */
async discard(): Promise<void> { async discard(): Promise<void> {
if (!this.eventId) {
return;
}
try { try {
await CoreDomUtils.showConfirm(Translate.instant('core.areyousure')); await CoreDomUtils.showConfirm(Translate.instant('core.areyousure'));
try { try {
await AddonCalendarOffline.deleteEvent(this.eventId!); await AddonCalendarOffline.deleteEvent(this.eventId);
CoreForms.triggerFormCancelledEvent(this.formElement, this.currentSite.getId()); CoreForms.triggerFormCancelledEvent(this.formElement, this.currentSite.getId());

View File

@ -214,7 +214,8 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
try { try {
// Get the event data. // Get the event data.
const event = await AddonCalendar.getEventById(this.eventId); const event = await AddonCalendar.getEventById(this.eventId);
this.event = await AddonCalendarHelper.formatEventData(event); const formattedEvent = await AddonCalendarHelper.formatEventData(event);
this.event = formattedEvent;
// Load reminders, and re-schedule them if needed (maybe the event time has changed). // Load reminders, and re-schedule them if needed (maybe the event time has changed).
this.loadReminders(); this.loadReminders();
@ -266,7 +267,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
// If it's a group event, get the name of the group. // If it's a group event, get the name of the group.
if (courseId && this.event.groupid) { if (courseId && this.event.groupid) {
promises.push(CoreGroups.getUserGroupsInCourse(courseId).then((groups) => { promises.push(CoreGroups.getUserGroupsInCourse(courseId).then((groups) => {
const group = groups.find((group) => group.id == this.event!.groupid); const group = groups.find((group) => group.id == formattedEvent.groupid);
this.groupName = group ? group.name : ''; this.groupName = group ? group.name : '';
@ -289,14 +290,14 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
// Check if event was deleted in offine. // Check if event was deleted in offine.
promises.push(AddonCalendarOffline.isEventDeleted(this.eventId).then((deleted) => { promises.push(AddonCalendarOffline.isEventDeleted(this.eventId).then((deleted) => {
this.event!.deleted = deleted; formattedEvent.deleted = deleted;
return; return;
})); }));
// Re-calculate the formatted time so it uses the device date. // Re-calculate the formatted time so it uses the device date.
promises.push(AddonCalendar.getCalendarTimeFormat().then(async (timeFormat) => { promises.push(AddonCalendar.getCalendarTimeFormat().then(async (timeFormat) => {
this.event!.formattedtime = await AddonCalendar.formatEventTime(this.event!, timeFormat); formattedEvent.formattedtime = await AddonCalendar.formatEventTime(formattedEvent, timeFormat);
return; return;
})); }));

View File

@ -222,7 +222,7 @@ export class AddonCalendarHelperProvider {
formatOfflineEventData(event: AddonCalendarOfflineEventDBRecord): AddonCalendarEventToDisplay { formatOfflineEventData(event: AddonCalendarOfflineEventDBRecord): AddonCalendarEventToDisplay {
const eventFormatted: AddonCalendarEventToDisplay = { const eventFormatted: AddonCalendarEventToDisplay = {
id: event.id!, id: event.id,
name: event.name, name: event.name,
timestart: event.timestart, timestart: event.timestart,
eventtype: event.eventtype, eventtype: event.eventtype,
@ -386,7 +386,7 @@ export class AddonCalendarHelperProvider {
year: number, year: number,
month: number, month: number,
siteId?: string, siteId?: string,
): Promise<{ daynames: Partial<AddonCalendarDayName>[]; weeks: Partial<AddonCalendarWeek>[] }> { ): Promise<{ daynames: Partial<AddonCalendarDayName>[]; weeks: AddonCalendarWeek[] }> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
// Get starting week day user preference, fallback to site configuration. // Get starting week day user preference, fallback to site configuration.
let startWeekDayStr = site.getStoredConfig('calendar_startwday'); let startWeekDayStr = site.getStoredConfig('calendar_startwday');
@ -395,7 +395,7 @@ export class AddonCalendarHelperProvider {
const today = moment(); const today = moment();
const isCurrentMonth = today.year() == year && today.month() == month - 1; const isCurrentMonth = today.year() == year && today.month() == month - 1;
const weeks: Partial<AddonCalendarWeek>[] = []; const weeks: AddonCalendarWeek[] = [];
let date = moment({ year, month: month - 1, date: 1 }); let date = moment({ year, month: month - 1, date: 1 });
for (let mday = 1; mday <= date.daysInMonth(); mday++) { for (let mday = 1; mday <= date.daysInMonth(); mday++) {
@ -422,7 +422,7 @@ export class AddonCalendarHelperProvider {
} }
// Add day to current week. // Add day to current week.
weeks[weeks.length - 1].days!.push({ weeks[weeks.length - 1].days.push({
events: [], events: [],
hasevents: false, hasevents: false,
mday: date.date(), mday: date.date(),
@ -501,11 +501,11 @@ export class AddonCalendarHelperProvider {
*/ */
getFilteredEvents( getFilteredEvents(
events: AddonCalendarEventToDisplay[], events: AddonCalendarEventToDisplay[],
filter: AddonCalendarFilter, filter: AddonCalendarFilter | undefined,
categories: { [id: number]: CoreCategoryData }, categories: { [id: number]: CoreCategoryData },
): AddonCalendarEventToDisplay[] { ): AddonCalendarEventToDisplay[] {
// Do not filter. // Do not filter.
if (!filter.filtered) { if (!filter || !filter.filtered) {
return events; return events;
} }
@ -526,9 +526,9 @@ export class AddonCalendarHelperProvider {
* Check if an event should be displayed based on the filter. * Check if an event should be displayed based on the filter.
* *
* @param event Event object. * @param event Event object.
* @param categories Categories indexed by ID.
* @param courseId Course ID to filter. * @param courseId Course ID to filter.
* @param categoryId Category ID the course belongs to. * @param categoryId Category ID the course belongs to.
* @param categories Categories indexed by ID.
* @return Whether it should be displayed. * @return Whether it should be displayed.
*/ */
protected shouldDisplayEvent( protected shouldDisplayEvent(
@ -543,7 +543,7 @@ export class AddonCalendarHelperProvider {
} }
if (event.eventtype == 'category' && categories) { if (event.eventtype == 'category' && categories) {
if (!event.categoryid || !Object.keys(categories).length) { if (!event.categoryid || !Object.keys(categories).length || !categoryId) {
// We can't tell if the course belongs to the category, display them all. // We can't tell if the course belongs to the category, display them all.
return true; return true;
} }
@ -554,7 +554,7 @@ export class AddonCalendarHelperProvider {
} }
// Check parent categories. // Check parent categories.
let category = categories[categoryId!]; let category = categories[categoryId];
while (category) { while (category) {
if (!category.parent) { if (!category.parent) {
// Category doesn't have parent, stop. // Category doesn't have parent, stop.
@ -618,7 +618,7 @@ export class AddonCalendarHelperProvider {
await AddonCalendar.getLocalEventsByRepeatIdFromLocalDb(eventData.repeatid, site.id); await AddonCalendar.getLocalEventsByRepeatIdFromLocalDb(eventData.repeatid, site.id);
await CoreUtils.allPromises(repeatedEvents.map((event) => await CoreUtils.allPromises(repeatedEvents.map((event) =>
AddonCalendar.invalidateEvent(event.id!))); AddonCalendar.invalidateEvent(event.id)));
return; return;
} }
@ -721,7 +721,7 @@ export class AddonCalendarHelperProvider {
*/ */
refreshAfterChangeEvent( refreshAfterChangeEvent(
event: { event: {
id?: number; id: number;
repeatid?: number; repeatid?: number;
timestart: number; timestart: number;
}, },
@ -730,7 +730,7 @@ export class AddonCalendarHelperProvider {
): Promise<void> { ): Promise<void> {
return this.refreshAfterChangeEvents( return this.refreshAfterChangeEvents(
[{ [{
id: event.id!, id: event.id,
repeatid: event.repeatid, repeatid: event.repeatid,
timestart: event.timestart, timestart: event.timestart,
repeated: repeated, repeated: repeated,

View File

@ -110,7 +110,7 @@ export class AddonCalendarOfflineProvider {
async getAllEditedEventsIds(siteId?: string): Promise<number[]> { async getAllEditedEventsIds(siteId?: string): Promise<number[]> {
const events = await this.getAllEditedEvents(siteId); const events = await this.getAllEditedEvents(siteId);
return events.map((event) => event.id!); return events.map((event) => event.id);
} }
/** /**

View File

@ -100,9 +100,10 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
async syncEvents(siteId?: string): Promise<AddonCalendarSyncEvents> { async syncEvents(siteId?: string): Promise<AddonCalendarSyncEvents> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(AddonCalendarSyncProvider.SYNC_ID, siteId)) { const currentSyncPromise = this.getOngoingSync(AddonCalendarSyncProvider.SYNC_ID, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this site, return the promise. // There's already a sync ongoing for this site, return the promise.
return this.getOngoingSync(AddonCalendarSyncProvider.SYNC_ID, siteId)!; return currentSyncPromise;
} }
this.logger.debug('Try to sync calendar events for site ' + siteId); this.logger.debug('Try to sync calendar events for site ' + siteId);
@ -272,7 +273,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
}); });
// Event sent, delete the offline data. // Event sent, delete the offline data.
return AddonCalendarOffline.deleteEvent(event.id!, siteId); return AddonCalendarOffline.deleteEvent(event.id, siteId);
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreUtils.isWebServiceError(error)) {
@ -283,7 +284,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
// The WebService has thrown an error, this means that the event cannot be created. Delete it. // The WebService has thrown an error, this means that the event cannot be created. Delete it.
result.updated = true; result.updated = true;
await AddonCalendarOffline.deleteEvent(event.id!, siteId); await AddonCalendarOffline.deleteEvent(event.id, siteId);
// Event deleted, add a warning. // Event deleted, add a warning.
this.addOfflineDataDeletedWarning(result.warnings, event.name, error); this.addOfflineDataDeletedWarning(result.warnings, event.name, error);

View File

@ -366,7 +366,7 @@ export class AddonCalendarProvider {
*/ */
async formatEventTime( async formatEventTime(
event: AddonCalendarEventToDisplay, event: AddonCalendarEventToDisplay,
format: string, format?: string,
useCommonWords = true, useCommonWords = true,
seenDay?: number, seenDay?: number,
showTime = 0, showTime = 0,
@ -716,18 +716,18 @@ export class AddonCalendarProvider {
eventConverted.iscategoryevent = originalEvent.eventtype == AddonCalendarEventType.CATEGORY; eventConverted.iscategoryevent = originalEvent.eventtype == AddonCalendarEventType.CATEGORY;
eventConverted.normalisedeventtype = this.getEventType(recordAsRecord); eventConverted.normalisedeventtype = this.getEventType(recordAsRecord);
try { try {
eventConverted.category = CoreTextUtils.parseJSON(recordAsRecord.category!); eventConverted.category = CoreTextUtils.parseJSON(recordAsRecord.category || '');
} catch { } catch {
// Ignore errors. // Ignore errors.
} }
try { try {
eventConverted.course = CoreTextUtils.parseJSON(recordAsRecord.course!); eventConverted.course = CoreTextUtils.parseJSON(recordAsRecord.course || '');
} catch { } catch {
// Ignore errors. // Ignore errors.
} }
try { try {
eventConverted.subscription = CoreTextUtils.parseJSON(recordAsRecord.subscription!); eventConverted.subscription = CoreTextUtils.parseJSON(recordAsRecord.subscription || '');
} catch { } catch {
// Ignore errors. // Ignore errors.
} }
@ -918,6 +918,10 @@ export class AddonCalendarProvider {
const start = initialTime + (CoreConstants.SECONDS_DAY * daysToStart); const start = initialTime + (CoreConstants.SECONDS_DAY * daysToStart);
const end = start + (CoreConstants.SECONDS_DAY * daysInterval) - 1; const end = start + (CoreConstants.SECONDS_DAY * daysInterval) - 1;
const events = {
courseids: <number[]> [],
groupids: <number[]> [],
};
const params: AddonCalendarGetCalendarEventsWSParams = { const params: AddonCalendarGetCalendarEventsWSParams = {
options: { options: {
userevents: true, userevents: true,
@ -925,23 +929,20 @@ export class AddonCalendarProvider {
timestart: start, timestart: start,
timeend: end, timeend: end,
}, },
events: { events: events,
courseids: [],
groupids: [],
},
}; };
const promises: Promise<void>[] = []; const promises: Promise<void>[] = [];
promises.push(CoreCourses.getUserCourses(false, siteId).then((courses) => { promises.push(CoreCourses.getUserCourses(false, siteId).then((courses) => {
params.events!.courseids = courses.map((course) => course.id); events.courseids = courses.map((course) => course.id);
params.events!.courseids.push(site.getSiteHomeId()); // Add front page. events.courseids.push(site.getSiteHomeId()); // Add front page.
return; return;
})); }));
promises.push(CoreGroups.getAllUserGroups(siteId).then((groups) => { promises.push(CoreGroups.getAllUserGroups(siteId).then((groups) => {
params.events!.groupids = groups.map((group) => group.id); events.groupids = groups.map((group) => group.id);
return; return;
})); }));
@ -1697,6 +1698,7 @@ export class AddonCalendarProvider {
siteId?: string, siteId?: string,
): Promise<AddonCalendarEvent> { ): Promise<AddonCalendarEvent> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
// Add data that is "hidden" in web. // Add data that is "hidden" in web.
formData.id = eventId; formData.id = eventId;
formData.userid = site.getUserId(); formData.userid = site.getUserId();
@ -1707,12 +1709,14 @@ export class AddonCalendarProvider {
} else { } else {
formData['_qf__core_calendar_local_event_forms_create'] = 1; formData['_qf__core_calendar_local_event_forms_create'] = 1;
} }
const params: AddonCalendarSubmitCreateUpdateFormWSParams = { const params: AddonCalendarSubmitCreateUpdateFormWSParams = {
formdata: CoreUtils.objectToGetParams(formData), formdata: CoreUtils.objectToGetParams(formData),
}; };
const result = const result =
await site.write<AddonCalendarSubmitCreateUpdateFormWSResponse>('core_calendar_submit_create_update_form', params); await site.write<AddonCalendarSubmitCreateUpdateFormWSResponse>('core_calendar_submit_create_update_form', params);
if (result.validationerror) {
if (result.validationerror || !result.event) {
// Simulate a WS error. // Simulate a WS error.
throw new CoreWSError({ throw new CoreWSError({
message: Translate.instant('core.invalidformdata'), message: Translate.instant('core.invalidformdata'),
@ -1720,7 +1724,7 @@ export class AddonCalendarProvider {
}); });
} }
return result.event!; return result.event;
} }
} }
@ -2180,7 +2184,8 @@ type AddonCalendarSubmitCreateUpdateFormWSParams = {
/** /**
* Form data on AddonCalendarSubmitCreateUpdateFormWSParams. * Form data on AddonCalendarSubmitCreateUpdateFormWSParams.
*/ */
export type AddonCalendarSubmitCreateUpdateFormDataWSParams = Omit<AddonCalendarOfflineEventDBRecord, 'description'> & { export type AddonCalendarSubmitCreateUpdateFormDataWSParams = Omit<AddonCalendarOfflineEventDBRecord, 'id'|'description'> & {
id?: number;
description?: { description?: {
text: string; text: string;
format: number; format: number;

View File

@ -135,7 +135,7 @@ export const CALENDAR_OFFLINE_SITE_SCHEMA: CoreSiteSchema = {
}; };
export type AddonCalendarOfflineEventDBRecord = { export type AddonCalendarOfflineEventDBRecord = {
id?: number; // Negative for offline entries. id: number; // Negative for offline entries.
name: string; name: string;
timestart: number; timestart: number;
eventtype: AddonCalendarEventType; eventtype: AddonCalendarEventType;

View File

@ -258,7 +258,7 @@ export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = {
}; };
export type AddonCalendarEventDBRecord = { export type AddonCalendarEventDBRecord = {
id?: number; id: number;
name: string; name: string;
description: string; description: string;
eventtype: AddonCalendarEventType; eventtype: AddonCalendarEventType;

View File

@ -147,9 +147,10 @@ export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessage
const syncId = this.getSyncId(conversationId, userId); const syncId = this.getSyncId(conversationId, userId);
if (this.isSyncing(syncId, siteId)) { const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this conversation, return the promise. // There's already a sync ongoing for this conversation, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
return this.addOngoingSync(syncId, this.performSyncDiscussion(conversationId, userId, siteId), siteId); return this.addOngoingSync(syncId, this.performSyncDiscussion(conversationId, userId, siteId), siteId);

View File

@ -163,9 +163,10 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
async syncAssign(assignId: number, siteId?: string): Promise<AddonModAssignSyncResult> { async syncAssign(assignId: number, siteId?: string): Promise<AddonModAssignSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(assignId, siteId)) { const currentSyncPromise = this.getOngoingSync(assignId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this assign, return the promise. // There's already a sync ongoing for this assign, return the promise.
return this.getOngoingSync(assignId, siteId)!; return currentSyncPromise;
} }
// Verify that assign isn't blocked. // Verify that assign isn't blocked.

View File

@ -122,9 +122,10 @@ export class AddonModChoiceSyncProvider extends CoreCourseActivitySyncBaseProvid
siteId = site.getId(); siteId = site.getId();
const syncId = this.getSyncId(choiceId, userId); const syncId = this.getSyncId(choiceId, userId);
if (this.isSyncing(syncId, siteId)) { const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this discussion, return the promise. // There's already a sync ongoing for this discussion, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
this.logger.debug(`Try to sync choice '${choiceId}' for user '${userId}'`); this.logger.debug(`Try to sync choice '${choiceId}' for user '${userId}'`);

View File

@ -135,9 +135,10 @@ export class AddonModDataSyncProvider extends CoreCourseActivitySyncBaseProvider
syncDatabase(dataId: number, siteId?: string): Promise<AddonModDataSyncResult> { syncDatabase(dataId: number, siteId?: string): Promise<AddonModDataSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(dataId, siteId)) { const currentSyncPromise = this.getOngoingSync(dataId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this database, return the promise. // There's already a sync ongoing for this database, return the promise.
return this.getOngoingSync(dataId, siteId)!; return currentSyncPromise;
} }
// Verify that database isn't blocked. // Verify that database isn't blocked.

View File

@ -130,9 +130,10 @@ export class AddonModFeedbackSyncProvider extends CoreCourseActivitySyncBaseProv
syncFeedback(feedbackId: number, siteId?: string): Promise<AddonModFeedbackSyncResult> { syncFeedback(feedbackId: number, siteId?: string): Promise<AddonModFeedbackSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(feedbackId, siteId)) { const currentSyncPromise = this.getOngoingSync(feedbackId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this feedback, return the promise. // There's already a sync ongoing for this feedback, return the promise.
return this.getOngoingSync(feedbackId, siteId)!; return currentSyncPromise;
} }
// Verify that feedback isn't blocked. // Verify that feedback isn't blocked.

View File

@ -198,10 +198,11 @@ export class AddonModForumSyncProvider extends CoreCourseActivitySyncBaseProvide
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const syncId = this.getForumSyncId(forumId, userId); const syncId = this.getForumSyncId(forumId, userId);
const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (this.isSyncing(syncId, siteId)) { if (currentSyncPromise) {
// There's already a sync ongoing for this discussion, return the promise. // There's already a sync ongoing for this discussion, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
// Verify that forum isn't blocked. // Verify that forum isn't blocked.
@ -429,10 +430,11 @@ export class AddonModForumSyncProvider extends CoreCourseActivitySyncBaseProvide
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const syncId = this.getDiscussionSyncId(discussionId, userId); const syncId = this.getDiscussionSyncId(discussionId, userId);
const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (this.isSyncing(syncId, siteId)) { if (currentSyncPromise) {
// There's already a sync ongoing for this discussion, return the promise. // There's already a sync ongoing for this discussion, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
// Verify that forum isn't blocked. // Verify that forum isn't blocked.

View File

@ -144,9 +144,10 @@ export class AddonModGlossarySyncProvider extends CoreCourseActivitySyncBaseProv
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const syncId = this.getGlossarySyncId(glossaryId, userId); const syncId = this.getGlossarySyncId(glossaryId, userId);
if (this.isSyncing(syncId, siteId)) { const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this glossary, return the promise. // There's already a sync ongoing for this glossary, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
// Verify that glossary isn't blocked. // Verify that glossary isn't blocked.

View File

@ -108,9 +108,10 @@ export class AddonModH5PActivitySyncProvider extends CoreCourseActivitySyncBaseP
throw new CoreNetworkError(); throw new CoreNetworkError();
} }
if (this.isSyncing(contextId, siteId)) { const currentSyncPromise = this.getOngoingSync(contextId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this discussion, return the promise. // There's already a sync ongoing for this discussion, return the promise.
return this.getOngoingSync(contextId, siteId)!; return currentSyncPromise;
} }
return this.addOngoingSync(contextId, this.syncActivityData(contextId, siteId), siteId); return this.addOngoingSync(contextId, this.syncActivityData(contextId, siteId), siteId);

View File

@ -263,9 +263,10 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
syncQuiz(quiz: AddonModQuizQuizWSData, askPreflight?: boolean, siteId?: string): Promise<AddonModQuizSyncResult> { syncQuiz(quiz: AddonModQuizQuizWSData, askPreflight?: boolean, siteId?: string): Promise<AddonModQuizSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(quiz.id, siteId)) { const currentSyncPromise = this.getOngoingSync(quiz.id, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this quiz, return the promise. // There's already a sync ongoing for this quiz, return the promise.
return this.getOngoingSync(quiz.id, siteId)!; return currentSyncPromise;
} }
// Verify that quiz isn't blocked. // Verify that quiz isn't blocked.

View File

@ -579,9 +579,10 @@ export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvide
syncScorm(scorm: AddonModScormScorm, siteId?: string): Promise<AddonModScormSyncResult> { syncScorm(scorm: AddonModScormScorm, siteId?: string): Promise<AddonModScormSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(scorm.id, siteId)) { const currentSyncPromise = this.getOngoingSync(scorm.id, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this SCORM, return the promise. // There's already a sync ongoing for this SCORM, return the promise.
return this.getOngoingSync(scorm.id, siteId)!; return currentSyncPromise;
} }
// Verify that SCORM isn't blocked. // Verify that SCORM isn't blocked.

View File

@ -124,10 +124,11 @@ export class AddonModSurveySyncProvider extends CoreCourseActivitySyncBaseProvid
userId = userId || site.getUserId(); userId = userId || site.getUserId();
const syncId = this.getSyncId(surveyId, userId); const syncId = this.getSyncId(surveyId, userId);
const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (this.isSyncing(syncId, siteId)) { if (currentSyncPromise) {
// There's already a sync ongoing for this site, return the promise. // There's already a sync ongoing for this site, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
this.logger.debug(`Try to sync survey '${surveyId}' for user '${userId}'`); this.logger.debug(`Try to sync survey '${surveyId}' for user '${userId}'`);

View File

@ -167,10 +167,11 @@ export class AddonModWikiSyncProvider extends CoreSyncBaseProvider<AddonModWikiS
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const subwikiBlockId = this.getSubwikiBlockId(subwikiId, wikiId, userId, groupId); const subwikiBlockId = this.getSubwikiBlockId(subwikiId, wikiId, userId, groupId);
const currentSyncPromise = this.getOngoingSync(subwikiBlockId, siteId);
if (this.isSyncing(subwikiBlockId, siteId)) { if (currentSyncPromise) {
// There's already a sync ongoing for this subwiki, return the promise. // There's already a sync ongoing for this subwiki, return the promise.
return this.getOngoingSync(subwikiBlockId, siteId)!; return currentSyncPromise;
} }
// Verify that subwiki isn't blocked. // Verify that subwiki isn't blocked.

View File

@ -129,9 +129,10 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider<AddonModW
syncWorkshop(workshopId: number, siteId?: string): Promise<AddonModWorkshopSyncResult> { syncWorkshop(workshopId: number, siteId?: string): Promise<AddonModWorkshopSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(workshopId, siteId)) { const currentSyncPromise = this.getOngoingSync(workshopId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this discussion, return the promise. // There's already a sync ongoing for this discussion, return the promise.
return this.getOngoingSync(workshopId, siteId)!; return currentSyncPromise;
} }
// Verify that workshop isn't blocked. // Verify that workshop isn't blocked.

View File

@ -112,9 +112,10 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider<AddonNotesSyncR
syncNotes(courseId: number, siteId?: string): Promise<AddonNotesSyncResult> { syncNotes(courseId: number, siteId?: string): Promise<AddonNotesSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(courseId, siteId)) { const currentSyncPromise = this.getOngoingSync(courseId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for notes, return the promise. // There's already a sync ongoing for notes, return the promise.
return this.getOngoingSync(courseId, siteId)!; return currentSyncPromise;
} }
this.logger.debug('Try to sync notes for course ' + courseId); this.logger.debug('Try to sync notes for course ' + courseId);

View File

@ -105,7 +105,7 @@ export class CoreSyncBaseProvider<T = void> {
try { try {
return await promise; return await promise;
} finally { } finally {
delete this.syncPromises[siteId!][uniqueId]; delete this.syncPromises[siteId][uniqueId];
} }
} }
@ -133,15 +133,11 @@ export class CoreSyncBaseProvider<T = void> {
*/ */
getOngoingSync(id: string | number, siteId?: string): Promise<T> | undefined { getOngoingSync(id: string | number, siteId?: string): Promise<T> | undefined {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (!this.isSyncing(id, siteId)) {
return;
}
// There's already a sync ongoing for this id, return the promise.
const uniqueId = this.getUniqueSyncId(id); const uniqueId = this.getUniqueSyncId(id);
return this.syncPromises[siteId][uniqueId]; if (this.syncPromises[siteId] && this.syncPromises[siteId][uniqueId] !== undefined) {
return this.syncPromises[siteId][uniqueId];
}
} }
/** /**
@ -223,11 +219,7 @@ export class CoreSyncBaseProvider<T = void> {
* @return Whether it's synchronizing. * @return Whether it's synchronizing.
*/ */
isSyncing(id: string | number, siteId?: string): boolean { isSyncing(id: string | number, siteId?: string): boolean {
siteId = siteId || CoreSites.getCurrentSiteId(); return !!this.getOngoingSync(id, siteId);
const uniqueId = this.getUniqueSyncId(id);
return !!(this.syncPromises[siteId] && this.syncPromises[siteId][uniqueId]);
} }
/** /**
@ -331,10 +323,10 @@ export class CoreSyncBaseProvider<T = void> {
*/ */
protected get componentTranslate(): string { protected get componentTranslate(): string {
if (!this.componentTranslateInternal) { if (!this.componentTranslateInternal) {
this.componentTranslateInternal = Translate.instant(this.componentTranslatableString); this.componentTranslateInternal = <string> Translate.instant(this.componentTranslatableString);
} }
return this.componentTranslateInternal!; return this.componentTranslateInternal;
} }
} }

View File

@ -158,10 +158,11 @@ export class CoreCommentsSyncProvider extends CoreSyncBaseProvider<CoreCommentsS
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const syncId = this.getSyncId(contextLevel, instanceId, component, itemId, area); const syncId = this.getSyncId(contextLevel, instanceId, component, itemId, area);
const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (this.isSyncing(syncId, siteId)) { if (currentSyncPromise) {
// There's already a sync ongoing for comments, return the promise. // There's already a sync ongoing for comments, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
this.logger.debug('Try to sync comments ' + syncId + ' in site ' + siteId); this.logger.debug('Try to sync comments ' + syncId + ' in site ' + siteId);

View File

@ -117,9 +117,10 @@ export class CoreCourseSyncProvider extends CoreSyncBaseProvider<CoreCourseSyncR
async syncCourse(courseId: number, siteId?: string): Promise<CoreCourseSyncResult> { async syncCourse(courseId: number, siteId?: string): Promise<CoreCourseSyncResult> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
if (this.isSyncing(courseId, siteId)) { const currentSyncPromise = this.getOngoingSync(courseId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this discussion, return the promise. // There's already a sync ongoing for this discussion, return the promise.
return this.getOngoingSync(courseId, siteId)!; return currentSyncPromise;
} }
this.logger.debug(`Try to sync course '${courseId}'`); this.logger.debug(`Try to sync course '${courseId}'`);

View File

@ -157,9 +157,10 @@ export class CoreRatingSyncProvider extends CoreSyncBaseProvider<CoreRatingSyncI
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const syncId = this.getItemSetSyncId(component, ratingArea, contextLevel, instanceId, itemSetId); const syncId = this.getItemSetSyncId(component, ratingArea, contextLevel, instanceId, itemSetId);
if (this.isSyncing(syncId, siteId)) { const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (currentSyncPromise) {
// There's already a sync ongoing for this item set, return the promise. // There's already a sync ongoing for this item set, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
this.logger.debug(`Try to sync ratings of component '${component}' rating area '${ratingArea}'` + this.logger.debug(`Try to sync ratings of component '${component}' rating area '${ratingArea}'` +

View File

@ -54,10 +54,11 @@ export class CoreUserSyncProvider extends CoreSyncBaseProvider<string[]> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const syncId = 'preferences'; const syncId = 'preferences';
const currentSyncPromise = this.getOngoingSync(syncId, siteId);
if (this.isSyncing(syncId, siteId)) { if (currentSyncPromise) {
// There's already a sync ongoing, return the promise. // There's already a sync ongoing, return the promise.
return this.getOngoingSync(syncId, siteId)!; return currentSyncPromise;
} }
this.logger.debug('Try to sync user preferences'); this.logger.debug('Try to sync user preferences');