forked from EVOgeek/Vmeda.Online
		
	
						commit
						f2c19b0a6b
					
				| @ -18,7 +18,7 @@ | |||||||
| 
 | 
 | ||||||
|             <ion-list *ngIf="!badges.empty" class="ion-no-margin"> |             <ion-list *ngIf="!badges.empty" class="ion-no-margin"> | ||||||
|                 <ion-item button class="ion-text-wrap" *ngFor="let badge of badges.items" [attr.aria-label]="badge.name" |                 <ion-item button class="ion-text-wrap" *ngFor="let badge of badges.items" [attr.aria-label]="badge.name" | ||||||
|                     (click)="badges.select(badge)" [attr.aria-current]="badges.getItemAriaCurrent(badge)"> |                     (click)="badges.select(badge)" [attr.aria-current]="badges.getItemAriaCurrent(badge)" detail="true"> | ||||||
|                     <ion-avatar slot="start"> |                     <ion-avatar slot="start"> | ||||||
|                         <img [src]="badge.badgeurl" [alt]="badge.name" core-external-content> |                         <img [src]="badge.badgeurl" [alt]="badge.name" core-external-content> | ||||||
|                     </ion-avatar> |                     </ion-avatar> | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ | |||||||
|         <h2>{{ 'addon.block_activitymodules.pluginname' | translate }}</h2> |         <h2>{{ 'addon.block_activitymodules.pluginname' | translate }}</h2> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin"> | ||||||
|     <ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="false" button |     <ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="true" button | ||||||
|         (click)="gotoCoureListModType(entry)"> |         (click)="gotoCoureListModType(entry)"> | ||||||
|         <img slot="start" [src]="entry.icon" alt="" role="presentation" class="core-module-icon"> |         <img slot="start" [src]="entry.icon" alt="" role="presentation" class="core-module-icon"> | ||||||
|         <ion-label>{{ entry.name }}</ion-label> |         <ion-label>{{ entry.name }}</ion-label> | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ | |||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|     </core-context-menu> |     </core-context-menu> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin"> | ||||||
|     <div class="safe-padding-horizontal" [hidden]="showFilter || !showSelectorFilter"> |     <div class="safe-padding-horizontal" [hidden]="showFilter || !showSelectorFilter"> | ||||||
|         <!-- "Time" selector. --> |         <!-- "Time" selector. --> | ||||||
|         <core-combobox [label]="'core.show' | translate" [selection]="selectedFilter" (onChange)="selectedChanged($event)"> |         <core-combobox [label]="'core.show' | translate" [selection]="selectedFilter" (onChange)="selectedChanged($event)"> | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ | |||||||
|         </core-horizontal-scroll-controls> |         </core-horizontal-scroll-controls> | ||||||
|     </div> |     </div> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page margin"> | ||||||
|     <core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true" |     <core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true" | ||||||
|         [message]="'addon.block_recentlyaccessedcourses.nocourses' | translate"></core-empty-box> |         [message]="'addon.block_recentlyaccessedcourses.nocourses' | translate"></core-empty-box> | ||||||
|     <!-- List of courses. --> |     <!-- List of courses. --> | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|         </core-horizontal-scroll-controls> |         </core-horizontal-scroll-controls> | ||||||
|     </div> |     </div> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page margin"> | ||||||
|     <div |     <div | ||||||
|         [id]="scrollElementId" |         [id]="scrollElementId" | ||||||
|         [hidden]="!items || items.length === 0" |         [hidden]="!items || items.length === 0" | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
|         <h2>{{ 'addon.block_sitemainmenu.pluginname' | translate }}</h2> |         <h2>{{ 'addon.block_sitemainmenu.pluginname' | translate }}</h2> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin"> | ||||||
|     <ng-container *ngIf="mainMenuBlock"> |     <ng-container *ngIf="mainMenuBlock"> | ||||||
|         <ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary"> |         <ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary"> | ||||||
|             <ion-label> |             <ion-label> | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ | |||||||
|         </core-horizontal-scroll-controls> |         </core-horizontal-scroll-controls> | ||||||
|     </div> |     </div> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page margin"> | ||||||
|     <core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true" |     <core-empty-box *ngIf="courses.length == 0" image="assets/img/icons/courses.svg" inline="true" | ||||||
|         [message]="'addon.block_starredcourses.nocourses' | translate"></core-empty-box> |         [message]="'addon.block_starredcourses.nocourses' | translate"></core-empty-box> | ||||||
|     <!-- List of courses. --> |     <!-- List of courses. --> | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ | |||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|     </core-context-menu> |     </core-context-menu> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin"> | ||||||
|     <div class="safe-padding-horizontal"> |     <div class="safe-padding-horizontal"> | ||||||
|         <core-combobox [selection]="filter" (onChange)="switchFilter($event)"> |         <core-combobox [selection]="filter" (onChange)="switchFilter($event)"> | ||||||
|             <ion-select-option class="ion-text-wrap" value="all"> |             <ion-select-option class="ion-text-wrap" value="all"> | ||||||
| @ -35,12 +35,12 @@ | |||||||
|             </ion-select-option> |             </ion-select-option> | ||||||
|         </core-combobox> |         </core-combobox> | ||||||
|     </div> |     </div> | ||||||
|     <core-loading [hideUntil]="timeline.loaded" [hidden]="sort != 'sortbydates'" [fullscreen]="false"> |     <core-loading [hideUntil]="timeline.loaded" [hidden]="sort != 'sortbydates'" [fullscreen]="false" class="margin"> | ||||||
|         <addon-block-timeline-events [events]="timeline.events" showCourse="true" [canLoadMore]="timeline.canLoadMore" |         <addon-block-timeline-events [events]="timeline.events" showCourse="true" [canLoadMore]="timeline.canLoadMore" | ||||||
|             (loadMore)="loadMoreTimeline()" [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events> |             (loadMore)="loadMoreTimeline()" [from]="dataFrom" [to]="dataTo"></addon-block-timeline-events> | ||||||
|     </core-loading> |     </core-loading> | ||||||
|     <core-loading [hideUntil]="timelineCourses.loaded" [hidden]="sort != 'sortbycourses'" |     <core-loading [hideUntil]="timelineCourses.loaded" [hidden]="sort != 'sortbycourses'" | ||||||
|         [fullscreen]="false" class="safe-area-page"> |         [fullscreen]="false" class="safe-area-page margin"> | ||||||
|         <ion-grid class="ion-no-padding"> |         <ion-grid class="ion-no-padding"> | ||||||
|             <ion-row class="ion-no-padding"> |             <ion-row class="ion-no-padding"> | ||||||
|                 <ion-col *ngFor="let course of timelineCourses.courses" class="ion-no-padding" size="12" size-md="6"> |                 <ion-col *ngFor="let course of timelineCourses.courses" class="ion-no-padding" size="12" size-md="6"> | ||||||
|  | |||||||
| @ -54,22 +54,18 @@ | |||||||
|                             <core-tag-list [tags]="entry.tags"></core-tag-list> |                             <core-tag-list [tags]="entry.tags"></core-tag-list> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                     <ion-item *ngIf="commentsEnabled" detail="true"> |                     <core-comments *ngIf="commentsEnabled" [component]="this.component" [itemId]="entry.id" area="format_blog" | ||||||
|                         <ion-label> |                         [instanceId]="entry.userid" contextLevel="user" [showItem]="true"> | ||||||
|                             <core-comments [component]="this.component" [itemId]="entry.id" area="format_blog" |  | ||||||
|                                 [instanceId]="entry.userid" contextLevel="user"> |  | ||||||
|                     </core-comments> |                     </core-comments> | ||||||
|                         </ion-label> |  | ||||||
|                     </ion-item> |  | ||||||
|                     <core-file *ngFor="let file of entry.attachmentfiles" [file]="file" [component]="this.component" |                     <core-file *ngFor="let file of entry.attachmentfiles" [file]="file" [component]="this.component" | ||||||
|                         [componentId]="entry.id"> |                         [componentId]="entry.id"> | ||||||
|                     </core-file> |                     </core-file> | ||||||
|                     <ion-item *ngIf="entry.uniquehash" [href]="entry.uniquehash" core-link> |                     <ion-item *ngIf="entry.uniquehash" [href]="entry.uniquehash" core-link detail="true"> | ||||||
|                         <ion-label>{{ 'addon.blog.linktooriginalentry' | translate }}</ion-label> |                         <ion-label>{{ 'addon.blog.linktooriginalentry' | translate }}</ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ion-card-content> |                 </ion-card-content> | ||||||
|                 <ion-row class="ion-text-center"> |                 <ion-row class="ion-text-center" *ngIf="entry.lastmodified > entry.created"> | ||||||
|                     <ion-col *ngIf="entry.lastmodified > entry.created"> |                     <ion-col> | ||||||
|                         <ion-note> |                         <ion-note> | ||||||
|                             <ion-icon name="fas-clock" |                             <ion-icon name="fas-clock" | ||||||
|                                 [attr.aria-label]="'core.lastmodified' | translate"></ion-icon> {{entry.lastmodified | coreTimeAgo}} |                                 [attr.aria-label]="'core.lastmodified' | translate"></ion-icon> {{entry.lastmodified | coreTimeAgo}} | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|     <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin"> |     <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin"> | ||||||
|         <ng-container *ngFor="let event of filteredEvents"> |         <ng-container *ngFor="let event of filteredEvents"> | ||||||
|             <ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button |             <ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button | ||||||
|                 [ngClass]="['addon-calendar-eventtype-'+event.eventtype]"> |                 [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" detail="true"> | ||||||
|                 <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" |                 <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" | ||||||
|                     role="presentation"> |                     role="presentation"> | ||||||
|                 <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true"> |                 <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true"> | ||||||
|  | |||||||
| @ -60,7 +60,7 @@ | |||||||
|         <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin"> |         <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin"> | ||||||
|             <ng-container *ngFor="let event of filteredEvents"> |             <ng-container *ngFor="let event of filteredEvents"> | ||||||
|                 <ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)" |                 <ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)" | ||||||
|                 [class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button> |                 [class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button detail="true"> | ||||||
|                     <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" |                     <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" | ||||||
|                         role="presentation"> |                         role="presentation"> | ||||||
|                     <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true"> |                     <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true"> | ||||||
|  | |||||||
| @ -101,7 +101,7 @@ | |||||||
|             </ng-container> |             </ng-container> | ||||||
| 
 | 
 | ||||||
|             <!-- Advanced options. --> |             <!-- Advanced options. --> | ||||||
|             <ion-item button class="ion-text-wrap core-expandable divider" (click)="toggleAdvanced()"> |             <ion-item button class="ion-text-wrap core-expandable divider" (click)="toggleAdvanced()" detail="false"> | ||||||
|                 <ion-icon *ngIf="!advanced" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon *ngIf="!advanced" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-icon *ngIf="advanced" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon *ngIf="advanced" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
| @ -138,7 +138,7 @@ | |||||||
|                             <ion-radio slot="end" value="0"></ion-radio> |                             <ion-radio slot="end" value="0"></ion-radio> | ||||||
|                             <ion-label>{{ 'addon.calendar.durationnone' | translate }}</ion-label> |                             <ion-label>{{ 'addon.calendar.durationnone' | translate }}</ion-label> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                         <ion-item button (click)="selectDuration('1')"> |                         <ion-item button (click)="selectDuration('1')" detail="false"> | ||||||
|                             <ion-radio slot="end" value="1"></ion-radio> |                             <ion-radio slot="end" value="1"></ion-radio> | ||||||
|                             <ion-label>{{ 'addon.calendar.durationuntil' | translate }}</ion-label> |                             <ion-label>{{ 'addon.calendar.durationuntil' | translate }}</ion-label> | ||||||
|                             <ion-datetime formControlName="timedurationuntil" [max]="maxDate" [min]="minDate" |                             <ion-datetime formControlName="timedurationuntil" [max]="maxDate" [min]="minDate" | ||||||
| @ -146,7 +146,7 @@ | |||||||
|                                 [displayFormat]="dateFormat" [disabled]="form.controls.duration.value != 1"> |                                 [displayFormat]="dateFormat" [disabled]="form.controls.duration.value != 1"> | ||||||
|                             </ion-datetime> |                             </ion-datetime> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                         <ion-item button (click)="selectDuration('2')"> |                         <ion-item button (click)="selectDuration('2')" detail="false"> | ||||||
|                             <ion-radio slot="end" value="2"></ion-radio> |                             <ion-radio slot="end" value="2"></ion-radio> | ||||||
|                             <ion-label>{{ 'addon.calendar.durationminutes' | translate }}</ion-label> |                             <ion-label>{{ 'addon.calendar.durationminutes' | translate }}</ion-label> | ||||||
|                             <ion-input type="number" name="timedurationminutes" slot="end" |                             <ion-input type="number" name="timedurationminutes" slot="end" | ||||||
|  | |||||||
| @ -166,12 +166,13 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy { | |||||||
|     ngOnInit(): void { |     ngOnInit(): void { | ||||||
|         this.notificationsEnabled = CoreLocalNotifications.isAvailable(); |         this.notificationsEnabled = CoreLocalNotifications.isAvailable(); | ||||||
| 
 | 
 | ||||||
|  |         this.loadUpcoming = !!CoreNavigator.getRouteBooleanParam('upcoming'); | ||||||
|  |         this.showCalendar = !this.loadUpcoming; | ||||||
|  | 
 | ||||||
|         this.route.queryParams.subscribe(async () => { |         this.route.queryParams.subscribe(async () => { | ||||||
|             this.filter.courseId = CoreNavigator.getRouteNumberParam('courseId'); |             this.filter.courseId = CoreNavigator.getRouteNumberParam('courseId'); | ||||||
|             this.year = CoreNavigator.getRouteNumberParam('year'); |             this.year = CoreNavigator.getRouteNumberParam('year'); | ||||||
|             this.month = CoreNavigator.getRouteNumberParam('month'); |             this.month = CoreNavigator.getRouteNumberParam('month'); | ||||||
|             this.loadUpcoming = !!CoreNavigator.getRouteBooleanParam('upcoming'); |  | ||||||
|             this.showCalendar = !this.loadUpcoming; |  | ||||||
|             this.filter.filtered = !!this.filter.courseId; |             this.filter.filtered = !!this.filter.courseId; | ||||||
| 
 | 
 | ||||||
|             this.fetchData(true, false); |             this.fetchData(true, false); | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ | |||||||
|                     </ion-item-divider> |                     </ion-item-divider> | ||||||
|                     <ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)" |                     <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'" |                         [attr.aria-current]="event.id == eventId ? 'page' : 'false'" | ||||||
|                         [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button> |                         [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button detail="true"> | ||||||
|                         <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" |                         <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt="" | ||||||
|                             role="presentation"> |                             role="presentation"> | ||||||
|                         <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" |                         <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
|             <ion-list> |             <ion-list> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let competency of competencies.items" |                 <ion-item class="ion-text-wrap" *ngFor="let competency of competencies.items" | ||||||
|                     [attr.aria-label]="competency.competency.shortname" (click)="competencies.select(competency)" |                     [attr.aria-label]="competency.competency.shortname" (click)="competencies.select(competency)" | ||||||
|                     [attr.aria-current]="competencies.getItemAriaCurrent(competency)" button> |                     [attr.aria-current]="competencies.getItemAriaCurrent(competency)" button detail="true"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading">{{ competency.competency.shortname }} <em>{{competency.competency.idnumber}}</em></p> |                         <p class="item-heading">{{ competency.competency.shortname }} <em>{{competency.competency.idnumber}}</em></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|  | |||||||
| @ -28,47 +28,50 @@ | |||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap only-links"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <strong>{{ 'addon.competency.path' | translate }}</strong> |                     <p class="item-heading">{{ 'addon.competency.path' | translate }}</p> | ||||||
|  |                     <p> | ||||||
|                         <a *ngIf="competency.competency.comppath.showlinks" |                         <a *ngIf="competency.competency.comppath.showlinks" | ||||||
|                             [href]="competency.competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + |                             [href]="competency.competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + | ||||||
|                             competency.competency.comppath.framework.id + '&pagecontextid=' + |                             competency.competency.comppath.framework.id + '&pagecontextid=' + | ||||||
|                             competency.competency.comppath.pagecontextid" |                             competency.competency.comppath.pagecontextid" | ||||||
|                         core-link [title]="competency.competency.comppath.framework.name"> |                             core-link> | ||||||
|                             {{ competency.competency.comppath.framework.name }} |                             {{ competency.competency.comppath.framework.name }} | ||||||
|                         </a> |                         </a> | ||||||
|                         <ng-container *ngIf="!competency.competency.comppath.showlinks"> |                         <ng-container *ngIf="!competency.competency.comppath.showlinks"> | ||||||
|                             {{ competency.competency.comppath.framework.name }} |                             {{ competency.competency.comppath.framework.name }} | ||||||
|                         </ng-container> |                         </ng-container> | ||||||
|                          /  |                          /  | ||||||
|                     <span *ngFor="let ancestor of competency.competency.comppath.ancestors"> |                         <ng-container *ngFor="let ancestor of competency.competency.comppath.ancestors"> | ||||||
|                         <a *ngIf="competency.competency.comppath.showlinks" (click)="openCompetencySummary(ancestor.id)"> |                             <button *ngIf="competency.competency.comppath.showlinks" (click)="openCompetencySummary(ancestor.id)" | ||||||
|  |                                 class="as-link"> | ||||||
|                                 {{ ancestor.name }} |                                 {{ ancestor.name }} | ||||||
|                         </a> |                             </button> | ||||||
|                             <ng-container *ngIf="!competency.competency.comppath.showlinks">{{ ancestor.name }}</ng-container> |                             <ng-container *ngIf="!competency.competency.comppath.showlinks">{{ ancestor.name }}</ng-container> | ||||||
|                             <ng-container *ngIf="!ancestor.last"> / </ng-container> |                             <ng-container *ngIf="!ancestor.last"> / </ng-container> | ||||||
|                     </span> |                         </ng-container> | ||||||
|  |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <strong>{{ 'addon.competency.crossreferencedcompetencies' | translate }}</strong>: |                     <p class="item-heading">{{ 'addon.competency.crossreferencedcompetencies' | translate }}</p> | ||||||
|                     <div *ngIf="!competency.competency.hasrelatedcompetencies"> |                     <p *ngIf="!competency.competency.hasrelatedcompetencies"> | ||||||
|                         {{ 'addon.competency.nocrossreferencedcompetencies' | translate }} |                         {{ 'addon.competency.nocrossreferencedcompetencies' | translate }} | ||||||
|                     </div> |  | ||||||
|                     <div *ngIf="competency.competency.hasrelatedcompetencies"> |  | ||||||
|                         <p *ngFor="let relatedcomp of competency.competency.relatedcompetencies"> |  | ||||||
|                             <a (click)="openCompetencySummary(relatedcomp.id)"> |  | ||||||
|                                 {{ relatedcomp.shortname }} - {{ relatedcomp.idnumber }} |  | ||||||
|                             </a> |  | ||||||
|                     </p> |                     </p> | ||||||
|                     </div> |                     <ng-container *ngIf="competency.competency.hasrelatedcompetencies"> | ||||||
|  |                         <p *ngFor="let relatedcomp of competency.competency.relatedcompetencies"> | ||||||
|  |                             <button (click)="openCompetencySummary(relatedcomp.id)" class="as-link"> | ||||||
|  |                                 {{ relatedcomp.shortname }} - {{ relatedcomp.idnumber }} | ||||||
|  |                             </button> | ||||||
|  |                         </p> | ||||||
|  |                     </ng-container> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="coursemodules"> |             <ion-item class="ion-text-wrap" *ngIf="coursemodules"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <strong>{{ 'addon.competency.activities' | translate }}</strong> |                     <p class="item-heading">{{ 'addon.competency.activities' | translate }}</p> | ||||||
|                     <p *ngIf="coursemodules.length == 0"> |                     <p *ngIf="coursemodules.length == 0"> | ||||||
|                         {{ 'addon.competency.noactivities' | translate }} |                         {{ 'addon.competency.noactivities' | translate }} | ||||||
|                     </p> |                     </p> | ||||||
| @ -87,13 +90,13 @@ | |||||||
|             <ng-container *ngIf="userCompetency"> |             <ng-container *ngIf="userCompetency"> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="competency.usercompetency && competency.usercompetency!.status"> |                 <ion-item class="ion-text-wrap" *ngIf="competency.usercompetency && competency.usercompetency!.status"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <strong>{{ 'addon.competency.reviewstatus' | translate }}</strong> |                         <p class="item-heading">{{ 'addon.competency.reviewstatus' | translate }}</p> | ||||||
|                         {{ competency.usercompetency!.statusname }} |                         <p>{{ competency.usercompetency!.statusname }}</p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap"> |                 <ion-item class="ion-text-wrap"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <strong>{{ 'addon.competency.proficient' | translate }}</strong> |                         <p class="item-heading">{{ 'addon.competency.proficient' | translate }}</p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                     <ion-badge slot="end" color="success" *ngIf="userCompetency.proficiency"> |                     <ion-badge slot="end" color="success" *ngIf="userCompetency.proficiency"> | ||||||
|                         {{ 'core.yes' | translate }} |                         {{ 'core.yes' | translate }} | ||||||
| @ -104,7 +107,7 @@ | |||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap"> |                 <ion-item class="ion-text-wrap"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <strong>{{ 'addon.competency.rating' | translate }}</strong> |                         <p class="item-heading">{{ 'addon.competency.rating' | translate }}</p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                     <ion-badge color="dark" slot="end">{{ userCompetency.gradename }}</ion-badge> |                     <ion-badge color="dark" slot="end">{{ userCompetency.gradename }}</ion-badge> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|  | |||||||
| @ -23,11 +23,15 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <strong>{{ 'addon.competency.path' | translate }}</strong> |                     <p class="item-heading">{{ 'addon.competency.path' | translate }}</p> | ||||||
|                     {{ competency.comppath.framework.name }} |                     <p>{{ competency.comppath.framework.name }} | ||||||
|                     <span *ngFor="let ancestor of competency.comppath.ancestors"> |                         <ng-container *ngFor="let ancestor of competency.comppath.ancestors"> | ||||||
|                          / <a (click)="openCompetencySummary(ancestor.id)">{{ ancestor.name }}</a> |                              /  | ||||||
|                     </span> |                             <button class="as-link" (click)="openCompetencySummary(ancestor.id)"> | ||||||
|  |                                 {{ ancestor.name }} | ||||||
|  |                             </button> | ||||||
|  |                         </ng-container> | ||||||
|  |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
|  | |||||||
| @ -34,11 +34,11 @@ | |||||||
|             <ion-item class="ion-text-wrap" |             <ion-item class="ion-text-wrap" | ||||||
|                 *ngIf="competencies.statistics.canmanagecoursecompetencies && competencies.statistics.leastproficientcount > 0"> |                 *ngIf="competencies.statistics.canmanagecoursecompetencies && competencies.statistics.leastproficientcount > 0"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <strong>{{ 'addon.competency.competenciesmostoftennotproficientincourse' | translate }}</strong>: |                     <p class="item-heading">{{ 'addon.competency.competenciesmostoftennotproficientincourse' | translate }}</p> | ||||||
|                     <p *ngFor="let comp of competencies.statistics.leastproficient"> |                     <p *ngFor="let comp of competencies.statistics.leastproficient"> | ||||||
|                         <a (click)="openCompetencySummary(comp.id)"> |                         <button class="as-link" (click)="openCompetencySummary(comp.id)"> | ||||||
|                             {{ comp.shortname }} - {{ comp.idnumber }} |                             {{ comp.shortname }} - {{ comp.idnumber }} | ||||||
|                         </a> |                         </button> | ||||||
|                     </p> |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| @ -63,7 +63,7 @@ | |||||||
|                     [attr.aria-label]="competency.competency.shortname" detail="true" button> |                     [attr.aria-label]="competency.competency.shortname" detail="true" button> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading"> |                         <p class="item-heading"> | ||||||
|                             <strong>{{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em></strong> |                             {{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em> | ||||||
|                         </p> |                         </p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                     <ion-badge slot="end" *ngIf="competency.usercompetencycourse && competency.usercompetencycourse.gradename" |                     <ion-badge slot="end" *ngIf="competency.usercompetencycourse && competency.usercompetencycourse.gradename" | ||||||
| @ -79,7 +79,8 @@ | |||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </p> |                         </p> | ||||||
|                         <div> |                         <div> | ||||||
|                             <strong>{{ 'addon.competency.path' | translate }}</strong> |                             <p class="item-heading">{{ 'addon.competency.path' | translate }}</p> | ||||||
|  |                             <p> | ||||||
|                                 <a *ngIf="competency.comppath.showlinks" |                                 <a *ngIf="competency.comppath.showlinks" | ||||||
|                                     [href]="competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + |                                     [href]="competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + | ||||||
|                                     competency.comppath.framework.id + '&pagecontextid=' + competency.comppath.pagecontextid" |                                     competency.comppath.framework.id + '&pagecontextid=' + competency.comppath.pagecontextid" | ||||||
| @ -90,22 +91,24 @@ | |||||||
|                                     {{ competency.comppath.framework.name }} |                                     {{ competency.comppath.framework.name }} | ||||||
|                                 </ng-container> |                                 </ng-container> | ||||||
|                                  /  |                                  /  | ||||||
|                             <span *ngFor="let ancestor of competency.comppath.ancestors"> |                                 <ng-container *ngFor="let ancestor of competency.comppath.ancestors"> | ||||||
|                                 <a *ngIf="competency.comppath.showlinks" (click)="openCompetencySummary(ancestor.id)"> |                                     <button class="as-link" *ngIf="competency.comppath.showlinks" | ||||||
|  |                                         (click)="openCompetencySummary(ancestor.id)"> | ||||||
|                                         {{ ancestor.name }} |                                         {{ ancestor.name }} | ||||||
|                                 </a> |                                     </button> | ||||||
|                                     <ng-container *ngIf="!competency.comppath.showlinks">{{ ancestor.name }}</ng-container> |                                     <ng-container *ngIf="!competency.comppath.showlinks">{{ ancestor.name }}</ng-container> | ||||||
|                                     <ng-container *ngIf="!ancestor.last"> / </ng-container> |                                     <ng-container *ngIf="!ancestor.last"> / </ng-container> | ||||||
|                             </span> |                                 </ng-container> | ||||||
|  |                             </p> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div *ngIf="competencies.statistics.canmanagecoursecompetencies"> |                         <div *ngIf="competencies.statistics.canmanagecoursecompetencies"> | ||||||
|                             <strong>{{ 'addon.competency.uponcoursecompletion' | translate }}</strong> |                             <p class="item-heading">{{ 'addon.competency.uponcoursecompletion' | translate }}</p> | ||||||
|                              <ng-container *ngFor="let ruleoutcome of competency.ruleoutcomeoptions"> |                              <ng-container *ngFor="let ruleoutcome of competency.ruleoutcomeoptions"> | ||||||
|                                 <span *ngIf="ruleoutcome.selected">{{ ruleoutcome.text }}</span> |                                 <span *ngIf="ruleoutcome.selected">{{ ruleoutcome.text }}</span> | ||||||
|                             </ng-container> |                             </ng-container> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div> |                         <div> | ||||||
|                             <strong>{{ 'addon.competency.activities' | translate }}</strong> |                             <p class="item-heading">{{ 'addon.competency.activities' | translate }}</p> | ||||||
|                             <p *ngIf="competency.coursemodules.length == 0"> |                             <p *ngIf="competency.coursemodules.length == 0"> | ||||||
|                                 {{ 'addon.competency.noactivities' | translate }} |                                 {{ 'addon.competency.noactivities' | translate }} | ||||||
|                             </p> |                             </p> | ||||||
| @ -121,7 +124,7 @@ | |||||||
|                             </ion-item> |                             </ion-item> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div *ngIf="competency.plans"> |                         <div *ngIf="competency.plans"> | ||||||
|                             <strong>{{ 'addon.competency.userplans' | translate }}</strong> |                             <p class="item-heading">{{ 'addon.competency.userplans' | translate }}</p> | ||||||
|                             <p *ngIf="competency.plans.length == 0"> |                             <p *ngIf="competency.plans.length == 0"> | ||||||
|                                 {{ 'addon.competency.nouserplanswithcompetency' | translate }} |                                 {{ 'addon.competency.nouserplanswithcompetency' | translate }} | ||||||
|                             </p> |                             </p> | ||||||
|  | |||||||
| @ -23,37 +23,35 @@ | |||||||
|             <ion-list> |             <ion-list> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.description" lines="none"> |                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.description" lines="none"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|  |                         <p> | ||||||
|                             <core-format-text [text]="plan.plan.description" contextLevel="user" |                             <core-format-text [text]="plan.plan.description" contextLevel="user" | ||||||
|                                 [contextInstanceId]="plan.plan.userid"> |                                 [contextInstanceId]="plan.plan.userid"> | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|  |                         </p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" lines="none"> |                 <ion-item class="ion-text-wrap" lines="none"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p> |                         <p class="item-heading">{{ 'addon.competency.status' | translate }}</p> | ||||||
|                             <strong>{{ 'addon.competency.status' | translate }}</strong>: {{ plan.plan.statusname }} |                         <p>{{ plan.plan.statusname }}</p> | ||||||
|                         </p> |  | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.duedate > 0" lines="none"> |                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.duedate > 0" lines="none"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p> |                         <p class="item-heading">{{ 'addon.competency.duedate' | translate }}</p> | ||||||
|                             <strong>{{ 'addon.competency.duedate' | translate }}</strong>: |                         <p>{{ plan.plan.duedate * 1000 | coreFormatDate }}</p> | ||||||
|                             {{ plan.plan.duedate * 1000 | coreFormatDate }} |  | ||||||
|                         </p> |  | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.template" lines="none"> |                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.template" lines="none"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p> |                         <p class="item-heading">{{ 'addon.competency.template' | translate }}</p> | ||||||
|                             <strong>{{ 'addon.competency.template' | translate }}</strong>: {{ plan.plan.template.shortname }} |                         <p>{{ plan.plan.template.shortname }}</p> | ||||||
|                         </p> |  | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" lines="none"> |                 <ion-item class="ion-text-wrap" lines="none"> | ||||||
|                     <ion-label> |                     <ion-label id="addon-competency-plan-{{plan.plan.id}}-progress"> | ||||||
|                         <p id="addon-competency-plan-{{plan.plan.id}}-progress"> |                         <p class="item-heading">{{ 'addon.competency.progress' | translate }}</p> | ||||||
|                             <strong>{{ 'addon.competency.progress' | translate }}</strong>: |                         <p> | ||||||
|                             {{ 'addon.competency.xcompetenciesproficientoutofy' | translate: |                             {{ 'addon.competency.xcompetenciesproficientoutofy' | translate: | ||||||
|                                 {$a: {x: plan.proficientcompetencycount, y: plan.competencycount} } }} |                                 {$a: {x: plan.proficientcompetencycount, y: plan.competencycount} } }} | ||||||
|                         </p> |                         </p> | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ | |||||||
|             </core-empty-box> |             </core-empty-box> | ||||||
|             <ion-list *ngIf="!plans.empty" class="ion-no-margin"> |             <ion-list *ngIf="!plans.empty" class="ion-no-margin"> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [attr.aria-label]="plan.name" |                 <ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [attr.aria-label]="plan.name" | ||||||
|                     (click)="plans.select(plan)" [attr.aria-current]="plans.getItemAriaCurrent(plan)" button> |                     (click)="plans.select(plan)" [attr.aria-current]="plans.getItemAriaCurrent(plan)" button detail="true"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading">{{ plan.name }}</p> |                         <p class="item-heading">{{ plan.name }}</p> | ||||||
|                         <p *ngIf="plan.duedate > 0"> |                         <p *ngIf="plan.duedate > 0"> | ||||||
|  | |||||||
| @ -8,10 +8,9 @@ | |||||||
|                 alt="" onError="this.src='assets/img/group-avatar.png'" core-external-content role="presentation" |                 alt="" onError="this.src='assets/img/group-avatar.png'" core-external-content role="presentation" | ||||||
|                 [siteId]="siteId || null"> |                 [siteId]="siteId || null"> | ||||||
|             <core-user-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" [user]="otherMember" |             <core-user-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" [user]="otherMember" | ||||||
|                 [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus" (click)="showInfo && viewInfo()"> |                 [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus"> | ||||||
|             </core-user-avatar> |             </core-user-avatar> | ||||||
|             <core-format-text [text]="title" contextLevel="system" [contextInstanceId]="0" |             <core-format-text [text]="title" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|                 (click)="showInfo && !isGroup && viewInfo()"></core-format-text> |  | ||||||
|             <ion-icon *ngIf="conversation && conversation.isfavourite" name="fas-star" |             <ion-icon *ngIf="conversation && conversation.isfavourite" name="fas-star" | ||||||
|                 [attr.aria-label]="'core.favourites' | translate"> |                 [attr.aria-label]="'core.favourites' | translate"> | ||||||
|             </ion-icon> |             </ion-icon> | ||||||
| @ -93,12 +92,16 @@ | |||||||
|                     [@coreSlideInOut]="message.useridfrom == currentUserId ? '' : 'fromLeft'"> |                     [@coreSlideInOut]="message.useridfrom == currentUserId ? '' : 'fromLeft'"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <!-- User data. --> |                         <!-- User data. --> | ||||||
|                         <div class="item-heading addon-message-user" [attr.aria-label]="message.useridfrom == currentUserId ? |                         <div *ngIf="message.showUserData" class="item-heading addon-message-user"> | ||||||
|                             ('addon.messages.you' | translate) : members[message.useridfrom].fullname"> |  | ||||||
|                             <core-user-avatar slot="start" [user]="members[message.useridfrom]" [linkProfile]="false" |                             <core-user-avatar slot="start" [user]="members[message.useridfrom]" [linkProfile]="false" | ||||||
|                                 *ngIf="message.showUserData"></core-user-avatar> |                                 aria-hidden="true"> | ||||||
| 
 |                             </core-user-avatar> | ||||||
|                             <div *ngIf="message.showUserData">{{ members[message.useridfrom].fullname }}</div> |                             {{ members[message.useridfrom].fullname }} | ||||||
|  |                         </div> | ||||||
|  |                         <div *ngIf="!message.showUserData" class="sr-only"> | ||||||
|  |                             {{ message.useridfrom == currentUserId | ||||||
|  |                             ? ('addon.messages.you' | translate) | ||||||
|  |                             : members[message.useridfrom].fullname }} | ||||||
|                         </div> |                         </div> | ||||||
| 
 | 
 | ||||||
|                         <!-- Some messages have <p> and some others don't. Add a <p> so they all have same styles. --> |                         <!-- Some messages have <p> and some others don't. Add a <p> so they all have same styles. --> | ||||||
|  | |||||||
| @ -250,6 +250,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView | |||||||
|                     this.title = user.fullname; |                     this.title = user.fullname; | ||||||
|                 } |                 } | ||||||
|                 this.conversationImage = user.profileimageurl; |                 this.conversationImage = user.profileimageurl; | ||||||
|  |                 this.members[user.id] = <AddonMessagesConversationMember>user; | ||||||
| 
 | 
 | ||||||
|                 return; |                 return; | ||||||
|             }).catch(() => { |             }).catch(() => { | ||||||
| @ -1302,7 +1303,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView | |||||||
|     async viewInfo(): Promise<void> { |     async viewInfo(): Promise<void> { | ||||||
|         if (this.isGroup) { |         if (this.isGroup) { | ||||||
|             // Display the group information.
 |             // Display the group information.
 | ||||||
|             const userId = await CoreDomUtils.openModal<number>({ |             const userId = await CoreDomUtils.openSideModal<number>({ | ||||||
|                 component: AddonMessagesConversationInfoComponent, |                 component: AddonMessagesConversationInfoComponent, | ||||||
|                 componentProps: { |                 componentProps: { | ||||||
|                     conversationId: this.conversationId, |                     conversationId: this.conversationId, | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ | |||||||
| 
 | 
 | ||||||
|         <core-search-box *ngIf="search.enabled" (onSubmit)="searchMessage($event)" (onClear)="clearSearch()" |         <core-search-box *ngIf="search.enabled" (onSubmit)="searchMessage($event)" (onClear)="clearSearch()" | ||||||
|             [placeholder]=" 'addon.messages.message' | translate" autocorrect="off" spellcheck="false" lengthCheck="2" |             [placeholder]=" 'addon.messages.message' | translate" autocorrect="off" spellcheck="false" lengthCheck="2" | ||||||
|             [disabled]="!loaded" searchArea="AddonMessagesDiscussions"></core-search-box> |             [disabled]="!loaded" searchArea="AddonMessagesDiscussions" [autoFocus]="false"></core-search-box> | ||||||
| 
 | 
 | ||||||
|         <core-loading [hideUntil]="loaded" [message]="loadingMessage"> |         <core-loading [hideUntil]="loaded" [message]="loadingMessage"> | ||||||
| 
 | 
 | ||||||
| @ -40,7 +40,7 @@ | |||||||
|                     </ion-item-divider> |                     </ion-item-divider> | ||||||
|                     <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button |                     <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button | ||||||
|                         [attr.aria-label]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" |                         [attr.aria-label]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" | ||||||
|                         [attr.aria-current]="result.userid == discussionUserId ? 'page' : 'false'"> |                         [attr.aria-current]="result.userid == discussionUserId ? 'page' : 'false'" detail="false"> | ||||||
|                         <core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar> |                         <core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <p class="item-heading">{{ result.fullname }}</p> |                             <p class="item-heading">{{ result.fullname }}</p> | ||||||
|  | |||||||
| @ -40,7 +40,8 @@ | |||||||
|         <ion-item class="ion-text-wrap"> |         <ion-item class="ion-text-wrap"> | ||||||
|             <ion-label> |             <ion-label> | ||||||
|                 <core-format-text [text]="description" [component]="component" [componentId]="componentId" maxHeight="120" |                 <core-format-text [text]="description" [component]="component" [componentId]="componentId" maxHeight="120" | ||||||
|                     contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId" (click)="expandDescription($event)"> |                     contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId" | ||||||
|  |                     (onClick)="expandDescription($event)"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </ion-label> |             </ion-label> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false"> | <core-loading [hideUntil]="loaded" class="margin"> | ||||||
| 
 | 
 | ||||||
|     <!-- User and status of the submission. --> |     <!-- User and status of the submission. --> | ||||||
|     <ion-item class="ion-text-wrap" *ngIf="!blindMarking && user" core-user-link [userId]="submitId" [courseId]="courseId" |     <ion-item class="ion-text-wrap" *ngIf="!blindMarking && user" core-user-link [userId]="submitId" [courseId]="courseId" | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ | |||||||
|                 <!-- List of submissions. --> |                 <!-- List of submissions. --> | ||||||
|                 <ng-container *ngFor="let submission of submissions.items"> |                 <ng-container *ngFor="let submission of submissions.items"> | ||||||
|                     <ion-item class="ion-text-wrap" (click)="submissions.select(submission)" button |                     <ion-item class="ion-text-wrap" (click)="submissions.select(submission)" button | ||||||
|                         [attr.aria-current]="submissions.getItemAriaCurrent(submission)"> |                         [attr.aria-current]="submissions.getItemAriaCurrent(submission)" detail="true"> | ||||||
|                         <core-user-avatar [user]="submission" [linkProfile]="false" slot="start"></core-user-avatar> |                         <core-user-avatar [user]="submission" [linkProfile]="false" slot="start"></core-user-avatar> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <p class="item-heading" *ngIf="submission.userfullname">{{submission.userfullname}}</p> |                             <p class="item-heading" *ngIf="submission.userfullname">{{submission.userfullname}}</p> | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| <ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="false" button> | <ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="true" button> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{plugin.name}}</h2> |         <h2>{{plugin.name}}</h2> | ||||||
|         <core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments" |         <core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments" | ||||||
|  | |||||||
| @ -13,11 +13,11 @@ | |||||||
|         <ion-list> |         <ion-list> | ||||||
|             <ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)" |             <ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)" | ||||||
|                 [attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button |                 [attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button | ||||||
|                 [class.item-dimmed]="chapter.hidden"> |                 [class.item-dimmed]="chapter.hidden" detail="false"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <p [class.ion-padding-left]="addPadding && chapter.level == 1 ? true : null"> |                     <p [class.ion-padding-left]="addPadding && chapter.level == 1 ? true : null" class="item-heading"> | ||||||
|                         <span *ngIf="showNumbers" class="addon-mod-book-number">{{chapter.indexNumber}}</span> |                         <span *ngIf="showNumbers" class="addon-mod-book-number">{{chapter.indexNumber}} </span> | ||||||
|                         <span *ngIf="showBullets" class="addon-mod-book-bullet">•</span> |                         <span *ngIf="showBullets" class="addon-mod-book-bullet">• </span> | ||||||
|                         <core-format-text [text]="chapter.title" contextLevel="module" [contextInstanceId]="moduleId" |                         <core-format-text [text]="chapter.title" contextLevel="module" [contextInstanceId]="moduleId" | ||||||
|                             [courseId]="courseId"> |                             [courseId]="courseId"> | ||||||
|                         </core-format-text> |                         </core-format-text> | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ | |||||||
|                 <ion-toggle [(ngModel)]="showAll" (ionChange)="fetchSessions(true)"></ion-toggle> |                 <ion-toggle [(ngModel)]="showAll" (ionChange)="fetchSessions(true)"></ion-toggle> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <ion-card *ngFor="let session of sessions.items" (click)="sessions.select(session)" |             <ion-card *ngFor="let session of sessions.items" (click)="sessions.select(session)" button | ||||||
|                 [attr.aria-current]="sessions.getItemAriaCurrent(session)" |                 [attr.aria-current]="sessions.getItemAriaCurrent(session)" | ||||||
|                 [class.addon-mod-chat-session-show-more]="session.sessionusers.length < session.allsessionusers.length"> |                 [class.addon-mod-chat-session-show-more]="session.sessionusers.length < session.allsessionusers.length"> | ||||||
| 
 | 
 | ||||||
| @ -47,11 +47,10 @@ | |||||||
|                         </ion-label> |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ion-card-content> |                 </ion-card-content> | ||||||
|                 <div *ngIf="session.sessionusers.length < session.allsessionusers.length"> |                 <ion-button *ngIf="session.sessionusers.length < session.allsessionusers.length" fill="clear" expand="block" | ||||||
|                     <ion-button fill="clear" (click)="showMoreUsers(session, $event)"> |                     (click)="showMoreUsers(session, $event)"> | ||||||
|                     {{ 'core.showmore' | translate }} |                     {{ 'core.showmore' | translate }} | ||||||
|                 </ion-button> |                 </ion-button> | ||||||
|                 </div> |  | ||||||
|             </ion-card> |             </ion-card> | ||||||
| 
 | 
 | ||||||
|             <core-empty-box *ngIf="sessions.empty" icon="far-comments" [message]="'addon.mod_chat.nosessionsfound' | translate"> |             <core-empty-box *ngIf="sessions.empty" icon="far-comments" [message]="'addon.mod_chat.nosessionsfound' | translate"> | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| <core-dynamic-component [component]="fieldComponent" [data]="pluginData"> | <core-dynamic-component [component]="fieldComponent" [data]="pluginData"> | ||||||
|     <!-- This content will be replaced by the component if found. --> |     <!-- This content will be replaced by the component if found. --> | ||||||
|     <core-loading [hideUntil]="fieldLoaded"> |     <core-loading [hideUntil]="fieldLoaded" [fullscreen]="false"></core-loading> | ||||||
|     </core-loading> |  | ||||||
| </core-dynamic-component> | </core-dynamic-component> | ||||||
|  | |||||||
| @ -103,16 +103,18 @@ | |||||||
| 
 | 
 | ||||||
|     <!-- Reset search. --> |     <!-- Reset search. --> | ||||||
|     <ng-container *ngIf="search.searching && !isEmpty"> |     <ng-container *ngIf="search.searching && !isEmpty"> | ||||||
|         <ion-item *ngIf="!foundRecordsTranslationData"> |         <ion-item (click)="searchReset()" button detail="false"> | ||||||
|             <ion-label> |             <ion-label color="primary"> | ||||||
|                 <a (click)="searchReset()">{{ 'addon.mod_data.resetsettings' | translate}}</a> |                 {{ 'addon.mod_data.resetsettings' | translate}} | ||||||
|             </ion-label> |             </ion-label> | ||||||
|         </ion-item> |         </ion-item> | ||||||
| 
 | 
 | ||||||
|         <ion-card class="core-success-card" *ngIf="foundRecordsTranslationData" (click)="searchReset()"> |         <ion-card class="core-success-card" *ngIf="foundRecordsTranslationData"> | ||||||
|             <ion-item><ion-label> |             <ion-item (click)="searchReset()" button detail="false"> | ||||||
|  |                 <ion-label> | ||||||
|                     <p [innerHTML]="'addon.mod_data.foundrecords' | translate:{$a: foundRecordsTranslationData}"></p> |                     <p [innerHTML]="'addon.mod_data.foundrecords' | translate:{$a: foundRecordsTranslationData}"></p> | ||||||
|             </ion-label></ion-item> |                 </ion-label> | ||||||
|  |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
|     </ng-container> |     </ng-container> | ||||||
| 
 | 
 | ||||||
| @ -144,7 +146,7 @@ | |||||||
| 
 | 
 | ||||||
|     <core-empty-box *ngIf="isEmpty && search.searching" icon="fas-database" [message]="'addon.mod_data.nomatch' | translate" |     <core-empty-box *ngIf="isEmpty && search.searching" icon="fas-database" [message]="'addon.mod_data.nomatch' | translate" | ||||||
|         class="core-empty-box-clickable"> |         class="core-empty-box-clickable"> | ||||||
|         <a (click)="searchReset()">{{ 'addon.mod_data.resetsettings' | translate}}</a> |         <button class="as-link" (click)="searchReset()">{{ 'addon.mod_data.resetsettings' | translate}}</button> | ||||||
|     </core-empty-box> |     </core-empty-box> | ||||||
| 
 | 
 | ||||||
| </core-loading> | </core-loading> | ||||||
|  | |||||||
| @ -48,6 +48,8 @@ import { AddonModDataPrefetchHandler } from '../../services/handlers/prefetch'; | |||||||
| import { AddonModDataComponentsCompileModule } from '../components-compile.module'; | import { AddonModDataComponentsCompileModule } from '../components-compile.module'; | ||||||
| import { AddonModDataSearchComponent } from '../search/search'; | import { AddonModDataSearchComponent } from '../search/search'; | ||||||
| 
 | 
 | ||||||
|  | const contentToken = '<!-- CORE-DATABASE-CONTENT-GOES-HERE -->'; | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Component that displays a data index page. |  * Component that displays a data index page. | ||||||
|  */ |  */ | ||||||
| @ -318,12 +320,22 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp | |||||||
|         if (!this.isEmpty) { |         if (!this.isEmpty) { | ||||||
|             this.entries = (entries.offlineEntries || []).concat(entries.entries); |             this.entries = (entries.offlineEntries || []).concat(entries.entries); | ||||||
| 
 | 
 | ||||||
|             let entriesHTML = AddonModDataHelper.getTemplate( |             let headerAndFooter = AddonModDataHelper.getTemplate( | ||||||
|                 this.database!, |                 this.database!, | ||||||
|                 AddonModDataTemplateType.LIST_HEADER, |                 AddonModDataTemplateType.LIST_HEADER, | ||||||
|                 this.fieldsArray, |                 this.fieldsArray, | ||||||
|             ); |             ); | ||||||
| 
 | 
 | ||||||
|  |             headerAndFooter += contentToken; | ||||||
|  | 
 | ||||||
|  |             headerAndFooter += AddonModDataHelper.getTemplate( | ||||||
|  |                 this.database!, | ||||||
|  |                 AddonModDataTemplateType.LIST_FOOTER, | ||||||
|  |                 this.fieldsArray, | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |             headerAndFooter = CoreDomUtils.fixHtml(headerAndFooter); | ||||||
|  | 
 | ||||||
|             // Get first entry from the whole list.
 |             // Get first entry from the whole list.
 | ||||||
|             if (!this.search.searching || !this.firstEntry) { |             if (!this.search.searching || !this.firstEntry) { | ||||||
|                 this.firstEntry = this.entries[0].id; |                 this.firstEntry = this.entries[0].id; | ||||||
| @ -331,6 +343,8 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp | |||||||
| 
 | 
 | ||||||
|             const template = AddonModDataHelper.getTemplate(this.database!, AddonModDataTemplateType.LIST, this.fieldsArray); |             const template = AddonModDataHelper.getTemplate(this.database!, AddonModDataTemplateType.LIST, this.fieldsArray); | ||||||
| 
 | 
 | ||||||
|  |             let entriesHTML = ''; | ||||||
|  | 
 | ||||||
|             const entriesById: Record<number, AddonModDataEntry> = {}; |             const entriesById: Record<number, AddonModDataEntry> = {}; | ||||||
|             this.entries.forEach((entry, index) => { |             this.entries.forEach((entry, index) => { | ||||||
|                 entriesById[entry.id] = entry; |                 entriesById[entry.id] = entry; | ||||||
| @ -349,9 +363,8 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp | |||||||
|                     actions, |                     actions, | ||||||
|                 ); |                 ); | ||||||
|             }); |             }); | ||||||
|             entriesHTML += AddonModDataHelper.getTemplate(this.database!, AddonModDataTemplateType.LIST_FOOTER, this.fieldsArray); |  | ||||||
| 
 | 
 | ||||||
|             this.entriesRendered = CoreDomUtils.fixHtml(entriesHTML); |             this.entriesRendered = headerAndFooter.replace(contentToken, entriesHTML); | ||||||
| 
 | 
 | ||||||
|             // Pass the input data to the component.
 |             // Pass the input data to the component.
 | ||||||
|             this.jsData = { |             this.jsData = { | ||||||
|  | |||||||
| @ -12,6 +12,10 @@ $grid-column-paddings: ( | |||||||
|   xl: var(--ion-grid-column-padding-xl, $grid-column-padding) |   xl: var(--ion-grid-column-padding-xl, $grid-column-padding) | ||||||
| ) !default; | ) !default; | ||||||
| 
 | 
 | ||||||
|  | :host { | ||||||
|  |     --border-color: var(--gray); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .addon-data-contents { | .addon-data-contents { | ||||||
|     overflow: visible; |     overflow: visible; | ||||||
|     white-space: normal; |     white-space: normal; | ||||||
| @ -19,9 +23,7 @@ $grid-column-paddings: ( | |||||||
|     padding: 16px; |     padding: 16px; | ||||||
| 
 | 
 | ||||||
|     background-color: var(--ion-item-background); |     background-color: var(--ion-item-background); | ||||||
|     border-width: 1px 0; |     border-bottom: 1px solid var(--border-color); | ||||||
|     border-style: solid; |  | ||||||
|     border-color: var(--gray-dark); |  | ||||||
| 
 | 
 | ||||||
|     ::ng-deep { |     ::ng-deep { | ||||||
|         table, tbody { |         table, tbody { | ||||||
|  | |||||||
| @ -14,9 +14,9 @@ | |||||||
|     <ion-input type="text" [formControlName]="'f_'+field.id" [placeholder]="field.name"></ion-input> |     <ion-input type="text" [formControlName]="'f_'+field.id" [placeholder]="field.name"></ion-input> | ||||||
| </span> | </span> | ||||||
| 
 | 
 | ||||||
| <span *ngIf="listMode && imageUrl" (click)="gotoEntry.emit(entryId)"> | <button class="as-link" *ngIf="listMode && imageUrl" (click)="navigateEntry()"> | ||||||
|     <img [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" core-external-content/> |     <img [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" core-external-content/> | ||||||
| </span> | </button> | ||||||
| 
 | 
 | ||||||
| <img *ngIf="showMode && imageUrl" [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" | <img *ngIf="showMode && imageUrl" [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" | ||||||
|     [attr.width]="width" [attr.height]="height" core-external-content/> |     [attr.width]="width" [attr.height]="height" core-external-content/> | ||||||
|  | |||||||
| @ -138,4 +138,11 @@ export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginCo | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Navigate to the entry. | ||||||
|  |      */ | ||||||
|  |     navigateEntry(): void { | ||||||
|  |         this.gotoEntry.emit(this.entryId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ | |||||||
|             </ion-select> |             </ion-select> | ||||||
|         </ion-item> |         </ion-item> | ||||||
| 
 | 
 | ||||||
|         <div class="addon-data-contents addon-data-entries-{{database.id}}" *ngIf="database && entry"> |         <div class="addon-data-contents addon-data-entry addon-data-entries-{{database.id}}" *ngIf="database && entry"> | ||||||
|             <core-style [css]="database.csstemplate" prefix=".addon-data-entries-{{database.id}}"></core-style> |             <core-style [css]="database.csstemplate" prefix=".addon-data-entries-{{database.id}}"></core-style> | ||||||
| 
 | 
 | ||||||
|             <core-compile-html [text]="entryHtml" [jsData]="jsData" [extraImports]="extraImports" |             <core-compile-html [text]="entryHtml" [jsData]="jsData" [extraImports]="extraImports" | ||||||
| @ -54,13 +54,10 @@ | |||||||
|             [scaleId]="database.scale"> |             [scaleId]="database.scale"> | ||||||
|         </core-rating-aggregate> |         </core-rating-aggregate> | ||||||
| 
 | 
 | ||||||
|         <ion-item *ngIf="database && database.comments && entry && entry.id > 0 && commentsEnabled"> |         <core-comments *ngIf="database && database.comments && entry && entry.id > 0 && commentsEnabled" | ||||||
|             <ion-label> |             contextLevel="module" [instanceId]="database.coursemodule" component="mod_data" [itemId]="entry.id" | ||||||
|                 <core-comments contextLevel="module" [instanceId]="database.coursemodule" component="mod_data" [itemId]="entry.id" |             area="database_entry" [courseId]="courseId" (onLoading)="setLoadingComments($event)" [showItem]="true"> | ||||||
|                     area="database_entry" [displaySpinner]="false" [courseId]="courseId" (onLoading)="setLoadingComments($event)"> |  | ||||||
|         </core-comments> |         </core-comments> | ||||||
|             </ion-label> |  | ||||||
|         </ion-item> |  | ||||||
| 
 | 
 | ||||||
|         <ion-grid *ngIf="hasPrevious || hasNext"> |         <ion-grid *ngIf="hasPrevious || hasNext"> | ||||||
|             <ion-row class="ion-align-items-center"> |             <ion-row class="ion-align-items-center"> | ||||||
|  | |||||||
| @ -658,7 +658,7 @@ export class AddonModDataHelperProvider { | |||||||
|         // Add core-link directive to links.
 |         // Add core-link directive to links.
 | ||||||
|         template = template.replace( |         template = template.replace( | ||||||
|             /<a ([^>]*href="[^>]*)>/ig, |             /<a ([^>]*href="[^>]*)>/ig, | ||||||
|             (match, attributes) => '<a core-link capture="true" ' + attributes + '>', |             (match, attributes) => '<button class="as-link" core-link capture="true" ' + attributes + '>', | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         return template; |         return template; | ||||||
|  | |||||||
| @ -1,36 +1,38 @@ | |||||||
| <ion-item class="ion-text-wrap" (click)="setLockState(true)" *ngIf="discussion.canlock && !discussion.locked"> | <ion-item button class="ion-text-wrap" (click)="setLockState(true)" *ngIf="discussion.canlock && !discussion.locked" detail="false"> | ||||||
|     <ion-icon name="fa-lock" slot="start" aria-hidden="true"></ion-icon> |     <ion-icon name="fa-lock" slot="start" aria-hidden="true"></ion-icon> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{ 'addon.mod_forum.lockdiscussion' | translate }}</h2> |         <p class="item-heading">{{ 'addon.mod_forum.lockdiscussion' | translate }}</p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item> | </ion-item> | ||||||
| <ion-item class="ion-text-wrap" (click)="setLockState(false)" *ngIf="discussion.canlock && discussion.locked"> | <ion-item button class="ion-text-wrap" (click)="setLockState(false)" *ngIf="discussion.canlock && discussion.locked" detail="false"> | ||||||
|     <ion-icon name="fa-unlock" slot="start" aria-hidden="true"></ion-icon> |     <ion-icon name="fa-unlock" slot="start" aria-hidden="true"></ion-icon> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{ 'addon.mod_forum.unlockdiscussion' | translate }}</h2> |         <p class="item-heading">{{ 'addon.mod_forum.unlockdiscussion' | translate }}</p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item> | </ion-item> | ||||||
| <ion-item class="ion-text-wrap" (click)="setPinState(true)" *ngIf="canPin && !discussion.pinned"> | <ion-item button class="ion-text-wrap" (click)="setPinState(true)" *ngIf="canPin && !discussion.pinned" detail="false"> | ||||||
|     <ion-icon name="fa-map-pin" slot="start" aria-hidden="true"></ion-icon> |     <ion-icon name="fa-map-pin" slot="start" aria-hidden="true"></ion-icon> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{ 'addon.mod_forum.pindiscussion' | translate }}</h2> |         <p class="item-heading">{{ 'addon.mod_forum.pindiscussion' | translate }}</p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item> | </ion-item> | ||||||
| <ion-item class="ion-text-wrap" (click)="setPinState(false)" *ngIf="canPin && discussion.pinned"> | <ion-item button class="ion-text-wrap" (click)="setPinState(false)" *ngIf="canPin && discussion.pinned" detail="false"> | ||||||
|     <ion-icon name="fa-map-pin" slot="start" class="icon-slash" aria-hidden="true"></ion-icon> |     <ion-icon name="fa-map-pin" slot="start" class="icon-slash" aria-hidden="true"></ion-icon> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{ 'addon.mod_forum.unpindiscussion' | translate }}</h2> |         <p class="item-heading">{{ 'addon.mod_forum.unpindiscussion' | translate }}</p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item> | </ion-item> | ||||||
| <ion-item class="ion-text-wrap" (click)="toggleFavouriteState(true)" *ngIf="discussion.canfavourite && !discussion.starred"> | <ion-item button class="ion-text-wrap" (click)="toggleFavouriteState(true)" *ngIf="discussion.canfavourite && !discussion.starred" | ||||||
|  |     detail="false"> | ||||||
|     <ion-icon name="fa-star" slot="start" aria-hidden="true"></ion-icon> |     <ion-icon name="fa-star" slot="start" aria-hidden="true"></ion-icon> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{ 'addon.mod_forum.addtofavourites' | translate }}</h2> |         <p class="item-heading">{{ 'addon.mod_forum.addtofavourites' | translate }}</p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item> | </ion-item> | ||||||
| <ion-item class="ion-text-wrap" (click)="toggleFavouriteState(false)" *ngIf="discussion.canfavourite && discussion.starred"> | <ion-item button class="ion-text-wrap" (click)="toggleFavouriteState(false)" *ngIf="discussion.canfavourite && discussion.starred" | ||||||
|  |     detail="false"> | ||||||
|     <ion-icon name="fa-star" slot="start" class="icon-slash" aria-hidden="true"></ion-icon> |     <ion-icon name="fa-star" slot="start" class="icon-slash" aria-hidden="true"></ion-icon> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{ 'addon.mod_forum.removefromfavourites' | translate }}</h2> |         <p class="item-heading">{{ 'addon.mod_forum.removefromfavourites' | translate }}</p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item> | </ion-item> | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ | |||||||
|             (action)="prefetch($event)"> |             (action)="prefetch($event)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="size" |         <core-context-menu-item *ngIf="size" | ||||||
|             iconDescription="cube" iconAction="trash" |             iconDescription="fas-archive" iconAction="trash" | ||||||
|             [priority]="400" [content]="'core.clearstoreddata' | translate:{$a: size}" [closeOnClick]="false" |             [priority]="400" [content]="'core.clearstoreddata' | translate:{$a: size}" [closeOnClick]="false" | ||||||
|             (action)="removeFiles($event)"> |             (action)="removeFiles($event)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|  | |||||||
| @ -1,26 +1,26 @@ | |||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin"> | ||||||
|     <ion-item class="ion-text-wrap" (click)="editPost()" *ngIf="offlinePost || (canEdit && isOnline)"> |     <ion-item button class="ion-text-wrap" (click)="editPost()" *ngIf="offlinePost || (canEdit && isOnline)" detail="false"> | ||||||
|         <ion-icon name="fas-pen" slot="start" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-pen" slot="start" aria-hidden="true"></ion-icon> | ||||||
|         <ion-label> |         <ion-label> | ||||||
|             <h2>{{ 'addon.mod_forum.edit' | translate }}</h2> |             <p class="item-heading">{{ 'addon.mod_forum.edit' | translate }}</p> | ||||||
|         </ion-label> |         </ion-label> | ||||||
|     </ion-item> |     </ion-item> | ||||||
|     <ion-item class="ion-text-wrap" (click)="deletePost()" *ngIf="offlinePost || (canDelete && isOnline)"> |     <ion-item button class="ion-text-wrap" (click)="deletePost()" *ngIf="offlinePost || (canDelete && isOnline)" detail="false"> | ||||||
|         <ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon> | ||||||
|         <ion-label> |         <ion-label> | ||||||
|             <h2 *ngIf="!offlinePost">{{ 'addon.mod_forum.delete' | translate }}</h2> |             <p  class="item-heading" *ngIf="!offlinePost">{{ 'addon.mod_forum.delete' | translate }}</p> | ||||||
|             <h2 *ngIf="offlinePost">{{ 'core.discard' | translate }}</h2> |             <p  class="item-heading" *ngIf="offlinePost">{{ 'core.discard' | translate }}</p> | ||||||
|         </ion-label> |         </ion-label> | ||||||
|     </ion-item> |     </ion-item> | ||||||
|     <ion-item class="ion-text-wrap" (click)="dismiss()" *ngIf="wordCount"> |     <ion-item class="ion-text-wrap" *ngIf="wordCount"> | ||||||
|         <ion-label> |         <ion-label> | ||||||
|             <h2>{{ 'core.numwords' | translate: {'$a': wordCount} }}</h2> |             <p  class="item-heading">{{ 'core.numwords' | translate: {'$a': wordCount} }}</p> | ||||||
|         </ion-label> |         </ion-label> | ||||||
|     </ion-item> |     </ion-item> | ||||||
|     <ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false"> |     <ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false" button detail="false"> | ||||||
|         <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> | ||||||
|         <ion-label> |         <ion-label> | ||||||
|             <h2>{{ 'core.openinbrowser' | translate }}</h2> |             <p  class="item-heading">{{ 'core.openinbrowser' | translate }}</p> | ||||||
|         </ion-label> |         </ion-label> | ||||||
|     </ion-item> |     </ion-item> | ||||||
| </core-loading> | </core-loading> | ||||||
|  | |||||||
| @ -58,13 +58,10 @@ | |||||||
|             <ion-item class="ion-text-wrap" *ngIf="!entry.approved"> |             <ion-item class="ion-text-wrap" *ngIf="!entry.approved"> | ||||||
|                 <ion-label><p><em>{{ 'addon.mod_glossary.entrypendingapproval' | translate }}</em></p></ion-label> |                 <ion-label><p><em>{{ 'addon.mod_glossary.entrypendingapproval' | translate }}</em></p></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item *ngIf="glossary && glossary.allowcomments && entry && entry.id > 0 && commentsEnabled"> |             <core-comments *ngIf="glossary && glossary.allowcomments && entry && entry.id > 0 && commentsEnabled" | ||||||
|                 <ion-label> |                 contextLevel="module" [instanceId]="glossary.coursemodule" component="mod_glossary" | ||||||
|                     <core-comments contextLevel="module" [instanceId]="glossary.coursemodule" component="mod_glossary" |                 [itemId]="entry.id" area="glossary_entry" [courseId]="glossary.course" [showItem]="true"> | ||||||
|                         [itemId]="entry.id" area="glossary_entry" [courseId]="glossary.course"> |  | ||||||
|             </core-comments> |             </core-comments> | ||||||
|                 </ion-label> |  | ||||||
|             </ion-item> |  | ||||||
|             <core-rating-rate *ngIf="glossary && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" |             <core-rating-rate *ngIf="glossary && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" | ||||||
|                 [instanceId]="glossary.coursemodule" [itemId]="entry.id" [itemSetId]="0" [courseId]="glossary.course" |                 [instanceId]="glossary.coursemodule" [itemId]="entry.id" [itemSetId]="0" [courseId]="glossary.course" | ||||||
|                 [aggregateMethod]="glossary.assessed" [scaleId]="glossary.scale" [userId]="entry.userid" |                 [aggregateMethod]="glossary.assessed" [scaleId]="glossary.scale" [userId]="entry.userid" | ||||||
|  | |||||||
| @ -63,7 +63,7 @@ | |||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2>{{ 'addon.mod_h5pactivity.outcome' | translate }}</h2> |                             <h2>{{ 'addon.mod_h5pactivity.outcome' | translate }}</h2> | ||||||
|                             <p *ngIf="attempt.success !== null && attempt.success" > |                             <p *ngIf="attempt.success !== null && attempt.success" > | ||||||
|                                 <ion-icon name="fa-check-circle" aria-hidden="true"></ion-icon> |                                 <ion-icon name="fas-check-circle" aria-hidden="true"></ion-icon> | ||||||
|                                 {{ 'addon.mod_h5pactivity.attempt_success_pass' | translate }} |                                 {{ 'addon.mod_h5pactivity.attempt_success_pass' | translate }} | ||||||
|                             </p> |                             </p> | ||||||
|                             <p *ngIf="attempt.success !== null && !attempt.success" > |                             <p *ngIf="attempt.success !== null && !attempt.success" > | ||||||
| @ -166,12 +166,12 @@ | |||||||
| <!-- Template to render an answer. --> | <!-- Template to render an answer. --> | ||||||
| <ng-template #answerTemplate let-answer="answer"> | <ng-template #answerTemplate let-answer="answer"> | ||||||
|     <p *ngIf="answer.correct"> |     <p *ngIf="answer.correct"> | ||||||
|         <ion-icon name="fa-check" [attr.aria-label]="'addon.mod_h5pactivity.answer_correct' | translate" color="success"> |         <ion-icon name="fas-check" [attr.aria-label]="'addon.mod_h5pactivity.answer_correct' | translate" color="success"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|         {{ answer.answer }} |         {{ answer.answer }} | ||||||
|     </p> |     </p> | ||||||
|     <p *ngIf="answer.incorrect"> |     <p *ngIf="answer.incorrect"> | ||||||
|         <ion-icon name="fa-remove" [attr.aria-label]="'addon.mod_h5pactivity.answer_incorrect' | translate" color="danger"> |         <ion-icon name="fas-times" [attr.aria-label]="'addon.mod_h5pactivity.answer_incorrect' | translate" color="danger"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|         {{ answer.answer }} |         {{ answer.answer }} | ||||||
|     </p> |     </p> | ||||||
| @ -179,15 +179,15 @@ | |||||||
|         {{ answer.answer }} |         {{ answer.answer }} | ||||||
|     </p> |     </p> | ||||||
|     <p *ngIf="answer.checked"> |     <p *ngIf="answer.checked"> | ||||||
|         <ion-icon name="fa-check-circle" [attr.aria-label]="'addon.mod_h5pactivity.answer_checked' | translate"> |         <ion-icon name="fas-check-circle" [attr.aria-label]="'addon.mod_h5pactivity.answer_checked' | translate"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|     </p> |     </p> | ||||||
|     <p *ngIf="answer.pass"> |     <p *ngIf="answer.pass"> | ||||||
|         <ion-icon name="fa-check" [attr.aria-label]="'addon.mod_h5pactivity.answer_pass' | translate" color="success"> |         <ion-icon name="fas-check" [attr.aria-label]="'addon.mod_h5pactivity.answer_pass' | translate" color="success"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|     </p> |     </p> | ||||||
|     <p *ngIf="answer.fail"> |     <p *ngIf="answer.fail"> | ||||||
|         <ion-icon name="fa-remove" [attr.aria-label]="'addon.mod_h5pactivity.answer_fail' | translate" color="danger"> |         <ion-icon name="fas-times" [attr.aria-label]="'addon.mod_h5pactivity.answer_fail' | translate" color="danger"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|     </p> |     </p> | ||||||
| </ng-template> | </ng-template> | ||||||
|  | |||||||
| @ -99,7 +99,7 @@ | |||||||
|                         [alt]="'addon.mod_h5pactivity.attempt_completion_no' | translate"> |                         [alt]="'addon.mod_h5pactivity.attempt_completion_no' | translate"> | ||||||
|                 </ion-col> |                 </ion-col> | ||||||
|                 <ion-col class="ion-text-center addon-mod_h5pactivity-table-success-col"> |                 <ion-col class="ion-text-center addon-mod_h5pactivity-table-success-col"> | ||||||
|                     <ion-icon *ngIf="attempt.success !== null && attempt.success" name="fa-check-circle" |                     <ion-icon *ngIf="attempt.success !== null && attempt.success" name="fas-check-circle" | ||||||
|                         [attr.aria-label]="'addon.mod_h5pactivity.attempt_success_pass' | translate"> |                         [attr.aria-label]="'addon.mod_h5pactivity.attempt_success_pass' | translate"> | ||||||
|                     </ion-icon> |                     </ion-icon> | ||||||
|                     <ion-icon *ngIf="attempt.success !== null && !attempt.success" name="far-circle" |                     <ion-icon *ngIf="attempt.success !== null && !attempt.success" name="far-circle" | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <ion-button (click)="showToc()" aria-haspopup="true" [attr.aria-label]="'addon.mod_imscp.toc' | translate"> |     <ion-button *ngIf="loaded" (click)="showToc()" aria-haspopup="true" [attr.aria-label]="'addon.mod_imscp.toc' | translate"> | ||||||
|         <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|     </ion-button> |     </ion-button> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|  | |||||||
| @ -12,9 +12,12 @@ | |||||||
|     <nav> |     <nav> | ||||||
|         <ion-list> |         <ion-list> | ||||||
|             <ion-item *ngFor="let item of items" (click)="loadItem(item.href)" |             <ion-item *ngFor="let item of items" (click)="loadItem(item.href)" | ||||||
|                 [attr.aria-current]="selected == item.href ? 'page' : 'false'" button> |                 [attr.aria-current]="selected == item.href ? 'page' : 'false'" button detail="false"> | ||||||
|                 <ion-label [class.core-bold]="!item.href"> |                 <ion-label [class.core-bold]="!item.href"> | ||||||
|                     <span class="ion-padding-left" *ngFor="let i of getNumberForPadding(item.level)"></span>{{item.title}} |                     <p class="item-heading"> | ||||||
|  |                         <span class="ion-padding-left" *ngFor="let i of getNumberForPadding(item.level)"></span> | ||||||
|  |                         {{item.title}} | ||||||
|  |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-list> |         </ion-list> | ||||||
|  | |||||||
| @ -296,7 +296,7 @@ | |||||||
|                         </ion-card-header> |                         </ion-card-header> | ||||||
| 
 | 
 | ||||||
|                         <ion-item class="ion-text-wrap" *ngFor="let student of overview.students" button |                         <ion-item class="ion-text-wrap" *ngFor="let student of overview.students" button | ||||||
|                             (click)="openRetake(student.id)"> |                             (click)="openRetake(student.id)" detail="true"> | ||||||
|                             <core-user-avatar [user]="student" slot="start" [userId]="student.id" [courseId]="courseId"> |                             <core-user-avatar [user]="student" slot="start" [userId]="student.id" [courseId]="courseId"> | ||||||
|                             </core-user-avatar> |                             </core-user-avatar> | ||||||
|                             <ion-label> |                             <ion-label> | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ | |||||||
| 
 | 
 | ||||||
|             <ion-item button class="ion-text-wrap {{question.stateClass}}" *ngFor="let question of navigation" |             <ion-item button class="ion-text-wrap {{question.stateClass}}" *ngFor="let question of navigation" | ||||||
|                 [attr.aria-current]="!summaryShown && currentPage == question.page ? 'page' : 'false'" |                 [attr.aria-current]="!summaryShown && currentPage == question.page ? 'page' : 'false'" | ||||||
|                 (click)="loadPage(question.page, question.slot)" detail="true"> |                 (click)="loadPage(question.page, question.slot)" detail="false"> | ||||||
| 
 | 
 | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <span *ngIf="question.number">{{ 'core.question.questionno' | translate:{$a: question.number} }}</span> |                     <span *ngIf="question.number">{{ 'core.question.questionno' | translate:{$a: question.number} }}</span> | ||||||
|  | |||||||
| @ -158,11 +158,11 @@ | |||||||
|                                 <ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" |                                 <ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" | ||||||
|                                     slot="start"> |                                     slot="start"> | ||||||
|                                 </ion-icon> |                                 </ion-icon> | ||||||
|                                 <a *ngIf="sco.prereq && sco.launch" (click)="open($event, false, sco.id)" tappable="true"> |                                 <button class="as-link" *ngIf="sco.prereq && sco.launch" (click)="open($event, false, sco.id)"> | ||||||
|                                     <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" |                                     <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" | ||||||
|                                         [courseId]="courseId"> |                                         [courseId]="courseId"> | ||||||
|                                     </core-format-text> |                                     </core-format-text> | ||||||
|                                 </a> |                                 </button> | ||||||
|                                 <span *ngIf="!sco.prereq || !sco.launch"> |                                 <span *ngIf="!sco.prereq || !sco.launch"> | ||||||
|                                     <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" |                                     <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" | ||||||
|                                         [courseId]="courseId"> |                                         [courseId]="courseId"> | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
|     <nav> |     <nav> | ||||||
|         <ion-list> |         <ion-list> | ||||||
|             <!-- Go to "home". --> |             <!-- Go to "home". --> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="homeView" (click)="goToWikiHome()" button> |             <ion-item class="ion-text-wrap" *ngIf="homeView" (click)="goToWikiHome()" button detail="true"> | ||||||
|                 <ion-icon name="fas-home" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-home" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label>{{ 'addon.mod_wiki.gowikihome' | translate }}</ion-label> |                 <ion-label>{{ 'addon.mod_wiki.gowikihome' | translate }}</ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| @ -21,7 +21,7 @@ | |||||||
|                     <ion-label><h2>{{ letter.label }}</h2></ion-label> |                     <ion-label><h2>{{ letter.label }}</h2></ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let page of letter.pages" (click)="goToPage(page)" |                 <ion-item class="ion-text-wrap" *ngFor="let page of letter.pages" (click)="goToPage(page)" | ||||||
|                     [attr.aria-current]="selectedTitle == page.title ? 'page' : 'false'" button> |                     [attr.aria-current]="selectedTitle == page.title ? 'page' : 'false'" button detail="false"> | ||||||
|                     <ion-icon name="fas-home" slot="start" *ngIf="page.firstpage" aria-hidden="true"></ion-icon> |                     <ion-icon name="fas-home" slot="start" *ngIf="page.firstpage" aria-hidden="true"></ion-icon> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <core-format-text [text]="page.title" contextLevel="module" [contextInstanceId]="moduleId" |                         <core-format-text [text]="page.title" contextLevel="module" [contextInstanceId]="moduleId" | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ import { HttpClient, HttpClientModule } from '@angular/common/http'; | |||||||
| import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; | import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; | ||||||
| import { TranslateHttpLoader } from '@ngx-translate/http-loader'; | import { TranslateHttpLoader } from '@ngx-translate/http-loader'; | ||||||
| 
 | 
 | ||||||
| import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; | import { IonicModule, IonicRouteStrategy, iosTransitionAnimation } from '@ionic/angular'; | ||||||
| 
 | 
 | ||||||
| import { CoreModule } from '@/core/core.module'; | import { CoreModule } from '@/core/core.module'; | ||||||
| import { AddonsModule } from '@/addons/addons.module'; | import { AddonsModule } from '@/addons/addons.module'; | ||||||
| @ -42,7 +42,11 @@ export function createTranslateLoader(http: HttpClient): TranslateHttpLoader { | |||||||
|     imports: [ |     imports: [ | ||||||
|         BrowserModule, |         BrowserModule, | ||||||
|         BrowserAnimationsModule, |         BrowserAnimationsModule, | ||||||
|         IonicModule.forRoot(), |         IonicModule.forRoot( | ||||||
|  |             { | ||||||
|  |                 navAnimation: iosTransitionAnimation, | ||||||
|  |             }, | ||||||
|  |         ), | ||||||
|         HttpClientModule, // HttpClient is used to make JSON requests. It fails for HEAD requests because there is no content.
 |         HttpClientModule, // HttpClient is used to make JSON requests. It fails for HEAD requests because there is no content.
 | ||||||
|         TranslateModule.forRoot({ |         TranslateModule.forRoot({ | ||||||
|             loader: { |             loader: { | ||||||
|  | |||||||
							
								
								
									
										58
									
								
								src/core/classes/modal-lateral-transition.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/core/classes/modal-lateral-transition.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | // (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 { createAnimation } from '@ionic/angular'; | ||||||
|  | import { Animation } from '@ionic/core'; | ||||||
|  | import { Platform } from '@singletons'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Sliding transition for lateral modals. | ||||||
|  |  */ | ||||||
|  | export function CoreModalLateralTransitionEnter(baseEl: HTMLElement): Animation { | ||||||
|  |     const OFF_RIGHT = Platform.isRTL ? '-100%' : '100%'; | ||||||
|  | 
 | ||||||
|  |     const backdropAnimation = createAnimation() | ||||||
|  |         .addElement(baseEl.querySelector('ion-backdrop')!) | ||||||
|  |         .fromTo('opacity', 0.01, 0.4); | ||||||
|  | 
 | ||||||
|  |     const wrapperAnimation = createAnimation() | ||||||
|  |         .addElement(baseEl.querySelector('.modal-wrapper')!) | ||||||
|  |         .fromTo('transform', 'translateX(' + OFF_RIGHT + ')', 'translateX(0)') | ||||||
|  |         .fromTo('opacity', 0.8, 1); | ||||||
|  | 
 | ||||||
|  |     return createAnimation() | ||||||
|  |         .addElement(baseEl) | ||||||
|  |         .easing('cubic-bezier(0.36,0.66,0.04,1)') | ||||||
|  |         .duration(300) | ||||||
|  |         .addAnimation([backdropAnimation, wrapperAnimation]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function CoreModalLateralTransitionLeave(baseEl: HTMLElement): Animation { | ||||||
|  |     const OFF_RIGHT = Platform.isRTL ? '-100%' : '100%'; | ||||||
|  | 
 | ||||||
|  |     const backdropAnimation = createAnimation() | ||||||
|  |         .addElement(baseEl.querySelector('ion-backdrop')!) | ||||||
|  |         .fromTo('opacity', 0.4, 0.0); | ||||||
|  | 
 | ||||||
|  |     const wrapperAnimation = createAnimation() | ||||||
|  |         .addElement(baseEl.querySelector('.modal-wrapper')!) | ||||||
|  |         .beforeStyles({ opacity: 1 }) | ||||||
|  |         .fromTo('transform', 'translateX(0)', 'translateX(' + OFF_RIGHT + ')'); | ||||||
|  | 
 | ||||||
|  |     return createAnimation() | ||||||
|  |         .addElement(baseEl) | ||||||
|  |         .easing('cubic-bezier(0.36,0.66,0.04,1)') | ||||||
|  |         .duration(300) | ||||||
|  |         .addAnimation([backdropAnimation, wrapperAnimation]); | ||||||
|  | } | ||||||
| @ -84,6 +84,7 @@ ion-button { | |||||||
|         text-transform: none; |         text-transform: none; | ||||||
|         font-weight: 400; |         font-weight: 400; | ||||||
|         font-size: 16px; |         font-size: 16px; | ||||||
|  |         line-height: 20px; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     .select-text { |     .select-text { | ||||||
|  | |||||||
| @ -1,5 +1,11 @@ | |||||||
| :host { | @import "~theme/globals"; | ||||||
|     ion-list { | 
 | ||||||
|  | ion-list { | ||||||
|     padding: 0; |     padding: 0; | ||||||
|     } | } | ||||||
|  | 
 | ||||||
|  | ion-icon[slot=start] { | ||||||
|  |     @include margin-horizontal(0, 10px); | ||||||
|  |     width: 0.8em; | ||||||
|  |     height: 0.8em; | ||||||
| } | } | ||||||
|  | |||||||
| @ -7,7 +7,9 @@ | |||||||
|         [detail]="(item.href && !item.iconAction) || null" role="menuitem" [button]="(item.href && !item.iconAction)"> |         [detail]="(item.href && !item.iconAction) || null" role="menuitem" [button]="(item.href && !item.iconAction)"> | ||||||
|         <ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" [attr.aria-label]="item.ariaDescription" slot="start"> |         <ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" [attr.aria-label]="item.ariaDescription" slot="start"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|         <ion-label><core-format-text [clean]="true" [text]="item.content" [filter]="false"></core-format-text></ion-label> |         <ion-label> | ||||||
|  |             <p class="item-heading"><core-format-text [clean]="true" [text]="item.content" [filter]="false"></core-format-text></p> | ||||||
|  |         </ion-label> | ||||||
|         <ion-icon *ngIf="(item.href || item.action) && item.iconAction && item.iconAction != 'spinner'" [name]="item.iconAction" |         <ion-icon *ngIf="(item.href || item.action) && item.iconAction && item.iconAction != 'spinner'" [name]="item.iconAction" | ||||||
|             [class.icon-slash]="item.iconSlash" slot="end"> |             [class.icon-slash]="item.iconSlash" slot="end"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|  | |||||||
| @ -1,8 +1,6 @@ | |||||||
| <div class="core-loading-container" *ngIf="!hideUntil" role="status" [@coreShowHideAnimation]> | <div class="core-loading-container" *ngIf="!hideUntil" role="status" [@coreShowHideAnimation]> | ||||||
|     <span class="core-loading-spinner"> |  | ||||||
|     <ion-spinner color="primary"></ion-spinner> |     <ion-spinner color="primary"></ion-spinner> | ||||||
|     <p class="core-loading-message" *ngIf="message" role="status">{{message}}</p> |     <p class="core-loading-message" *ngIf="message" role="status">{{message}}</p> | ||||||
|     </span> |  | ||||||
| </div> | </div> | ||||||
| <div #content class="core-loading-content" [id]="uniqueId" [attr.aria-busy]="hideUntil" [@coreShowHideAnimation]> | <div #content class="core-loading-content" [id]="uniqueId" [attr.aria-busy]="hideUntil" [@coreShowHideAnimation]> | ||||||
|     <ng-content *ngIf="hideUntil"> |     <ng-content *ngIf="hideUntil"> | ||||||
|  | |||||||
| @ -4,35 +4,44 @@ | |||||||
|     --loading-background: var(--ion-background-color); |     --loading-background: var(--ion-background-color); | ||||||
|     --loading-spinner: var(--ion-color-primary); |     --loading-spinner: var(--ion-color-primary); | ||||||
|     --loading-text-color: var(--ion-text-color); |     --loading-text-color: var(--ion-text-color); | ||||||
|  |     --loading-inline-margin: 0; | ||||||
|  |     --loading-inline-min-height: 28px; | ||||||
| 
 | 
 | ||||||
|     position: static; |     position: static; | ||||||
|     color: var(--loading-text-color); |     color: var(--loading-text-color); | ||||||
| 
 | 
 | ||||||
|  |     &.margin { | ||||||
|  |         --loading-inline-margin: 10px; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     &.core-loading-loaded { | ||||||
|  |         --loading-inline-margin: 0; | ||||||
|  |         --loading-inline-min-height: 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     ion-spinner { |     ion-spinner { | ||||||
|         --color: var(--loading-spinner); |         --color: var(--loading-spinner); | ||||||
|         color: var(--color); |         color: var(--color); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     > .core-loading-container { |     .core-loading-container { | ||||||
|         position: absolute; |         position: absolute; | ||||||
|         @include position(0, 0, 0, 0); |         @include position(0, 0, 0, 0); | ||||||
|         display: table; |         display: flex; | ||||||
|         height: 100%; |         height: 100%; | ||||||
|         width: 100%; |         width: 100%; | ||||||
|         text-align: center; |         justify-content: center; | ||||||
|         clear: both; |         align-items: center; | ||||||
|  |         flex-direction: column; | ||||||
|         z-index: 3; |         z-index: 3; | ||||||
|         margin: 0; |         margin: 0; | ||||||
|         padding: 10px 0 0 0; |         padding: 0; | ||||||
|         background-color: var(--loading-background); |         background-color: var(--loading-background); | ||||||
|         -webkit-transition: all 200ms ease-in-out; |         @include core-transition(all, 200ms); | ||||||
|         transition: all 200ms ease-in-out; |  | ||||||
| 
 |  | ||||||
|         .core-loading-spinner { |  | ||||||
|             display: table-cell; |  | ||||||
|             text-align: center; |  | ||||||
|             vertical-align: middle; |  | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     .core-loading-message { | ||||||
|  |         @include margin(10px, 0, 0, 0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     .core-loading-content { |     .core-loading-content { | ||||||
| @ -48,21 +57,26 @@ | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     &.core-loading-inline { |     &.core-loading-inline { | ||||||
|  |         --loading-background: transparent; | ||||||
|  |         position: relative; | ||||||
|         display: block; |         display: block; | ||||||
|  |         min-height: var(--loading-inline-min-height); | ||||||
|  |         margin-top: var(--loading-inline-margin); | ||||||
|  |         margin-bottom: var(--loading-inline-margin); | ||||||
| 
 | 
 | ||||||
|         .core-loading-container { |         .core-loading-message { | ||||||
|             padding-top: 20px; |             @include margin(0, 0, 0, 10px); | ||||||
|             position: relative; |  | ||||||
|         } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|     &.core-loading-loaded.core-loading-inline { |  | ||||||
|         position: relative; |  | ||||||
|         min-height: 102px; |  | ||||||
| 
 |  | ||||||
|         .core-loading-container { |         .core-loading-container { | ||||||
|             padding-top: 10px; |             flex-direction: row; | ||||||
|             position: absolute; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | :host-context(ion-item) { | ||||||
|  |     &.core-loading-inline { | ||||||
|  |         position: static; | ||||||
|  |         display: block; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
|     <ion-tab-bar slot="top" class="core-tabs-bar" [hidden]="!tabs || numTabsShown <= 1" #tabBar> |     <ion-tab-bar slot="top" class="core-tabs-bar" [hidden]="!tabs || numTabsShown <= 1" #tabBar> | ||||||
|         <ion-spinner *ngIf="!hideUntil"></ion-spinner> |         <ion-spinner *ngIf="!hideUntil"></ion-spinner> | ||||||
|         <ion-row *ngIf="hideUntil"> |         <ion-row *ngIf="hideUntil"> | ||||||
|             <ion-col class="col-with-arrow ion-no-padding" (click)="slidePrev()" size="1"> |             <ion-col class="col-with-arrow ion-no-padding" (click)="slidePrev()" size="1" [class.clickable]="showPrevButton"> | ||||||
|                 <ion-icon *ngIf="showPrevButton" name="fas-chevron-left" [attr.aria-label]="'core.previous' | translate"></ion-icon> |                 <ion-icon *ngIf="showPrevButton" name="fas-chevron-left" [attr.aria-label]="'core.previous' | translate"></ion-icon> | ||||||
|             </ion-col> |             </ion-col> | ||||||
|             <ion-col class="ion-no-padding" size="10"> |             <ion-col class="ion-no-padding" size="10"> | ||||||
| @ -41,7 +41,7 @@ | |||||||
|                     </ng-container> |                     </ng-container> | ||||||
|                 </ion-slides> |                 </ion-slides> | ||||||
|             </ion-col> |             </ion-col> | ||||||
|             <ion-col class="col-with-arrow ion-no-padding" (click)="slideNext()" size="1"> |             <ion-col class="col-with-arrow ion-no-padding" (click)="slideNext()" size="1" [class.clickable]="showNextButton"> | ||||||
|                 <ion-icon *ngIf="showNextButton" name="fas-chevron-right" [attr.aria-label]="'core.next' | translate"></ion-icon> |                 <ion-icon *ngIf="showNextButton" name="fas-chevron-right" [attr.aria-label]="'core.next' | translate"></ion-icon> | ||||||
|             </ion-col> |             </ion-col> | ||||||
|         </ion-row> |         </ion-row> | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| <ion-tab-bar slot="top" class="core-tabs-bar" [hidden]="!tabs || numTabsShown <= 1" #tabBar> | <ion-tab-bar slot="top" class="core-tabs-bar" [hidden]="!tabs || numTabsShown <= 1" #tabBar> | ||||||
|     <ion-spinner *ngIf="!hideUntil"></ion-spinner> |     <ion-spinner *ngIf="!hideUntil"></ion-spinner> | ||||||
|     <ion-row *ngIf="hideUntil"> |     <ion-row *ngIf="hideUntil"> | ||||||
|         <ion-col class="col-with-arrow ion-no-padding" (click)="slidePrev()" size="1"> |         <ion-col class="col-with-arrow ion-no-padding" (click)="slidePrev()" size="1" [class.clickable]="showPrevButton"> | ||||||
|             <ion-icon *ngIf="showPrevButton" name="fas-chevron-left" [attr.aria-label]="'core.previous' | translate"></ion-icon> |             <ion-icon *ngIf="showPrevButton" name="fas-chevron-left" [attr.aria-label]="'core.previous' | translate"></ion-icon> | ||||||
|         </ion-col> |         </ion-col> | ||||||
|         <ion-col class="ion-no-padding" size="10"> |         <ion-col class="ion-no-padding" size="10"> | ||||||
| @ -39,7 +39,7 @@ | |||||||
|                 </ng-container> |                 </ng-container> | ||||||
|             </ion-slides> |             </ion-slides> | ||||||
|         </ion-col> |         </ion-col> | ||||||
|         <ion-col class="col-with-arrow ion-no-padding" (click)="slideNext()" size="1"> |         <ion-col class="col-with-arrow ion-no-padding" (click)="slideNext()" size="1" [class.clickable]="showNextButton"> | ||||||
|             <ion-icon *ngIf="showNextButton" name="fas-chevron-right" [attr.aria-label]="'core.next' | translate"></ion-icon> |             <ion-icon *ngIf="showNextButton" name="fas-chevron-right" [attr.aria-label]="'core.next' | translate"></ion-icon> | ||||||
|         </ion-col> |         </ion-col> | ||||||
|     </ion-row> |     </ion-row> | ||||||
|  | |||||||
| @ -80,6 +80,7 @@ export class CoreFormatTextDirective implements OnChanges { | |||||||
|     @Input() maxHeight?: number; |     @Input() maxHeight?: number; | ||||||
| 
 | 
 | ||||||
|     @Output() afterRender: EventEmitter<void>; // Called when the data is rendered.
 |     @Output() afterRender: EventEmitter<void>; // Called when the data is rendered.
 | ||||||
|  |     @Output() onClick: EventEmitter<void> = new EventEmitter(); // Called when clicked.
 | ||||||
| 
 | 
 | ||||||
|     protected element: HTMLElement; |     protected element: HTMLElement; | ||||||
|     protected showMoreDisplayed = false; |     protected showMoreDisplayed = false; | ||||||
| @ -286,6 +287,13 @@ export class CoreFormatTextDirective implements OnChanges { | |||||||
|             // Ignore it if the event was prevented by some other listener.
 |             // Ignore it if the event was prevented by some other listener.
 | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         if (this.onClick.observers.length > 0) { | ||||||
|  |             this.onClick.emit(); | ||||||
|  | 
 | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (!this.text) { |         if (!this.text) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -57,7 +57,36 @@ export class CoreLinkDirective implements OnInit { | |||||||
|     ngOnInit(): void { |     ngOnInit(): void { | ||||||
|         this.inApp = typeof this.inApp == 'undefined' ? this.inApp : CoreUtils.isTrueOrOne(this.inApp); |         this.inApp = typeof this.inApp == 'undefined' ? this.inApp : CoreUtils.isTrueOrOne(this.inApp); | ||||||
| 
 | 
 | ||||||
|  |         if (this.element.tagName != 'BUTTON' && this.element.tagName != 'A') { | ||||||
|  |             this.element.setAttribute('tabindex', '0'); | ||||||
|  |             this.element.setAttribute('role', 'button'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         this.element.addEventListener('click', async (event) => { |         this.element.addEventListener('click', async (event) => { | ||||||
|  |             this.performAction(event); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         this.element.addEventListener('keydown', (event: KeyboardEvent) => { | ||||||
|  |             if ((event.key == ' ' || event.key == 'Enter')) { | ||||||
|  |                 event.preventDefault(); | ||||||
|  |                 event.stopPropagation(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         this.element.addEventListener('keyup', (event: KeyboardEvent) => { | ||||||
|  |             if ((event.key == ' ' || event.key == 'Enter')) { | ||||||
|  |                 this.performAction(event); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Perform "click" action. | ||||||
|  |      * | ||||||
|  |      * @param event Event. | ||||||
|  |      * @returns Resolved when done. | ||||||
|  |      */ | ||||||
|  |     protected async performAction(event: Event): Promise<void> { | ||||||
|         if (event.defaultPrevented) { |         if (event.defaultPrevented) { | ||||||
|             return; // Link already treated, stop.
 |             return; // Link already treated, stop.
 | ||||||
|         } |         } | ||||||
| @ -84,7 +113,6 @@ export class CoreLinkDirective implements OnInit { | |||||||
|         } else { |         } else { | ||||||
|             this.navigate(href, openIn); |             this.navigate(href, openIn); | ||||||
|         } |         } | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <div *ngIf="blocks && blocks.length > 0 && !hideBlocks" [class.core-hide-blocks]="hideBottomBlocks" class="core-course-blocks-side"> | <div *ngIf="blocks && blocks.length > 0 && !hideBlocks" [class.core-hide-blocks]="hideBottomBlocks" class="core-course-blocks-side"> | ||||||
|     <core-loading [hideUntil]="dataLoaded" [fullscreen]="false"> |     <core-loading [hideUntil]="dataLoaded" [fullscreen]="false" class="margin"> | ||||||
|         <ion-list> |         <ion-list> | ||||||
|             <!-- Course expand="block"s. --> |             <!-- Course expand="block"s. --> | ||||||
|             <ng-container *ngFor="let block of blocks"> |             <ng-container *ngFor="let block of blocks"> | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|         </h2> |         </h2> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| </ion-item-divider> | </ion-item-divider> | ||||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false"> | <core-loading [hideUntil]="loaded" [fullscreen]="false" class="margin"> | ||||||
|     <ion-item *ngIf="block.contents?.content" class="ion-text-wrap core-block-content"> |     <ion-item *ngIf="block.contents?.content" class="ion-text-wrap core-block-content"> | ||||||
|         <ion-label> |         <ion-label> | ||||||
|             <core-format-text [text]="block.contents?.content" contextLevel="block" [contextInstanceId]="block.instanceid" |             <core-format-text [text]="block.contents?.content" contextLevel="block" [contextInstanceId]="block.instanceid" | ||||||
|  | |||||||
| @ -1,4 +0,0 @@ | |||||||
| .core-comments-clickable { |  | ||||||
|     pointer-events: auto; |  | ||||||
|     cursor: pointer; |  | ||||||
| } |  | ||||||
| @ -29,7 +29,6 @@ import { ContextLevel } from '@/core/constants'; | |||||||
| @Component({ | @Component({ | ||||||
|     selector: 'core-comments', |     selector: 'core-comments', | ||||||
|     templateUrl: 'core-comments.html', |     templateUrl: 'core-comments.html', | ||||||
|     styleUrls: ['comments.scss'], |  | ||||||
| }) | }) | ||||||
| export class CoreCommentsCommentsComponent implements OnInit, OnChanges, OnDestroy { | export class CoreCommentsCommentsComponent implements OnInit, OnChanges, OnDestroy { | ||||||
| 
 | 
 | ||||||
| @ -39,9 +38,9 @@ export class CoreCommentsCommentsComponent implements OnInit, OnChanges, OnDestr | |||||||
|     @Input() itemId!: number; |     @Input() itemId!: number; | ||||||
|     @Input() area = ''; |     @Input() area = ''; | ||||||
|     @Input() title?: string; |     @Input() title?: string; | ||||||
|     @Input() displaySpinner = true; // Whether to display the loading spinner.
 |     @Output() onLoading: EventEmitter<boolean>; // Event that indicates whether the component is loading data.
 | ||||||
|     @Output() onLoading: EventEmitter<boolean>; // Eevent that indicates whether the component is loading data.
 |  | ||||||
|     @Input() courseId?: number; // Course ID the comments belong to. It can be used to improve performance with filters.
 |     @Input() courseId?: number; // Course ID the comments belong to. It can be used to improve performance with filters.
 | ||||||
|  |     @Input() showItem = false; // Show button as an item.
 | ||||||
| 
 | 
 | ||||||
|     commentsLoaded = false; |     commentsLoaded = false; | ||||||
|     commentsCount = ''; |     commentsCount = ''; | ||||||
|  | |||||||
| @ -1,8 +1,27 @@ | |||||||
| <core-loading *ngIf="!disabled" [hideUntil]="commentsLoaded || !displaySpinner"> | <ng-container *ngIf="!disabled"> | ||||||
|     <div *ngIf="!countError" (click)="openComments($event)" [class.core-comments-clickable]="!disabled"> |     <core-loading *ngIf="!showItem" [hideUntil]="commentsLoaded" [fullscreen]="false" class="margin"> | ||||||
|  |         <button *ngIf="!countError" (click)="openComments($event)" class="as-link"> | ||||||
|             {{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }} |             {{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }} | ||||||
|     </div> |         </button> | ||||||
|         <div *ngIf="countError"> |         <div *ngIf="countError"> | ||||||
|             {{ 'core.comments.commentsnotworking' | translate }} |             {{ 'core.comments.commentsnotworking' | translate }} | ||||||
|         </div> |         </div> | ||||||
| </core-loading> |     </core-loading> | ||||||
|  |     <ion-item | ||||||
|  |         *ngIf="showItem" | ||||||
|  |         button | ||||||
|  |         [detail]="!countError && commentsLoaded" | ||||||
|  |         (click)="openComments($event)" | ||||||
|  |         [disabled]="countError"> | ||||||
|  |         <core-loading [hideUntil]="commentsLoaded" [fullscreen]="false"> | ||||||
|  |             <ion-label> | ||||||
|  |                 <p *ngIf="!countError" class="item-heading"> | ||||||
|  |                     {{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }} | ||||||
|  |                 </p> | ||||||
|  |                 <p *ngIf="countError"> | ||||||
|  |                     {{ 'core.comments.commentsnotworking' | translate }} | ||||||
|  |                 </p> | ||||||
|  |             </ion-label> | ||||||
|  |         </core-loading> | ||||||
|  |     </ion-item> | ||||||
|  | </ng-container> | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| <ion-item class="ion-text-wrap" *ngFor="let item of items" (click)="openCourse(item.courseId)" [attr.aria-label]="item.courseName" | <ion-item class="ion-text-wrap" *ngFor="let item of items" (click)="openCourse(item.courseId)" [attr.aria-label]="item.courseName" | ||||||
|     button> |     button detail="true"> | ||||||
|     <ion-icon name="fas-graduation-cap" slot="start" aria-hidden="true"></ion-icon> |     <ion-icon name="fas-graduation-cap" slot="start" aria-hidden="true"></ion-icon> | ||||||
|     <ion-label> |     <ion-label> | ||||||
|         <p class="item-heading">{{ item.courseName }}</p> |         <p class="item-heading">{{ item.courseName }}</p> | ||||||
|  | |||||||
| @ -114,11 +114,12 @@ | |||||||
|                 <ion-spinner *ngIf="prefetchCourseData.loading" slot="start"></ion-spinner> |                 <ion-spinner *ngIf="prefetchCourseData.loading" slot="start"></ion-spinner> | ||||||
|                 <ion-label><h2>{{ 'core.course.downloadcourse' | translate }}</h2></ion-label> |                 <ion-label><h2>{{ 'core.course.downloadcourse' | translate }}</h2></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item button (click)="openCourse()" [attr.aria-label]="course.fullname" *ngIf="!avoidOpenCourse && canAccessCourse"> |             <ion-item button (click)="openCourse()" [attr.aria-label]="course.fullname" *ngIf="!avoidOpenCourse && canAccessCourse" | ||||||
|  |                 detail="true"> | ||||||
|                 <ion-icon name="fas-briefcase" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-briefcase" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label><h2>{{ 'core.course.contents' | translate }}</h2></ion-label> |                 <ion-label><h2>{{ 'core.course.contents' | translate }}</h2></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item [href]="courseUrl" core-link [attr.aria-label]="course.fullname"> |             <ion-item [href]="courseUrl" core-link [attr.aria-label]="course.fullname" button detail="false"> | ||||||
|                 <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label><h2>{{ 'core.openinbrowser' | translate }}</h2></ion-label> |                 <ion-label><h2>{{ 'core.openinbrowser' | translate }}</h2></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| <ion-item class="ion-text-wrap" (click)="openCourse()" [class.item-disabled]="course.visible == 0" | <ion-item class="ion-text-wrap" (click)="openCourse()" [class.item-disabled]="course.visible == 0" | ||||||
| [attr.aria-label]="course.displayname || course.fullname" detail="true" button> |     [attr.aria-label]="course.displayname || course.fullname" detail="true" button> | ||||||
|     <ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" slot="start" class="course-icon" |     <ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" slot="start" class="course-icon" | ||||||
|         [attr.course-color]="course.color ? null : course.colorNumber" [style.color]="course.color"></ion-icon> |         [attr.course-color]="course.color ? null : course.colorNumber" [style.color]="course.color"></ion-icon> | ||||||
|     <ion-avatar *ngIf="course.courseImage" slot="start"> |     <ion-avatar *ngIf="course.courseImage" slot="start"> | ||||||
|  | |||||||
| @ -32,7 +32,9 @@ | |||||||
|                     <tbody> |                     <tbody> | ||||||
|                         <tr |                         <tr | ||||||
|                             *ngFor="let row of grades.rows" |                             *ngFor="let row of grades.rows" | ||||||
|                             (click)="row.itemtype != 'category' && grades.select(row)" |                             role="button row" | ||||||
|  |                             [attr.tabindex]="row.itemtype != 'category' ? 0 : null" | ||||||
|  |                             (ariaButtonClick)="row.itemtype != 'category' && grades.select(row)" | ||||||
|                             [class]="row.rowclass" |                             [class]="row.rowclass" | ||||||
|                             [ngClass]='{"core-grades-grade-clickable": row.itemtype != "category"}' |                             [ngClass]='{"core-grades-grade-clickable": row.itemtype != "category"}' | ||||||
|                         > |                         > | ||||||
|  | |||||||
| @ -4,13 +4,28 @@ | |||||||
|     --header-background: var(--white); |     --header-background: var(--white); | ||||||
|     --odd-cell-background: var(--gray-lighter); |     --odd-cell-background: var(--gray-lighter); | ||||||
|     --even-cell-background: var(--white); |     --even-cell-background: var(--white); | ||||||
|  |     --odd-cell-hover: var(--gray-light); | ||||||
|  |     --even-cell-hover: var(--gray-lighter); | ||||||
|     --icon-color: #999999; |     --icon-color: #999999; | ||||||
|  | 
 | ||||||
|  |     .odd { | ||||||
|  |         --cell-background: var(--odd-cell-background); | ||||||
|  |         --cell-hover: var(--odd-cell-hover); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .even { | ||||||
|  |         --cell-background: var(--even-cell-background); | ||||||
|  |         --cell-hover: var(--even-cell-hover); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| :host-context(body.dark) { | :host-context(body.dark) { | ||||||
|     --header-background: var(--black); |     --header-background: var(--black); | ||||||
|     --odd-cell-background: var(--gray-darker); |     --odd-cell-background: var(--gray-darker); | ||||||
|     --even-cell-background: var(--black); |     --even-cell-background: var(--black); | ||||||
|  |     --odd-cell-hover: var(--gray-dark); | ||||||
|  |     --even-cell-hover: var(--gray-darker); | ||||||
|     --icon-color: #eeeeee; |     --icon-color: #eeeeee; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -91,21 +106,19 @@ | |||||||
|         opacity: .7; |         opacity: .7; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     .odd { |     .odd, .even { | ||||||
|         td, th, th[aria-current="page"] { |         td, th, th[aria-current="page"] { | ||||||
|             background-color: var(--odd-cell-background); |             background-color: var(--cell-background); | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     .even { |  | ||||||
|         td, th, th[aria-current="page"] { |  | ||||||
|             background-color: var(--even-cell-background); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     .core-grades-grade-clickable { |     .core-grades-grade-clickable { | ||||||
|         cursor: pointer; |         cursor: pointer; | ||||||
|  |         &:hover { | ||||||
|  |             td, th, th[aria-current="page"] { | ||||||
|  |                 background-color: var(--cell-hover); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -78,7 +78,7 @@ | |||||||
|                 <ion-label><h3 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h3></ion-label> |                 <ion-label><h3 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h3></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item button *ngFor="let provider of identityProviders" class="ion-text-wrap core-oauth-icon" |             <ion-item button *ngFor="let provider of identityProviders" class="ion-text-wrap core-oauth-icon" | ||||||
|                 (click)="oauthClicked(provider)" [attr.aria-label]="provider.name"> |                 (click)="oauthClicked(provider)" [attr.aria-label]="provider.name" detail="false"> | ||||||
|                 <img [src]="provider.iconurl" alt="" width="32" height="32" slot="start"> |                 <img [src]="provider.iconurl" alt="" width="32" height="32" slot="start"> | ||||||
|                 <ion-label>{{provider.name}}</ion-label> |                 <ion-label>{{provider.name}}</ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|  | |||||||
| @ -88,7 +88,7 @@ | |||||||
|             <ion-label><h3 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h3></ion-label> |             <ion-label><h3 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h3></ion-label> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|         <ion-item button *ngFor="let provider of identityProviders" class="ion-text-wrap core-oauth-icon" |         <ion-item button *ngFor="let provider of identityProviders" class="ion-text-wrap core-oauth-icon" | ||||||
|             (click)="oauthClicked(provider)"> |             (click)="oauthClicked(provider)" detail="false"> | ||||||
|             <img [src]="provider.iconurl" alt="" role="presentation" width="32" height="32" slot="start"> |             <img [src]="provider.iconurl" alt="" role="presentation" width="32" height="32" slot="start"> | ||||||
|             <ion-label>{{provider.name}}</ion-label> |             <ion-label>{{provider.name}}</ion-label> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ | |||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|     <ion-list> |     <ion-list> | ||||||
|         <ion-item button (click)="login(site.id)" *ngFor="let site of sites"> |         <ion-item button (click)="login(site.id)" *ngFor="let site of sites" detail="true"> | ||||||
|             <ion-avatar slot="start"> |             <ion-avatar slot="start"> | ||||||
|                 <img [src]="site.avatar" core-external-content [siteId]="site.id" |                 <img [src]="site.avatar" core-external-content [siteId]="site.id" | ||||||
|                     alt="{{ 'core.pictureof' | translate:{$a: site.fullName} }}" onError="this.src='assets/img/user-avatar.png'"> |                     alt="{{ 'core.pictureof' | translate:{$a: site.fullName} }}" onError="this.src='assets/img/user-avatar.png'"> | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ | |||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  |     <core-loading [hideUntil]="!loggedOut"> | ||||||
|         <ion-list> |         <ion-list> | ||||||
|             <ion-item button *ngIf="siteInfo" class="ion-text-wrap" core-user-link [userId]="siteInfo.userid"> |             <ion-item button *ngIf="siteInfo" class="ion-text-wrap" core-user-link [userId]="siteInfo.userid"> | ||||||
|                 <core-user-avatar [user]="siteInfo" slot="start"></core-user-avatar> |                 <core-user-avatar [user]="siteInfo" slot="start"></core-user-avatar> | ||||||
| @ -25,7 +26,7 @@ | |||||||
|                 <ion-label><ion-spinner></ion-spinner></ion-label> |                 <ion-label><ion-spinner></ion-spinner></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item button *ngFor="let handler of handlers" [ngClass]="['core-moremenu-handler', handler.class || '']" |             <ion-item button *ngFor="let handler of handlers" [ngClass]="['core-moremenu-handler', handler.class || '']" | ||||||
|             (click)="openHandler(handler)" [attr.aria-label]="handler.title | translate" detail="true" detail="true"> |                 (click)="openHandler(handler)" [attr.aria-label]="handler.title | translate" detail="true"> | ||||||
|                 <ion-icon [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <p class="item-heading">{{ handler.title | translate}}</p> |                     <p class="item-heading">{{ handler.title | translate}}</p> | ||||||
| @ -94,4 +95,5 @@ | |||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-list> |         </ion-list> | ||||||
|  |     </core-loading> | ||||||
| </ion-content> | </ion-content> | ||||||
|  | |||||||
| @ -50,6 +50,7 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy { | |||||||
|     docsUrl?: string; |     docsUrl?: string; | ||||||
|     customItems?: CoreMainMenuCustomItem[]; |     customItems?: CoreMainMenuCustomItem[]; | ||||||
|     siteUrl?: string; |     siteUrl?: string; | ||||||
|  |     loggedOut = false; | ||||||
| 
 | 
 | ||||||
|     protected subscription!: Subscription; |     protected subscription!: Subscription; | ||||||
|     protected langObserver: CoreEventObserver; |     protected langObserver: CoreEventObserver; | ||||||
| @ -203,6 +204,7 @@ export class CoreMainMenuMorePage implements OnInit, OnDestroy { | |||||||
|      * Logout the user. |      * Logout the user. | ||||||
|      */ |      */ | ||||||
|     logout(): void { |     logout(): void { | ||||||
|  |         this.loggedOut = true; | ||||||
|         CoreSites.logout(); |         CoreSites.logout(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ | |||||||
|             <ion-list> |             <ion-list> | ||||||
|                 <ion-item *ngIf="siteInfo" class="ion-text-wrap"> |                 <ion-item *ngIf="siteInfo" class="ion-text-wrap"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{siteInfo!.fullname}}</h2> |                         <p class="item-heading">{{siteInfo!.fullname}}</p> | ||||||
|                         <p> |                         <p> | ||||||
|                             <core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" |                             <core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" | ||||||
|                                 [wsNotFiltered]="true"></core-format-text> |                                 [wsNotFiltered]="true"></core-format-text> | ||||||
| @ -33,19 +33,19 @@ | |||||||
|                     <ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon" aria-hidden="true"> |                     <ion-icon [name]="handler.icon" slot="start" *ngIf="handler.icon" aria-hidden="true"> | ||||||
|                     </ion-icon> |                     </ion-icon> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ handler.title | translate}}</h2> |                         <p class="item-heading">{{ handler.title | translate}}</p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|                 <ion-card> |                 <ion-card> | ||||||
|                     <ion-item class="ion-text-wrap" *ngIf="spaceUsage"> |                     <ion-item class="ion-text-wrap" *ngIf="spaceUsage"> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2 class="ion-text-wrap">{{ 'core.settings.spaceusage' | translate }} <ion-icon |                             <p class="item-heading ion-text-wrap">{{ 'core.settings.spaceusage' | translate }}</p> | ||||||
|                                     name="fas-info-circle" color="info" [attr.aria-label]="'core.info' | translate" |  | ||||||
|                                     (click)="showSpaceInfo()"></ion-icon> |  | ||||||
|                             </h2> |  | ||||||
|                             <p *ngIf="spaceUsage.spaceUsage">{{ spaceUsage.spaceUsage | coreBytesToSize }}</p> |                             <p *ngIf="spaceUsage.spaceUsage">{{ spaceUsage.spaceUsage | coreBytesToSize }}</p> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|  |                         <ion-button fill="clear" [attr.aria-label]="'core.info' | translate" (click)="showSpaceInfo()" slot="end"> | ||||||
|  |                             <ion-icon name="fas-info-circle" color="info" slot="icon-only"></ion-icon> | ||||||
|  |                         </ion-button> | ||||||
|                         <ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage()" |                         <ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage()" | ||||||
|                             [hidden]="spaceUsage.spaceUsage! + spaceUsage.cacheEntries! <= 0" |                             [hidden]="spaceUsage.spaceUsage! + spaceUsage.cacheEntries! <= 0" | ||||||
|                             [attr.aria-label]="'core.settings.deletesitefilestitle' | translate"> |                             [attr.aria-label]="'core.settings.deletesitefilestitle' | translate"> | ||||||
| @ -54,13 +54,13 @@ | |||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                     <ion-item class="ion-text-wrap"> |                     <ion-item class="ion-text-wrap"> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2>{{ 'core.settings.synchronizenow' | translate }} <ion-icon name="fas-info-circle" |                             <p class="item-heading">{{ 'core.settings.synchronizenow' | translate }}</p> | ||||||
|                                     color="info" [attr.aria-label]="'core.info' | translate" (click)="showSyncInfo()"> |  | ||||||
|                                 </ion-icon> |  | ||||||
|                             </h2> |  | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|  |                         <ion-button fill="clear" [attr.aria-label]="'core.info' | translate" (click)="showSyncInfo()" slot="end"> | ||||||
|  |                             <ion-icon name="fas-info-circle" color="info" slot="icon-only"></ion-icon> | ||||||
|  |                         </ion-button> | ||||||
|                         <ion-button fill="clear" slot="end" *ngIf="!isSynchronizing()" (click)="synchronize()" |                         <ion-button fill="clear" slot="end" *ngIf="!isSynchronizing()" (click)="synchronize()" | ||||||
|                             [title]="siteName" [attr.aria-label]="'core.settings.synchronizenow' | translate"> |                             [attr.aria-label]="'core.settings.synchronizenow' | translate"> | ||||||
|                             <ion-icon name="fas-sync-alt" slot="icon-only" aria-hidden="true"></ion-icon> |                             <ion-icon name="fas-sync-alt" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|                         </ion-button> |                         </ion-button> | ||||||
|                         <ion-spinner slot="end" *ngIf="isSynchronizing()"></ion-spinner> |                         <ion-spinner slot="end" *ngIf="isSynchronizing()"></ion-spinner> | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ | |||||||
|                 (onClick)="filePicked(file)" (onDelete)="fileDeleted(idx)" (onRename)="fileRenamed(idx, $event)"> |                 (onClick)="filePicked(file)" (onDelete)="fileDeleted(idx)" (onRename)="fileRenamed(idx, $event)"> | ||||||
|             </core-local-file> |             </core-local-file> | ||||||
| 
 | 
 | ||||||
|             <ion-item button *ngIf="!file.isFile" class="ion-text-wrap item-file" (click)="openFolder(file)"> |             <ion-item button *ngIf="!file.isFile" class="ion-text-wrap item-file" (click)="openFolder(file)" detail="true"> | ||||||
|                 <ion-thumbnail slot="start" aria-hidden="true"> |                 <ion-thumbnail slot="start" aria-hidden="true"> | ||||||
|                     <img src="assets/img/files/folder-64.png" alt=""> |                     <img src="assets/img/files/folder-64.png" alt=""> | ||||||
|                 </ion-thumbnail> |                 </ion-thumbnail> | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ | |||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="!displaySize || !size || ( |         <core-context-menu-item [hidden]="!displaySize || !size || ( | ||||||
|             content?.compileComponent?.componentInstance?.displaySize === false)" [priority]="500" |             content?.compileComponent?.componentInstance?.displaySize === false)" [priority]="500" | ||||||
|             [content]="'core.clearstoreddata' | translate:{$a: size}" [iconDescription]="'cube'" (action)="removeFiles()" |             [content]="'core.clearstoreddata' | translate:{$a: size}" [iconDescription]="'fas-archive'" (action)="removeFiles()" | ||||||
|             iconAction="fas-trash" [closeOnClick]="false"> |             iconAction="fas-trash" [closeOnClick]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|     </core-context-menu> |     </core-context-menu> | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| <core-loading [hideUntil]="dataLoaded" [fullscreen]="false"> | <core-loading [hideUntil]="dataLoaded" [fullscreen]="false" class="margin"> | ||||||
|     <core-compile-html [text]="content" [javascript]="javascript" [jsData]="jsData" [forceCompile]="forceCompile" #compile> |     <core-compile-html [text]="content" [javascript]="javascript" [jsData]="jsData" [forceCompile]="forceCompile" #compile> | ||||||
|     </core-compile-html> |     </core-compile-html> | ||||||
| </core-loading> | </core-loading> | ||||||
|  | |||||||
| @ -19,7 +19,8 @@ | |||||||
|                     <ion-label class="ion-text-wrap">{{ 'core.tag.warningareasnotsupported' | translate }}</ion-label> |                     <ion-label class="ion-text-wrap">{{ 'core.tag.warningareasnotsupported' | translate }}</ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let area of areas" [attr.aria-label]="area.nameKey | translate" |                 <ion-item class="ion-text-wrap" *ngFor="let area of areas" [attr.aria-label]="area.nameKey | translate" | ||||||
|                     (click)="openArea(area)" [attr.aria-current]="area!.id == selectedAreaId ? 'page' : 'false'" button> |                     (click)="openArea(area)" [attr.aria-current]="area!.id == selectedAreaId ? 'page' : 'false'" button | ||||||
|  |                     detail="true"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ area!.nameKey | translate }}</h2> |                         <h2>{{ area!.nameKey | translate }}</h2> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ | |||||||
|             <ion-list *ngIf="!participants.empty"> |             <ion-list *ngIf="!participants.empty"> | ||||||
|                 <ion-item *ngFor="let participant of participants.items" |                 <ion-item *ngFor="let participant of participants.items" | ||||||
|                     class="ion-text-wrap" [attr.aria-current]="participants.getItemAriaCurrent(participant)" |                     class="ion-text-wrap" [attr.aria-current]="participants.getItemAriaCurrent(participant)" | ||||||
|                     [attr.aria-label]="participant.fullname" (click)="participants.select(participant)" button> |                     [attr.aria-label]="participant.fullname" (click)="participants.select(participant)" button detail="true"> | ||||||
| 
 | 
 | ||||||
|                     <core-user-avatar [user]="participant" [linkProfile]="false" [checkOnline]="true" slot="start"> |                     <core-user-avatar [user]="participant" [linkProfile]="false" [checkOnline]="true" slot="start"> | ||||||
|                     </core-user-avatar> |                     </core-user-avatar> | ||||||
|  | |||||||
| @ -37,6 +37,7 @@ import { CoreNetworkError } from '@classes/errors/network-error'; | |||||||
| import { CoreBSTooltipComponent } from '@components/bs-tooltip/bs-tooltip'; | import { CoreBSTooltipComponent } from '@components/bs-tooltip/bs-tooltip'; | ||||||
| import { CoreViewerImageComponent } from '@features/viewer/components/image/image'; | import { CoreViewerImageComponent } from '@features/viewer/components/image/image'; | ||||||
| import { CoreFormFields, CoreForms } from '../../singletons/form'; | import { CoreFormFields, CoreForms } from '../../singletons/form'; | ||||||
|  | import { CoreModalLateralTransitionEnter, CoreModalLateralTransitionLeave } from '@classes/modal-lateral-transition'; | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  * "Utils" service with helper functions for UI, DOM elements and HTML code. |  * "Utils" service with helper functions for UI, DOM elements and HTML code. | ||||||
| @ -1721,8 +1722,8 @@ export class CoreDomUtilsProvider { | |||||||
|             cssClass: 'core-modal-lateral', |             cssClass: 'core-modal-lateral', | ||||||
|             showBackdrop: true, |             showBackdrop: true, | ||||||
|             backdropDismiss: true, |             backdropDismiss: true, | ||||||
|             // @todo enterAnimation: 'core-modal-lateral-transition',
 |             enterAnimation: CoreModalLateralTransitionEnter, | ||||||
|             // @todo leaveAnimation: 'core-modal-lateral-transition',
 |             leaveAnimation: CoreModalLateralTransitionLeave, | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         return await this.openModal<T>(modalOptions); |         return await this.openModal<T>(modalOptions); | ||||||
|  | |||||||
| @ -78,6 +78,8 @@ core-format-text { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         &.core-expand-in-fullview { |         &.core-expand-in-fullview { | ||||||
|  |             cursor: pointer; | ||||||
|  | 
 | ||||||
|             .core-show-more { |             .core-show-more { | ||||||
|                 @include push-arrow-color(626262, true); |                 @include push-arrow-color(626262, true); | ||||||
|                 @include padding-horizontal(null, 5px); |                 @include padding-horizontal(null, 5px); | ||||||
|  | |||||||
| @ -137,16 +137,6 @@ ion-item.ion-text-wrap ion-label { | |||||||
|     white-space: normal !important; |     white-space: normal !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // It fixes the click on links where ion-ripple-effect is present. |  | ||||||
| .ion-activatable ion-label, |  | ||||||
| .item-multiple-items ion-label { |  | ||||||
|     z-index: 3; |  | ||||||
|     pointer-events: none; |  | ||||||
|     ion-anchor, ion-button, a, button { |  | ||||||
|         pointer-events: visible; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @each $color-name, $value in $colors { | @each $color-name, $value in $colors { | ||||||
|     $value: map-get($colors, $color-name); |     $value: map-get($colors, $color-name); | ||||||
|     $base: map-get($value, base); |     $base: map-get($value, base); | ||||||
| @ -195,6 +185,8 @@ ion-header ion-toolbar { | |||||||
| 
 | 
 | ||||||
| // Ionic icon. | // Ionic icon. | ||||||
| ion-icon { | ion-icon { | ||||||
|  |     position: relative; | ||||||
|  | 
 | ||||||
|     &.icon-slash::after, |     &.icon-slash::after, | ||||||
|     &.icon-backslash::after { |     &.icon-backslash::after { | ||||||
|         content: " "; |         content: " "; | ||||||
| @ -238,7 +230,8 @@ button, | |||||||
|     min-width: var(--a11y-min-target-size); |     min-width: var(--a11y-min-target-size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| [role="button"] { | [role="button"], | ||||||
|  | .clickable { | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
| 
 | 
 | ||||||
|     [disabled], |     [disabled], | ||||||
| @ -256,6 +249,21 @@ ion-button.core-button-as-link { | |||||||
|     white-space: break-spaces; |     white-space: break-spaces; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | button.as-link { | ||||||
|  |     display: inline; | ||||||
|  |     min-height: auto; | ||||||
|  |     min-width: auto; | ||||||
|  |     color: var(--core-link-color); | ||||||
|  |     background: none; | ||||||
|  |     border: 0; | ||||||
|  |     line-height: inherit; | ||||||
|  |     margin: 0; | ||||||
|  |     padding: 0; | ||||||
|  |     text-align: start; | ||||||
|  |     font-size: inherit; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| // Ionic alert. | // Ionic alert. | ||||||
| ion-alert.core-alert-network-error .alert-head, | ion-alert.core-alert-network-error .alert-head, | ||||||
| div.core-iframe-network-error { | div.core-iframe-network-error { | ||||||
| @ -658,8 +666,11 @@ audio.core-media-adapt-width { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // It fixes the click on links where ion-ripple-effect is present. | ||||||
| // Make links clickable when inside radio or checkbox items. Pointer and cursor part. | // Make links clickable when inside radio or checkbox items. Pointer and cursor part. | ||||||
| ion-item.item-multiple-inputs { | ion-item.item-multiple-inputs:not(.only-links), | ||||||
|  | ion-item.ion-activatable:not(.only-links) { | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     ion-label { |     ion-label { | ||||||
|         z-index: 3; |         z-index: 3; | ||||||
| @ -677,6 +688,12 @@ ion-item.item-multiple-inputs { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | ion-item.item-multiple-inputs.only-links { | ||||||
|  |     a { | ||||||
|  |         cursor: pointer; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Case with ion-input + ion-select inside. | // Case with ion-input + ion-select inside. | ||||||
| ion-item.item-input.item-multiple-inputs { | ion-item.item-input.item-multiple-inputs { | ||||||
|     .flex-row { |     .flex-row { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user