forked from CIT/Vmeda.Online
		
	
						commit
						136f50ba37
					
				
							
								
								
									
										19
									
								
								.eslintrc.js
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								.eslintrc.js
									
									
									
									
									
								
							@ -15,7 +15,6 @@ const appConfig = {
 | 
			
		||||
        'eslint:recommended',
 | 
			
		||||
        'plugin:@typescript-eslint/recommended',
 | 
			
		||||
        'prettier',
 | 
			
		||||
        'prettier/@typescript-eslint',
 | 
			
		||||
        'plugin:@angular-eslint/recommended',
 | 
			
		||||
        'plugin:promise/recommended',
 | 
			
		||||
    ],
 | 
			
		||||
@ -90,7 +89,16 @@ const appConfig = {
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
        '@typescript-eslint/member-ordering': 'error',
 | 
			
		||||
        '@typescript-eslint/member-ordering': [
 | 
			
		||||
            'error',
 | 
			
		||||
            {
 | 
			
		||||
                default:
 | 
			
		||||
                {
 | 
			
		||||
                    order: 'as-written',
 | 
			
		||||
                },
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
        '@typescript-eslint/naming-convention': [
 | 
			
		||||
            'error',
 | 
			
		||||
            {
 | 
			
		||||
@ -276,6 +284,13 @@ module.exports = {
 | 
			
		||||
            extends: ['plugin:@angular-eslint/template/recommended'],
 | 
			
		||||
            rules: {
 | 
			
		||||
                'max-len': ['warn', { code: 140 }],
 | 
			
		||||
                '@angular-eslint/template/accessibility-valid-aria': 'warn',
 | 
			
		||||
                '@angular-eslint/template/accessibility-alt-text': 'error',
 | 
			
		||||
                '@angular-eslint/template/accessibility-elements-content': 'error',
 | 
			
		||||
                '@angular-eslint/template/accessibility-label-for': 'error',
 | 
			
		||||
                '@angular-eslint/template/no-positive-tabindex': 'error',
 | 
			
		||||
                '@angular-eslint/template/accessibility-table-scope': 'error',
 | 
			
		||||
                '@angular-eslint/template/accessibility-valid-aria': 'error',
 | 
			
		||||
            },
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										816
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										816
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										28
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								package.json
									
									
									
									
									
								
							@ -126,11 +126,11 @@
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@angular-devkit/architect": "^0.1101.2",
 | 
			
		||||
    "@angular-devkit/build-angular": "~0.1000.0",
 | 
			
		||||
    "@angular-eslint/builder": "0.5.0-beta.2",
 | 
			
		||||
    "@angular-eslint/eslint-plugin": "0.5.0-beta.2",
 | 
			
		||||
    "@angular-eslint/eslint-plugin-template": "0.5.0-beta.2",
 | 
			
		||||
    "@angular-eslint/schematics": "^0.5.0-beta.2",
 | 
			
		||||
    "@angular-eslint/template-parser": "0.5.0-beta.2",
 | 
			
		||||
    "@angular-eslint/builder": "^4.2.0",
 | 
			
		||||
    "@angular-eslint/eslint-plugin": "^4.2.0",
 | 
			
		||||
    "@angular-eslint/eslint-plugin-template": "^4.2.0",
 | 
			
		||||
    "@angular-eslint/schematics": "^4.2.0",
 | 
			
		||||
    "@angular-eslint/template-parser": "^4.2.0",
 | 
			
		||||
    "@angular/cli": "~10.0.5",
 | 
			
		||||
    "@angular/compiler": "~10.0.0",
 | 
			
		||||
    "@angular/compiler-cli": "~10.0.0",
 | 
			
		||||
@ -141,17 +141,17 @@
 | 
			
		||||
    "@types/faker": "^5.1.3",
 | 
			
		||||
    "@types/node": "^12.12.64",
 | 
			
		||||
    "@types/webpack-env": "^1.16.0",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "4.3.0",
 | 
			
		||||
    "@typescript-eslint/parser": "4.3.0",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^4.22.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^4.22.0",
 | 
			
		||||
    "check-es-compat": "^1.1.1",
 | 
			
		||||
    "eslint": "^7.21.0",
 | 
			
		||||
    "eslint-config-prettier": "^6.12.0",
 | 
			
		||||
    "eslint-plugin-header": "^3.1.0",
 | 
			
		||||
    "eslint": "^7.25.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-header": "^3.1.1",
 | 
			
		||||
    "eslint-plugin-import": "^2.22.1",
 | 
			
		||||
    "eslint-plugin-jest": "^24.1.0",
 | 
			
		||||
    "eslint-plugin-jsdoc": "^30.6.3",
 | 
			
		||||
    "eslint-plugin-prefer-arrow": "^1.2.2",
 | 
			
		||||
    "eslint-plugin-promise": "^4.2.1",
 | 
			
		||||
    "eslint-plugin-jest": "^24.3.6",
 | 
			
		||||
    "eslint-plugin-jsdoc": "^32.3.3",
 | 
			
		||||
    "eslint-plugin-prefer-arrow": "^1.2.3",
 | 
			
		||||
    "eslint-plugin-promise": "^5.1.0",
 | 
			
		||||
    "faker": "^5.1.0",
 | 
			
		||||
    "fs-extra": "^9.1.0",
 | 
			
		||||
    "gulp": "4.0.2",
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="badge">{{ badge.name }}</ion-title>
 | 
			
		||||
        <ion-title *ngIf="!badge">{{ 'addon.badges.badges' | translate }}</ion-title>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.badges.badges' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -17,8 +17,8 @@
 | 
			
		||||
            </core-empty-box>
 | 
			
		||||
 | 
			
		||||
            <ion-list *ngIf="!badges.empty"  class="ion-no-margin">
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngFor="let badge of badges.items" [title]="badge.name"
 | 
			
		||||
                    (click)="badges.select(badge)" [class.core-selected-item]="badges.isSelected(badge)">
 | 
			
		||||
                <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)">
 | 
			
		||||
                    <ion-avatar slot="start">
 | 
			
		||||
                        <img [src]="badge.badgeurl" [alt]="badge.name" core-external-content>
 | 
			
		||||
                    </ion-avatar>
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,8 @@
 | 
			
		||||
    </ion-label>
 | 
			
		||||
</ion-item-divider>
 | 
			
		||||
<core-loading [hideUntil]="loaded" class="core-loading-center">
 | 
			
		||||
    <ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="false" (click)="gotoCoureListModType(entry)">
 | 
			
		||||
    <ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="false" button
 | 
			
		||||
        (click)="gotoCoureListModType(entry)">
 | 
			
		||||
        <img slot="start" [src]="entry.icon" alt="" role="presentation" class="core-module-icon">
 | 
			
		||||
        <ion-label>{{ entry.name }}</ion-label>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,9 @@
 | 
			
		||||
    <!-- Download all courses. -->
 | 
			
		||||
    <div *ngIf="downloadCoursesEnabled && downloadEnabled && filteredCourses.length > 1 && !showFilter" class="core-button-spinner"
 | 
			
		||||
        slot="end">
 | 
			
		||||
        <ion-button *ngIf="!prefetchCoursesData[selectedFilter].loading" fill="clear" color="dark" (click)="prefetchCourses()">
 | 
			
		||||
            <ion-icon [name]="prefetchCoursesData[selectedFilter].icon" slot="icon-only">
 | 
			
		||||
        <ion-button *ngIf="!prefetchCoursesData[selectedFilter].loading" fill="clear" color="dark" (click)="prefetchCourses()"
 | 
			
		||||
            [attr.aria-label]="'core.courses.downloadcourses' | translate">
 | 
			
		||||
            <ion-icon [name]="prefetchCoursesData[selectedFilter].icon" slot="icon-only" aria-hidden="true">
 | 
			
		||||
            </ion-icon>
 | 
			
		||||
        </ion-button>
 | 
			
		||||
        <ion-badge class="core-course-download-courses-progress" *ngIf="prefetchCoursesData[selectedFilter].badge">
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,8 @@
 | 
			
		||||
    </ion-label>
 | 
			
		||||
    <div *ngIf="downloadCoursesEnabled && downloadEnabled && courses && courses.length > 1" class="core-button-spinner" slot="end">
 | 
			
		||||
        <ion-button *ngIf="prefetchCoursesData.icon && !prefetchCoursesData.loading" fill="clear" color="dark"
 | 
			
		||||
            (click)="prefetchCourses()">
 | 
			
		||||
            <ion-icon [name]="prefetchCoursesData.icon" slot="icon-only">
 | 
			
		||||
            </ion-icon>
 | 
			
		||||
            (click)="prefetchCourses()" [attr.aria-label]="'core.courses.downloadcourses' | translate">
 | 
			
		||||
            <ion-icon [name]="prefetchCoursesData.icon" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
        </ion-button>
 | 
			
		||||
        <ion-badge class="core-course-download-courses-progress" *ngIf="prefetchCoursesData.badge">
 | 
			
		||||
            {{prefetchCoursesData.badge}}
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,8 @@
 | 
			
		||||
    </ion-label>
 | 
			
		||||
    <div *ngIf="downloadCoursesEnabled && downloadEnabled && courses && courses.length > 1" class="core-button-spinner" slot="end">
 | 
			
		||||
        <ion-button *ngIf="prefetchCoursesData.icon && !prefetchCoursesData.loading" fill="clear" color="dark"
 | 
			
		||||
            (click)="prefetchCourses()">
 | 
			
		||||
            <ion-icon [name]="prefetchCoursesData.icon" slot="icon-only">
 | 
			
		||||
            </ion-icon>
 | 
			
		||||
            (click)="prefetchCourses()" [attr.aria-label]="'core.courses.downloadcourses' | translate">
 | 
			
		||||
            <ion-icon [name]="prefetchCoursesData.icon" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
        </ion-button>
 | 
			
		||||
        <ion-badge class="core-course-download-courses-progress" *ngIf="prefetchCoursesData.badge">
 | 
			
		||||
            {{prefetchCoursesData.badge}}
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,11 @@
 | 
			
		||||
    </ion-item-divider>
 | 
			
		||||
    <ng-container *ngFor="let event of dayEvents.events">
 | 
			
		||||
        <ion-item class="ion-text-wrap core-course-module-handler item-media" detail="false" (click)="action($event, event.url)"
 | 
			
		||||
            [title]="event.name">
 | 
			
		||||
            [attr.aria-label]="event.name" button>
 | 
			
		||||
            <img slot="start" [src]="event.iconUrl" alt="" role="presentation" *ngIf="event.iconUrl" class="core-module-icon">
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <!-- Add the icon title so accessibility tools read it. -->
 | 
			
		||||
                <span class="sr-only" *ngIf="event.iconTitle">{{ event.iconTitle }}</span>
 | 
			
		||||
                <h2>
 | 
			
		||||
                    <core-format-text [text]="event.name" contextLevel="module" [contextInstanceId]="event.id"
 | 
			
		||||
                        [courseId]="event.course && event.course.id">
 | 
			
		||||
 | 
			
		||||
@ -103,6 +103,7 @@ export class AddonBlockTimelineEventsComponent implements OnChanges {
 | 
			
		||||
            return start <= event.timesort;
 | 
			
		||||
        }).map((event) => {
 | 
			
		||||
            event.iconUrl = CoreCourse.getModuleIconSrc(event.icon.component);
 | 
			
		||||
            event.iconTitle = event.modulename && CoreCourse.translateModuleName(event.modulename);
 | 
			
		||||
 | 
			
		||||
            return event;
 | 
			
		||||
        });
 | 
			
		||||
@ -145,6 +146,7 @@ export class AddonBlockTimelineEventsComponent implements OnChanges {
 | 
			
		||||
 | 
			
		||||
type AddonBlockTimelineEvent = AddonCalendarEvent & {
 | 
			
		||||
    iconUrl?: string;
 | 
			
		||||
    iconTitle?: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type AddonBlockTimelineEventFilteredEvent = {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ title | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end"></ion-buttons>
 | 
			
		||||
@ -54,7 +54,7 @@
 | 
			
		||||
                            <core-tag-list [tags]="entry.tags"></core-tag-list>
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
                    <ion-item *ngIf="commentsEnabled" detail>
 | 
			
		||||
                    <ion-item *ngIf="commentsEnabled" detail="true">
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <core-comments [component]="this.component" [itemId]="entry.id" area="format_blog"
 | 
			
		||||
                                [instanceId]="entry.userid" contextLevel="user">
 | 
			
		||||
@ -71,7 +71,8 @@
 | 
			
		||||
                <ion-row class="ion-text-center">
 | 
			
		||||
                    <ion-col *ngIf="entry.lastmodified > entry.created">
 | 
			
		||||
                        <ion-note>
 | 
			
		||||
                            <ion-icon name="fas-clock"></ion-icon> {{entry.lastmodified | coreTimeAgo}}
 | 
			
		||||
                            <ion-icon name="fas-clock"
 | 
			
		||||
                                [attr.aria-label]="'core.lastmodified' | translate"></ion-icon> {{entry.lastmodified | coreTimeAgo}}
 | 
			
		||||
                        </ion-note>
 | 
			
		||||
                    </ion-col>
 | 
			
		||||
                </ion-row>
 | 
			
		||||
 | 
			
		||||
@ -13,16 +13,16 @@
 | 
			
		||||
    <ion-grid class="ion-no-padding addon-calendar-navigation">
 | 
			
		||||
        <ion-row class="ion-align-items-center">
 | 
			
		||||
            <ion-col class="ion-text-start" *ngIf="canNavigate">
 | 
			
		||||
                <ion-button fill="clear" (click)="loadPrevious()" [title]="'core.previous' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-left" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-button fill="clear" (click)="loadPrevious()" [attr.aria-label]="'core.previous' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-left" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
            <ion-col class="ion-text-center addon-calendar-period">
 | 
			
		||||
                <h3>{{ periodName }}</h3>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
            <ion-col class="ion-text-end" *ngIf="canNavigate">
 | 
			
		||||
                <ion-button fill="clear" (click)="loadNext()" [title]="'core.next' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-right" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-button fill="clear" (click)="loadNext()" [attr.aria-label]="'core.next' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-right" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
        </ion-row>
 | 
			
		||||
@ -42,8 +42,8 @@
 | 
			
		||||
        <ion-row *ngFor="let week of weeks" class="addon-calendar-week">
 | 
			
		||||
            <!-- Empty slots (first week). -->
 | 
			
		||||
            <ion-col *ngFor="let value of week.prepadding" class="dayblank addon-calendar-day"></ion-col>
 | 
			
		||||
            <ion-col class="addon-calendar-day ion-text-center" *ngFor="let day of week.days"  (click)="dayClicked(day.mday)"
 | 
			
		||||
            [ngClass]='{"hasevents": day.hasevents, "today": isCurrentMonth && day.istoday,
 | 
			
		||||
            <ion-col class="addon-calendar-day ion-text-center" *ngFor="let day of week.days" (click)="dayClicked(day.mday)"
 | 
			
		||||
                [ngClass]='{"hasevents": day.hasevents, "today": isCurrentMonth && day.istoday,
 | 
			
		||||
                "weekend": day.isweekend, "duration_finish": day.haslastdayofevent}'
 | 
			
		||||
                [class.addon-calendar-event-past-day]="isPastMonth || day.ispast">
 | 
			
		||||
                <p class="addon-calendar-day-number"><span>{{ day.mday }}</span></p>
 | 
			
		||||
@ -55,16 +55,23 @@
 | 
			
		||||
                <!-- In tablet, display list of events. -->
 | 
			
		||||
                <div class="ion-hide-md-down addon-calendar-day-events">
 | 
			
		||||
                    <ng-container *ngFor="let event of day.filteredEvents | slice:0:4; let index = index">
 | 
			
		||||
                        <p *ngIf="index < 3 || day.filteredEvents.length == 4" class="addon-calendar-event"
 | 
			
		||||
                        (click)="eventClicked(event, $event)" [class.addon-calendar-event-past]="event.ispast">
 | 
			
		||||
                        <div role="button" *ngIf="index < 3 || day.filteredEvents.length == 4" class="addon-calendar-event"
 | 
			
		||||
                            (click)="eventClicked(event, $event)" [class.addon-calendar-event-past]="event.ispast">
 | 
			
		||||
                            <span class="calendar_event_type calendar_event_{{event.formattedType}}"></span>
 | 
			
		||||
                            <ion-icon *ngIf="event.offline && !event.deleted" name="far-clock"></ion-icon>
 | 
			
		||||
                            <ion-icon *ngIf="event.deleted" name="fas-trash"></ion-icon>
 | 
			
		||||
                            <ion-icon *ngIf="event.offline && !event.deleted" name="fas-clock"
 | 
			
		||||
                                [attr.aria-label]="'core.notsent' | translate"></ion-icon>
 | 
			
		||||
                            <ion-icon *ngIf="event.deleted" name="fas-trash" [attr.aria-label]="'core.deletedoffline' | translate">
 | 
			
		||||
                            </ion-icon>
 | 
			
		||||
                            <span class="addon-calendar-event-time">{{ event.timestart * 1000 | coreFormatDate: timeFormat }}</span>
 | 
			
		||||
                            <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" alt="" role="presentation"
 | 
			
		||||
                                class="core-module-icon">
 | 
			
		||||
                            <!-- Add the icon title so accessibility tools read it. -->
 | 
			
		||||
                            <span class="sr-only">
 | 
			
		||||
                                {{ 'addon.calendar.type' + event.formattedType | translate }}
 | 
			
		||||
                                <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span>
 | 
			
		||||
                            </span>
 | 
			
		||||
                            <span class="addon-calendar-event-name">{{event.name}}</span>
 | 
			
		||||
                        </p>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </ng-container>
 | 
			
		||||
                    <p *ngIf="day.filteredEvents.length > 4" class="addon-calendar-day-more">
 | 
			
		||||
                        <b>{{ 'core.nummore' | translate:{$a: day.filteredEvents.length - 3} }}</b>
 | 
			
		||||
 | 
			
		||||
@ -70,6 +70,7 @@
 | 
			
		||||
            margin-bottom: 0.6em;
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
            white-space: nowrap;
 | 
			
		||||
            color: var(--text-color);
 | 
			
		||||
 | 
			
		||||
            &.addon-calendar-event-past {
 | 
			
		||||
                opacity: 0.5;
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
<ion-list>
 | 
			
		||||
    <ion-item *ngFor="let type of types" class="addon-calendar-event" [ngClass]="['addon-calendar-eventtype-'+type]">
 | 
			
		||||
        <ion-icon [name]="typeIcons[type]" slot="start"></ion-icon>
 | 
			
		||||
        <ion-icon [name]="typeIcons[type]" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
        <ion-label>{{ 'addon.calendar.' + type + 'events' | translate}}</ion-label>
 | 
			
		||||
        <ion-toggle [(ngModel)]="filter[type]" (ionChange)="onChange()" slot="end"></ion-toggle>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -4,22 +4,28 @@
 | 
			
		||||
 | 
			
		||||
    <ion-list *ngIf="filteredEvents && filteredEvents.length"  class="ion-no-margin">
 | 
			
		||||
        <ng-container *ngFor="let event of filteredEvents">
 | 
			
		||||
            <ion-item class="ion-text-wrap addon-calendar-event" [title]="event.name" (click)="eventClicked(event)"
 | 
			
		||||
            <ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button
 | 
			
		||||
                [ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
 | 
			
		||||
                <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon">
 | 
			
		||||
                <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start">
 | 
			
		||||
                <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt=""
 | 
			
		||||
                    role="presentation">
 | 
			
		||||
                <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true">
 | 
			
		||||
                </ion-icon>
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <!-- Add the icon title so accessibility tools read it. -->
 | 
			
		||||
                    <span class="sr-only">
 | 
			
		||||
                        {{ 'addon.calendar.type' + event.formattedType | translate }}
 | 
			
		||||
                        <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span>
 | 
			
		||||
                    </span>
 | 
			
		||||
                    <h2><core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
 | 
			
		||||
                        [contextInstanceId]="event.contextInstanceId"></core-format-text></h2>
 | 
			
		||||
                    <p [innerHTML]="event.formattedtime"></p>
 | 
			
		||||
                </ion-label>
 | 
			
		||||
                <ion-note *ngIf="event.offline && !event.deleted" slot="end">
 | 
			
		||||
                    <ion-icon name="far-clock"></ion-icon>
 | 
			
		||||
                    <ion-icon name="fas-clock" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <span class="ion-text-wrap">{{ 'core.notsent' | translate }}</span>
 | 
			
		||||
                </ion-note>
 | 
			
		||||
                <ion-note *ngIf="event.deleted" slot="end">
 | 
			
		||||
                    <ion-icon name="fas-trash"></ion-icon>
 | 
			
		||||
                    <ion-icon name="fas-trash" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <span class="ion-text-wrap">{{ 'core.deletedoffline' | translate }}</span>
 | 
			
		||||
                </ion-note>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.calendar.calendarevents' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="openFilter($event)" [attr.aria-label]="'core.filter' | translate">
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-filter"></ion-icon>
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-filter" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
            <core-context-menu>
 | 
			
		||||
                <core-context-menu-item *ngIf="!isCurrentDay" [priority]="900" [content]="'addon.calendar.today' | translate"
 | 
			
		||||
@ -29,26 +29,26 @@
 | 
			
		||||
    <ion-grid class="ion-no-padding safe-area-page">
 | 
			
		||||
        <ion-row class="ion-align-items-center">
 | 
			
		||||
            <ion-col class="ion-text-start" *ngIf="currentMoment">
 | 
			
		||||
                <ion-button fill="clear" (click)="loadPrevious()" [title]="'addon.calendar.dayprev' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-left" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-button fill="clear" (click)="loadPrevious()" [attr.aria-label]="'addon.calendar.dayprev' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-left" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
            <ion-col class="ion-text-center addon-calendar-period">
 | 
			
		||||
                <h3>{{ periodName }}</h3>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
            <ion-col class="ion-text-end" *ngIf="currentMoment">
 | 
			
		||||
                <ion-button fill="clear" (click)="loadNext()" [title]="'addon.calendar.daynext' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-right" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-button fill="clear" (click)="loadNext()" [attr.aria-label]="'addon.calendar.daynext' | translate">
 | 
			
		||||
                    <ion-icon name="fas-chevron-right" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
        </ion-row>
 | 
			
		||||
    </ion-grid>
 | 
			
		||||
 | 
			
		||||
    <core-loading [hideUntil]="loaded" class="safe-area-page">
 | 
			
		||||
        <!-- There is data to be synchronized -->          <!-- There is data to be synchronized -->
 | 
			
		||||
        <!-- There is data to be synchronized -->
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="hasOffline">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'core.hasdatatosync' | translate:{$a: 'core.day' | translate} }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -59,22 +59,28 @@
 | 
			
		||||
 | 
			
		||||
        <ion-list *ngIf="filteredEvents && filteredEvents.length"  class="ion-no-margin">
 | 
			
		||||
            <ng-container *ngFor="let event of filteredEvents">
 | 
			
		||||
                <ion-item class="addon-calendar-event ion-text-wrap" [title]="event.name" (click)="gotoEvent(event.id)"
 | 
			
		||||
                [class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
 | 
			
		||||
                    <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon">
 | 
			
		||||
                    <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start">
 | 
			
		||||
                <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>
 | 
			
		||||
                    <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt=""
 | 
			
		||||
                        role="presentation">
 | 
			
		||||
                    <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true">
 | 
			
		||||
                    </ion-icon>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <!-- Add the icon title so accessibility tools read it. -->
 | 
			
		||||
                        <span class="sr-only">
 | 
			
		||||
                            {{ 'addon.calendar.type' + event.formattedType | translate }}
 | 
			
		||||
                            <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span>
 | 
			
		||||
                        </span>
 | 
			
		||||
                        <h2><core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
 | 
			
		||||
                            [contextInstanceId]="event.contextInstanceId"></core-format-text></h2>
 | 
			
		||||
                        <p [innerHTML]="event.formattedtime"></p>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
                    <ion-note *ngIf="event.offline && !event.deleted" slot="end">
 | 
			
		||||
                        <ion-icon name="far-clock"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-clock" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        <span class="ion-text-wrap">{{ 'core.notsent' | translate }}</span>
 | 
			
		||||
                    </ion-note>
 | 
			
		||||
                    <ion-note *ngIf="event.deleted" slot="end">
 | 
			
		||||
                        <ion-icon name="fas-trash"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-trash" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        <span class="ion-text-wrap">{{ 'core.deletedoffline' | translate }}</span>
 | 
			
		||||
                    </ion-note>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
@ -85,7 +91,7 @@
 | 
			
		||||
    <!-- Create a calendar event. -->
 | 
			
		||||
    <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canCreate && loaded">
 | 
			
		||||
        <ion-fab-button (click)="openEdit()" [attr.aria-label]="'addon.calendar.newevent' | translate">
 | 
			
		||||
            <ion-icon name="fas-plus"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
 | 
			
		||||
        </ion-fab-button>
 | 
			
		||||
    </ion-fab>
 | 
			
		||||
</ion-content>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ title | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -120,9 +120,10 @@
 | 
			
		||||
            </ng-container>
 | 
			
		||||
 | 
			
		||||
            <!-- Advanced options. -->
 | 
			
		||||
            <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()">
 | 
			
		||||
                <ion-icon *ngIf="!advanced" name="fas-caret-right" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon *ngIf="advanced" name="fas-caret-down" slot="start"></ion-icon>
 | 
			
		||||
            <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()"
 | 
			
		||||
                [attr.aria-label]="(advanced ? 'core.showless' : 'core.showmore') | translate" role="button">
 | 
			
		||||
                <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-label>
 | 
			
		||||
                    <span *ngIf="!advanced">{{ 'core.showmore' | translate }}</span>
 | 
			
		||||
                    <span *ngIf="advanced">{{ 'core.showless' | translate }}</span>
 | 
			
		||||
@ -161,14 +162,14 @@
 | 
			
		||||
                            <ion-radio slot="end" value="0"></ion-radio>
 | 
			
		||||
                            <ion-label>{{ 'addon.calendar.durationnone' | translate }}</ion-label>
 | 
			
		||||
                        </ion-item>
 | 
			
		||||
                        <ion-item  (click)="selectDuration('1')">
 | 
			
		||||
                        <ion-item button (click)="selectDuration('1')">
 | 
			
		||||
                            <ion-radio slot="end" value="1"></ion-radio>
 | 
			
		||||
                            <ion-label>{{ 'addon.calendar.durationuntil' | translate }}</ion-label>
 | 
			
		||||
                            <ion-datetime formControlName="timedurationuntil"
 | 
			
		||||
                                [placeholder]="'addon.calendar.durationuntil' | translate"
 | 
			
		||||
                                [displayFormat]="dateFormat" [disabled]="form.controls.duration.value != 1"></ion-datetime>
 | 
			
		||||
                        </ion-item>
 | 
			
		||||
                        <ion-item (click)="selectDuration('2')">
 | 
			
		||||
                        <ion-item button (click)="selectDuration('2')">
 | 
			
		||||
                            <ion-radio slot="end" value="2"></ion-radio>
 | 
			
		||||
                            <ion-label>{{ 'addon.calendar.durationminutes' | translate }}</ion-label>
 | 
			
		||||
                            <ion-input type="number" name="timedurationminutes" slot="end"
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,16 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="event">
 | 
			
		||||
            <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" alt="" role="presentation" class="core-module-icon">
 | 
			
		||||
            <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon"></ion-icon>
 | 
			
		||||
            <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <!-- Add the icon title so accessibility tools read it. -->
 | 
			
		||||
            <span class="sr-only">
 | 
			
		||||
                {{ 'addon.calendar.type' + event.formattedType | translate }}
 | 
			
		||||
                <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span>
 | 
			
		||||
            </span>
 | 
			
		||||
            <core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
 | 
			
		||||
                [contextInstanceId]="event.contextInstanceId"></core-format-text>
 | 
			
		||||
        </ion-title>
 | 
			
		||||
@ -38,7 +43,7 @@
 | 
			
		||||
        <!-- There is data to be synchronized -->
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="hasOffline || (event && event.deleted)">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'core.hasdatatosync' | translate:{$a: 'addon.calendar.calendarevent' | translate} }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -48,17 +53,21 @@
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngIf="isSplitViewOn">
 | 
			
		||||
                    <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" alt="" role="presentation"
 | 
			
		||||
                        class="core-module-icon">
 | 
			
		||||
                    <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start">
 | 
			
		||||
                    <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start" aria-hidden="true">
 | 
			
		||||
                    </ion-icon>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <span class="sr-only">
 | 
			
		||||
                            {{ 'addon.calendar.type' + event.formattedType | translate }}
 | 
			
		||||
                            <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span>
 | 
			
		||||
                        </span>
 | 
			
		||||
                        <h2>{{ 'addon.calendar.eventname' | translate }}</h2>
 | 
			
		||||
                        <p>
 | 
			
		||||
                            <core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
 | 
			
		||||
                             [contextInstanceId]="event.contextInstanceId"></core-format-text>
 | 
			
		||||
                                [contextInstanceId]="event.contextInstanceId"></core-format-text>
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
                    <ion-note slot="end" *ngIf="event.deleted">
 | 
			
		||||
                        <ion-icon name="fas-trash"></ion-icon> {{ 'core.deletedoffline' | translate }}
 | 
			
		||||
                        <ion-icon name="fas-trash" aria-hidden="true"></ion-icon> {{ 'core.deletedoffline' | translate }}
 | 
			
		||||
                    </ion-note>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
                <ion-item>
 | 
			
		||||
@ -67,7 +76,7 @@
 | 
			
		||||
                        <p [innerHTML]="event.formattedtime"></p>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
                    <ion-note slot="end" *ngIf="!isSplitViewOn && event.deleted">
 | 
			
		||||
                        <ion-icon name="fas-trash"></ion-icon> {{ 'core.deletedoffline' | translate }}
 | 
			
		||||
                        <ion-icon name="fas-trash" aria-hidden="true"></ion-icon> {{ 'core.deletedoffline' | translate }}
 | 
			
		||||
                    </ion-note>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
                <ion-item>
 | 
			
		||||
@ -144,9 +153,9 @@
 | 
			
		||||
                        <p *ngIf="reminder.time > 0">{{ reminder.time * 1000 | coreFormatDate }}</p>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
                    <ion-button fill="clear" (click)="cancelNotification(reminder.id, $event)"
 | 
			
		||||
                        [attr.aria-label]=" 'core.delete' | translate" slot="end"
 | 
			
		||||
                        [attr.aria-label]="'core.delete' | translate" slot="end"
 | 
			
		||||
                        *ngIf="(reminder.time == -1 ? (event.timestart - defaultTime) : reminder.time) > currentTime!">
 | 
			
		||||
                        <ion-icon name="fas-trash" color="danger" slot="icon-only"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-trash" color="danger" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
            </ng-container>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ (showCalendar ? 'addon.calendar.calendarevents' : 'addon.calendar.upcomingevents') | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="openFilter($event)" [attr.aria-label]="'core.filter' | translate">
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-filter"></ion-icon>
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-filter" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
            <core-context-menu>
 | 
			
		||||
                <core-context-menu-item *ngIf="showCalendar" [priority]="800"
 | 
			
		||||
@ -33,7 +33,7 @@
 | 
			
		||||
    <!-- There is data to be synchronized -->
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="hasOffline">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'core.hasdatatosync' | translate:{$a: 'addon.calendar.calendar' | translate} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
@ -49,7 +49,7 @@
 | 
			
		||||
    <!-- Create a calendar event. -->
 | 
			
		||||
    <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canCreate">
 | 
			
		||||
        <ion-fab-button (click)="openEdit()" [attr.aria-label]="'addon.calendar.newevent' | translate">
 | 
			
		||||
            <ion-icon name="fas-plus"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
 | 
			
		||||
        </ion-fab-button>
 | 
			
		||||
    </ion-fab>
 | 
			
		||||
</ion-content>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.calendar.calendarevents' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="openFilter($event)" [attr.aria-label]="'core.filter' | translate">
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-filter"></ion-icon>
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-filter" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
            <core-context-menu>
 | 
			
		||||
                <core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
            <!-- There is data to be synchronized -->
 | 
			
		||||
            <ion-card class="core-warning-card" *ngIf="hasOffline">
 | 
			
		||||
                <ion-item>
 | 
			
		||||
                    <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                    <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label>{{ 'core.hasdatatosync' | translate:{$a: 'addon.calendar.calendar' | translate} }}</ion-label>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
            </ion-card>
 | 
			
		||||
@ -42,13 +42,21 @@
 | 
			
		||||
                    <ion-item-divider *ngIf="event.showDate">
 | 
			
		||||
                        <ion-label>{{ event.timestart * 1000 | coreFormatDate: "strftimedayshort" }}</ion-label>
 | 
			
		||||
                    </ion-item-divider>
 | 
			
		||||
                    <ion-item class="addon-calendar-event ion-text-wrap" [title]="event.name" (click)="gotoEvent(event.id)"
 | 
			
		||||
                    [class.core-selected-item]="event.id == eventId" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
 | 
			
		||||
                        <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon">
 | 
			
		||||
                        <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start">
 | 
			
		||||
                    <ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)"
 | 
			
		||||
                        [attr.aria-current]="event.id == eventId ? 'page' : 'false'"
 | 
			
		||||
                        [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button>
 | 
			
		||||
                        <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" slot="start" class="core-module-icon" alt=""
 | 
			
		||||
                            role="presentation">
 | 
			
		||||
                        <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" slot="start"
 | 
			
		||||
                            aria-hidden="true">
 | 
			
		||||
                        </ion-icon>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2>
 | 
			
		||||
                                <!-- Add the icon title so accessibility tools read it. -->
 | 
			
		||||
                                <span class="sr-only">
 | 
			
		||||
                                    {{ 'addon.calendar.type' + event.formattedType | translate }}
 | 
			
		||||
                                    <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span>
 | 
			
		||||
                                </span>
 | 
			
		||||
                                <core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
 | 
			
		||||
                                    [contextInstanceId]="event.contextInstanceId">
 | 
			
		||||
                                </core-format-text>
 | 
			
		||||
@ -64,11 +72,11 @@
 | 
			
		||||
                            </p>
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
                        <ion-note *ngIf="event.offline && !event.deleted" slot="end">
 | 
			
		||||
                            <ion-icon name="far-clock"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-clock" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            <span class="ion-text-wrap">{{ 'core.notsent' | translate }}</span>
 | 
			
		||||
                        </ion-note>
 | 
			
		||||
                        <ion-note *ngIf="event.deleted" slot="end">
 | 
			
		||||
                            <ion-icon name="fas-trash"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-trash" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            <span class="ion-text-wrap">{{ 'core.deletedoffline' | translate }}</span>
 | 
			
		||||
                        </ion-note>
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
@ -82,7 +90,7 @@
 | 
			
		||||
        <!-- Create a calendar event. -->
 | 
			
		||||
        <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canCreate">
 | 
			
		||||
            <ion-fab-button (click)="openEdit()" [attr.aria-label]="'addon.calendar.newevent' | translate">
 | 
			
		||||
                <ion-icon name="fas-plus"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-fab-button>
 | 
			
		||||
        </ion-fab>
 | 
			
		||||
    </core-split-view>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'core.settings.settings' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
 | 
			
		||||
@ -189,6 +189,7 @@ export class AddonCalendarHelperProvider {
 | 
			
		||||
        if (event.modulename) {
 | 
			
		||||
            eventFormatted.eventIcon = CoreCourse.getModuleIconSrc(event.modulename);
 | 
			
		||||
            eventFormatted.moduleIcon = eventFormatted.eventIcon;
 | 
			
		||||
            eventFormatted.iconTitle = CoreCourse.translateModuleName(event.modulename);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        eventFormatted.formattedType = AddonCalendar.getEventType(event);
 | 
			
		||||
 | 
			
		||||
@ -2250,6 +2250,7 @@ export type AddonCalendarEventToDisplay = Partial<AddonCalendarCalendarEvent> &
 | 
			
		||||
    deleted?: boolean; // Calculated in the app. Whether it has been deleted in offline.
 | 
			
		||||
    encodedLocation?: SafeUrl; // Calculated in the app. Sanitized location link.
 | 
			
		||||
    eventIcon?: string; // Calculated in the app. Event icon.
 | 
			
		||||
    iconTitle?: string;
 | 
			
		||||
    moduleIcon?: string; // Calculated in the app. Module icon.
 | 
			
		||||
    formattedType: string; // Calculated in the app. Formatted type.
 | 
			
		||||
    duration?: number; // Calculated in the app. Duration of offline event.
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ title }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -14,8 +14,8 @@
 | 
			
		||||
        <core-loading [hideUntil]="competencies.loaded">
 | 
			
		||||
            <ion-list>
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngFor="let competency of competencies.items"
 | 
			
		||||
                    [title]="competency.competency.shortname" (click)="competencies.select(competency)"
 | 
			
		||||
                    [class.core-selected-item]="competencies.isSelected(competency)">
 | 
			
		||||
                    [attr.aria-label]="competency.competency.shortname" (click)="competencies.select(competency)"
 | 
			
		||||
                    [attr.aria-current]="competencies.getItemAriaCurrent(competency)" button>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <h2>{{ competency.competency.shortname }} <em>{{competency.competency.idnumber}}</em></h2>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="competency">
 | 
			
		||||
            {{ competency.competency.competency.shortname }} <small>{{ competency.competency.competency.idnumber }}</small>
 | 
			
		||||
@ -73,9 +73,9 @@
 | 
			
		||||
                    <p *ngIf="coursemodules.length == 0">
 | 
			
		||||
                        {{ 'addon.competency.noactivities' | translate }}
 | 
			
		||||
                    </p>
 | 
			
		||||
                    <ion-item class="ion-text-wrap" *ngFor="let activity of coursemodules" [href]="activity.url" [title]="activity.name"
 | 
			
		||||
                        core-link capture="true">
 | 
			
		||||
                        <img slot="start" core-external-content [src]="activity.iconurl" alt="" role="presentation" *ngIf="activity.iconurl"
 | 
			
		||||
                    <ion-item class="ion-text-wrap" *ngFor="let activity of coursemodules" [href]="activity.url"
 | 
			
		||||
                        [attr.aria-label]="activity.name" core-link capture="true">
 | 
			
		||||
                        <img slot="start" core-external-content [src]="activity.iconurl" alt="" *ngIf="activity.iconurl"
 | 
			
		||||
                            class="core-module-icon">
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <core-format-text [text]="activity.name" contextLevel="module" [contextInstanceId]="activity.id"
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="competency">
 | 
			
		||||
            {{ competency.competency.shortname }} <small>{{ competency.competency.idnumber }}</small>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.competency.coursecompetencies' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -56,7 +56,7 @@
 | 
			
		||||
        <div *ngIf="competencies">
 | 
			
		||||
            <ion-card *ngFor="let competency of competencies.competencies">
 | 
			
		||||
                <ion-item class="ion-text-wrap" (click)="openCompetency(competency.competency.id)"
 | 
			
		||||
                    [title]="competency.competency.shortname" detail="true">
 | 
			
		||||
                    [attr.aria-label]="competency.competency.shortname" detail="true" button>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <h2><strong>{{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em></strong></h2>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
@ -103,9 +103,9 @@
 | 
			
		||||
                            <p *ngIf="competency.coursemodules.length == 0">
 | 
			
		||||
                                {{ 'addon.competency.noactivities' | translate }}
 | 
			
		||||
                            </p>
 | 
			
		||||
                            <ion-item class="ion-text-wrap core-course-module-handler item-media" [title]="activity.name" core-link
 | 
			
		||||
                                *ngFor="let activity of competency.coursemodules" [href]="activity.url" capture="true">
 | 
			
		||||
                                <img slot="start" [src]="activity.iconurl" core-external-content alt="" role="presentation"
 | 
			
		||||
                            <ion-item class="ion-text-wrap core-course-module-handler item-media" [attr.aria-label]="activity.name"
 | 
			
		||||
                                core-link *ngFor="let activity of competency.coursemodules" [href]="activity.url" capture="true">
 | 
			
		||||
                                <img slot="start" [src]="activity.iconurl" core-external-content alt=""
 | 
			
		||||
                                    *ngIf="activity.iconurl" class="core-module-icon">
 | 
			
		||||
                                <ion-label>
 | 
			
		||||
                                    <core-format-text [text]="activity.name" contextLevel="module" [contextInstanceId]="activity.id"
 | 
			
		||||
@ -120,7 +120,7 @@
 | 
			
		||||
                                {{ 'addon.competency.nouserplanswithcompetency' | translate }}
 | 
			
		||||
                            </p>
 | 
			
		||||
                            <ion-item class="ion-text-wrap" *ngFor="let plan of competency.plans" [href]="plan.url"
 | 
			
		||||
                                [title]="plan.name" core-link capture="true">
 | 
			
		||||
                                [attr.aria-label]="plan.name" core-link capture="true">
 | 
			
		||||
                                <ion-label>
 | 
			
		||||
                                   <core-format-text [text]="plan.name" contextLevel="user" [contextInstanceId]="plan.userid">
 | 
			
		||||
                                   </core-format-text>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="plan">{{plan.plan.name}}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -75,7 +75,7 @@
 | 
			
		||||
                </ion-item>
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngFor="let competency of plan.competencies"
 | 
			
		||||
                    (click)="openCompetency(competency.competency.id)"
 | 
			
		||||
                    [title]="competency.competency.shortname" detail="true">
 | 
			
		||||
                    [attr.aria-label]="competency.competency.shortname" detail="true" button>
 | 
			
		||||
                    <ion-label><h2>{{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em></h2></ion-label>
 | 
			
		||||
                    <ion-badge *ngIf="competency.usercompetencyplan" slot="end"
 | 
			
		||||
                        [color]="competency.usercompetencyplan.proficiency ? 'success' : 'danger'">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.competency.userplans' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -16,8 +16,8 @@
 | 
			
		||||
 | 
			
		||||
            </core-empty-box>
 | 
			
		||||
            <ion-list *ngIf="!plans.empty"  class="ion-no-margin">
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [title]="plan.name" (click)="plans.select(plan)"
 | 
			
		||||
                    [class.core-selected-item]="plans.isSelected(plan)">
 | 
			
		||||
                <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>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <h2>{{ plan.name }}</h2>
 | 
			
		||||
                        <p *ngIf="plan.duedate > 0">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.coursecompletion.coursecompletion' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -84,7 +84,7 @@
 | 
			
		||||
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="!tracked">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'addon.coursecompletion.nottracked' | translate }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.messageoutput_airnotifier.processorsettingsdesc' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
        <ion-title>{{ 'addon.messages.groupinfo' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <div class="large-avatar">
 | 
			
		||||
                    <img class="avatar" [src]="conversation!.imageurl" core-external-content [alt]="conversation!.name"
 | 
			
		||||
                    role="presentation" onError="this.src='assets/img/group-avatar.png'">
 | 
			
		||||
                    onError="this.src='assets/img/group-avatar.png'">
 | 
			
		||||
                </div>
 | 
			
		||||
                <h2>
 | 
			
		||||
                    <core-format-text [text]="conversation!.name" contextLevel="system" [contextInstanceId]="0"></core-format-text>
 | 
			
		||||
@ -33,13 +33,14 @@
 | 
			
		||||
        </ion-item>
 | 
			
		||||
 | 
			
		||||
        <ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let member of members"
 | 
			
		||||
            (click)="closeModal(member.id)" detail>
 | 
			
		||||
            (click)="closeModal(member.id)" detail="true" button>
 | 
			
		||||
            <core-user-avatar [user]="member" [linkProfile]="false" [checkOnline]="member.showonlinestatus" slot="start">
 | 
			
		||||
            </core-user-avatar>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <h2>
 | 
			
		||||
                    {{ member.fullname }}
 | 
			
		||||
                    <ion-icon name="fas-user-slash" *ngIf="member.isblocked" [title]="'addon.messages.contactblocked' | translate">
 | 
			
		||||
                    <ion-icon name="fas-user-slash" *ngIf="member.isblocked"
 | 
			
		||||
                        [attr.aria-label]="'addon.messages.contactblocked' | translate">
 | 
			
		||||
                    </ion-icon>
 | 
			
		||||
                </h2>
 | 
			
		||||
            </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.messages.contacts' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
@ -38,8 +38,8 @@
 | 
			
		||||
                        <!-- Don't show deleted users -->
 | 
			
		||||
                        <ion-item class="ion-text-wrap addon-messages-conversation-item"
 | 
			
		||||
                            *ngIf="contact.profileimageurl || contact.profileimageurlsmall"
 | 
			
		||||
                            [title]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail
 | 
			
		||||
                            [class.core-selected-item]="contact.id == discussionUserId">
 | 
			
		||||
                            [attr.aria-label]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail="true" button
 | 
			
		||||
                            [attr.aria-current]="contact.id == discussionUserId ? 'page' :  'false'">
 | 
			
		||||
                            <core-user-avatar [user]="contact" slot="start" [checkOnline]="contact.showonlinestatus"></core-user-avatar>
 | 
			
		||||
                            <ion-label><h2>{{ contact.fullname }}</h2></ion-label>
 | 
			
		||||
                        </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.messages.contacts' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="gotoSearch()" [attr.aria-label]="'addon.messages.search' | translate">
 | 
			
		||||
                <ion-icon name="fas-search" slot="icon-only"></ion-icon>
 | 
			
		||||
            <ion-button (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate">
 | 
			
		||||
                <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
            <!-- Add an empty context menu so discussion page can add items in split view, otherwise the menu
 | 
			
		||||
                disappears in some cases. -->
 | 
			
		||||
@ -26,9 +26,9 @@
 | 
			
		||||
                    </ion-refresher>
 | 
			
		||||
                    <core-loading [hideUntil]="confirmedLoaded" class="core-loading-center">
 | 
			
		||||
                        <ion-list  class="ion-no-margin">
 | 
			
		||||
                            <ion-item class="ion-text-wrap addon-messages-conversation-item"
 | 
			
		||||
                                *ngFor="let contact of confirmedContacts" [title]="contact.fullname" detail
 | 
			
		||||
                                (click)="selectUser(contact.id)" [class.core-selected-item]="contact.id == selectedUserId">
 | 
			
		||||
                            <ion-item class="ion-text-wrap addon-messages-conversation-item" (click)="selectUser(contact.id)" button
 | 
			
		||||
                                *ngFor="let contact of confirmedContacts" [attr.aria-label]="contact.fullname" detail="true"
 | 
			
		||||
                                [attr.aria-current]="contact.id == selectedUserId ? 'page' :  'false'">
 | 
			
		||||
                                <core-user-avatar slot="start" [user]="contact"
 | 
			
		||||
                                    [checkOnline]="contact.showonlinestatus" [linkProfile]="false">
 | 
			
		||||
                                </core-user-avatar>
 | 
			
		||||
@ -36,7 +36,8 @@
 | 
			
		||||
                                    <h2>
 | 
			
		||||
                                        <core-format-text [text]="contact.fullname" contextLevel="system" [contextInstanceId]="0">
 | 
			
		||||
                                        </core-format-text>
 | 
			
		||||
                                        <ion-icon *ngIf="contact.isblocked" name="fas-user-slash" slot="end">
 | 
			
		||||
                                        <ion-icon *ngIf="contact.isblocked" name="fas-user-slash" slot="end"
 | 
			
		||||
                                            [attr.aria-label]="'addon.messages.contactblocked' | translate">
 | 
			
		||||
                                        </ion-icon>
 | 
			
		||||
                                    </h2>
 | 
			
		||||
                                </ion-label>
 | 
			
		||||
@ -63,8 +64,8 @@
 | 
			
		||||
                    <core-loading [hideUntil]="requestsLoaded" class="core-loading-center">
 | 
			
		||||
                        <ion-list  class="ion-no-margin">
 | 
			
		||||
                            <ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let request of requests"
 | 
			
		||||
                                [title]="request.fullname" (click)="selectUser(request.id)"
 | 
			
		||||
                                [class.core-selected-item]="request.id == selectedUserId" detail>
 | 
			
		||||
                                [attr.aria-label]="request.fullname" (click)="selectUser(request.id)" button
 | 
			
		||||
                                [attr.aria-current]="request.id == selectedUserId ? 'page' :  'false'" detail="true">
 | 
			
		||||
                                <core-user-avatar slot="start" [user]="request" [linkProfile]="false"></core-user-avatar>
 | 
			
		||||
                                <ion-label>
 | 
			
		||||
                                    <core-format-text [text]="request.fullname" contextLevel="system" [contextInstanceId]="0">
 | 
			
		||||
 | 
			
		||||
@ -1,29 +1,30 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <div class="toolbar-title">
 | 
			
		||||
                <img *ngIf="loaded && !otherMember && conversationImage" class="core-bar-button-image" [src]="conversationImage"
 | 
			
		||||
                    [alt]="title" 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">
 | 
			
		||||
                <core-user-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" [user]="otherMember"
 | 
			
		||||
                    [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus" (click)="showInfo && viewInfo()">
 | 
			
		||||
                </core-user-avatar>
 | 
			
		||||
                <core-format-text [text]="title" contextLevel="system" [contextInstanceId]="0"
 | 
			
		||||
                    (click)="showInfo && !isGroup && viewInfo()"></core-format-text>
 | 
			
		||||
                <ion-icon *ngIf="conversation && conversation.isfavourite" name="fas-star" [title]="'core.favourites' | translate">
 | 
			
		||||
                <ion-icon *ngIf="conversation && conversation.isfavourite" name="fas-star"
 | 
			
		||||
                    [attr.aria-label]="'core.favourites' | translate">
 | 
			
		||||
                </ion-icon>
 | 
			
		||||
                <ion-icon *ngIf="conversation && conversation.ismuted" name="fas-bell-slash"
 | 
			
		||||
                    [title]="'addon.messages.mutedconversation' | translate">
 | 
			
		||||
                    [attr.aria-label]="'addon.messages.mutedconversation' | translate">
 | 
			
		||||
                </ion-icon>
 | 
			
		||||
            </div>
 | 
			
		||||
        </ion-title>
 | 
			
		||||
        <ion-buttons slot="end"></ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
    <core-navbar-buttons slot="end">
 | 
			
		||||
        <core-context-menu [aria-label]="'addon.messages.conversationactions' | translate">
 | 
			
		||||
        <core-context-menu [attr.aria-label]="'addon.messages.conversationactions' | translate">
 | 
			
		||||
            <core-context-menu-item [hidden]="isSelf || !showInfo || isGroup" [priority]="1000"
 | 
			
		||||
                [content]="'addon.messages.info' | translate" (action)="viewInfo()"
 | 
			
		||||
                iconAction="fas-info-circle"></core-context-menu-item>
 | 
			
		||||
@ -82,7 +83,7 @@
 | 
			
		||||
                <ion-chip class="addon-messages-unreadfrom" *ngIf="unreadMessageFrom && message.id == unreadMessageFrom"
 | 
			
		||||
                    color="light">
 | 
			
		||||
                    <ion-label>{{ 'addon.messages.newmessages' | translate }}</ion-label>
 | 
			
		||||
                    <ion-icon name="arrow-round-down"></ion-icon>
 | 
			
		||||
                    <ion-icon name="fas-arrow-down" aria-hidden="true"></ion-icon>
 | 
			
		||||
                </ion-chip>
 | 
			
		||||
 | 
			
		||||
                <ion-item class="ion-text-wrap addon-message" (longPress)="copyMessage(message)"
 | 
			
		||||
@ -99,7 +100,9 @@
 | 
			
		||||
                            <div *ngIf="message.showUserData">{{ members[message.useridfrom].fullname }}</div>
 | 
			
		||||
 | 
			
		||||
                            <ion-note *ngIf="!message.pending">{{ message.timecreated | coreFormatDate: "strftimetime" }}</ion-note>
 | 
			
		||||
                            <ion-note *ngIf="message.pending"><ion-icon name="far-clock"></ion-icon></ion-note>
 | 
			
		||||
                            <ion-note *ngIf="message.pending">
 | 
			
		||||
                                <ion-icon name="fas-clock" [attr.aria-label]="'core.notsent' | translate "></ion-icon>
 | 
			
		||||
                            </ion-note>
 | 
			
		||||
                        </h2>
 | 
			
		||||
 | 
			
		||||
                        <!-- Some messages have <p> and some others don't. Add a <p> so they all have same styles. -->
 | 
			
		||||
@ -111,7 +114,7 @@
 | 
			
		||||
                    <ion-button fill="clear" *ngIf="!message.sending && showDelete" (click)="deleteMessage(message, index)"
 | 
			
		||||
                        class="addon-messages-delete-button" [@coreSlideInOut]="'fromRight'"
 | 
			
		||||
                        [attr.aria-label]=" 'addon.messages.deletemessage' | translate" slot="end">
 | 
			
		||||
                        <ion-icon name="fas-trash" color="danger" slot="icon-only"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-trash" color="danger" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
 | 
			
		||||
                    <div class="tail" *ngIf="message.showTail"></div>
 | 
			
		||||
@ -126,7 +129,7 @@
 | 
			
		||||
    <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="loaded && newMessages > 0">
 | 
			
		||||
        <ion-fab-button size="small" (click)="scrollToFirstUnreadMessage()" color="light"
 | 
			
		||||
        [attr.aria-label]="'addon.messages.newmessages' | translate">
 | 
			
		||||
            <ion-icon name="fas-arrow-down"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-arrow-down" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <span class="core-discussion-messages-badge">{{ newMessages }}</span>
 | 
			
		||||
        </ion-fab-button>
 | 
			
		||||
    </ion-fab>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.messages.messages' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
@ -26,8 +26,8 @@
 | 
			
		||||
            <ion-list   class="ion-no-margin">
 | 
			
		||||
 | 
			
		||||
                <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()"
 | 
			
		||||
                    [attr.aria-label]="'addon.messages.contacts' | translate" detail>
 | 
			
		||||
                    <ion-icon name="fas-address-book" slot="start"></ion-icon>
 | 
			
		||||
                    [attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button>
 | 
			
		||||
                    <ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label><h2>{{ 'addon.messages.contacts' | translate }}</h2></ion-label>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -38,9 +38,9 @@
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
                        <ion-note slot="end" class="ion-padding-end"><ion-badge>{{ search.results.length }}</ion-badge></ion-note>
 | 
			
		||||
                    </ion-item-divider>
 | 
			
		||||
                    <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" [title]="result.fullname"
 | 
			
		||||
                        (click)="gotoDiscussion(result.userid, result.messageid)"
 | 
			
		||||
                        [class.core-selected-item]="result.userid == discussionUserId">
 | 
			
		||||
                    <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-current]="result.userid == discussionUserId ? 'page' :  'false'">
 | 
			
		||||
                        <core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                                <h2>{{ result.fullname }}</h2>
 | 
			
		||||
@ -50,9 +50,9 @@
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
                <ng-container *ngIf="!search.showResults">
 | 
			
		||||
                    <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let discussion of discussions"
 | 
			
		||||
                        [title]="discussion.fullname" (click)="gotoDiscussion(discussion.message!.user)"
 | 
			
		||||
                        [class.core-selected-item]="discussion.message!.user == discussionUserId">
 | 
			
		||||
                    <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let discussion of discussions" button
 | 
			
		||||
                        [attr.aria-label]="discussion.fullname" (click)="gotoDiscussion(discussion.message!.user)"
 | 
			
		||||
                        [attr.aria-current]="discussion.message!.user == discussionUserId ? 'page' :  'false'">
 | 
			
		||||
                        <core-user-avatar [user]="discussion" slot="start" checkOnline="false"></core-user-avatar>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2>{{ discussion.fullname }}</h2>
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,15 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.messages.messages' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="gotoSearch()" [attr.aria-label]="'addon.messages.search' | translate">
 | 
			
		||||
                <ion-icon name="fas-search" slot="icon-only"></ion-icon>
 | 
			
		||||
            <ion-button (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate">
 | 
			
		||||
                <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
            <ion-button (click)="gotoSettings()" [attr.aria-label]="'addon.messages.messagepreferences' | translate">
 | 
			
		||||
                <ion-icon name="fas-cog" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-cog" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
            <!-- Add an empty context menu so discussion page can add items in split view,
 | 
			
		||||
                otherwise the menu disappears in some cases. -->
 | 
			
		||||
@ -26,15 +26,17 @@
 | 
			
		||||
        <core-loading [hideUntil]="loaded" [message]="loadingMessage">
 | 
			
		||||
            <ion-list>
 | 
			
		||||
                <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()"
 | 
			
		||||
                    [attr.aria-label]="'addon.messages.contacts' | translate" detail>
 | 
			
		||||
                    <ion-icon name="fas-address-book" slot="start"></ion-icon>
 | 
			
		||||
                    [attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button>
 | 
			
		||||
                    <ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label><h2>{{ 'addon.messages.contacts' | translate }}</h2></ion-label>
 | 
			
		||||
                    <ion-badge *ngIf="contactRequestsCount > 0" slot="end">{{contactRequestsCount}}</ion-badge>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
                <!-- Favourite conversations. -->
 | 
			
		||||
                <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(favourites)" sticky="true">
 | 
			
		||||
                    <ion-icon *ngIf="!favourites.expanded" name="fas-caret-right" slot="start"></ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="favourites.expanded" name="fas-caret-down" slot="start"></ion-icon>
 | 
			
		||||
                <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(favourites)" sticky="true"
 | 
			
		||||
                    [attr.aria-label]="(favourites.expanded ? 'core.collapse' : 'core.expand') | translate"
 | 
			
		||||
                    [attr.aria-expanded]="favourites.expanded" role="heading button">
 | 
			
		||||
                    <ion-icon *ngIf="!favourites.expanded" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="favourites.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label>{{ 'core.favourites' | translate }} ({{ favourites.count }})</ion-label>
 | 
			
		||||
                    <ion-badge slot="end" *ngIf="favourites.unread">{{ favourites.unread }}</ion-badge>
 | 
			
		||||
                </ion-item-divider>
 | 
			
		||||
@ -53,9 +55,11 @@
 | 
			
		||||
                </ion-item>
 | 
			
		||||
 | 
			
		||||
                <!-- Group conversations. -->
 | 
			
		||||
                <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(group)" sticky="true">
 | 
			
		||||
                    <ion-icon *ngIf="!group.expanded" name="fas-caret-right" slot="start"></ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="group.expanded" name="fas-caret-down" slot="start"></ion-icon>
 | 
			
		||||
                <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(group)" sticky="true"
 | 
			
		||||
                    [attr.aria-label]="(group.expanded ? 'core.collapse' : 'core.expand') | translate"
 | 
			
		||||
                    [attr.aria-expanded]="group.expanded" role="heading button">
 | 
			
		||||
                    <ion-icon *ngIf="!group.expanded" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="group.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label>{{ 'addon.messages.groupconversations' | translate }} ({{ group.count }})</ion-label>
 | 
			
		||||
                    <ion-badge slot="end" *ngIf="group.unread">{{ group.unread }}</ion-badge>
 | 
			
		||||
                </ion-item-divider>
 | 
			
		||||
@ -73,9 +77,11 @@
 | 
			
		||||
                    <ion-label><ion-spinner></ion-spinner></ion-label>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
 | 
			
		||||
                <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(individual)" sticky="true">
 | 
			
		||||
                    <ion-icon *ngIf="!individual.expanded" name="fas-caret-right" slot="start"></ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="individual.expanded" name="fas-caret-down" slot="start"></ion-icon>
 | 
			
		||||
                <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggle(individual)" sticky="true"
 | 
			
		||||
                    [attr.aria-label]="(individual.expanded ? 'core.collapse' : 'core.expand') | translate"
 | 
			
		||||
                    [attr.aria-expanded]="individual.expanded" role="heading button">
 | 
			
		||||
                    <ion-icon *ngIf="!individual.expanded" name="fas-caret-right" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="individual.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label>{{ 'addon.messages.individualconversations' | translate }} ({{ individual.count }})</ion-label>
 | 
			
		||||
                    <ion-badge slot="end" *ngIf="individual.unread">{{ individual.unread }}</ion-badge>
 | 
			
		||||
                </ion-item-divider>
 | 
			
		||||
@ -100,10 +106,10 @@
 | 
			
		||||
 | 
			
		||||
<!-- Template to render a list of conversations. -->
 | 
			
		||||
<ng-template #conversationsTemplate let-conversations="conversations">
 | 
			
		||||
    <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let conversation of conversations" [title]="conversation.name"
 | 
			
		||||
        (click)="gotoConversation(conversation.id, conversation.userid)"
 | 
			
		||||
        [class.core-selected-item]="(conversation.id && conversation.id == selectedConversationId) ||
 | 
			
		||||
            (conversation.userid && conversation.userid == selectedUserId)"
 | 
			
		||||
    <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let conversation of conversations" button
 | 
			
		||||
        [attr.aria-label]="conversation.name" (click)="gotoConversation(conversation.id, conversation.userid)"
 | 
			
		||||
        [attr.aria-current]="((conversation.id && conversation.id == selectedConversationId) ||
 | 
			
		||||
            (conversation.userid && conversation.userid == selectedUserId)) ? 'page': 'false'"
 | 
			
		||||
        id="addon-message-conversation-{{ conversation.id ? conversation.id : 'user-' + conversation.userid }}">
 | 
			
		||||
        <!-- Group conversation image. -->
 | 
			
		||||
        <ion-avatar slot="start" *ngIf="conversation.type == typeGroup">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.messages.searchcombined' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
@ -42,13 +42,16 @@
 | 
			
		||||
        </ion-item-divider>
 | 
			
		||||
 | 
			
		||||
        <!-- List of results -->
 | 
			
		||||
        <ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [title]="result.fullname"
 | 
			
		||||
            (click)="openConversation(result)" [class.core-selected-item]="result == selectedResult" detail>
 | 
			
		||||
        <ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [attr.aria-label]="result.fullname"
 | 
			
		||||
            (click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' :  'false'" detail="true"
 | 
			
		||||
            button>
 | 
			
		||||
            <core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <h2>
 | 
			
		||||
                    <core-format-text [text]="result.fullname" [highlight]="result.highlightName" [filter]="false"></core-format-text>
 | 
			
		||||
                    <ion-icon name="fa-ban" *ngIf="result.isblocked" [title]="'addon.messages.contactblocked' | translate">
 | 
			
		||||
                    <core-format-text [text]="result.fullname" [highlight]="result.highlightName" [filter]="false">
 | 
			
		||||
                    </core-format-text>
 | 
			
		||||
                    <ion-icon name="fa-ban" *ngIf="result.isblocked"
 | 
			
		||||
                        [attr.aria-label]="'addon.messages.contactblocked' | translate">
 | 
			
		||||
                    </ion-icon>
 | 
			
		||||
                </h2>
 | 
			
		||||
                <ion-note *ngIf="result.lastmessagedate > 0">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.messages.messages' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
        <ion-title>{{ plugin.name }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-times"></ion-icon>
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@
 | 
			
		||||
    <!-- Assign has something offline. -->
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="hasOffline">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
@ -84,7 +84,8 @@
 | 
			
		||||
            </ion-item>
 | 
			
		||||
 | 
			
		||||
            <!-- Summary of all submissions. -->
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngIf="summary && summary.participantcount" (click)="goToSubmissionList()" detail>
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngIf="summary && summary.participantcount" (click)="goToSubmissionList()" detail="true"
 | 
			
		||||
                button>
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h2 *ngIf="assign.teamsubmission">{{ 'addon.mod_assign.numberofteams' | translate }}</h2>
 | 
			
		||||
                    <h2 *ngIf="!assign.teamsubmission">{{ 'addon.mod_assign.numberofparticipants' | translate }}</h2>
 | 
			
		||||
@ -97,6 +98,7 @@
 | 
			
		||||
            <!-- Summary of submissions with draft status. -->
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngIf="assign.submissiondrafts && summary && summary.submissionsenabled"
 | 
			
		||||
                [detail]="!showNumbers || summary.submissiondraftscount"
 | 
			
		||||
                [button]="!showNumbers || summary.submissiondraftscount"
 | 
			
		||||
                (click)="goToSubmissionList(submissionStatusDraft, !!summary.submissiondraftscount)">
 | 
			
		||||
                <ion-label><h2>{{ 'addon.mod_assign.numberofdraftsubmissions' | translate }}</h2></ion-label>
 | 
			
		||||
                <ion-badge slot="end" *ngIf="showNumbers" color="primary">
 | 
			
		||||
@ -107,6 +109,7 @@
 | 
			
		||||
            <!-- Summary of submissions with submitted status. -->
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled"
 | 
			
		||||
                [detail]="!showNumbers || summary.submissionssubmittedcount"
 | 
			
		||||
                [button]="!showNumbers || summary.submissionssubmittedcount"
 | 
			
		||||
                (click)="goToSubmissionList(submissionStatusSubmitted, !!summary.submissionssubmittedcount)">
 | 
			
		||||
                <ion-label><h2>{{ 'addon.mod_assign.numberofsubmittedassignments' | translate }}</h2></ion-label>
 | 
			
		||||
                <ion-badge slot="end" *ngIf="showNumbers" color="primary">
 | 
			
		||||
@ -116,7 +119,7 @@
 | 
			
		||||
 | 
			
		||||
            <!-- Summary of submissions that need grading. -->
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled && !assign.teamsubmission && showNumbers"
 | 
			
		||||
                [detail]="needsGradingAvalaible"
 | 
			
		||||
                [detail]="needsGradingAvalaible" [button]="needsGradingAvalaible"
 | 
			
		||||
                (click)="goToSubmissionList(needGrading, needsGradingAvalaible)">
 | 
			
		||||
                <ion-label><h2>{{ 'addon.mod_assign.numberofsubmissionsneedgrading' | translate }}</h2></ion-label>
 | 
			
		||||
                <ion-badge slot="end" color="primary">
 | 
			
		||||
@ -128,7 +131,7 @@
 | 
			
		||||
        <!-- Ungrouped users. -->
 | 
			
		||||
        <ion-card *ngIf="assign.teamsubmission && summary && summary.warnofungroupedusers" class="core-info-card">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-question-circle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-question-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'addon.mod_assign.'+summary.warnofungroupedusers | translate }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
    <!-- User and status of the submission. -->
 | 
			
		||||
    <ion-item class="ion-text-wrap" *ngIf="!blindMarking && user" core-user-link [userId]="submitId" [courseId]="courseId"
 | 
			
		||||
        [title]="user!.fullname">
 | 
			
		||||
        [attr.aria-label]="user!.fullname">
 | 
			
		||||
        <core-user-avatar [user]="user" slot="start"></core-user-avatar>
 | 
			
		||||
        <ion-label>
 | 
			
		||||
            <h2>{{ user!.fullname }}</h2>
 | 
			
		||||
@ -183,7 +183,7 @@
 | 
			
		||||
                <ng-container *ngIf="membersToSubmit && membersToSubmit.length > 0 && !blindMarking">
 | 
			
		||||
                    <ng-container *ngFor="let user of membersToSubmit">
 | 
			
		||||
                        <ion-item class="ion-text-wrap" core-user-link [userId]="user.id"
 | 
			
		||||
                            [courseId]="courseId" [title]="user.fullname">
 | 
			
		||||
                            [courseId]="courseId" [attr.aria-label]="user.fullname">
 | 
			
		||||
                            <core-user-avatar [user]="user" slot="start"></core-user-avatar>
 | 
			
		||||
                            <ion-label><h2>{{ user.fullname }}</h2></ion-label>
 | 
			
		||||
                        </ion-item>
 | 
			
		||||
@ -225,8 +225,9 @@
 | 
			
		||||
                        <h2>{{ 'addon.mod_assign.currentgrade' | translate }}</h2>
 | 
			
		||||
                        <p><core-format-text [text]="feedback!.gradefordisplay" [filter]="false"></core-format-text></p>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
                    <ion-button slot="end" *ngIf="feedback!.advancedgrade" (click)="showAdvancedGrade()">
 | 
			
		||||
                        <ion-icon name="fas-search" slot="icon-only"></ion-icon>
 | 
			
		||||
                    <ion-button slot="end" *ngIf="feedback!.advancedgrade" (click)="showAdvancedGrade()"
 | 
			
		||||
                        [attr.aria-label]="'core.showadvanced' |translate">
 | 
			
		||||
                        <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -328,7 +329,7 @@
 | 
			
		||||
 | 
			
		||||
                <!-- Data about the grader (teacher who graded). -->
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngIf="grader" core-user-link [userId]="grader!.id" [courseId]="courseId"
 | 
			
		||||
                    [title]="grader!.fullname" detail="true">
 | 
			
		||||
                    [attr.aria-label]="grader!.fullname" detail="true">
 | 
			
		||||
                    <core-user-avatar [user]="grader" slot="start"></core-user-avatar>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <h2>{{ 'addon.mod_assign.gradedby' | translate }}</h2>
 | 
			
		||||
@ -348,12 +349,12 @@
 | 
			
		||||
                <!-- Warning message if cannot save grades. -->
 | 
			
		||||
                <ion-card *ngIf="isGrading && !canSaveGrades" class="core-warning-card">
 | 
			
		||||
                    <ion-item>
 | 
			
		||||
                        <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <p>{{ 'addon.mod_assign.cannotgradefromapp' | translate }}</p>
 | 
			
		||||
                            <ion-button expand="block" *ngIf="gradeUrl" [href]="gradeUrl" core-link >
 | 
			
		||||
                                {{ 'core.openinbrowser' | translate }}
 | 
			
		||||
                                <ion-icon name="fas-external-link-alt" slot="end"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            </ion-button>
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -11,13 +11,13 @@
 | 
			
		||||
    </ion-label>
 | 
			
		||||
    <div slot="end">
 | 
			
		||||
        <div class="ion-text-end">
 | 
			
		||||
            <ion-button fill="clear" *ngIf="canEdit" (click)="editComment()" color="dark">
 | 
			
		||||
                <ion-icon name="fas-pen" slot="icon-only"></ion-icon>
 | 
			
		||||
            <ion-button fill="clear" *ngIf="canEdit" (click)="editComment()" color="dark"
 | 
			
		||||
                [attr.aria-label]="'core.edit' | translate">
 | 
			
		||||
                <ion-icon name="fas-pen" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <ion-note *ngIf="!isSent" color="dark">
 | 
			
		||||
            <ion-icon name="far-clock"></ion-icon>
 | 
			
		||||
            {{ 'core.notsent' | translate }}
 | 
			
		||||
            <ion-icon name="fas-clock" aria-hidden="true"></ion-icon> {{ 'core.notsent' | translate }}
 | 
			
		||||
        </ion-note>
 | 
			
		||||
    </div>
 | 
			
		||||
</ion-item>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId"  [courseId]="courseId">
 | 
			
		||||
@ -39,8 +39,8 @@
 | 
			
		||||
                </ion-item>
 | 
			
		||||
                <!-- List of submissions. -->
 | 
			
		||||
                <ng-container *ngFor="let submission of submissions.items">
 | 
			
		||||
                    <ion-item class="ion-text-wrap" (click)="submissions.select(submission)"
 | 
			
		||||
                        [class.core-selected-item]="submissions.isSelected(submission)">
 | 
			
		||||
                    <ion-item class="ion-text-wrap" (click)="submissions.select(submission)" button
 | 
			
		||||
                        [attr.aria-current]="submissions.getItemAriaCurrent(submission)">
 | 
			
		||||
                        <core-user-avatar [user]="submission" [linkProfile]="false" slot="start"></core-user-avatar>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2 *ngIf="submission.userfullname">{{submission.userfullname}}</h2>
 | 
			
		||||
@ -75,7 +75,7 @@
 | 
			
		||||
 | 
			
		||||
                <ion-card class="ion-text-wrap core-warning-card" *ngIf="!haveAllParticipants">
 | 
			
		||||
                    <ion-item>
 | 
			
		||||
                        <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        <ion-label>{{ 'addon.mod_assign.notallparticipantsareshown' | translate }}</ion-label>
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
                </ion-card>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
<ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="false">
 | 
			
		||||
<ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="false" button>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{plugin.name}}</h2>
 | 
			
		||||
        <core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments"
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<!-- Buttons to add to the header. -->
 | 
			
		||||
<core-navbar-buttons slot="end">
 | 
			
		||||
    <ion-button (click)="showToc()" [attr.aria-label]="'addon.mod_book.toc' | translate" aria-haspopup="true" *ngIf="loaded">
 | 
			
		||||
        <ion-icon name="fas-bookmark" slot="icon-only"></ion-icon>
 | 
			
		||||
        <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
    </ion-button>
 | 
			
		||||
    <core-context-menu>
 | 
			
		||||
        <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate"
 | 
			
		||||
@ -27,8 +27,10 @@
 | 
			
		||||
        contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description>
 | 
			
		||||
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="warning">
 | 
			
		||||
        <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
        <span [innerHTML]="warning"></span>
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label><span [innerHTML]="warning"></span></ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
 | 
			
		||||
    <div class="ion-padding safe-padding-horizontal">
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
        <ion-title>{{ 'addon.mod_book.toc' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
    <nav>
 | 
			
		||||
        <ion-list>
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)"
 | 
			
		||||
                [class.core-selected-item]="selected == chapter.id"
 | 
			
		||||
                [attr.aria-current]="selected == chapter.id ? 'page' :  'false'" button
 | 
			
		||||
                [class.item-dimmed]="chapter.hidden">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <p [class.ion-padding-left]="addPadding && chapter.level == 1 ? true : null">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@
 | 
			
		||||
 | 
			
		||||
    <ion-card *ngIf="chatInfo" class="core-info-card">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-clock" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-clock" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'addon.mod_chat.sessionstart' | translate:{$a: chatInfo} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.mod_chat.currentusers' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-times"></ion-icon>
 | 
			
		||||
                <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -21,11 +21,11 @@
 | 
			
		||||
                <h2>{{ user.fullname }}</h2>
 | 
			
		||||
                <ng-container *ngIf="currentUserId != user.id && isOnline">
 | 
			
		||||
                    <ion-button fill="clear" (click)="talkTo(user)">
 | 
			
		||||
                        <ion-icon name="fas-comments" slot="start"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-comments" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        {{ 'addon.mod_chat.talk' | translate }}
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
                    <ion-button fill="clear" (click)="beepTo(user)">
 | 
			
		||||
                        <ion-icon name="fas-bell" slot="start"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-bell" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        {{ 'addon.mod_chat.beep' | translate }}
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
 | 
			
		||||
@ -9,7 +9,7 @@
 | 
			
		||||
        </ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button *ngIf="loaded" (click)="showChatUsers()" [attr.aria-label]="'core.users' | translate">
 | 
			
		||||
                <ion-icon name="fas-users" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-users" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -26,7 +26,7 @@
 | 
			
		||||
                <div class="ion-text-center addon-mod_chat-notice" *ngIf="message.special">
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="success" *ngIf="message.system && message.message == 'enter'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-sign-in-alt"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-sign-in-alt" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -34,7 +34,7 @@
 | 
			
		||||
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="danger" *ngIf="message.system && message.message == 'exit'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-sign-out-alt"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-sign-out-alt" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -42,7 +42,7 @@
 | 
			
		||||
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="primary" *ngIf="message.beep == 'all'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-bell"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-bell" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messagebeepseveryone' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -51,7 +51,7 @@
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="primary"
 | 
			
		||||
                        *ngIf="message.userid != currentUserId && message.beep == currentUserId">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-bell"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-bell" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messagebeepsyou' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -60,7 +60,7 @@
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="light"
 | 
			
		||||
                        *ngIf="message.userid == currentUserId && message.beep && message.beep != 'all'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-bell"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-bell" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepWho} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -68,7 +68,7 @@
 | 
			
		||||
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="info" *ngIf="!message.system && !message.beep">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-asterisk"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-asterisk" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            <strong>
 | 
			
		||||
                                {{ message.userfullname }} <core-format-text [text]="message.message" contextLevel="module"
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.mod_chat.messages' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -21,7 +21,7 @@
 | 
			
		||||
                <div class="ion-text-center addon-mod_chat-notice" *ngIf="message.special">
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="success" *ngIf="message.issystem && message.message == 'enter'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-sign-in-alt"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-sign-in-alt" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messageenter' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -29,7 +29,7 @@
 | 
			
		||||
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="danger" *ngIf="message.issystem && message.message == 'exit'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-sign-out-alt"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-sign-out-alt" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messageexit' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -37,7 +37,7 @@
 | 
			
		||||
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="primary" *ngIf="message.beep == 'all'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-bell"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-bell" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messagebeepseveryone' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -46,7 +46,7 @@
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="primary"
 | 
			
		||||
                        *ngIf="message.userid != currentUserId && message.beep == currentUserId">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-bell"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-bell" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messagebeepsyou' | translate:{$a: message.userfullname} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -55,7 +55,7 @@
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="light"
 | 
			
		||||
                        *ngIf="message.userid == currentUserId && message.beep && message.beep != 'all'">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-bell"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-bell" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            {{ 'addon.mod_chat.messageyoubeep' | translate:{$a: message.beepWho} }}
 | 
			
		||||
                        </span>
 | 
			
		||||
@ -63,7 +63,7 @@
 | 
			
		||||
 | 
			
		||||
                    <ion-badge class="ion-text-wrap" color="info" *ngIf="!message.issystem && !message.beep">
 | 
			
		||||
                        <span>
 | 
			
		||||
                            <ion-icon name="fas-asterisk"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-asterisk" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }}
 | 
			
		||||
                            <strong>
 | 
			
		||||
                                {{ message.userfullname }} <core-format-text [text]="message.message" contextLevel="module"
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.mod_chat.chatreport' | translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -31,7 +31,7 @@
 | 
			
		||||
            </ion-item>
 | 
			
		||||
 | 
			
		||||
            <ion-card *ngFor="let session of sessions.items" (click)="sessions.select(session)"
 | 
			
		||||
                [class.core-selected-item]="sessions.isSelected(session)"
 | 
			
		||||
                [attr.aria-current]="sessions.getItemAriaCurrent(session)"
 | 
			
		||||
                [class.addon-mod-chat-session-show-more]="session.sessionusers.length < session.allsessionusers.length">
 | 
			
		||||
 | 
			
		||||
                <ion-item class="ion-text-wrap">
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@
 | 
			
		||||
    <!-- Activity availability messages -->
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="choiceNotOpenYet">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <p *ngIf="options.length">{{ 'addon.mod_choice.previewonly' | translate:{$a: openTimeReadable} }}</p>
 | 
			
		||||
                <p *ngIf="!options.length">{{ 'addon.mod_choice.notopenyet' | translate:{$a: openTimeReadable} }}</p>
 | 
			
		||||
@ -45,7 +45,7 @@
 | 
			
		||||
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="choiceClosed">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <p *ngIf="options.length">
 | 
			
		||||
                    {{ 'addon.mod_choice.yourselection' | translate }}
 | 
			
		||||
@ -61,7 +61,7 @@
 | 
			
		||||
    <!-- Choice done in offline but not synchronized -->
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="hasOffline">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'core.hasdatatosync' | translate:{$a: moduleName} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
@ -69,7 +69,7 @@
 | 
			
		||||
    <!-- Inform what will happen with the choices. -->
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="canEdit && publishInfo && options.length">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ publishInfo | translate }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
@ -111,7 +111,7 @@
 | 
			
		||||
            <ion-row>
 | 
			
		||||
                <ion-col size="12" size-lg="5">
 | 
			
		||||
                    <ion-item class="ion-text-wrap core-warning-item" *ngIf="hasOffline">
 | 
			
		||||
                        <ion-icon slot="start" name="fas-exclamation-triangle" color="warning"></ion-icon>
 | 
			
		||||
                        <ion-icon slot="start" name="fas-exclamation-triangle" color="warning" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        <ion-label>{{ 'addon.mod_choice.resultsnotsynced' | translate }}</ion-label>
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
                    <ion-item>
 | 
			
		||||
@ -141,7 +141,7 @@
 | 
			
		||||
                            </ion-label>
 | 
			
		||||
                        </ion-item-divider>
 | 
			
		||||
                        <ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseId"
 | 
			
		||||
                            [userId]="user.userid" [title]="user.fullname" class="ion-text-wrap">
 | 
			
		||||
                            [userId]="user.userid" [attr.aria-label]="user.fullname" class="ion-text-wrap">
 | 
			
		||||
                            <core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar>
 | 
			
		||||
                            <ion-label><p>{{user.fullname}}</p></ion-label>
 | 
			
		||||
                        </ion-item>
 | 
			
		||||
@ -153,7 +153,7 @@
 | 
			
		||||
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="!canSeeResults && !choiceNotOpenYet">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label><p>{{ 'addon.mod_choice.noresultsviewable' | translate }}</p></ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,26 +1,26 @@
 | 
			
		||||
<ion-button *ngIf="action == 'more'" fill="clear" (click)="viewEntry()" [title]="'addon.mod_data.more' | translate">
 | 
			
		||||
    <ion-icon name="fas-search" slot="icon-only"></ion-icon>
 | 
			
		||||
<ion-button *ngIf="action == 'more'" fill="clear" (click)="viewEntry()" [attr.aria-label]="'addon.mod_data.more' | translate">
 | 
			
		||||
    <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
<ion-button *ngIf="action == 'edit'" fill="clear" (click)="editEntry()"  [title]="'core.edit' | translate">
 | 
			
		||||
    <ion-icon name="fas-cog" slot="icon-only"></ion-icon>
 | 
			
		||||
<ion-button *ngIf="action == 'edit'" fill="clear" (click)="editEntry()"  [attr.aria-label]="'core.edit' | translate">
 | 
			
		||||
    <ion-icon name="fas-cog" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
<ion-button *ngIf="action == 'delete' && !entry.deleted" fill="clear" (click)="deleteEntry()" [title]="'core.delete' | translate">
 | 
			
		||||
    <ion-icon name="fas-trash" slot="icon-only"></ion-icon>
 | 
			
		||||
<ion-button *ngIf="action == 'delete' && !entry.deleted" fill="clear" (click)="deleteEntry()" [attr.aria-label]="'core.delete' | translate">
 | 
			
		||||
    <ion-icon name="fas-trash" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
<ion-button *ngIf="action == 'delete' && entry.deleted" fill="clear" (click)="undoDelete()" [title]="'core.restore' | translate">
 | 
			
		||||
    <ion-icon name="fas-undo-alt" slot="icon-only"></ion-icon>
 | 
			
		||||
<ion-button *ngIf="action == 'delete' && entry.deleted" fill="clear" (click)="undoDelete()" [attr.aria-label]="'core.restore' | translate">
 | 
			
		||||
    <ion-icon name="fas-undo-alt" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
<ion-button *ngIf="action == 'approve'" fill="clear" (click)="approveEntry()" [title]="'addon.mod_data.approve' | translate">
 | 
			
		||||
    <ion-icon name="fas-thumbs-up" slot="icon-only"></ion-icon>
 | 
			
		||||
<ion-button *ngIf="action == 'approve'" fill="clear" (click)="approveEntry()" [attr.aria-label]="'addon.mod_data.approve' | translate">
 | 
			
		||||
    <ion-icon name="fas-thumbs-up" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
<ion-button *ngIf="action == 'disapprove'" fill="clear" (click)="disapproveEntry()"
 | 
			
		||||
    [title]="'addon.mod_data.disapprove' | translate">
 | 
			
		||||
    <ion-icon name="far-thumbs-down" slot="icon-only"></ion-icon>
 | 
			
		||||
    [attr.aria-label]="'addon.mod_data.disapprove' | translate">
 | 
			
		||||
    <ion-icon name="far-thumbs-down" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
<core-comments *ngIf="action == 'comments' && mode == 'list'" contextLevel="module" [instanceId]="database.coursemodule"
 | 
			
		||||
@ -32,7 +32,7 @@ component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="datab
 | 
			
		||||
 | 
			
		||||
<a *ngIf="action == 'userpicture'" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">
 | 
			
		||||
    <img class="avatar-round" [src]="userPicture" [alt]="'core.pictureof' | translate:{$a: entry.fullname}" core-external-content
 | 
			
		||||
    onError="this.src='assets/img/user-avatar.png'" role="presentation">
 | 
			
		||||
    onError="this.src='assets/img/user-avatar.png'">
 | 
			
		||||
</a>
 | 
			
		||||
 | 
			
		||||
<a *ngIf="action == 'user' && entry" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<!-- Buttons to add to the header. -->
 | 
			
		||||
<core-navbar-buttons slot="end">
 | 
			
		||||
    <ion-button *ngIf="canSearch" (click)="showSearch()" [attr.aria-label]="'addon.mod_data.search' | translate">
 | 
			
		||||
        <ion-icon name="fas-search" slot="icon-only"></ion-icon>
 | 
			
		||||
        <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
    </ion-button>
 | 
			
		||||
    <core-context-menu>
 | 
			
		||||
        <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate"
 | 
			
		||||
@ -46,7 +46,7 @@
 | 
			
		||||
    <!-- Data done in offline but not synchronized -->
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="hasOffline || hasOfflineRatings">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
@ -66,21 +66,21 @@
 | 
			
		||||
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="!access?.timeavailable && timeAvailableFrom">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'addon.mod_data.notopenyet' | translate:{$a: timeAvailableFromReadable} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="!access?.timeavailable && timeAvailableTo">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'addon.mod_data.expired' | translate:{$a: timeAvailableToReadable} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="access && access.entrieslefttoview">>
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                {{ 'addon.mod_data.entrieslefttoaddtoview' | translate:{$a: {entrieslefttoview: access.entrieslefttoview} } }}
 | 
			
		||||
            </ion-label>
 | 
			
		||||
@ -89,7 +89,7 @@
 | 
			
		||||
 | 
			
		||||
    <ion-card class="core-info-card" *ngIf="access && access.entrieslefttoadd">>
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                {{ 'addon.mod_data.entrieslefttoadd' | translate:{$a: {entriesleft: access.entrieslefttoadd} } }}
 | 
			
		||||
            </ion-label>
 | 
			
		||||
@ -121,14 +121,14 @@
 | 
			
		||||
        <ion-row class="ion-align-items-center">
 | 
			
		||||
            <ion-col *ngIf="search.page > 0">
 | 
			
		||||
                <ion-button expand="block" fill="outline" (click)="searchEntries(search.page - 1)">
 | 
			
		||||
                    <ion-icon name="fas-chevron-left" slot="start"></ion-icon>
 | 
			
		||||
                    <ion-icon name="fas-chevron-left" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    {{ 'core.previous' | translate }}
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
            <ion-col *ngIf="hasNextPage">
 | 
			
		||||
                <ion-button expand="block" (click)="searchEntries(search.page + 1)">
 | 
			
		||||
                    {{ 'core.next' | translate }}
 | 
			
		||||
                    <ion-icon name="fas-chevron-right" slot="end"></ion-icon>
 | 
			
		||||
                    <ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </ion-col>
 | 
			
		||||
        </ion-row>
 | 
			
		||||
@ -146,6 +146,6 @@
 | 
			
		||||
 | 
			
		||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canAdd">
 | 
			
		||||
    <ion-fab-button (click)="gotoAddEntries()" [attr.aria-label]="'addon.mod_data.addentries' | translate">
 | 
			
		||||
        <ion-icon name="fas-plus"></ion-icon>
 | 
			
		||||
        <ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
 | 
			
		||||
    </ion-fab-button>
 | 
			
		||||
</ion-fab>
 | 
			
		||||
 | 
			
		||||
@ -90,7 +90,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
 | 
			
		||||
    entriesRendered = '';
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
 | 
			
		||||
    jsData? : {
 | 
			
		||||
    jsData?: {
 | 
			
		||||
        fields: Record<number, AddonModDataField>;
 | 
			
		||||
        entries: Record<number, AddonModDataEntry>;
 | 
			
		||||
        database: AddonModDataData;
 | 
			
		||||
@ -100,7 +100,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Data for found records translation.
 | 
			
		||||
    foundRecordsTranslationData? : {
 | 
			
		||||
    foundRecordsTranslationData?: {
 | 
			
		||||
        num: number;
 | 
			
		||||
        max: number;
 | 
			
		||||
        reseturl: string;
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.mod_data.search' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -60,7 +60,7 @@
 | 
			
		||||
        </ion-list>
 | 
			
		||||
        <div class="ion-padding">
 | 
			
		||||
            <ion-button expand="block" type="submit">
 | 
			
		||||
                <ion-icon name="fas-search" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-search" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                {{ 'addon.mod_data.search' | translate }}
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ export class AddonModDataSearchComponent implements OnInit {
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
 | 
			
		||||
    searchForm: FormGroup;
 | 
			
		||||
    jsData? : {
 | 
			
		||||
    jsData?: {
 | 
			
		||||
        fields: Record<number, AddonModDataField>;
 | 
			
		||||
        form: FormGroup;
 | 
			
		||||
        search: CoreFormFields;
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="addon-data-latlong" *ngIf="locationServicesEnabled">
 | 
			
		||||
            <ion-button (click)="getLocation($event)">
 | 
			
		||||
                <ion-icon name="fas-crosshairs" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-crosshairs" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                {{ 'addon.mod_data.mylocation' | translate }}
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,7 @@ export class AddonModDataEditPage implements OnInit {
 | 
			
		||||
    editFormRender = '';
 | 
			
		||||
    editForm: FormGroup;
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    jsData? : {
 | 
			
		||||
    jsData?: {
 | 
			
		||||
        fields: Record<number, AddonModDataField>;
 | 
			
		||||
        database?: AddonModDataData;
 | 
			
		||||
        contents: AddonModDataEntryFields;
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
			
		||||
@ -19,7 +19,7 @@
 | 
			
		||||
        <!-- Database entries found to be synchronized -->
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="entry && entry.hasOffline">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -66,14 +66,14 @@
 | 
			
		||||
            <ion-row class="ion-align-items-center">
 | 
			
		||||
                <ion-col *ngIf="hasPrevious">
 | 
			
		||||
                    <ion-button expand="block" fill="outline" (click)="gotoEntry(offset! -1)">
 | 
			
		||||
                        <ion-icon name="fas-chevron-left" slot="start"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-chevron-left" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        {{ 'core.previous' | translate }}
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
                </ion-col>
 | 
			
		||||
                <ion-col *ngIf="hasNext">
 | 
			
		||||
                    <ion-button expand="block" (click)="gotoEntry(offset! + 1)">
 | 
			
		||||
                        {{ 'core.next' | translate }}
 | 
			
		||||
                        <ion-icon name="fas-chevron-right" slot="end"></ion-icon>
 | 
			
		||||
                        <ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
                </ion-col>
 | 
			
		||||
            </ion-row>
 | 
			
		||||
 | 
			
		||||
@ -78,7 +78,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
 | 
			
		||||
    entryHtml = '';
 | 
			
		||||
    siteId: string;
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    jsData? : {
 | 
			
		||||
    jsData?: {
 | 
			
		||||
        fields: Record<number, AddonModDataField>;
 | 
			
		||||
        entries: Record<number, AddonModDataEntry>;
 | 
			
		||||
        database: AddonModDataData;
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -68,14 +68,15 @@
 | 
			
		||||
                </ion-select-option>
 | 
			
		||||
            </ion-select>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
        <ion-item class="ion-text-wrap" (click)="openRespondents()" [detail]="access.canviewreports && completedCount > 0">
 | 
			
		||||
        <ion-item class="ion-text-wrap" (click)="openRespondents()" [detail]="access.canviewreports && completedCount > 0"
 | 
			
		||||
            button>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <h2>{{ 'addon.mod_feedback.completed_feedbacks' | translate }}</h2>
 | 
			
		||||
            </ion-label>
 | 
			
		||||
            <ion-badge slot="end">{{completedCount}}</ion-badge>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
        <ion-item class="ion-text-wrap" *ngIf="!access.isanonymous && access.canviewreports" (click)="openNonRespondents()"
 | 
			
		||||
            detail="true" tappable="true">
 | 
			
		||||
            detail="true" button>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <h2>{{ 'addon.mod_feedback.show_nonrespondents' | translate }}</h2>
 | 
			
		||||
            </ion-label>
 | 
			
		||||
@ -97,21 +98,21 @@
 | 
			
		||||
        <!-- Feedback done in offline but not synchronized -->
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="hasOffline">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'core.hasdatatosync' | translate:{$a: moduleName} }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <ion-card class="core-info-card" *ngIf="access && access.cancomplete && !access.isopen">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-question-circle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-question-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'addon.mod_feedback.feedback_is_not_open' | translate }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <ion-card class="core-success-card" *ngIf="access && access.cancomplete && access.isopen && !access.cansubmit">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-check" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'addon.mod_feedback.this_feedback_is_already_submitted' | translate }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -149,7 +150,7 @@
 | 
			
		||||
                    <ion-row class="ion-align-items-center">
 | 
			
		||||
                        <ion-col>
 | 
			
		||||
                            <ion-button expand="block" fill="outline" (click)="gotoAnswerQuestions(true)" class="ion-text-wrap">
 | 
			
		||||
                                <ion-icon name="fas-search" slot="start"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fas-search" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                                {{ 'addon.mod_feedback.preview' | translate }}
 | 
			
		||||
                            </ion-button>
 | 
			
		||||
                        </ion-col>
 | 
			
		||||
@ -161,7 +162,7 @@
 | 
			
		||||
                                <ng-container *ngIf="goPage">
 | 
			
		||||
                                    {{ 'addon.mod_feedback.continue_the_form' | translate }}
 | 
			
		||||
                                </ng-container>
 | 
			
		||||
                                <ion-icon name="fas-chevron-right" slot="end"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            </ion-button>
 | 
			
		||||
                        </ion-col>
 | 
			
		||||
                    </ion-row>
 | 
			
		||||
@ -180,7 +181,7 @@
 | 
			
		||||
        <ng-container *ngIf="access && (access.canedititems || !access.isempty)">
 | 
			
		||||
            <ion-card class="core-info-card" *ngIf="warning">
 | 
			
		||||
                <ion-item>
 | 
			
		||||
                    <ion-icon name="fas-question-circle" slot="start"></ion-icon>
 | 
			
		||||
                    <ion-icon name="fas-question-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label>{{ warning }}</ion-label>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
            </ion-card>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <ng-container *ngIf="attempt">{{ attempt.fullname }}</ng-container>
 | 
			
		||||
@ -15,7 +15,7 @@
 | 
			
		||||
    <core-loading [hideUntil]="loaded">
 | 
			
		||||
        <ion-list class="ion-no-margin" *ngIf="attempt || anonAttempt">
 | 
			
		||||
            <ion-item *ngIf="attempt" class="ion-text-wrap" core-user-link [userId]="attempt.userid"
 | 
			
		||||
                [attr.aria-label]=" 'core.user.viewprofile' | translate" [courseId]="attempt.courseid" [title]="attempt.fullname">
 | 
			
		||||
                [attr.aria-label]=" 'core.user.viewprofile' | translate" [courseId]="attempt.courseid">
 | 
			
		||||
                <core-user-avatar [user]="attempt" slot="start"></core-user-avatar>
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h2>{{attempt.fullname}}</h2>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
 | 
			
		||||
@ -59,7 +59,7 @@
 | 
			
		||||
                            </ng-container>
 | 
			
		||||
 | 
			
		||||
                            <ion-textarea *ngIf="item.templateName == 'textarea'" [required]="item.required"
 | 
			
		||||
                                name="{{item.typ}}_{{item.id}}" [attr.aria-multiline]="true" [(ngModel)]="item.value">
 | 
			
		||||
                                name="{{item.typ}}_{{item.id}}" [(ngModel)]="item.value">
 | 
			
		||||
                            </ion-textarea>
 | 
			
		||||
 | 
			
		||||
                            <ion-select *ngIf="item.templateName == 'multichoice-d'" [required]="item.required"
 | 
			
		||||
@ -106,7 +106,7 @@
 | 
			
		||||
                            </core-recaptcha>
 | 
			
		||||
                            <div *ngIf="!preview && (!item.captcha || offline)" class="core-warning-card">
 | 
			
		||||
                                <ion-item>
 | 
			
		||||
                                    <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                                    <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                                    <ion-label>{{ 'addon.mod_feedback.captchaofflinewarning' | translate }}</ion-label>
 | 
			
		||||
                                </ion-item>
 | 
			
		||||
                            </div>
 | 
			
		||||
@ -117,14 +117,14 @@
 | 
			
		||||
                    <ion-row class="ion-align-items-center">
 | 
			
		||||
                        <ion-col *ngIf="hasPrevPage">
 | 
			
		||||
                            <ion-button expand="block" fill="outline" (click)="gotoPage(true)" class="ion-text-wrap">
 | 
			
		||||
                                <ion-icon name="fas-chevron-left" slot="start"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fas-chevron-left" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                                {{ 'addon.mod_feedback.previous_page' | translate }}
 | 
			
		||||
                            </ion-button>
 | 
			
		||||
                        </ion-col>
 | 
			
		||||
                        <ion-col *ngIf="hasNextPage">
 | 
			
		||||
                            <ion-button expand="block" (click)="gotoPage(false)" class="ion-text-wrap">
 | 
			
		||||
                                {{ 'addon.mod_feedback.next_page' | translate }}
 | 
			
		||||
                                <ion-icon name="fas-chevron-right" slot="end"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            </ion-button>
 | 
			
		||||
                        </ion-col>
 | 
			
		||||
                        <ion-col *ngIf="!hasNextPage">
 | 
			
		||||
@ -139,7 +139,7 @@
 | 
			
		||||
 | 
			
		||||
        <ion-card class="core-success-card" *ngIf="completed">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-check" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <p *ngIf="!completionPageContents && !completedOffline">
 | 
			
		||||
                        {{ 'addon.mod_feedback.this_feedback_is_already_submitted' | translate }}
 | 
			
		||||
@ -161,14 +161,14 @@
 | 
			
		||||
                <ion-row class="ion-align-items-center">
 | 
			
		||||
                    <ion-col *ngIf="access!.canviewanalysis">
 | 
			
		||||
                        <ion-button expand="block" fill="outline" (click)="showAnalysis()" class="ion-text-wrap">
 | 
			
		||||
                            <ion-icon name="fas-chart-bar" slot="start"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-chart-bar" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                            {{ 'addon.mod_feedback.completed_feedbacks' | translate }}
 | 
			
		||||
                        </ion-button>
 | 
			
		||||
                    </ion-col>
 | 
			
		||||
                    <ion-col *ngIf="hasNextPage">
 | 
			
		||||
                        <ion-button expand="block" (click)="continue()" class="ion-text-wrap">
 | 
			
		||||
                            {{ 'core.continue' | translate }}
 | 
			
		||||
                            <ion-icon name="fas-chevron-right" slot="end"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        </ion-button>
 | 
			
		||||
                    </ion-col>
 | 
			
		||||
                </ion-row>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.mod_feedback.responses' |translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.mod_feedback.responses' |translate }}</ion-title>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -32,8 +32,8 @@
 | 
			
		||||
                            {{ 'addon.mod_feedback.non_anonymous_entries' | translate : {$a: responses.responses.total } }}
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
                    </ion-item-divider>
 | 
			
		||||
                    <ion-item *ngFor="let attempt of responses.responses.attempts" class="ion-text-wrap" tappable detail="true"
 | 
			
		||||
                        (click)="responses.select(attempt)" [class.core-selected-item]="responses.isSelected(attempt)">
 | 
			
		||||
                    <ion-item *ngFor="let attempt of responses.responses.attempts" class="ion-text-wrap" button detail="true"
 | 
			
		||||
                        (click)="responses.select(attempt)" [attr.aria-current]="responses.getItemAriaCurrent(attempt)">
 | 
			
		||||
                        <core-user-avatar [user]="attempt" slot="start"></core-user-avatar>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2>{{ attempt.fullname }}</h2>
 | 
			
		||||
@ -57,8 +57,8 @@
 | 
			
		||||
                            {{ 'addon.mod_feedback.anonymous_entries' |translate : {$a: responses.anonResponses.total } }}
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
                    </ion-item-divider>
 | 
			
		||||
                    <ion-item *ngFor="let attempt of responses.anonResponses.attempts" class="ion-text-wrap" tappable detail="true"
 | 
			
		||||
                        (click)="responses.select(attempt)" [class.core-selected-item]="responses.isSelected(attempt)">
 | 
			
		||||
                    <ion-item *ngFor="let attempt of responses.anonResponses.attempts" class="ion-text-wrap" button detail="true"
 | 
			
		||||
                        (click)="responses.select(attempt)" [attr.aria-current]="responses.getItemAriaCurrent(attempt)">
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2>{{ 'addon.mod_feedback.response_nr' |translate }}: {{attempt.number}}</h2>
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@
 | 
			
		||||
    <ion-list *ngIf="subfolder && (subfolder!.files.length + subfolder!.folders.length > 0)">
 | 
			
		||||
        <ng-container *ngFor="let folder of subfolder!.folders">
 | 
			
		||||
            <ion-item class="item-file" (click)="openFolder(folder)" detail="true" button>
 | 
			
		||||
                <ion-icon name="fas-folder" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-folder" slot="start" [attr.aria-label]="'core.folder' | translate"></ion-icon>
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h2>{{folder.filename}}</h2>
 | 
			
		||||
                </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,35 +1,35 @@
 | 
			
		||||
<ion-item class="ion-text-wrap" (click)="setLockState(true)" *ngIf="discussion.canlock && !discussion.locked">
 | 
			
		||||
    <ion-icon name="fa-lock" slot="start"></ion-icon>
 | 
			
		||||
    <ion-icon name="fa-lock" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{ 'addon.mod_forum.lockdiscussion' | translate }}</h2>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
</ion-item>
 | 
			
		||||
<ion-item class="ion-text-wrap" (click)="setLockState(false)" *ngIf="discussion.canlock && discussion.locked">
 | 
			
		||||
    <ion-icon name="fa-unlock" slot="start"></ion-icon>
 | 
			
		||||
    <ion-icon name="fa-unlock" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{ 'addon.mod_forum.unlockdiscussion' | translate }}</h2>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
</ion-item>
 | 
			
		||||
<ion-item class="ion-text-wrap" (click)="setPinState(true)" *ngIf="canPin && !discussion.pinned">
 | 
			
		||||
    <ion-icon name="fa-map-pin" slot="start"></ion-icon>
 | 
			
		||||
    <ion-icon name="fa-map-pin" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{ 'addon.mod_forum.pindiscussion' | translate }}</h2>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
</ion-item>
 | 
			
		||||
<ion-item class="ion-text-wrap" (click)="setPinState(false)" *ngIf="canPin && discussion.pinned">
 | 
			
		||||
    <ion-icon name="fa-map-pin" slot="start" class="icon-slash"></ion-icon>
 | 
			
		||||
    <ion-icon name="fa-map-pin" slot="start" class="icon-slash" aria-hidden="true"></ion-icon>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{ 'addon.mod_forum.unpindiscussion' | translate }}</h2>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
</ion-item>
 | 
			
		||||
<ion-item class="ion-text-wrap" (click)="toggleFavouriteState(true)" *ngIf="discussion.canfavourite && !discussion.starred">
 | 
			
		||||
    <ion-icon name="fa-star" slot="start"></ion-icon>
 | 
			
		||||
    <ion-icon name="fa-star" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{ 'addon.mod_forum.addtofavourites' | translate }}</h2>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
</ion-item>
 | 
			
		||||
<ion-item class="ion-text-wrap" (click)="toggleFavouriteState(false)" *ngIf="discussion.canfavourite && discussion.starred">
 | 
			
		||||
    <ion-icon name="fa-star" slot="start" class="icon-slash"></ion-icon>
 | 
			
		||||
    <ion-icon name="fa-star" slot="start" class="icon-slash" aria-hidden="true"></ion-icon>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{ 'addon.mod_forum.removefromfavourites' | translate }}</h2>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
        <ion-title>{{ 'addon.mod_forum.yourreply' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon name="close" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -25,9 +25,10 @@
 | 
			
		||||
                (contentChanged)="onMessageChange($event)">
 | 
			
		||||
            </core-rich-text-editor>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
        <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()">
 | 
			
		||||
            <ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon *ngIf="advanced" name="fa-caret-down" slot="start"></ion-icon>
 | 
			
		||||
        <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()" role="heading button"
 | 
			
		||||
            [attr.aria-expanded]="advanced" [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate">
 | 
			
		||||
            <ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-icon *ngIf="advanced" name="fa-caret-down" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'addon.mod_forum.advanced' | translate }}</ion-label>
 | 
			
		||||
        </ion-item-divider>
 | 
			
		||||
        <ng-container *ngIf="advanced">
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,7 @@
 | 
			
		||||
        <!-- Forum discussions found to be synchronized -->
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="hasOffline || hasOfflineRatings">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'core.hasdatatosync' | translate:{$a: moduleName} }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -58,7 +58,7 @@
 | 
			
		||||
        <!-- Cut-off date or due date message -->
 | 
			
		||||
        <ion-card class="core-info-card" *ngIf="availabilityMessage">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-info-circle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ availabilityMessage }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -71,7 +71,7 @@
 | 
			
		||||
                <ion-button *ngIf="sortingAvailable" id="addon-mod-forum-sort-order-button"
 | 
			
		||||
                    class="core-button-select button-no-uppercase"
 | 
			
		||||
                    aria-haspopup="true" aria-controls="addon-mod-forum-sort-order-selector"
 | 
			
		||||
                    [attr.aria-label]="('core.sort' | translate)" [attr.aria-expanded]="sortOrderSelectorExpanded"
 | 
			
		||||
                    [attr.aria-label]="('core.sort' | translate)"
 | 
			
		||||
                    (click)="showSortOrderSelector()">
 | 
			
		||||
                    <span class="core-button-select-text">{{ selectedSortOrder.label | translate }}</span>
 | 
			
		||||
                    <div class="select-icon" slot="end"><div class="select-icon-inner"></div></div>
 | 
			
		||||
@ -80,13 +80,15 @@
 | 
			
		||||
 | 
			
		||||
            <ion-item *ngFor="let discussion of discussions.items"
 | 
			
		||||
                class="addon-mod-forum-discussion" detail="true"
 | 
			
		||||
                [lines]="discussion.groupname && 'none'" [class.core-selected-item]="discussions.isSelected(discussion)"
 | 
			
		||||
                [lines]="discussion.groupname && 'none'" [attr.aria-current]="discussions.getItemAriaCurrent(discussion)"
 | 
			
		||||
                (click)="discussions.select(discussion)">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <div class="addon-mod-forum-discussion-title">
 | 
			
		||||
                        <h2 class="ion-text-wrap">
 | 
			
		||||
                            <ion-icon name="fa-map-pin" *ngIf="discussion.pinned"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fa-star" class="addon-forum-star" *ngIf="!discussion.pinned && discussion.starred"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fa-map-pin" *ngIf="discussion.pinned"
 | 
			
		||||
                                [attr.aria-label]="'addon.mod_forum.discussionpinned' | translate"></ion-icon>
 | 
			
		||||
                            <ion-icon name="fa-star" class="addon-forum-star" *ngIf="!discussion.pinned && discussion.starred"
 | 
			
		||||
                                [attr.aria-label]="'addon.mod_forum.favourites' | translate"></ion-icon>
 | 
			
		||||
                            <core-format-text
 | 
			
		||||
                                [text]="discussion.subject"
 | 
			
		||||
                                contextLevel="module" [contextInstanceId]="module && module.id" [courseId]="courseId">
 | 
			
		||||
@ -96,7 +98,7 @@
 | 
			
		||||
                            fill="clear" color="dark"
 | 
			
		||||
                            [attr.aria-label]="('core.displayoptions' | translate)"
 | 
			
		||||
                            (click)="showOptionsMenu($event, discussion)">
 | 
			
		||||
                            <ion-icon name="ellipsis-vertical" slot="icon-only">
 | 
			
		||||
                            <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true">
 | 
			
		||||
                            </ion-icon>
 | 
			
		||||
                        </ion-button>
 | 
			
		||||
                    </div>
 | 
			
		||||
@ -105,12 +107,15 @@
 | 
			
		||||
                        </core-user-avatar>
 | 
			
		||||
                        <div class="addon-mod-forum-discussion-author">
 | 
			
		||||
                            <h3 *ngIf="discussion.userfullname">{{discussion.userfullname}}</h3>
 | 
			
		||||
                            <p *ngIf="discussion.groupname"><ion-icon name="people"></ion-icon> {{ discussion.groupname }}</p>
 | 
			
		||||
                            <p *ngIf="discussion.groupname">
 | 
			
		||||
                                <ion-icon name="fas-users" [attr.aria-label]="'addon.mod_forum.group' | translate">
 | 
			
		||||
                                </ion-icon> {{ discussion.groupname }}
 | 
			
		||||
                            </p>
 | 
			
		||||
                            <p *ngIf="discussions.isOnlineDiscussion(discussion)">
 | 
			
		||||
                                {{discussion.created * 1000 | coreFormatDate: "strftimerecentfull"}}
 | 
			
		||||
                            </p>
 | 
			
		||||
                            <p *ngIf="discussions.isOfflineDiscussion(discussion)">
 | 
			
		||||
                                <ion-icon name="fas-clock"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fas-clock" aria-hidden="true"></ion-icon>
 | 
			
		||||
                                {{ 'core.notsent' | translate }}
 | 
			
		||||
                            </p>
 | 
			
		||||
                        </div>
 | 
			
		||||
@ -119,7 +124,7 @@
 | 
			
		||||
                        class="ion-text-center addon-mod-forum-discussion-more-info">
 | 
			
		||||
                        <ion-col class="ion-text-start">
 | 
			
		||||
                            <ion-note>
 | 
			
		||||
                                <ion-icon name="fas-clock"></ion-icon> {{ 'addon.mod_forum.lastpost' | translate }}
 | 
			
		||||
                                <ion-icon name="fas-clock" aria-hidden="true"></ion-icon> {{ 'addon.mod_forum.lastpost' | translate }}
 | 
			
		||||
                                <ng-container *ngIf="discussion.timemodified > discussion.created">
 | 
			
		||||
                                    {{ discussion.timemodified | coreTimeAgo }}
 | 
			
		||||
                                </ng-container>
 | 
			
		||||
@ -130,7 +135,7 @@
 | 
			
		||||
                        </ion-col>
 | 
			
		||||
                        <ion-col class="ion-text-end">
 | 
			
		||||
                            <ion-note>
 | 
			
		||||
                                <ion-icon name="fas-comments"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fas-comments" aria-hidden="true"></ion-icon>
 | 
			
		||||
                                {{ 'addon.mod_forum.numreplies' | translate:{numreplies: discussion.numreplies} }}
 | 
			
		||||
                                <ion-badge *ngIf="discussion.numunread" class="ion-text-center"
 | 
			
		||||
                                    [attr.aria-label]="'addon.mod_forum.unreadpostsnumber' | translate:{ '$a' : discussion.numunread}">
 | 
			
		||||
@ -151,7 +156,7 @@
 | 
			
		||||
 | 
			
		||||
    <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="forum && canAddDiscussion">
 | 
			
		||||
        <ion-fab-button (click)="openNewDiscussion()" [attr.aria-label]="addDiscussionText">
 | 
			
		||||
            <ion-icon name="fas-plus"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
 | 
			
		||||
        </ion-fab-button>
 | 
			
		||||
    </ion-fab>
 | 
			
		||||
</core-split-view>
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,6 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
 | 
			
		||||
    sortingAvailable!: boolean;
 | 
			
		||||
    sortOrders: AddonModForumSortOrder[] = [];
 | 
			
		||||
    selectedSortOrder: AddonModForumSortOrder | null = null;
 | 
			
		||||
    sortOrderSelectorExpanded = false;
 | 
			
		||||
    canPin = false;
 | 
			
		||||
 | 
			
		||||
    protected syncEventName = AddonModForumSyncProvider.AUTO_SYNCED;
 | 
			
		||||
@ -635,14 +634,10 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
 | 
			
		||||
            },
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        modal.present();
 | 
			
		||||
 | 
			
		||||
        this.sortOrderSelectorExpanded = true;
 | 
			
		||||
        await modal.present();
 | 
			
		||||
 | 
			
		||||
        const result = await modal.onDidDismiss<AddonModForumSortOrder>();
 | 
			
		||||
 | 
			
		||||
        this.sortOrderSelectorExpanded = false;
 | 
			
		||||
 | 
			
		||||
        if (result.data && result.data.value != this.selectedSortOrder?.value) {
 | 
			
		||||
            this.selectedSortOrder = result.data;
 | 
			
		||||
            this.page = 0;
 | 
			
		||||
@ -673,7 +668,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
 | 
			
		||||
            event,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        popover.present();
 | 
			
		||||
        await popover.present();
 | 
			
		||||
 | 
			
		||||
        const result = await popover.onDidDismiss<{ action?: string; value: boolean }>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
<core-loading [hideUntil]="loaded" class="core-loading-center">
 | 
			
		||||
    <ion-item class="ion-text-wrap" (click)="editPost()" *ngIf="offlinePost || (canEdit && isOnline)">
 | 
			
		||||
        <ion-icon name="create" slot="start"></ion-icon>
 | 
			
		||||
        <ion-icon name="fas-pen" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
        <ion-label>
 | 
			
		||||
            <h2>{{ 'addon.mod_forum.edit' | translate }}</h2>
 | 
			
		||||
        </ion-label>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
    <ion-item class="ion-text-wrap" (click)="deletePost()" *ngIf="offlinePost || (canDelete && isOnline)">
 | 
			
		||||
        <ion-icon name="fas-trash" slot="start"></ion-icon>
 | 
			
		||||
        <ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
        <ion-label>
 | 
			
		||||
            <h2 *ngIf="!offlinePost">{{ 'addon.mod_forum.delete' | translate }}</h2>
 | 
			
		||||
            <h2 *ngIf="offlinePost">{{ 'core.discard' | translate }}</h2>
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
        </ion-label>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
    <ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false">
 | 
			
		||||
        <ion-icon name="open" slot="start"></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>
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,11 @@
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <div class="addon-mod-forum-post-title" *ngIf="displaySubject">
 | 
			
		||||
                    <h2 class="ion-text-wrap">
 | 
			
		||||
                        <ion-icon name="fa-map-pin" *ngIf="discussion && !post.parentid && discussion.pinned">
 | 
			
		||||
                        <ion-icon name="fa-map-pin" *ngIf="discussion && !post.parentid && discussion.pinned"
 | 
			
		||||
                            [attr.aria-label]="'addon.mod_forum.discussionpinned' | translate">
 | 
			
		||||
                        </ion-icon>
 | 
			
		||||
                        <ion-icon name="fa-star" class="addon-forum-star"
 | 
			
		||||
                            [attr.aria-label]="'addon.mod_forum.favourites' | translate"
 | 
			
		||||
                            *ngIf="discussion && !post.parentid && !discussion.pinned && discussion.starred">
 | 
			
		||||
                        </ion-icon>
 | 
			
		||||
                        <core-format-text
 | 
			
		||||
@ -16,13 +18,12 @@
 | 
			
		||||
                    </h2>
 | 
			
		||||
                    <ion-note *ngIf="trackPosts && post.unread"
 | 
			
		||||
                        class="ion-float-end ion-padding-left ion-text-end" [attr.aria-label]="'addon.mod_forum.unread' | translate">
 | 
			
		||||
                        <ion-icon name="fa-circle" color="primary">
 | 
			
		||||
                        </ion-icon>
 | 
			
		||||
                        <ion-icon name="fa-circle" color="primary" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    </ion-note>
 | 
			
		||||
                    <ion-button *ngIf="optionsMenuEnabled"
 | 
			
		||||
                        fill="clear" color="dark" [attr.aria-label]="('core.displayoptions' | translate)"
 | 
			
		||||
                        (click)="showOptionsMenu($event)">
 | 
			
		||||
                        <ion-icon name="ellipsis-vertical" slot="icon-only">
 | 
			
		||||
                        <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true">
 | 
			
		||||
                        </ion-icon>
 | 
			
		||||
                    </ion-button>
 | 
			
		||||
                </div>
 | 
			
		||||
@ -33,23 +34,24 @@
 | 
			
		||||
                        <h3 *ngIf="post.author && post.author.fullname">{{post.author.fullname}}</h3>
 | 
			
		||||
                        <p *ngIf="post.author && post.author.groups">
 | 
			
		||||
                            <ng-container *ngFor="let group of post.author.groups">
 | 
			
		||||
                                <ion-icon name="people"></ion-icon> {{ group.name }}
 | 
			
		||||
                                <ion-icon name="fas-users" [attr.aria-label]="'addon.mod_forum.group' | translate">
 | 
			
		||||
                                </ion-icon> {{ group.name }}
 | 
			
		||||
                            </ng-container>
 | 
			
		||||
                        </p>
 | 
			
		||||
                        <p *ngIf="post.timecreated">{{post.timecreated * 1000 | coreFormatDate: "strftimerecentfull"}}</p>
 | 
			
		||||
                        <p *ngIf="!post.timecreated"><ion-icon name="fas-clock"></ion-icon> {{ 'core.notsent' | translate }}</p>
 | 
			
		||||
                        <p *ngIf="!post.timecreated">
 | 
			
		||||
                            <ion-icon name="fas-clock" aria-hidden="true"></ion-icon> {{ 'core.notsent' | translate }}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <ng-container *ngIf="!displaySubject">
 | 
			
		||||
                        <ion-note *ngIf="trackPosts && post.unread"
 | 
			
		||||
                            class="ion-float-end ion-padding-left ion-text-end" [attr.aria-label]="'addon.mod_forum.unread' | translate">
 | 
			
		||||
                            <ion-icon name="fa-circle" color="primary">
 | 
			
		||||
                            </ion-icon>
 | 
			
		||||
                            <ion-icon name="fa-circle" color="primary" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        </ion-note>
 | 
			
		||||
                        <ion-button *ngIf="optionsMenuEnabled"
 | 
			
		||||
                            fill="clear" color="dark" [attr.aria-label]="('core.displayoptions' | translate)"
 | 
			
		||||
                            (click)="showOptionsMenu($event)">
 | 
			
		||||
                            <ion-icon name="ellipsis-vertical" slot="icon-only">
 | 
			
		||||
                            </ion-icon>
 | 
			
		||||
                            <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        </ion-button>
 | 
			
		||||
                    </ng-container>
 | 
			
		||||
                </div>
 | 
			
		||||
@ -92,7 +94,7 @@
 | 
			
		||||
                    [attr.aria-controls]="'addon-forum-reply-edit-form-' + uniqueId"
 | 
			
		||||
                    [attr.aria-expanded]="replyData.replyingTo === post.id"
 | 
			
		||||
                    (click)="showReplyForm()">
 | 
			
		||||
                    <ion-icon name="fa-reply" slot="start">
 | 
			
		||||
                    <ion-icon name="fa-reply" slot="start" aria-hidden="true">
 | 
			
		||||
                    </ion-icon> {{ 'addon.mod_forum.reply' | translate }}
 | 
			
		||||
                </ion-button>
 | 
			
		||||
            </ion-label>
 | 
			
		||||
@ -120,12 +122,11 @@
 | 
			
		||||
            <ion-checkbox slot="end" [(ngModel)]="replyData.isprivatereply" name="isprivatereply"></ion-checkbox>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
        <ng-container *ngIf="forum.id && forum.maxattachments > 0">
 | 
			
		||||
            <ion-item-divider class="core-expandable ion-text-wrap" (click)="toggleAdvanced()">
 | 
			
		||||
            <ion-item-divider class="core-expandable ion-text-wrap" (click)="toggleAdvanced()" [attr.aria-expanded]="advanced"
 | 
			
		||||
                [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') |translate" role="button">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start">
 | 
			
		||||
                    </ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="advanced" name="fa-caret-down" slot="start">
 | 
			
		||||
                    </ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-icon *ngIf="advanced" name="fa-caret-down" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    {{ 'addon.mod_forum.advanced' | translate }}
 | 
			
		||||
                </ion-label>
 | 
			
		||||
            </ion-item-divider>
 | 
			
		||||
 | 
			
		||||
@ -228,7 +228,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
 | 
			
		||||
            event,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        popover.present();
 | 
			
		||||
        await popover.present();
 | 
			
		||||
 | 
			
		||||
        const result = await popover.onDidDismiss<{ action?: string }>();
 | 
			
		||||
 | 
			
		||||
@ -265,7 +265,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
 | 
			
		||||
            backdropDismiss: false,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        modal.present();
 | 
			
		||||
        await modal.present();
 | 
			
		||||
 | 
			
		||||
        const result = await modal.onDidDismiss<AddonModForumReply>();
 | 
			
		||||
        const data = result.data;
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
        <ion-title>{{ 'core.sort' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
            <ion-button (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
 | 
			
		||||
                <ion-icon name="close" slot="icon-only"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
            </ion-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
    </ion-toolbar>
 | 
			
		||||
@ -11,9 +11,9 @@
 | 
			
		||||
<ion-content>
 | 
			
		||||
    <ion-list id="addon-mod-forum-sort-selector" role="menu" aria-labelledby="addon-mod-forum-sort-order-button">
 | 
			
		||||
        <ng-container *ngFor="let sortOrder of sortOrders">
 | 
			
		||||
            <ion-item class="ion-text-wrap" detail="false" role="menuitem"
 | 
			
		||||
                [class.core-selected-item]="selected == sortOrder.value" [attr.aria-label]="sortOrder.label | translate"
 | 
			
		||||
                (click)="selectSortOrder(sortOrder)">
 | 
			
		||||
            <ion-item class="ion-text-wrap" detail="false" role="combobox"
 | 
			
		||||
                [attr.aria-current]="selected == sortOrder.value ? 'page' :  'false'" [attr.aria-label]="sortOrder.label | translate"
 | 
			
		||||
                (click)="selectSortOrder(sortOrder)" button aria-haspopup="dialog">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h2>{{ sortOrder.label | translate }}</h2>
 | 
			
		||||
                </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@
 | 
			
		||||
    "errorgetforum": "Error getting forum data.",
 | 
			
		||||
    "errorgetgroups": "Error getting group settings.",
 | 
			
		||||
    "errorposttoallgroups": "Could not create new discussion in all groups.",
 | 
			
		||||
    "favourites": "Starred",
 | 
			
		||||
    "favouriteupdated": "Your star option has been updated.",
 | 
			
		||||
    "forumnodiscussionsyet": "There are no discussions yet in this forum.",
 | 
			
		||||
    "group": "Group",
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="startingPost">
 | 
			
		||||
            <core-format-text contextLevel="module" [text]="startingPost.subject" [contextInstanceId]="cmId" [courseId]="courseId">
 | 
			
		||||
@ -69,7 +69,7 @@
 | 
			
		||||
        <!-- Discussion replies found to be synchronized -->
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="postHasOffline || hasOfflineRatings">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'core.hasdatatosync' | translate:{$a: discussionStr} }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -77,14 +77,14 @@
 | 
			
		||||
        <!-- Cut-off date or due date message -->
 | 
			
		||||
        <ion-card class="core-info-card" *ngIf="availabilityMessage">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="information-circle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ availabilityMessage }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <ion-card class="core-info-card" *ngIf="discussion && discussion.locked">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fa-lock" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fa-lock" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'addon.mod_forum.discussionlocked' | translate }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>{{ 'addon.mod_forum.addanewdiscussion' | translate }}</ion-title>
 | 
			
		||||
        <ion-buttons slot="end">
 | 
			
		||||
@ -31,11 +31,10 @@
 | 
			
		||||
                    (contentChanged)="onMessageChange($event)">
 | 
			
		||||
                </core-rich-text-editor>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
            <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()">
 | 
			
		||||
                <ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start">
 | 
			
		||||
                </ion-icon>
 | 
			
		||||
                <ion-icon *ngIf="advanced" name="fa-caret-down" slot="start">
 | 
			
		||||
                </ion-icon>
 | 
			
		||||
            <ion-item-divider class="ion-text-wrap core-expandable" (click)="toggleAdvanced()" [attr.aria-expanded]="advanced"
 | 
			
		||||
                [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') |translate" role="heading button">
 | 
			
		||||
                <ion-icon *ngIf="!advanced" name="fa-caret-right" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-icon *ngIf="advanced" name="fa-caret-down" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'addon.mod_forum.advanced' | translate }}</ion-label>
 | 
			
		||||
            </ion-item-divider>
 | 
			
		||||
            <ng-container *ngIf="advanced">
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,11 @@
 | 
			
		||||
<core-navbar-buttons slot="end">
 | 
			
		||||
    <ion-button *ngIf="glossary && glossary.browsemodes && glossary.browsemodes.length > 1" (click)="openModePicker($event)"
 | 
			
		||||
        [attr.aria-label]="'addon.mod_glossary.browsemode' | translate">
 | 
			
		||||
        <ion-icon name="fas-sort"></ion-icon>
 | 
			
		||||
        <ion-icon name="fas-sort" aria-hidden="true"></ion-icon>
 | 
			
		||||
    </ion-button>
 | 
			
		||||
 | 
			
		||||
    <ion-button *ngIf="glossary" (click)="toggleSearch()" [attr.aria-label]="'addon.mod_glossary.bysearch' | translate">
 | 
			
		||||
        <ion-icon name="fas-search"></ion-icon>
 | 
			
		||||
        <ion-icon name="fas-search" aria-hidden="true"></ion-icon>
 | 
			
		||||
    </ion-button>
 | 
			
		||||
 | 
			
		||||
    <core-context-menu>
 | 
			
		||||
@ -57,7 +57,7 @@
 | 
			
		||||
        <!-- Has offline data to be synchronized -->
 | 
			
		||||
        <ion-card class="core-warning-card" *ngIf="hasOffline || hasOfflineRatings">
 | 
			
		||||
            <ion-item>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
                <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
                <ion-label>{{ 'core.hasdatatosync' | translate:{$a: moduleName} }}</ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
@ -66,8 +66,8 @@
 | 
			
		||||
            <ion-item-divider>
 | 
			
		||||
                <ion-label>{{ 'addon.mod_glossary.entriestobesynced' | translate }}</ion-label>
 | 
			
		||||
            </ion-item-divider>
 | 
			
		||||
            <ion-item *ngFor="let entry of entries.offlineEntries" (click)="entries.select(entry)" detail="false"
 | 
			
		||||
                [class.core-selected-item]="entries.isSelected(entry)">
 | 
			
		||||
            <ion-item *ngFor="let entry of entries.offlineEntries" (click)="entries.select(entry)" detail="false" button
 | 
			
		||||
                [attr.aria-current]="entries.getItemAriaCurrent(entry)">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="glossary!.coursemodule"
 | 
			
		||||
                        [courseId]="courseId">
 | 
			
		||||
@ -82,7 +82,8 @@
 | 
			
		||||
                    {{ getDivider!(entry) }}
 | 
			
		||||
                </ion-item-divider>
 | 
			
		||||
 | 
			
		||||
                <ion-item (click)="entries.select(entry)" [class.core-selected-item]="entries.isSelected(entry)" detail="false">
 | 
			
		||||
                <ion-item button (click)="entries.select(entry)" [attr.aria-current]="entries.getItemAriaCurrent(entry)"
 | 
			
		||||
                    detail="false">
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="glossary!.coursemodule"
 | 
			
		||||
                            [courseId]="courseId">
 | 
			
		||||
@ -101,7 +102,7 @@
 | 
			
		||||
 | 
			
		||||
    <ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canAdd">
 | 
			
		||||
        <ion-fab-button (click)="openNewEntry()" [attr.aria-label]="'addon.mod_glossary.addentry' | translate">
 | 
			
		||||
            <ion-icon name="fas-plus"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-plus" aria-hidden="true"></ion-icon>
 | 
			
		||||
        </ion-fab-button>
 | 
			
		||||
    </ion-fab>
 | 
			
		||||
</core-split-view>
 | 
			
		||||
 | 
			
		||||
@ -414,7 +414,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
            event,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        popover.present();
 | 
			
		||||
        await popover.present();
 | 
			
		||||
 | 
			
		||||
        const result = await popover.onDidDismiss<AddonModGlossaryFetchMode>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="glossary">
 | 
			
		||||
            <core-format-text [text]="glossary.name" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title *ngIf="entry">
 | 
			
		||||
            <core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="componentId" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@
 | 
			
		||||
    <!-- Offline data stored. -->
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="hasOffline">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
    </ion-card>
 | 
			
		||||
@ -47,7 +47,7 @@
 | 
			
		||||
    <!-- Offline disabled. -->
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="!siteCanDownload && playing">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                {{ 'core.h5p.offlinedisabled' | translate }} {{ 'addon.mod_h5pactivity.offlinedisabledwarning' | translate }}
 | 
			
		||||
            </ion-label>
 | 
			
		||||
@ -57,7 +57,7 @@
 | 
			
		||||
    <!-- Preview mode. -->
 | 
			
		||||
    <ion-card class="core-warning-card" *ngIf="accessInfo && !trackComponent">
 | 
			
		||||
        <ion-item>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
 | 
			
		||||
            <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                {{ 'addon.mod_h5pactivity.previewmode' | translate }}
 | 
			
		||||
            </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module"
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
        <ng-container *ngIf="attempt">
 | 
			
		||||
            <!-- Attempt number and user that did the attempt. -->
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngIf="user" core-user-link [userId]="user.id" [courseId]="courseId"
 | 
			
		||||
                [title]="user.fullname">
 | 
			
		||||
                [attr.aria-label]="user.fullname">
 | 
			
		||||
                <core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar>
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h2>{{ 'addon.mod_h5pactivity.attempt' | translate }} #{{attempt.attempt}}: {{user.fullname}}</h2>
 | 
			
		||||
@ -63,11 +63,11 @@
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2>{{ 'addon.mod_h5pactivity.outcome' | translate }}</h2>
 | 
			
		||||
                            <p *ngIf="attempt.success !== null && attempt.success" >
 | 
			
		||||
                                <ion-icon name="fa-check-circle"></ion-icon>
 | 
			
		||||
                                <ion-icon name="fa-check-circle" aria-hidden="true"></ion-icon>
 | 
			
		||||
                                {{ 'addon.mod_h5pactivity.attempt_success_pass' | translate }}
 | 
			
		||||
                            </p>
 | 
			
		||||
                            <p *ngIf="attempt.success !== null && !attempt.success" >
 | 
			
		||||
                                <ion-icon name="far-circle"></ion-icon>
 | 
			
		||||
                                <ion-icon name="far-circle" aria-hidden="true"></ion-icon>
 | 
			
		||||
                                {{ 'addon.mod_h5pactivity.attempt_success_fail' | translate }}
 | 
			
		||||
                            </p>
 | 
			
		||||
                            <p *ngIf="attempt.success === null" >
 | 
			
		||||
@ -152,7 +152,7 @@
 | 
			
		||||
 | 
			
		||||
                    <!-- Result doesn't support tracking. -->
 | 
			
		||||
                    <ion-item class="ion-text-wrap core-warning-item" *ngIf="!result.track" lines="none">
 | 
			
		||||
                        <ion-icon slot="start" name="fas-exclamation-triangle" color="warning"></ion-icon>
 | 
			
		||||
                        <ion-icon slot="start" name="fas-exclamation-triangle" color="warning" aria-hidden="true"></ion-icon>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            {{ 'addon.mod_h5pactivity.no_compatible_track' | translate:{$a: result.interactiontype} }}
 | 
			
		||||
                        </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<ion-header>
 | 
			
		||||
    <ion-toolbar>
 | 
			
		||||
        <ion-buttons slot="start">
 | 
			
		||||
            <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module"
 | 
			
		||||
@ -17,7 +17,7 @@
 | 
			
		||||
    <core-loading [hideUntil]="loaded">
 | 
			
		||||
        <!-- User viewed. -->
 | 
			
		||||
        <ion-item class="ion-text-wrap" *ngIf="user && !isCurrentUser" core-user-link [userId]="user.id" [courseId]="courseId"
 | 
			
		||||
            [title]="user.fullname">
 | 
			
		||||
            [attr.aria-label]="user.fullname">
 | 
			
		||||
            <core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
                <h2>{{ user.fullname }}</h2>
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user