MOBILE-3320 calendar: Fix calendar list page navigation
This commit is contained in:
		
							parent
							
								
									a57297b09a
								
							
						
					
					
						commit
						5a528381b2
					
				| @ -18,7 +18,7 @@ import { Route, RouterModule, ROUTES, Routes } from '@angular/router'; | ||||
| import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module'; | ||||
| 
 | ||||
| export const AddonCalendarEditRoute: Route = { | ||||
|     path: 'edit', | ||||
|     path: 'edit/:eventId', | ||||
|     loadChildren: () => | ||||
|         import('@/addons/calendar/pages/edit-event/edit-event.module').then(m => m.AddonCalendarEditEventPageModule), | ||||
| }; | ||||
|  | ||||
| @ -553,10 +553,9 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { | ||||
|     openEdit(eventId?: number): void { | ||||
|         const params: Params = {}; | ||||
| 
 | ||||
|         if (eventId) { | ||||
|             params.eventId = eventId; | ||||
|         } else { | ||||
|         if (!eventId) { | ||||
|             // It's a new event, set the time.
 | ||||
|             eventId = 0; | ||||
|             params.timestamp = moment().year(this.year).month(this.month - 1).date(this.day).unix() * 1000; | ||||
|         } | ||||
| 
 | ||||
| @ -564,7 +563,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { | ||||
|             params.courseId = this.filter.courseId; | ||||
|         } | ||||
| 
 | ||||
|         CoreNavigator.navigateToSitePath('/calendar/edit', { params }); | ||||
|         CoreNavigator.navigateToSitePath(`/calendar/edit/${eventId}`, { params }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -132,7 +132,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { | ||||
|      * Component being initialized. | ||||
|      */ | ||||
|     ngOnInit(): void { | ||||
|         this.eventId = CoreNavigator.getRouteNumberParam('eventId'); | ||||
|         this.eventId = CoreNavigator.getRouteNumberParam('eventId') || undefined; | ||||
|         this.courseId = CoreNavigator.getRouteNumberParam('courseId') || 0; | ||||
|         this.title = this.eventId ? 'addon.calendar.editevent' : 'addon.calendar.newevent'; | ||||
| 
 | ||||
|  | ||||
| @ -424,7 +424,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { | ||||
|      * Open the page to edit the event. | ||||
|      */ | ||||
|     openEdit(): void { | ||||
|         CoreNavigator.navigateToSitePath('/calendar/edit', { params: { eventId: this.eventId } }); | ||||
|         CoreNavigator.navigateToSitePath(`/calendar/edit/${this.eventId}`); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -351,15 +351,13 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy { | ||||
|      */ | ||||
|     openEdit(eventId?: number): void { | ||||
|         const params: Params = {}; | ||||
|         eventId = eventId || 0; | ||||
| 
 | ||||
|         if (eventId) { | ||||
|             params.eventId = eventId; | ||||
|         } | ||||
|         if (this.filter.courseId) { | ||||
|             params.courseId = this.filter.courseId; | ||||
|         } | ||||
| 
 | ||||
|         CoreNavigator.navigateToSitePath('/calendar/edit', { params }); | ||||
|         CoreNavigator.navigateToSitePath(`/calendar/edit/${eventId}`, { params }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -20,78 +20,76 @@ | ||||
|     </ion-toolbar> | ||||
| </ion-header> | ||||
| <ion-content> | ||||
|     <core-split-view> | ||||
|         <ion-refresher slot="fixed" [disabled]="!eventsLoaded" (ionRefresh)="doRefresh($event.target)"> | ||||
|             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|         </ion-refresher> | ||||
|         <core-loading [hideUntil]="eventsLoaded"> | ||||
|             <!-- There is data to be synchronized --> | ||||
|             <ion-card class="core-warning-card" *ngIf="hasOffline"> | ||||
|                 <ion-item> | ||||
|                     <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> | ||||
|                     <ion-label>{{ 'core.hasdatatosync' | translate:{$a: 'addon.calendar.calendar' | translate} }}</ion-label> | ||||
|     <ion-refresher slot="fixed" [disabled]="!eventsLoaded" (ionRefresh)="doRefresh($event.target)"> | ||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|     </ion-refresher> | ||||
|     <core-loading [hideUntil]="eventsLoaded"> | ||||
|         <!-- There is data to be synchronized --> | ||||
|         <ion-card class="core-warning-card" *ngIf="hasOffline"> | ||||
|             <ion-item> | ||||
|                 <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> | ||||
|                 <ion-label>{{ 'core.hasdatatosync' | translate:{$a: 'addon.calendar.calendar' | translate} }}</ion-label> | ||||
|             </ion-item> | ||||
|         </ion-card> | ||||
| 
 | ||||
|         <core-empty-box *ngIf="!filteredEvents || !filteredEvents.length" icon="fas-calendar" | ||||
|             [message]="'addon.calendar.noevents' | translate"> | ||||
|         </core-empty-box> | ||||
| 
 | ||||
|         <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin"> | ||||
|             <ng-container *ngFor="let event of filteredEvents"> | ||||
|                 <ion-item-divider *ngIf="event.showDate"> | ||||
|                     <ion-label><p class="item-heading">{{ event.timestart * 1000 | coreFormatDate: "strftimedayshort" }}</p></ion-label> | ||||
|                 </ion-item-divider> | ||||
|                 <ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)" | ||||
|                     [attr.aria-current]="event.id == eventId ? 'page' : 'false'" | ||||
|                     [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button detail="true"> | ||||
|                     <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" | ||||
|                         role="presentation"> | ||||
|                     <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" | ||||
|                         aria-hidden="true"> | ||||
|                     </ion-icon> | ||||
|                     <ion-label> | ||||
|                         <p class="item-heading"> | ||||
|                             <!-- Add the icon title so accessibility tools read it. --> | ||||
|                             <span class="sr-only"> | ||||
|                                 {{ 'addon.calendar.type' + event.formattedType | translate }} | ||||
|                                 <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span> | ||||
|                             </span> | ||||
|                             <core-format-text [text]="event.name" [contextLevel]="event.contextLevel" | ||||
|                                 [contextInstanceId]="event.contextInstanceId"> | ||||
|                             </core-format-text> | ||||
|                         </p> | ||||
|                         <p> | ||||
|                             {{ event.timestart * 1000 | coreFormatDate: "strftimetime" }} | ||||
|                             <span *ngIf="event.timeduration && event.endsSameDay"> | ||||
|                                 - {{ (event.timestart + event.timeduration) * 1000 | coreFormatDate: "strftimetime" }} | ||||
|                             </span> | ||||
|                             <span *ngIf="event.timeduration && !event.endsSameDay"> | ||||
|                                 - {{ (event.timestart + event.timeduration) * 1000 | coreFormatDate: "strftimedatetimeshort" }} | ||||
|                             </span> | ||||
|                         </p> | ||||
|                     </ion-label> | ||||
|                     <ion-note *ngIf="event.offline && !event.deleted" slot="end"> | ||||
|                         <ion-icon name="fas-clock" aria-hidden="true"></ion-icon> | ||||
|                         <span class="ion-text-wrap">{{ 'core.notsent' | translate }}</span> | ||||
|                     </ion-note> | ||||
|                     <ion-note *ngIf="event.deleted" slot="end"> | ||||
|                         <ion-icon name="fas-trash" aria-hidden="true"></ion-icon> | ||||
|                         <span class="ion-text-wrap">{{ 'core.deletedoffline' | translate }}</span> | ||||
|                     </ion-note> | ||||
|                 </ion-item> | ||||
|             </ion-card> | ||||
|             </ng-container> | ||||
|         </ion-list> | ||||
| 
 | ||||
|             <core-empty-box *ngIf="!filteredEvents || !filteredEvents.length" icon="fas-calendar" | ||||
|                 [message]="'addon.calendar.noevents' | translate"> | ||||
|             </core-empty-box> | ||||
|         <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreEvents($event)" [error]="loadMoreError"> | ||||
|         </core-infinite-loading> | ||||
|     </core-loading> | ||||
| 
 | ||||
|             <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin"> | ||||
|                 <ng-container *ngFor="let event of filteredEvents"> | ||||
|                     <ion-item-divider *ngIf="event.showDate"> | ||||
|                         <ion-label><p class="item-heading">{{ event.timestart * 1000 | coreFormatDate: "strftimedayshort" }}</p></ion-label> | ||||
|                     </ion-item-divider> | ||||
|                     <ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)" | ||||
|                         [attr.aria-current]="event.id == eventId ? 'page' : 'false'" | ||||
|                         [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button detail="true"> | ||||
|                         <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" | ||||
|                             role="presentation"> | ||||
|                         <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" | ||||
|                             aria-hidden="true"> | ||||
|                         </ion-icon> | ||||
|                         <ion-label> | ||||
|                             <p class="item-heading"> | ||||
|                                 <!-- Add the icon title so accessibility tools read it. --> | ||||
|                                 <span class="sr-only"> | ||||
|                                     {{ 'addon.calendar.type' + event.formattedType | translate }} | ||||
|                                     <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span> | ||||
|                                 </span> | ||||
|                                 <core-format-text [text]="event.name" [contextLevel]="event.contextLevel" | ||||
|                                     [contextInstanceId]="event.contextInstanceId"> | ||||
|                                 </core-format-text> | ||||
|                             </p> | ||||
|                             <p> | ||||
|                                 {{ event.timestart * 1000 | coreFormatDate: "strftimetime" }} | ||||
|                                 <span *ngIf="event.timeduration && event.endsSameDay"> | ||||
|                                      - {{ (event.timestart + event.timeduration) * 1000 | coreFormatDate: "strftimetime" }} | ||||
|                                 </span> | ||||
|                                 <span *ngIf="event.timeduration && !event.endsSameDay"> | ||||
|                                      - {{ (event.timestart + event.timeduration) * 1000 | coreFormatDate: "strftimedatetimeshort" }} | ||||
|                                 </span> | ||||
|                             </p> | ||||
|                         </ion-label> | ||||
|                         <ion-note *ngIf="event.offline && !event.deleted" slot="end"> | ||||
|                             <ion-icon name="fas-clock" aria-hidden="true"></ion-icon> | ||||
|                             <span class="ion-text-wrap">{{ 'core.notsent' | translate }}</span> | ||||
|                         </ion-note> | ||||
|                         <ion-note *ngIf="event.deleted" slot="end"> | ||||
|                             <ion-icon name="fas-trash" aria-hidden="true"></ion-icon> | ||||
|                             <span class="ion-text-wrap">{{ 'core.deletedoffline' | translate }}</span> | ||||
|                         </ion-note> | ||||
|                     </ion-item> | ||||
|                 </ng-container> | ||||
|             </ion-list> | ||||
| 
 | ||||
|             <core-infinite-loading [enabled]="canLoadMore" (action)="loadMoreEvents($event)" [error]="loadMoreError"> | ||||
|             </core-infinite-loading> | ||||
|         </core-loading> | ||||
| 
 | ||||
|         <!-- Create a calendar event. --> | ||||
|         <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canCreate"> | ||||
|             <ion-fab-button (click)="openEdit()" [attr.aria-label]="'addon.calendar.newevent' | translate"> | ||||
|                 <ion-icon name="fas-plus" aria-hidden="true"></ion-icon> | ||||
|             </ion-fab-button> | ||||
|         </ion-fab> | ||||
|     </core-split-view> | ||||
|     <!-- Create a calendar event. --> | ||||
|     <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canCreate"> | ||||
|         <ion-fab-button (click)="openEdit()" [attr.aria-label]="'addon.calendar.newevent' | translate"> | ||||
|             <ion-icon name="fas-plus" aria-hidden="true"></ion-icon> | ||||
|         </ion-fab-button> | ||||
|     </ion-fab> | ||||
| </ion-content> | ||||
|  | ||||
| @ -29,7 +29,6 @@ import { CoreSites } from '@services/sites'; | ||||
| import { CoreLocalNotifications } from '@services/local-notifications'; | ||||
| import { CoreEventObserver, CoreEvents } from '@singletons/events'; | ||||
| import { CoreApp } from '@services/app'; | ||||
| import { CoreSplitViewComponent } from '@components/split-view/split-view'; | ||||
| import moment from 'moment'; | ||||
| import { CoreConstants } from '@/core/constants'; | ||||
| import { AddonCalendarFilterPopoverComponent } from '../../components/filter/filter'; | ||||
| @ -51,7 +50,6 @@ import { CoreNavigator } from '@services/navigator'; | ||||
| export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
| 
 | ||||
|     @ViewChild(IonContent) content?: IonContent; | ||||
|     @ViewChild(CoreSplitViewComponent) splitviewCtrl?: CoreSplitViewComponent; | ||||
| 
 | ||||
|     protected initialTime = 0; | ||||
|     protected daysLoaded = 0; | ||||
| @ -117,26 +115,12 @@ export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
|         this.newEventObserver = CoreEvents.on(AddonCalendarProvider.NEW_EVENT_EVENT, (data) => { | ||||
|             if (data && data.eventId) { | ||||
|                 this.eventsLoaded = false; | ||||
|                 this.refreshEvents(true, false).finally(() => { | ||||
| 
 | ||||
|                     // In tablet mode try to open the event (only if it's an online event).
 | ||||
|                     if (this.splitviewCtrl?.outletActivated && data.eventId > 0) { | ||||
|                         this.gotoEvent(data.eventId); | ||||
|                     } else if (this.splitviewCtrl?.outletActivated) { | ||||
|                         // Discussion added, clear details page.
 | ||||
|                         this.emptySplitView(); | ||||
|                     } | ||||
|                 }); | ||||
|                 this.refreshEvents(true, false); | ||||
|             } | ||||
|         }, this.currentSiteId); | ||||
| 
 | ||||
|         // Listen for new event discarded event. When it does, reload the data.
 | ||||
|         this.discardedObserver = CoreEvents.on(AddonCalendarProvider.NEW_EVENT_DISCARDED_EVENT, () => { | ||||
|             if (this.splitviewCtrl?.outletActivated) { | ||||
|                 // Discussion added, clear details page.
 | ||||
|                 this.emptySplitView(); | ||||
|             } | ||||
| 
 | ||||
|             this.eventsLoaded = false; | ||||
|             this.refreshEvents(true, false); | ||||
|         }, this.currentSiteId); | ||||
| @ -150,15 +134,9 @@ export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
|         }, this.currentSiteId); | ||||
| 
 | ||||
|         // Refresh data if calendar events are synchronized automatically.
 | ||||
|         this.syncObserver = CoreEvents.on(AddonCalendarSyncProvider.AUTO_SYNCED, (data) => { | ||||
|         this.syncObserver = CoreEvents.on(AddonCalendarSyncProvider.AUTO_SYNCED, () => { | ||||
|             this.eventsLoaded = false; | ||||
|             this.refreshEvents(); | ||||
| 
 | ||||
|             if (this.splitviewCtrl?.outletActivated && | ||||
|                 this.eventId && data && data.deleted && data.deleted.indexOf(this.eventId) != -1) { | ||||
|                 // Current selected event was deleted. Clear details.
 | ||||
|                 this.emptySplitView(); | ||||
|             } | ||||
|         }, this.currentSiteId); | ||||
| 
 | ||||
|         // Refresh data if calendar events are synchronized manually but not by this page.
 | ||||
| @ -167,12 +145,6 @@ export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
|                 this.eventsLoaded = false; | ||||
|                 this.refreshEvents(); | ||||
|             } | ||||
| 
 | ||||
|             if (this.splitviewCtrl?.outletActivated && | ||||
|                 this.eventId && data && data.deleted && data.deleted.indexOf(this.eventId) != -1) { | ||||
|                 // Current selected event was deleted. Clear details.
 | ||||
|                 this.emptySplitView(); | ||||
|             } | ||||
|         }, this.currentSiteId); | ||||
| 
 | ||||
|         // Update the list when an event is deleted.
 | ||||
| @ -185,11 +157,7 @@ export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
|                     this.deletedEvents.push(data.eventId); | ||||
|                     this.hasOffline = true; | ||||
|                 } else { | ||||
|                     // Event deleted, clear the details if needed and refresh the view.
 | ||||
|                     if (this.splitviewCtrl?.outletActivated) { | ||||
|                         this.emptySplitView(); | ||||
|                     } | ||||
| 
 | ||||
|                     // Event deleted, refresh the view.
 | ||||
|                     this.eventsLoaded = false; | ||||
|                     this.refreshEvents(); | ||||
|                 } | ||||
| @ -248,27 +216,6 @@ export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
|         this.syncIcon = CoreConstants.ICON_LOADING; | ||||
| 
 | ||||
|         await this.fetchData(false, true, false); | ||||
| 
 | ||||
|         if (!this.eventId && this.splitviewCtrl?.outletActivated && this.events.length > 0) { | ||||
|             // Take first online event and load it. If no online event, load the first offline.
 | ||||
|             if (this.onlineEvents[0]) { | ||||
|                 this.gotoEvent(this.onlineEvents[0].id); | ||||
|             } else { | ||||
|                 this.gotoEvent(this.offlineEvents[0].id); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Convenience function to clear detail view of the split view. | ||||
|      */ | ||||
|     protected emptySplitView(): void { | ||||
|         // Empty details.
 | ||||
|         const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/calendar/list/event') || | ||||
|             CoreNavigator.isCurrentPathInTablet('**/calendar/list/edit'); | ||||
|         if (splitViewLoaded) { | ||||
|             CoreNavigator.navigate('../'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -633,20 +580,15 @@ export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
|      */ | ||||
|     openEdit(eventId?: number): void { | ||||
|         this.eventId = undefined; | ||||
|         eventId = eventId || 0; | ||||
| 
 | ||||
|         const params: Params = {}; | ||||
| 
 | ||||
|         if (eventId) { | ||||
|             params.eventId = eventId; | ||||
|         } | ||||
|         if (this.filter.courseId) { | ||||
|             params.courseId = this.filter.courseId; | ||||
|         } | ||||
| 
 | ||||
|         const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/calendar/list/event') || | ||||
|             CoreNavigator.isCurrentPathInTablet('**/calendar/list/edit'); | ||||
|         const path = (splitViewLoaded ? '../' : '') + 'edit'; | ||||
|         CoreNavigator.navigate(path, { params }); | ||||
|         CoreNavigator.navigateToSitePath(`calendar/edit/${eventId}`, { params }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -664,16 +606,11 @@ export class AddonCalendarListPage implements OnInit, OnDestroy { | ||||
|     gotoEvent(eventId: number): void { | ||||
|         this.eventId = eventId; | ||||
| 
 | ||||
|         if (eventId < 0) { | ||||
|         if (eventId <= 0) { | ||||
|             // It's an offline event, go to the edit page.
 | ||||
|             this.openEdit(eventId); | ||||
|         } else { | ||||
|             const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/calendar/list/event') || | ||||
|                 CoreNavigator.isCurrentPathInTablet('**/calendar/list/edit'); | ||||
|             const path = (splitViewLoaded ? '../' : '') + 'event'; | ||||
|             CoreNavigator.navigate(path, { params: { | ||||
|                 id: eventId, | ||||
|             } }); | ||||
|             CoreNavigator.navigateToSitePath(`/calendar/event/${eventId}`); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -512,7 +512,7 @@ type NewEntryForm = { newEntry: true }; | ||||
| /** | ||||
|  * Type of items that can be held by the entries manager. | ||||
|  */ | ||||
|  type EntryItem = AddonModGlossaryEntry | AddonModGlossaryOfflineEntry | NewEntryForm; | ||||
| type EntryItem = AddonModGlossaryEntry | AddonModGlossaryOfflineEntry | NewEntryForm; | ||||
| 
 | ||||
| /** | ||||
|  * Entries manager. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user