forked from CIT/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"
 | 
					                    </core-comments>
 | 
				
			||||||
                                [instanceId]="entry.userid" contextLevel="user">
 | 
					 | 
				
			||||||
                            </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>
 | 
				
			||||||
                    <a *ngIf="competency.competency.comppath.showlinks"
 | 
					                    <p>
 | 
				
			||||||
                        [href]="competency.competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' +
 | 
					                        <a *ngIf="competency.competency.comppath.showlinks"
 | 
				
			||||||
                        competency.competency.comppath.framework.id + '&pagecontextid=' +
 | 
					                            [href]="competency.competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' +
 | 
				
			||||||
                        competency.competency.comppath.pagecontextid"
 | 
					                            competency.competency.comppath.framework.id + '&pagecontextid=' +
 | 
				
			||||||
                        core-link [title]="competency.competency.comppath.framework.name">
 | 
					                            competency.competency.comppath.pagecontextid"
 | 
				
			||||||
                        {{ competency.competency.comppath.framework.name }}
 | 
					                            core-link>
 | 
				
			||||||
                    </a>
 | 
					                            {{ competency.competency.comppath.framework.name }}
 | 
				
			||||||
                    <ng-container *ngIf="!competency.competency.comppath.showlinks">
 | 
					 | 
				
			||||||
                        {{ competency.competency.comppath.framework.name }}
 | 
					 | 
				
			||||||
                    </ng-container>
 | 
					 | 
				
			||||||
                     / 
 | 
					 | 
				
			||||||
                    <span *ngFor="let ancestor of competency.competency.comppath.ancestors">
 | 
					 | 
				
			||||||
                        <a *ngIf="competency.competency.comppath.showlinks" (click)="openCompetencySummary(ancestor.id)">
 | 
					 | 
				
			||||||
                            {{ ancestor.name }}
 | 
					 | 
				
			||||||
                        </a>
 | 
					                        </a>
 | 
				
			||||||
                        <ng-container *ngIf="!competency.competency.comppath.showlinks">{{ ancestor.name }}</ng-container>
 | 
					                        <ng-container *ngIf="!competency.competency.comppath.showlinks">
 | 
				
			||||||
                        <ng-container *ngIf="!ancestor.last"> / </ng-container>
 | 
					                            {{ competency.competency.comppath.framework.name }}
 | 
				
			||||||
                    </span>
 | 
					                        </ng-container>
 | 
				
			||||||
 | 
					                         / 
 | 
				
			||||||
 | 
					                        <ng-container *ngFor="let ancestor of competency.competency.comppath.ancestors">
 | 
				
			||||||
 | 
					                            <button *ngIf="competency.competency.comppath.showlinks" (click)="openCompetencySummary(ancestor.id)"
 | 
				
			||||||
 | 
					                                class="as-link">
 | 
				
			||||||
 | 
					                                {{ ancestor.name }}
 | 
				
			||||||
 | 
					                            </button>
 | 
				
			||||||
 | 
					                            <ng-container *ngIf="!competency.competency.comppath.showlinks">{{ ancestor.name }}</ng-container>
 | 
				
			||||||
 | 
					                            <ng-container *ngIf="!ancestor.last"> / </ng-container>
 | 
				
			||||||
 | 
					                        </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>
 | 
					                    </p>
 | 
				
			||||||
                    <div *ngIf="competency.competency.hasrelatedcompetencies">
 | 
					                    <ng-container *ngIf="competency.competency.hasrelatedcompetencies">
 | 
				
			||||||
                        <p *ngFor="let relatedcomp of competency.competency.relatedcompetencies">
 | 
					                        <p *ngFor="let relatedcomp of competency.competency.relatedcompetencies">
 | 
				
			||||||
                            <a (click)="openCompetencySummary(relatedcomp.id)">
 | 
					                            <button (click)="openCompetencySummary(relatedcomp.id)" class="as-link">
 | 
				
			||||||
                                {{ relatedcomp.shortname }} - {{ relatedcomp.idnumber }}
 | 
					                                {{ relatedcomp.shortname }} - {{ relatedcomp.idnumber }}
 | 
				
			||||||
                            </a>
 | 
					                            </button>
 | 
				
			||||||
                        </p>
 | 
					                        </p>
 | 
				
			||||||
                    </div>
 | 
					                    </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,33 +79,36 @@
 | 
				
			|||||||
                            </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>
 | 
				
			||||||
                            <a *ngIf="competency.comppath.showlinks"
 | 
					                            <p>
 | 
				
			||||||
                                [href]="competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' +
 | 
					                                <a *ngIf="competency.comppath.showlinks"
 | 
				
			||||||
                                competency.comppath.framework.id + '&pagecontextid=' + competency.comppath.pagecontextid"
 | 
					                                    [href]="competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' +
 | 
				
			||||||
                                core-link [title]="competency.comppath.framework.name">
 | 
					                                    competency.comppath.framework.id + '&pagecontextid=' + competency.comppath.pagecontextid"
 | 
				
			||||||
                                {{ competency.comppath.framework.name }}
 | 
					                                    core-link [title]="competency.comppath.framework.name">
 | 
				
			||||||
                            </a>
 | 
					                                    {{ competency.comppath.framework.name }}
 | 
				
			||||||
                            <ng-container *ngIf="!competency.comppath.showlinks">
 | 
					 | 
				
			||||||
                                {{ competency.comppath.framework.name }}
 | 
					 | 
				
			||||||
                            </ng-container>
 | 
					 | 
				
			||||||
                             / 
 | 
					 | 
				
			||||||
                            <span *ngFor="let ancestor of competency.comppath.ancestors">
 | 
					 | 
				
			||||||
                                <a *ngIf="competency.comppath.showlinks" (click)="openCompetencySummary(ancestor.id)">
 | 
					 | 
				
			||||||
                                    {{ ancestor.name }}
 | 
					 | 
				
			||||||
                                </a>
 | 
					                                </a>
 | 
				
			||||||
                                <ng-container *ngIf="!competency.comppath.showlinks">{{ ancestor.name }}</ng-container>
 | 
					                                <ng-container *ngIf="!competency.comppath.showlinks">
 | 
				
			||||||
                                <ng-container *ngIf="!ancestor.last"> / </ng-container>
 | 
					                                    {{ competency.comppath.framework.name }}
 | 
				
			||||||
                            </span>
 | 
					                                </ng-container>
 | 
				
			||||||
 | 
					                                 / 
 | 
				
			||||||
 | 
					                                <ng-container *ngFor="let ancestor of competency.comppath.ancestors">
 | 
				
			||||||
 | 
					                                    <button class="as-link" *ngIf="competency.comppath.showlinks"
 | 
				
			||||||
 | 
					                                        (click)="openCompetencySummary(ancestor.id)">
 | 
				
			||||||
 | 
					                                        {{ ancestor.name }}
 | 
				
			||||||
 | 
					                                    </button>
 | 
				
			||||||
 | 
					                                    <ng-container *ngIf="!competency.comppath.showlinks">{{ ancestor.name }}</ng-container>
 | 
				
			||||||
 | 
					                                    <ng-container *ngIf="!ancestor.last"> / </ng-container>
 | 
				
			||||||
 | 
					                                </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>
 | 
				
			||||||
                        <core-format-text [text]="plan.plan.description" contextLevel="user"
 | 
					                        <p>
 | 
				
			||||||
                            [contextInstanceId]="plan.plan.userid">
 | 
					                            <core-format-text [text]="plan.plan.description" contextLevel="user"
 | 
				
			||||||
                        </core-format-text>
 | 
					                                [contextInstanceId]="plan.plan.userid">
 | 
				
			||||||
 | 
					                            </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. -->
 | 
				
			||||||
@ -128,7 +131,7 @@
 | 
				
			|||||||
    <!-- Scroll bottom. -->
 | 
					    <!-- Scroll bottom. -->
 | 
				
			||||||
    <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="loaded && newMessages > 0">
 | 
					    <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="loaded && newMessages > 0">
 | 
				
			||||||
        <ion-fab-button size="small" (click)="scrollToFirstUnreadMessage()" color="light"
 | 
					        <ion-fab-button size="small" (click)="scrollToFirstUnreadMessage()" color="light"
 | 
				
			||||||
        [attr.aria-label]="'addon.messages.newmessages' | translate">
 | 
					            [attr.aria-label]="'addon.messages.newmessages' | translate">
 | 
				
			||||||
            <ion-icon name="fas-arrow-down" aria-hidden="true"></ion-icon>
 | 
					            <ion-icon name="fas-arrow-down" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            <span class="core-discussion-messages-badge">{{ newMessages }}</span>
 | 
					            <span class="core-discussion-messages-badge">{{ newMessages }}</span>
 | 
				
			||||||
        </ion-fab-button>
 | 
					        </ion-fab-button>
 | 
				
			||||||
 | 
				
			|||||||
@ -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,11 +19,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        <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">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ion-list   class="ion-no-margin">
 | 
					            <ion-list class="ion-no-margin">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()"
 | 
					                <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()"
 | 
				
			||||||
                    [attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button>
 | 
					                    [attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button>
 | 
				
			||||||
@ -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">
 | 
				
			||||||
            <p [innerHTML]="'addon.mod_data.foundrecords' | translate:{$a: foundRecordsTranslationData}"></p>
 | 
					                <ion-label>
 | 
				
			||||||
            </ion-label></ion-item>
 | 
					                    <p [innerHTML]="'addon.mod_data.foundrecords' | translate:{$a: foundRecordsTranslationData}"></p>
 | 
				
			||||||
 | 
					                </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 {
 | 
					
 | 
				
			||||||
        padding: 0;
 | 
					ion-list {
 | 
				
			||||||
    }
 | 
					    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 {
 | 
					    .core-loading-message {
 | 
				
			||||||
            display: table-cell;
 | 
					        @include margin(10px, 0, 0, 0);
 | 
				
			||||||
            text-align: center;
 | 
					 | 
				
			||||||
            vertical-align: middle;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .core-loading-content {
 | 
					    .core-loading-content {
 | 
				
			||||||
@ -48,21 +57,26 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    &.core-loading-inline {
 | 
					    &.core-loading-inline {
 | 
				
			||||||
        display: block;
 | 
					        --loading-background: transparent;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        .core-loading-container {
 | 
					 | 
				
			||||||
            padding-top: 20px;
 | 
					 | 
				
			||||||
            position: relative;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &.core-loading-loaded.core-loading-inline {
 | 
					 | 
				
			||||||
        position: relative;
 | 
					        position: relative;
 | 
				
			||||||
        min-height: 102px;
 | 
					        display: block;
 | 
				
			||||||
 | 
					        min-height: var(--loading-inline-min-height);
 | 
				
			||||||
 | 
					        margin-top: var(--loading-inline-margin);
 | 
				
			||||||
 | 
					        margin-bottom: var(--loading-inline-margin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .core-loading-message {
 | 
				
			||||||
 | 
					            @include margin(0, 0, 0, 10px);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .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,34 +57,62 @@ 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) => {
 | 
				
			||||||
            if (event.defaultPrevented) {
 | 
					            this.performAction(event);
 | 
				
			||||||
                return; // Link already treated, stop.
 | 
					        });
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let href = this.href || this.element.getAttribute('href') || this.element.getAttribute('xlink:href');
 | 
					        this.element.addEventListener('keydown', (event: KeyboardEvent) => {
 | 
				
			||||||
 | 
					            if ((event.key == ' ' || event.key == 'Enter')) {
 | 
				
			||||||
            if (!href || CoreUrlUtils.getUrlScheme(href) == 'javascript') {
 | 
					                event.preventDefault();
 | 
				
			||||||
                return;
 | 
					                event.stopPropagation();
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            event.preventDefault();
 | 
					 | 
				
			||||||
            event.stopPropagation();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const openIn = this.element.getAttribute('data-open-in');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (CoreUtils.isTrueOrOne(this.capture)) {
 | 
					 | 
				
			||||||
                href = CoreTextUtils.decodeURI(href);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                const treated = await CoreContentLinksHelper.handleLink(href, undefined, true, true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!treated) {
 | 
					 | 
				
			||||||
                    this.navigate(href, openIn);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                this.navigate(href, openIn);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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) {
 | 
				
			||||||
 | 
					            return; // Link already treated, stop.
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let href = this.href || this.element.getAttribute('href') || this.element.getAttribute('xlink:href');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!href || CoreUrlUtils.getUrlScheme(href) == 'javascript') {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        event.preventDefault();
 | 
				
			||||||
 | 
					        event.stopPropagation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const openIn = this.element.getAttribute('data-open-in');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (CoreUtils.isTrueOrOne(this.capture)) {
 | 
				
			||||||
 | 
					            href = CoreTextUtils.decodeURI(href);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const treated = await CoreContentLinksHelper.handleLink(href, undefined, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!treated) {
 | 
				
			||||||
 | 
					                this.navigate(href, openIn);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            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">
 | 
				
			||||||
        {{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
 | 
					        <button *ngIf="!countError" (click)="openComments($event)" class="as-link">
 | 
				
			||||||
    </div>
 | 
					            {{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
 | 
				
			||||||
    <div *ngIf="countError">
 | 
					        </button>
 | 
				
			||||||
        {{ 'core.comments.commentsnotworking' | translate }}
 | 
					        <div *ngIf="countError">
 | 
				
			||||||
    </div>
 | 
					            {{ 'core.comments.commentsnotworking' | translate }}
 | 
				
			||||||
</core-loading>
 | 
					        </div>
 | 
				
			||||||
 | 
					    </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">
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@
 | 
				
			|||||||
                    <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					                    <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                </ion-button>
 | 
					                </ion-button>
 | 
				
			||||||
                <ion-button [hidden]="!downloadAllCoursesEnabled || !courses || courses.length < 2 || downloadAllCoursesLoading"
 | 
					                <ion-button [hidden]="!downloadAllCoursesEnabled || !courses || courses.length < 2 || downloadAllCoursesLoading"
 | 
				
			||||||
                (click)="prefetchCourses()" [attr.aria-label]="'core.courses.downloadcourses' | translate">
 | 
					                    (click)="prefetchCourses()" [attr.aria-label]="'core.courses.downloadcourses' | translate">
 | 
				
			||||||
                    <ion-icon [name]="downloadAllCoursesIcon" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					                    <ion-icon [name]="downloadAllCoursesIcon" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                </ion-button>
 | 
					                </ion-button>
 | 
				
			||||||
                <ion-spinner [hidden]="!downloadAllCoursesEnabled || !courses || courses.length < 2 ||
 | 
					                <ion-spinner [hidden]="!downloadAllCoursesEnabled || !courses || courses.length < 2 ||
 | 
				
			||||||
 | 
				
			|||||||
@ -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,90 +8,92 @@
 | 
				
			|||||||
    </ion-toolbar>
 | 
					    </ion-toolbar>
 | 
				
			||||||
</ion-header>
 | 
					</ion-header>
 | 
				
			||||||
<ion-content>
 | 
					<ion-content>
 | 
				
			||||||
    <ion-list>
 | 
					    <core-loading [hideUntil]="!loggedOut">
 | 
				
			||||||
        <ion-item button *ngIf="siteInfo" class="ion-text-wrap" core-user-link [userId]="siteInfo.userid">
 | 
					        <ion-list>
 | 
				
			||||||
            <core-user-avatar [user]="siteInfo" slot="start"></core-user-avatar>
 | 
					            <ion-item button *ngIf="siteInfo" class="ion-text-wrap" core-user-link [userId]="siteInfo.userid">
 | 
				
			||||||
            <ion-label>
 | 
					                <core-user-avatar [user]="siteInfo" slot="start"></core-user-avatar>
 | 
				
			||||||
                <h2>{{siteInfo.fullname}}</h2>
 | 
					 | 
				
			||||||
                <p>
 | 
					 | 
				
			||||||
                    <core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
 | 
					 | 
				
			||||||
                    </core-format-text>
 | 
					 | 
				
			||||||
                </p>
 | 
					 | 
				
			||||||
                <p>{{ siteUrl }}</p>
 | 
					 | 
				
			||||||
            </ion-label>
 | 
					 | 
				
			||||||
        </ion-item>
 | 
					 | 
				
			||||||
        <core-spacer></core-spacer>
 | 
					 | 
				
			||||||
        <ion-item class="ion-text-center" *ngIf="(!handlers || !handlers.length) && !handlersLoaded">
 | 
					 | 
				
			||||||
            <ion-label><ion-spinner></ion-spinner></ion-label>
 | 
					 | 
				
			||||||
        </ion-item>
 | 
					 | 
				
			||||||
        <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">
 | 
					 | 
				
			||||||
            <ion-icon [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
					 | 
				
			||||||
            <ion-label>
 | 
					 | 
				
			||||||
                <p class="item-heading">{{ handler.title | translate}}</p>
 | 
					 | 
				
			||||||
            </ion-label>
 | 
					 | 
				
			||||||
            <ion-badge slot="end" *ngIf="handler.showBadge" [hidden]="handler.loading || !handler.badge" aria-hidden="true">
 | 
					 | 
				
			||||||
                {{handler.badge}}
 | 
					 | 
				
			||||||
            </ion-badge>
 | 
					 | 
				
			||||||
            <span *ngIf="handler.showBadge && handler.badge && handler.badgeA11yText" class="sr-only">
 | 
					 | 
				
			||||||
                {{ handler.badgeA11yText | translate: {$a : handler.badge } }}
 | 
					 | 
				
			||||||
            </span>
 | 
					 | 
				
			||||||
            <ion-spinner slot="end" *ngIf="handler.showBadge && handler.loading"></ion-spinner>
 | 
					 | 
				
			||||||
        </ion-item>
 | 
					 | 
				
			||||||
        <ng-container *ngFor="let item of customItems">
 | 
					 | 
				
			||||||
            <ion-item button *ngIf="item.type != 'embedded'" [href]="item.url" [attr.aria-label]="item.label" core-link
 | 
					 | 
				
			||||||
                [capture]="item.type == 'app'" [inApp]="item.type == 'inappbrowser'" class="core-moremenu-customitem" detail="true">
 | 
					 | 
				
			||||||
                <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
					 | 
				
			||||||
                <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
                    <p class="item-heading">{{item.label}}</p>
 | 
					                    <h2>{{siteInfo.fullname}}</h2>
 | 
				
			||||||
 | 
					                    <p>
 | 
				
			||||||
 | 
					                        <core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
 | 
				
			||||||
 | 
					                        </core-format-text>
 | 
				
			||||||
 | 
					                    </p>
 | 
				
			||||||
 | 
					                    <p>{{ siteUrl }}</p>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
            <ion-item button *ngIf="item.type == 'embedded'" (click)="openItem(item)" [attr.aria-label]="item.label"
 | 
					            <core-spacer></core-spacer>
 | 
				
			||||||
                class="core-moremenu-customitem" detail="true">
 | 
					            <ion-item class="ion-text-center" *ngIf="(!handlers || !handlers.length) && !handlersLoaded">
 | 
				
			||||||
                <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-label><ion-spinner></ion-spinner></ion-label>
 | 
				
			||||||
 | 
					            </ion-item>
 | 
				
			||||||
 | 
					            <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">
 | 
				
			||||||
 | 
					                <ion-icon [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
                    <p class="item-heading">{{item.label}}</p>
 | 
					                    <p class="item-heading">{{ handler.title | translate}}</p>
 | 
				
			||||||
 | 
					                </ion-label>
 | 
				
			||||||
 | 
					                <ion-badge slot="end" *ngIf="handler.showBadge" [hidden]="handler.loading || !handler.badge" aria-hidden="true">
 | 
				
			||||||
 | 
					                    {{handler.badge}}
 | 
				
			||||||
 | 
					                </ion-badge>
 | 
				
			||||||
 | 
					                <span *ngIf="handler.showBadge && handler.badge && handler.badgeA11yText" class="sr-only">
 | 
				
			||||||
 | 
					                    {{ handler.badgeA11yText | translate: {$a : handler.badge } }}
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					                <ion-spinner slot="end" *ngIf="handler.showBadge && handler.loading"></ion-spinner>
 | 
				
			||||||
 | 
					            </ion-item>
 | 
				
			||||||
 | 
					            <ng-container *ngFor="let item of customItems">
 | 
				
			||||||
 | 
					                <ion-item button *ngIf="item.type != 'embedded'" [href]="item.url" [attr.aria-label]="item.label" core-link
 | 
				
			||||||
 | 
					                    [capture]="item.type == 'app'" [inApp]="item.type == 'inappbrowser'" class="core-moremenu-customitem" detail="true">
 | 
				
			||||||
 | 
					                    <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
 | 
					                    <ion-label>
 | 
				
			||||||
 | 
					                        <p class="item-heading">{{item.label}}</p>
 | 
				
			||||||
 | 
					                    </ion-label>
 | 
				
			||||||
 | 
					                </ion-item>
 | 
				
			||||||
 | 
					                <ion-item button *ngIf="item.type == 'embedded'" (click)="openItem(item)" [attr.aria-label]="item.label"
 | 
				
			||||||
 | 
					                    class="core-moremenu-customitem" detail="true">
 | 
				
			||||||
 | 
					                    <ion-icon [name]="item.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
 | 
					                    <ion-label>
 | 
				
			||||||
 | 
					                        <p class="item-heading">{{item.label}}</p>
 | 
				
			||||||
 | 
					                    </ion-label>
 | 
				
			||||||
 | 
					                </ion-item>
 | 
				
			||||||
 | 
					            </ng-container>
 | 
				
			||||||
 | 
					            <ion-item button *ngIf="showScanQR" (click)="scanQR()" detail="true">
 | 
				
			||||||
 | 
					                <ion-icon name="fas-qrcode" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
 | 
					                <ion-label>
 | 
				
			||||||
 | 
					                    <p class="item-heading">{{ 'core.scanqr' | translate }}</p>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
        </ng-container>
 | 
					            <ion-item button *ngIf="showWeb && siteInfo" [href]="siteInfo.siteurl" core-link autoLogin="yes"
 | 
				
			||||||
        <ion-item button *ngIf="showScanQR" (click)="scanQR()" detail="true">
 | 
					                [attr.aria-label]="'core.mainmenu.website' | translate" detail="true">
 | 
				
			||||||
            <ion-icon name="fas-qrcode" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-globe" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
                <p class="item-heading">{{ 'core.scanqr' | translate }}</p>
 | 
					                    <p class="item-heading">{{ 'core.mainmenu.website' | translate }}</p>
 | 
				
			||||||
            </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
        <ion-item button *ngIf="showWeb && siteInfo" [href]="siteInfo.siteurl" core-link autoLogin="yes"
 | 
					            <ion-item button *ngIf="showHelp" [href]="docsUrl" core-link autoLogin="no"
 | 
				
			||||||
            [attr.aria-label]="'core.mainmenu.website' | translate" detail="true">
 | 
					                [attr.aria-label]="'core.mainmenu.help' | translate" detail="true">
 | 
				
			||||||
            <ion-icon name="fas-globe" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="far-life-ring" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
                <p class="item-heading">{{ 'core.mainmenu.website' | translate }}</p>
 | 
					                    <p class="item-heading">{{ 'core.mainmenu.help' | translate }}</p>
 | 
				
			||||||
            </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
        <ion-item button *ngIf="showHelp" [href]="docsUrl" core-link autoLogin="no"
 | 
					            <ion-item button (click)="openPreferences()" [attr.aria-label]="'core.settings.preferences' | translate" detail="true">
 | 
				
			||||||
            [attr.aria-label]="'core.mainmenu.help' | translate" detail="true">
 | 
					                <ion-icon name="fas-wrench" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            <ion-icon name="far-life-ring" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-label>
 | 
				
			||||||
            <ion-label>
 | 
					                    <p class="item-heading">{{ 'core.settings.preferences' | translate }}</p>
 | 
				
			||||||
                <p class="item-heading">{{ 'core.mainmenu.help' | translate }}</p>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-item>
 | 
				
			||||||
        </ion-item>
 | 
					            <ion-item button (click)="logout()" [attr.aria-label]="logoutLabel | translate" detail="true">
 | 
				
			||||||
        <ion-item button (click)="openPreferences()" [attr.aria-label]="'core.settings.preferences' | translate" detail="true">
 | 
					                <ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            <ion-icon name="fas-wrench" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-label>
 | 
				
			||||||
            <ion-label>
 | 
					                    <p class="item-heading">{{ logoutLabel | translate }}</p>
 | 
				
			||||||
                <p class="item-heading">{{ 'core.settings.preferences' | translate }}</p>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-item>
 | 
				
			||||||
        </ion-item>
 | 
					            <core-spacer></core-spacer>
 | 
				
			||||||
        <ion-item button (click)="logout()" [attr.aria-label]="logoutLabel | translate" detail="true">
 | 
					            <ion-item button (click)="openSettings()" [attr.aria-label]="'core.settings.appsettings' | translate" detail="true">
 | 
				
			||||||
            <ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-cogs" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
                <p class="item-heading">{{ logoutLabel | translate }}</p>
 | 
					                    <p class="item-heading">{{ 'core.settings.appsettings' | translate }}</p>
 | 
				
			||||||
            </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
        <core-spacer></core-spacer>
 | 
					        </ion-list>
 | 
				
			||||||
        <ion-item button (click)="openSettings()" [attr.aria-label]="'core.settings.appsettings' | translate" detail="true">
 | 
					    </core-loading>
 | 
				
			||||||
            <ion-icon name="fas-cogs" slot="start" aria-hidden="true"></ion-icon>
 | 
					 | 
				
			||||||
            <ion-label>
 | 
					 | 
				
			||||||
                <p class="item-heading">{{ 'core.settings.appsettings' | translate }}</p>
 | 
					 | 
				
			||||||
            </ion-label>
 | 
					 | 
				
			||||||
        </ion-item>
 | 
					 | 
				
			||||||
    </ion-list>
 | 
					 | 
				
			||||||
</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