commit
						bcbecc48f2
					
				| @ -3,8 +3,10 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="badge">{{ badge.name }}</h1> |             <h1 *ngIf="badge">{{ badge.name }}</h1> | ||||||
|             <h1 *ngIf="!badge">{{ 'addon.badges.badges' | translate }}</h1> |             <h1 *ngIf="!badge">{{ 'addon.badges.badges' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -157,7 +159,9 @@ | |||||||
|             <!-- Endorsement --> |             <!-- Endorsement --> | ||||||
|             <ion-item-group *ngIf="badge.endorsement"> |             <ion-item-group *ngIf="badge.endorsement"> | ||||||
|                 <ion-item-divider> |                 <ion-item-divider> | ||||||
|                     <ion-label><h2>{{ 'addon.badges.bendorsement' | translate}}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.badges.bendorsement' | translate}}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="badge.endorsement.issuername"> |                 <ion-item class="ion-text-wrap" *ngIf="badge.endorsement.issuername"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
| @ -169,8 +173,7 @@ | |||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'addon.badges.issueremail' | translate}}</h2> |                         <h2>{{ 'addon.badges.issueremail' | translate}}</h2> | ||||||
|                         <p> |                         <p> | ||||||
|                             <a href="mailto:{{badge.endorsement.issueremail}}" core-link auto-login="no" |                             <a href="mailto:{{badge.endorsement.issueremail}}" core-link auto-login="no" [showBrowserWarning]="false"> | ||||||
|                                 [showBrowserWarning]="false"> |  | ||||||
|                                 {{ badge.endorsement.issueremail }} |                                 {{ badge.endorsement.issueremail }} | ||||||
|                             </a> |                             </a> | ||||||
|                         </p> |                         </p> | ||||||
| @ -205,27 +208,39 @@ | |||||||
|             <!-- Related badges --> |             <!-- Related badges --> | ||||||
|             <ion-item-group *ngIf="badge.relatedbadges"> |             <ion-item-group *ngIf="badge.relatedbadges"> | ||||||
|                 <ion-item-divider> |                 <ion-item-divider> | ||||||
|                     <ion-label><h2>{{ 'addon.badges.relatedbages' | translate}}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.badges.relatedbages' | translate}}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let relatedBadge of badge.relatedbadges"> |                 <ion-item class="ion-text-wrap" *ngFor="let relatedBadge of badge.relatedbadges"> | ||||||
|                     <ion-label><h2>{{ relatedBadge.name }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ relatedBadge.name }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="badge.relatedbadges.length == 0"> |                 <ion-item class="ion-text-wrap" *ngIf="badge.relatedbadges.length == 0"> | ||||||
|                     <ion-label><h2>{{ 'addon.badges.norelated' | translate}}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.badges.norelated' | translate}}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|             </ion-item-group> |             </ion-item-group> | ||||||
| 
 | 
 | ||||||
|             <!-- Competencies alignment --> |             <!-- Competencies alignment --> | ||||||
|             <ion-item-group *ngIf="badge.alignment"> |             <ion-item-group *ngIf="badge.alignment"> | ||||||
|                 <ion-item-divider> |                 <ion-item-divider> | ||||||
|                     <ion-label><h2>{{ 'addon.badges.alignment' | translate}}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.badges.alignment' | translate}}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let alignment of badge.alignment" [href]="alignment.targeturl" core-link |                 <ion-item class="ion-text-wrap" *ngFor="let alignment of badge.alignment" [href]="alignment.targeturl" core-link | ||||||
|                     auto-login="no"> |                     auto-login="no"> | ||||||
|                     <ion-label><h2>{{ alignment.targetname }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ alignment.targetname }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="badge.alignment.length == 0"> |                 <ion-item class="ion-text-wrap" *ngIf="badge.alignment.length == 0"> | ||||||
|                     <ion-label><h2>{{ 'addon.badges.noalignment' | translate}}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.badges.noalignment' | translate}}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|             </ion-item-group> |             </ion-item-group> | ||||||
|         </ng-container> |         </ng-container> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.badges.badges' | translate }}</h1> |             <h1>{{ 'addon.badges.badges' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -12,8 +14,7 @@ | |||||||
|             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|         </ion-refresher> |         </ion-refresher> | ||||||
|         <core-loading [hideUntil]="badges.loaded"> |         <core-loading [hideUntil]="badges.loaded"> | ||||||
|             <core-empty-box *ngIf="badges.empty" icon="fas-trophy" |             <core-empty-box *ngIf="badges.empty" icon="fas-trophy" [message]="'addon.badges.nobadges' | translate"> | ||||||
|                 [message]="'addon.badges.nobadges' | translate"> |  | ||||||
|             </core-empty-box> |             </core-empty-box> | ||||||
| 
 | 
 | ||||||
|             <ion-list *ngIf="!badges.empty" class="ion-no-margin"> |             <ion-list *ngIf="!badges.empty" class="ion-no-margin"> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ title | translate }}</h1> |             <h1>{{ title | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <core-user-menu-button></core-user-menu-button> |             <core-user-menu-button></core-user-menu-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
| @ -18,8 +20,7 @@ | |||||||
|             <ion-label>{{ 'addon.blog.showonlyyourentries' | translate }}</ion-label> |             <ion-label>{{ 'addon.blog.showonlyyourentries' | translate }}</ion-label> | ||||||
|             <ion-toggle [(ngModel)]="onlyMyEntries" (ionChange)="onlyMyEntriesToggleChanged(onlyMyEntries)"></ion-toggle> |             <ion-toggle [(ngModel)]="onlyMyEntries" (ionChange)="onlyMyEntriesToggleChanged(onlyMyEntries)"></ion-toggle> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|         <core-empty-box *ngIf="entries && entries.length == 0" icon="far-newspaper" |         <core-empty-box *ngIf="entries && entries.length == 0" icon="far-newspaper" [message]="'addon.blog.noentriesyet' | translate"> | ||||||
|             [message]="'addon.blog.noentriesyet' | translate"> |  | ||||||
|         </core-empty-box> |         </core-empty-box> | ||||||
|         <ng-container *ngFor="let entry of entries"> |         <ng-container *ngFor="let entry of entries"> | ||||||
|             <ion-card *ngIf="!onlyMyEntries || entry.userid == currentUserId"> |             <ion-card *ngIf="!onlyMyEntries || entry.userid == currentUserId"> | ||||||
| @ -27,8 +28,7 @@ | |||||||
|                     <core-user-avatar [user]="entry.user" slot="start" [courseId]="entry.courseid"></core-user-avatar> |                     <core-user-avatar [user]="entry.user" slot="start" [courseId]="entry.courseid"></core-user-avatar> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading"> |                         <p class="item-heading"> | ||||||
|                             <core-format-text [text]="entry.subject" [contextLevel]="contextLevel" |                             <core-format-text [text]="entry.subject" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"> | ||||||
|                                 [contextInstanceId]="contextInstanceId"> |  | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                             <ion-note class="ion-float-end ion-padding-start ion-text-end"> |                             <ion-note class="ion-float-end ion-padding-start ion-text-end"> | ||||||
|                                 {{ 'addon.blog.' + entry.publishTranslated! | translate}} |                                 {{ 'addon.blog.' + entry.publishTranslated! | translate}} | ||||||
| @ -68,8 +68,8 @@ | |||||||
|                 </ion-card-content> |                 </ion-card-content> | ||||||
|                 <div class="ion-text-center ion-margin-bottom" *ngIf="entry.lastmodified > entry.created"> |                 <div class="ion-text-center ion-margin-bottom" *ngIf="entry.lastmodified > entry.created"> | ||||||
|                     <ion-note> |                     <ion-note> | ||||||
|                         <ion-icon name="fas-clock" |                         <ion-icon name="fas-clock" [attr.aria-label]="'core.lastmodified' | translate"></ion-icon> {{entry.lastmodified | | ||||||
|                             [attr.aria-label]="'core.lastmodified' | translate"></ion-icon> {{entry.lastmodified | coreTimeAgo}} |                         coreTimeAgo}} | ||||||
|                     </ion-note> |                     </ion-note> | ||||||
|                 </div> |                 </div> | ||||||
|             </ion-card> |             </ion-card> | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2>{{ 'addon.calendar.reminders' | translate }}</h2> |             <h2>{{ 'addon.calendar.reminders' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
| @ -36,15 +38,13 @@ | |||||||
| 
 | 
 | ||||||
|             <div class="flex-row"> |             <div class="flex-row"> | ||||||
|                 <!-- Input to enter the value. --> |                 <!-- Input to enter the value. --> | ||||||
|                 <ion-input type="number" name="customvalue" [(ngModel)]="customValue" [disabled]="radioValue != 'custom'" |                 <ion-input type="number" name="customvalue" [(ngModel)]="customValue" [disabled]="radioValue != 'custom'" placeholder="10"> | ||||||
|                     placeholder="10"> |  | ||||||
|                 </ion-input> |                 </ion-input> | ||||||
| 
 | 
 | ||||||
|                 <!-- Units. --> |                 <!-- Units. --> | ||||||
|                 <label class="accesshide" for="reminderUnits">{{ 'addon.calendar.units' | translate }}</label> |                 <label class="accesshide" for="reminderUnits">{{ 'addon.calendar.units' | translate }}</label> | ||||||
|                 <ion-select id="reminderUnits" name="customunits" [(ngModel)]="customUnits" interface="action-sheet" |                 <ion-select id="reminderUnits" name="customunits" [(ngModel)]="customUnits" interface="action-sheet" | ||||||
|                     [disabled]="radioValue != 'custom'" slot="end" |                     [disabled]="radioValue != 'custom'" slot="end" [interfaceOptions]="{header: 'addon.calendar.units' | translate}"> | ||||||
|                     [interfaceOptions]="{header: 'addon.calendar.units' | translate}"> |  | ||||||
|                     <ion-select-option *ngFor="let option of customUnitsOptions" [value]="option.value"> |                     <ion-select-option *ngFor="let option of customUnitsOptions" [value]="option.value"> | ||||||
|                         {{ option.label | translate }} |                         {{ option.label | translate }} | ||||||
|                     </ion-select-option> |                     </ion-select-option> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.calendar.calendarevents' | translate }}</h1> |             <h1>{{ 'addon.calendar.calendarevents' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="openFilter($event)" [attr.aria-label]="'core.filter' | translate"> |             <ion-button fill="clear" (click)="openFilter($event)" [attr.aria-label]="'core.filter' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-filter" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-filter" aria-hidden="true"></ion-icon> | ||||||
| @ -13,8 +15,8 @@ | |||||||
|                     iconAction="fas-calendar-day" (action)="goToCurrentDay()"> |                     iconAction="fas-calendar-day" (action)="goToCurrentDay()"> | ||||||
|                 </core-context-menu-item> |                 </core-context-menu-item> | ||||||
|                 <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400" |                 <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400" | ||||||
|                     [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event)" |                     [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event)" [iconAction]="syncIcon" | ||||||
|                     [iconAction]="syncIcon" [closeOnClick]="false"> |                     [closeOnClick]="false"> | ||||||
|                 </core-context-menu-item> |                 </core-context-menu-item> | ||||||
|             </core-context-menu> |             </core-context-menu> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ title | translate }}</h1> |             <h1>{{ title | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -40,12 +42,8 @@ | |||||||
|                     <p class="item-heading" [core-mark-required]="true">{{ 'addon.calendar.eventkind' | translate }}</p> |                     <p class="item-heading" [core-mark-required]="true">{{ 'addon.calendar.eventkind' | translate }}</p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|                 <p *ngIf="eventTypes.length == 1" slot="end">{{eventTypes[0].name | translate }}</p> |                 <p *ngIf="eventTypes.length == 1" slot="end">{{eventTypes[0].name | translate }}</p> | ||||||
|                 <ion-select |                 <ion-select *ngIf="eventTypes.length > 1" formControlName="eventtype" interface="action-sheet" | ||||||
|                     *ngIf="eventTypes.length > 1" |                     [interfaceOptions]="{header: 'addon.calendar.eventkind' | translate}"> | ||||||
|                     formControlName="eventtype" |  | ||||||
|                     interface="action-sheet" |  | ||||||
|                     [interfaceOptions]="{header: 'addon.calendar.eventkind' | translate}" |  | ||||||
|                 > |  | ||||||
|                     <ion-select-option *ngFor="let type of eventTypes" [value]="type.value"> |                     <ion-select-option *ngFor="let type of eventTypes" [value]="type.value"> | ||||||
|                         {{ type.name | translate }} |                         {{ type.name | translate }} | ||||||
|                     </ion-select-option> |                     </ion-select-option> | ||||||
| @ -83,8 +81,7 @@ | |||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading" [core-mark-required]="true">{{ 'core.course' | translate }}</p> |                         <p class="item-heading" [core-mark-required]="true">{{ 'core.course' | translate }}</p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                     <ion-select formControlName="groupcourseid" |                     <ion-select formControlName="groupcourseid" interface="action-sheet" [placeholder]="'core.noselection' | translate" | ||||||
|                         interface="action-sheet" [placeholder]="'core.noselection' | translate" |  | ||||||
|                         (ionChange)="groupCourseSelected()" [interfaceOptions]="{header: 'core.course' | translate}"> |                         (ionChange)="groupCourseSelected()" [interfaceOptions]="{header: 'core.course' | translate}"> | ||||||
|                         <ion-select-option *ngFor="let course of courses" [value]="course.id"> |                         <ion-select-option *ngFor="let course of courses" [value]="course.id"> | ||||||
|                             {{ course.fullname }} |                             {{ course.fullname }} | ||||||
| @ -93,7 +90,9 @@ | |||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <!-- The course has no groups. --> |                 <!-- The course has no groups. --> | ||||||
|                 <ion-item class="ion-text-wrap core-danger-item" *ngIf="!loadingGroups && courseGroupSet && !groups.length"> |                 <ion-item class="ion-text-wrap core-danger-item" *ngIf="!loadingGroups && courseGroupSet && !groups.length"> | ||||||
|                     <ion-label><p>{{ 'core.coursenogroups' | translate }}</p></ion-label> |                     <ion-label> | ||||||
|  |                         <p>{{ 'core.coursenogroups' | translate }}</p> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <!-- Select the group. --> |                 <!-- Select the group. --> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="!loadingGroups && groups.length > 0"> |                 <ion-item class="ion-text-wrap" *ngIf="!loadingGroups && groups.length > 0"> | ||||||
| @ -128,8 +127,7 @@ | |||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p>{{ reminder.label }}</p> |                         <p>{{ reminder.label }}</p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                     <ion-button fill="clear" (click)="removeReminder(reminder)" [attr.aria-label]="'core.delete' | translate" |                     <ion-button fill="clear" (click)="removeReminder(reminder)" [attr.aria-label]="'core.delete' | translate" slot="end"> | ||||||
|                         slot="end"> |  | ||||||
|                         <ion-icon name="fas-trash" color="danger" slot="icon-only" aria-hidden="true"></ion-icon> |                         <ion-icon name="fas-trash" color="danger" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|                     </ion-button> |                     </ion-button> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| @ -158,8 +156,7 @@ | |||||||
|                     <ion-item *ngIf="form.controls.duration.value === 1"> |                     <ion-item *ngIf="form.controls.duration.value === 1"> | ||||||
|                         <ion-label position="stacked"></ion-label> |                         <ion-label position="stacked"></ion-label> | ||||||
|                         <ion-datetime formControlName="timedurationuntil" [max]="maxDate" [min]="minDate" |                         <ion-datetime formControlName="timedurationuntil" [max]="maxDate" [min]="minDate" | ||||||
|                             [placeholder]="'addon.calendar.durationuntil' | translate" |                             [placeholder]="'addon.calendar.durationuntil' | translate" [displayFormat]="dateFormat" display-timezone="utc"> | ||||||
|                             [displayFormat]="dateFormat" display-timezone="utc"> |  | ||||||
|                         </ion-datetime> |                         </ion-datetime> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                     <ion-item lines="none"> |                     <ion-item lines="none"> | ||||||
| @ -171,8 +168,7 @@ | |||||||
|                     <ion-item *ngIf="form.controls.duration.value === 2"> |                     <ion-item *ngIf="form.controls.duration.value === 2"> | ||||||
|                         <ion-label class="sr-only">{{ 'addon.calendar.durationminutes' | translate }}</ion-label> |                         <ion-label class="sr-only">{{ 'addon.calendar.durationminutes' | translate }}</ion-label> | ||||||
|                         <ion-input type="number" name="timedurationminutes" slot="end" |                         <ion-input type="number" name="timedurationminutes" slot="end" | ||||||
|                             [placeholder]="'addon.calendar.durationminutes' | translate" |                             [placeholder]="'addon.calendar.durationminutes' | translate" formControlName="timedurationminutes"></ion-input> | ||||||
|                             formControlName="timedurationminutes"></ion-input> |  | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ion-radio-group> |                 </ion-radio-group> | ||||||
|             </div> |             </div> | ||||||
| @ -223,8 +219,8 @@ | |||||||
|                     <p class="item-heading">{{ 'core.description' | translate }}</p> |                     <p class="item-heading">{{ 'core.description' | translate }}</p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|                 <core-rich-text-editor [control]="descriptionControl" [attr.aria-label]="'core.description' | translate" |                 <core-rich-text-editor [control]="descriptionControl" [attr.aria-label]="'core.description' | translate" | ||||||
|                     [placeholder]="'core.description' | translate" name="description" [component]="component" |                     [placeholder]="'core.description' | translate" name="description" [component]="component" [componentId]="eventId" | ||||||
|                     [componentId]="eventId" [autoSave]="false"></core-rich-text-editor> |                     [autoSave]="false"></core-rich-text-editor> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <!-- Location. --> |             <!-- Location. --> | ||||||
|  | |||||||
| @ -3,30 +3,31 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="event"> |             <h1 *ngIf="event"> | ||||||
|             <core-mod-icon *ngIf="event.moduleIcon" [modicon]="event.moduleIcon" [showAlt]="false" |                 <core-mod-icon *ngIf="event.moduleIcon" [modicon]="event.moduleIcon" [showAlt]="false" [modname]="event.modulename" | ||||||
|                 [modname]="event.modulename" [componentId]="event.instance"></core-mod-icon> |                     [componentId]="event.instance"></core-mod-icon> | ||||||
|                 <ion-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" aria-hidden="true"></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. --> |                 <!-- Add the icon title so accessibility tools read it. --> | ||||||
|                 <span class="sr-only"> |                 <span class="sr-only"> | ||||||
|                     {{ 'addon.calendar.type' + event.formattedType | translate }} |                     {{ 'addon.calendar.type' + event.formattedType | translate }} | ||||||
|                     <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span> |                     <span class="sr-only" *ngIf="event.moduleIcon && event.iconTitle">{{ event.iconTitle }}</span> | ||||||
|                 </span> |                 </span> | ||||||
|             <core-format-text [text]="event.name" [contextLevel]="event.contextLevel" |                 <core-format-text [text]="event.name" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"> | ||||||
|                 [contextInstanceId]="event.contextInstanceId"></core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <core-context-menu> |             <core-context-menu> | ||||||
|                 <core-context-menu-item [hidden]="!eventLoaded || (!hasOffline && event && !event.deleted) || !isOnline" |                 <core-context-menu-item [hidden]="!eventLoaded || (!hasOffline && event && !event.deleted) || !isOnline" [priority]="400" | ||||||
|                     [priority]="400" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)" |                     [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)" | ||||||
|                     [iconAction]="syncIcon" [closeOnClick]="false"> |                     [iconAction]="syncIcon" [closeOnClick]="false"> | ||||||
|                 </core-context-menu-item> |                 </core-context-menu-item> | ||||||
|                 <core-context-menu-item [hidden]="!event || !event.canedit || event.deleted || (!canEdit && event.id > 0)" |                 <core-context-menu-item [hidden]="!event || !event.canedit || event.deleted || (!canEdit && event.id > 0)" [priority]="300" | ||||||
|                     [priority]="300" [content]="'core.edit' | translate" (action)="openEdit()" iconAction="fas-edit"> |                     [content]="'core.edit' | translate" (action)="openEdit()" iconAction="fas-edit"> | ||||||
|                 </core-context-menu-item> |                 </core-context-menu-item> | ||||||
|                 <core-context-menu-item [hidden]="!event || !event.candelete || event.deleted" [priority]="200" |                 <core-context-menu-item [hidden]="!event || !event.candelete || event.deleted" [priority]="200" | ||||||
|                     [content]="'core.delete' | translate" (action)="deleteEvent()" |                     [content]="'core.delete' | translate" (action)="deleteEvent()" iconAction="fas-trash"></core-context-menu-item> | ||||||
|                     iconAction="fas-trash"></core-context-menu-item> |  | ||||||
|                 <core-context-menu-item [hidden]="!event || !event.deleted" [priority]="200" [content]="'core.restore' | translate" |                 <core-context-menu-item [hidden]="!event || !event.deleted" [priority]="200" [content]="'core.restore' | translate" | ||||||
|                     (action)="undoDelete()" iconAction="fas-undo-alt"></core-context-menu-item> |                     (action)="undoDelete()" iconAction="fas-undo-alt"></core-context-menu-item> | ||||||
|             </core-context-menu> |             </core-context-menu> | ||||||
| @ -82,8 +83,10 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="categoryPath"> |                 <ion-item class="ion-text-wrap" *ngIf="categoryPath"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'core.category' | translate}}</h2> |                         <h2>{{ 'core.category' | translate}}</h2> | ||||||
|                         <p><core-format-text [text]="categoryPath" contextLevel="coursecat" |                         <p> | ||||||
|                             [contextInstanceId]="event.categoryid"></core-format-text></p> |                             <core-format-text [text]="categoryPath" contextLevel="coursecat" [contextInstanceId]="event.categoryid"> | ||||||
|  |                             </core-format-text> | ||||||
|  |                         </p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="event.description"> |                 <ion-item class="ion-text-wrap" *ngIf="event.description"> | ||||||
| @ -123,13 +126,12 @@ | |||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ng-container *ngFor="let reminder of reminders"> |             <ng-container *ngFor="let reminder of reminders"> | ||||||
|                 <ion-item *ngIf="reminder.timestamp > 0" class="ion-text-wrap" |                 <ion-item *ngIf="reminder.timestamp > 0" class="ion-text-wrap" [class.item-dimmed]="reminder.timestamp <= currentTime"> | ||||||
|                     [class.item-dimmed]="reminder.timestamp <= currentTime"> |  | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p>{{ reminder.label }}</p> |                         <p>{{ reminder.label }}</p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                     <ion-button fill="clear" (click)="cancelNotification(reminder.id, $event)" |                     <ion-button fill="clear" (click)="cancelNotification(reminder.id, $event)" [attr.aria-label]="'core.delete' | translate" | ||||||
|                         [attr.aria-label]="'core.delete' | translate" slot="end" *ngIf="reminder.timestamp > currentTime"> |                         slot="end" *ngIf="reminder.timestamp > currentTime"> | ||||||
|                         <ion-icon name="fas-trash" color="danger" slot="icon-only" aria-hidden="true"></ion-icon> |                         <ion-icon name="fas-trash" color="danger" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|                     </ion-button> |                     </ion-button> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|  | |||||||
| @ -3,20 +3,20 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ (showCalendar ? 'addon.calendar.calendarevents' : 'addon.calendar.upcomingevents') | translate }}</h1> |             <h1>{{ (showCalendar ? 'addon.calendar.calendarevents' : 'addon.calendar.upcomingevents') | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="openFilter($event)" [attr.aria-label]="'core.filter' | translate"> |             <ion-button fill="clear" (click)="openFilter($event)" [attr.aria-label]="'core.filter' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-filter" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-filter" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
|             <core-context-menu> |             <core-context-menu> | ||||||
|                 <core-context-menu-item *ngIf="showCalendar" [priority]="800" |                 <core-context-menu-item *ngIf="showCalendar" [priority]="800" [content]="'addon.calendar.upcomingevents' | translate" | ||||||
|                 [content]="'addon.calendar.upcomingevents' | translate" iconAction="fas-th-list" |                     iconAction="fas-th-list" (action)="toggleDisplay()"></core-context-menu-item> | ||||||
|                 (action)="toggleDisplay()"></core-context-menu-item> |                 <core-context-menu-item *ngIf="!showCalendar" [priority]="800" [content]="'addon.calendar.monthlyview' | translate" | ||||||
|                 <core-context-menu-item *ngIf="!showCalendar" [priority]="800" |                     iconAction="fas-calendar-alt" (action)="toggleDisplay()"></core-context-menu-item> | ||||||
|                 [content]="'addon.calendar.monthlyview' | translate" iconAction="fas-calendar-alt" |                 <core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600" [content]="'core.settings.settings' | translate" | ||||||
|                 (action)="toggleDisplay()"></core-context-menu-item> |                     (action)="openSettings()" iconAction="fas-cogs"> | ||||||
|                 <core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600" |  | ||||||
|                 [content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs"> |  | ||||||
|                 </core-context-menu-item> |                 </core-context-menu-item> | ||||||
|                 <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400" |                 <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400" | ||||||
|                     [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)" |                     [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)" | ||||||
| @ -43,8 +43,7 @@ | |||||||
|         [displayNavButtons]="showCalendar" (onEventClicked)="gotoEvent($event)" (onDayClicked)="gotoDay($event)"> |         [displayNavButtons]="showCalendar" (onEventClicked)="gotoEvent($event)" (onDayClicked)="gotoDay($event)"> | ||||||
|     </addon-calendar-calendar> |     </addon-calendar-calendar> | ||||||
| 
 | 
 | ||||||
|     <addon-calendar-upcoming-events *ngIf="loadUpcoming" [hidden]="showCalendar" [filter]="filter" |     <addon-calendar-upcoming-events *ngIf="loadUpcoming" [hidden]="showCalendar" [filter]="filter" (onEventClicked)="gotoEvent($event)"> | ||||||
|         (onEventClicked)="gotoEvent($event)"> |  | ||||||
|     </addon-calendar-upcoming-events> |     </addon-calendar-upcoming-events> | ||||||
| 
 | 
 | ||||||
|     <!-- Create a calendar event. --> |     <!-- Create a calendar event. --> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'core.settings.settings' | translate }}</h1> |             <h1>{{ 'core.settings.settings' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ title }}</h1> |             <h1>{{ title }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  | |||||||
| @ -3,9 +3,11 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="competency"> |             <h1 *ngIf="competency"> | ||||||
|                 {{ competency.competency.competency.shortname }} <small>{{ competency.competency.competency.idnumber }}</small> |                 {{ competency.competency.competency.shortname }} <small>{{ competency.competency.competency.idnumber }}</small> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -16,7 +18,9 @@ | |||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap"> | ||||||
|                 <core-user-avatar [user]="user" slot="start"></core-user-avatar> |                 <core-user-avatar [user]="user" slot="start"></core-user-avatar> | ||||||
|                 <ion-label><h2>{{ user.fullname }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ user.fullname }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
| 
 | 
 | ||||||
| @ -32,11 +36,9 @@ | |||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <p class="item-heading">{{ 'addon.competency.path' | translate }}</p> |                     <p class="item-heading">{{ 'addon.competency.path' | translate }}</p> | ||||||
|                     <p> |                     <p> | ||||||
|                         <a *ngIf="competency.competency.comppath.showlinks" |                         <a *ngIf="competency.competency.comppath.showlinks" [href]="competency.competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + | ||||||
|                             [href]="competency.competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + |  | ||||||
|                             competency.competency.comppath.framework.id + '&pagecontextid=' + |                             competency.competency.comppath.framework.id + '&pagecontextid=' + | ||||||
|                             competency.competency.comppath.pagecontextid" |                             competency.competency.comppath.pagecontextid" core-link> | ||||||
|                             core-link> |  | ||||||
|                             {{ competency.competency.comppath.framework.name }} |                             {{ competency.competency.comppath.framework.name }} | ||||||
|                         </a> |                         </a> | ||||||
|                         <ng-container *ngIf="!competency.competency.comppath.showlinks"> |                         <ng-container *ngIf="!competency.competency.comppath.showlinks"> | ||||||
| @ -129,7 +131,9 @@ | |||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap"> |                 <ion-item class="ion-text-wrap"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p><ion-badge color="dark">{{ evidence.gradename }}</ion-badge></p> |                         <p> | ||||||
|  |                             <ion-badge color="dark">{{ evidence.gradename }}</ion-badge> | ||||||
|  |                         </p> | ||||||
|                         <p class="ion-margin-top" *ngIf="evidence.description">{{ evidence.description }}</p> |                         <p class="ion-margin-top" *ngIf="evidence.description">{{ evidence.description }}</p> | ||||||
|                         <blockquote *ngIf="evidence.note">{{ evidence.note }}</blockquote> |                         <blockquote *ngIf="evidence.note">{{ evidence.note }}</blockquote> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|  | |||||||
| @ -3,9 +3,11 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="competency"> |             <h1 *ngIf="competency"> | ||||||
|                 {{ competency.competency.shortname }} <small>{{ competency.competency.idnumber }}</small> |                 {{ competency.competency.shortname }} <small>{{ competency.competency.idnumber }}</small> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.competency.coursecompetencies' | translate }}</h1> |             <h1>{{ 'addon.competency.coursecompetencies' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -50,11 +52,13 @@ | |||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap"> | ||||||
|                 <core-user-avatar [user]="user" slot="start"></core-user-avatar> |                 <core-user-avatar [user]="user" slot="start"></core-user-avatar> | ||||||
|                <ion-label><h2>{{ user.fullname }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ user.fullname }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
|         <core-empty-box *ngIf="competencies && competencies.statistics.competencycount == 0" |         <core-empty-box *ngIf="competencies && competencies.statistics.competencycount == 0" icon="fas-award" | ||||||
|             icon="fas-award" message="{{ 'addon.competency.nocompetenciesincourse' | translate }}"> |             message="{{ 'addon.competency.nocompetenciesincourse' | translate }}"> | ||||||
|         </core-empty-box> |         </core-empty-box> | ||||||
| 
 | 
 | ||||||
|         <div *ngIf="competencies"> |         <div *ngIf="competencies"> | ||||||
| @ -81,10 +85,9 @@ | |||||||
|                         <div> |                         <div> | ||||||
|                             <p class="item-heading">{{ 'addon.competency.path' | translate }}</p> |                             <p class="item-heading">{{ 'addon.competency.path' | translate }}</p> | ||||||
|                             <p> |                             <p> | ||||||
|                                 <a *ngIf="competency.comppath.showlinks" |                                 <a *ngIf="competency.comppath.showlinks" [href]="competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + | ||||||
|                                     [href]="competency.comppath.pluginbaseurl + '/competencies.php?competencyframeworkid=' + |                                     competency.comppath.framework.id + '&pagecontextid=' + competency.comppath.pagecontextid" core-link | ||||||
|                                     competency.comppath.framework.id + '&pagecontextid=' + competency.comppath.pagecontextid" |                                     [title]="competency.comppath.framework.name"> | ||||||
|                                     core-link [title]="competency.comppath.framework.name"> |  | ||||||
|                                     {{ competency.comppath.framework.name }} |                                     {{ competency.comppath.framework.name }} | ||||||
|                                 </a> |                                 </a> | ||||||
|                                 <ng-container *ngIf="!competency.comppath.showlinks"> |                                 <ng-container *ngIf="!competency.comppath.showlinks"> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="plan">{{plan.plan.name}}</h1> |             <h1 *ngIf="plan">{{plan.plan.name}}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -24,8 +26,7 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.description" lines="none"> |                 <ion-item class="ion-text-wrap" *ngIf="plan.plan.description" lines="none"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p> |                         <p> | ||||||
|                             <core-format-text [text]="plan.plan.description" contextLevel="user" |                             <core-format-text [text]="plan.plan.description" contextLevel="user" [contextInstanceId]="plan.plan.userid"> | ||||||
|                                 [contextInstanceId]="plan.plan.userid"> |  | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </p> |                         </p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
| @ -74,8 +75,8 @@ | |||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let competency of plan.competencies" |                 <ion-item class="ion-text-wrap" *ngFor="let competency of plan.competencies" | ||||||
|                     (click)="openCompetency(competency.competency.id)" |                     (click)="openCompetency(competency.competency.id)" [attr.aria-label]="competency.competency.shortname" detail="true" | ||||||
|                     [attr.aria-label]="competency.competency.shortname" detail="true" button> |                     button> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading">{{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em></p> |                         <p class="item-heading">{{competency.competency.shortname}} <em>{{competency.competency.idnumber}}</em></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.competency.userplans' | translate }}</h1> |             <h1>{{ 'addon.competency.userplans' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -16,8 +18,8 @@ | |||||||
| 
 | 
 | ||||||
|             </core-empty-box> |             </core-empty-box> | ||||||
|             <ion-list *ngIf="!plans.empty" class="ion-no-margin"> |             <ion-list *ngIf="!plans.empty" class="ion-no-margin"> | ||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [attr.aria-label]="plan.name" |                 <ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [attr.aria-label]="plan.name" (click)="plans.select(plan)" | ||||||
|                     (click)="plans.select(plan)" [attr.aria-current]="plans.getItemAriaCurrent(plan)" button detail="true"> |                     [attr.aria-current]="plans.getItemAriaCurrent(plan)" button detail="true"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading">{{ plan.name }}</p> |                         <p class="item-heading">{{ plan.name }}</p> | ||||||
|                         <p *ngIf="plan.duedate > 0"> |                         <p *ngIf="plan.duedate > 0"> | ||||||
| @ -30,4 +32,4 @@ | |||||||
|             </ion-list> |             </ion-list> | ||||||
|         </core-loading> |         </core-loading> | ||||||
|     </core-split-view> |     </core-split-view> | ||||||
|     </ion-content> | </ion-content> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.coursecompletion.coursecompletion' | translate }}</h1> |             <h1>{{ 'addon.coursecompletion.coursecompletion' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -28,14 +30,18 @@ | |||||||
|         </ion-card> |         </ion-card> | ||||||
|         <ion-card *ngIf="completion && tracked"> |         <ion-card *ngIf="completion && tracked"> | ||||||
|             <ion-item-divider> |             <ion-item-divider> | ||||||
|                 <ion-label><h2>{{ 'addon.coursecompletion.requiredcriteria' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.coursecompletion.requiredcriteria' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ion-item class="ion-hide-md-up ion-text-wrap" *ngFor="let criteria of completion.completions"> |             <ion-item class="ion-hide-md-up ion-text-wrap" *ngFor="let criteria of completion.completions"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <p class="item-heading"> |                     <p class="item-heading"> | ||||||
|                         <core-format-text clean="true" [text]="criteria.details.criteria" [filter]="false"></core-format-text> |                         <core-format-text clean="true" [text]="criteria.details.criteria" [filter]="false"></core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
|                     <p><core-format-text clean="true" [text]="criteria.details.requirement" [filter]="false"></core-format-text></p> |                     <p> | ||||||
|  |                         <core-format-text clean="true" [text]="criteria.details.requirement" [filter]="false"></core-format-text> | ||||||
|  |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|                 <strong slot="end">{{ criteria.status }}</strong> |                 <strong slot="end">{{ criteria.status }}</strong> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| @ -73,7 +79,9 @@ | |||||||
|         </ion-card> |         </ion-card> | ||||||
|         <ion-card *ngIf="showSelfComplete && tracked"> |         <ion-card *ngIf="showSelfComplete && tracked"> | ||||||
|             <ion-item-divider> |             <ion-item-divider> | ||||||
|                 <ion-label><h2>{{ 'addon.coursecompletion.manualselfcompletion' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.coursecompletion.manualselfcompletion' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.messageoutput_airnotifier.processorsettingsdesc' | translate }}</h1> |             <h1>{{ 'addon.messageoutput_airnotifier.processorsettingsdesc' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -21,10 +23,7 @@ | |||||||
|                     <p>{{ device.platform }} {{ device.version }}</p> |                     <p>{{ device.platform }} {{ device.version }}</p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|                 <core-button-with-spinner [loading]="device.updating" slot="end"> |                 <core-button-with-spinner [loading]="device.updating" slot="end"> | ||||||
|                     <ion-toggle |                     <ion-toggle [(ngModel)]="device.enable" (ngModelChange)="enableDevice(device, device.enable)"> | ||||||
|                         [(ngModel)]="device.enable" |  | ||||||
|                         (ngModelChange)="enableDevice(device, device.enable)" |  | ||||||
|                     > |  | ||||||
|                     </ion-toggle> |                     </ion-toggle> | ||||||
|                 </core-button-with-spinner> |                 </core-button-with-spinner> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2>{{ 'addon.messages.groupinfo' | translate }}</h2> |             <h2>{{ 'addon.messages.groupinfo' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
| @ -32,8 +34,8 @@ | |||||||
|             </ion-label> |             </ion-label> | ||||||
|         </ion-item> |         </ion-item> | ||||||
| 
 | 
 | ||||||
|         <ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let member of members" |         <ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let member of members" (click)="closeModal(member.id)" | ||||||
|             (click)="closeModal(member.id)" detail="true" button> |             detail="true" button> | ||||||
|             <core-user-avatar [user]="member" [linkProfile]="false" [checkOnline]="member.showonlinestatus" slot="start"> |             <core-user-avatar [user]="member" [linkProfile]="false" [checkOnline]="member.showonlinestatus" slot="start"> | ||||||
|             </core-user-avatar> |             </core-user-avatar> | ||||||
|             <ion-label> |             <ion-label> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.messages.contacts' | translate }}</h1> |             <h1>{{ 'addon.messages.contacts' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| @ -14,9 +16,8 @@ | |||||||
|             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|         </ion-refresher> |         </ion-refresher> | ||||||
| 
 | 
 | ||||||
|         <core-search-box (onSubmit)="search($event)" (onClear)="clearSearch()" |         <core-search-box (onSubmit)="search($event)" (onClear)="clearSearch()" [placeholder]="'addon.messages.contactname' | translate" | ||||||
|             [placeholder]="'addon.messages.contactname' | translate" autocorrect="off" spellcheck="false" lengthCheck="2" |             autocorrect="off" spellcheck="false" lengthCheck="2" [disabled]="!loaded" searchArea="AddonMessagesContacts"></core-search-box> | ||||||
|             [disabled]="!loaded" searchArea="AddonMessagesContacts"></core-search-box> |  | ||||||
| 
 | 
 | ||||||
|         <core-loading [hideUntil]="loaded" [message]="loadingMessage"> |         <core-loading [hideUntil]="loaded" [message]="loadingMessage"> | ||||||
|             <core-empty-box *ngIf="!hasContacts && searchString == ''" icon="fas-address-book" |             <core-empty-box *ngIf="!hasContacts && searchString == ''" icon="fas-address-book" | ||||||
| @ -28,17 +29,23 @@ | |||||||
|             <ion-list *ngFor="let contactType of contactTypes" class="ion-no-margin"> |             <ion-list *ngFor="let contactType of contactTypes" class="ion-no-margin"> | ||||||
|                 <ng-container *ngIf="contacts[contactType] && (contacts[contactType].length > 0 || contactType === searchType)"> |                 <ng-container *ngIf="contacts[contactType] && (contacts[contactType].length > 0 || contactType === searchType)"> | ||||||
|                     <ion-item-divider> |                     <ion-item-divider> | ||||||
|                         <ion-label><p class="item-heading">{{ 'addon.messages.type_' + contactType | translate }}</p></ion-label> |                         <ion-label> | ||||||
|                         <ion-note slot="end" class="ion-padding-end"><ion-badge>{{ contacts[contactType].length }}</ion-badge></ion-note> |                             <p class="item-heading">{{ 'addon.messages.type_' + contactType | translate }}</p> | ||||||
|  |                         </ion-label> | ||||||
|  |                         <ion-note slot="end" class="ion-padding-end"> | ||||||
|  |                             <ion-badge>{{ contacts[contactType].length }}</ion-badge> | ||||||
|  |                         </ion-note> | ||||||
|                     </ion-item-divider> |                     </ion-item-divider> | ||||||
|                     <ng-container *ngFor="let contact of contacts[contactType]"> |                     <ng-container *ngFor="let contact of contacts[contactType]"> | ||||||
|                         <!-- Don't show deleted users --> |                         <!-- Don't show deleted users --> | ||||||
|                         <ion-item class="ion-text-wrap addon-messages-conversation-item" |                         <ion-item class="ion-text-wrap addon-messages-conversation-item" | ||||||
|                             *ngIf="contact.profileimageurl || contact.profileimageurlsmall" |                             *ngIf="contact.profileimageurl || contact.profileimageurlsmall" [attr.aria-label]="contact.fullname" | ||||||
|                             [attr.aria-label]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail="true" button |                             (click)="gotoDiscussion(contact.id)" detail="true" button | ||||||
|                             [attr.aria-current]="contact.id == discussionUserId ? 'page' : 'false'"> |                             [attr.aria-current]="contact.id == discussionUserId ? 'page' : 'false'"> | ||||||
|                             <core-user-avatar [user]="contact" slot="start" [checkOnline]="contact.showonlinestatus"></core-user-avatar> |                             <core-user-avatar [user]="contact" slot="start" [checkOnline]="contact.showonlinestatus"></core-user-avatar> | ||||||
|                             <ion-label><p class="item-heading">{{ contact.fullname }}</p></ion-label> |                             <ion-label> | ||||||
|  |                                 <p class="item-heading">{{ contact.fullname }}</p> | ||||||
|  |                             </ion-label> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                     </ng-container> |                     </ng-container> | ||||||
|                 </ng-container> |                 </ng-container> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.messages.contacts' | translate }}</h1> |             <h1>{{ 'addon.messages.contacts' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate"> |             <ion-button fill="clear" (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate"> | ||||||
|                 <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
| @ -26,8 +28,8 @@ | |||||||
|                             <ion-item class="ion-text-wrap addon-messages-conversation-item" (click)="selectUser(contact.id)" button |                             <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" |                                 *ngFor="let contact of confirmedContacts" [attr.aria-label]="contact.fullname" detail="true" | ||||||
|                                 [attr.aria-current]="contact.id == selectedUserId ? 'page' : 'false'"> |                                 [attr.aria-current]="contact.id == selectedUserId ? 'page' : 'false'"> | ||||||
|                                 <core-user-avatar slot="start" [user]="contact" |                                 <core-user-avatar slot="start" [user]="contact" [checkOnline]="contact.showonlinestatus" | ||||||
|                                     [checkOnline]="contact.showonlinestatus" [linkProfile]="false"> |                                     [linkProfile]="false"> | ||||||
|                                 </core-user-avatar> |                                 </core-user-avatar> | ||||||
|                                 <ion-label> |                                 <ion-label> | ||||||
|                                     <p class="item-heading"> |                                     <p class="item-heading"> | ||||||
| @ -45,8 +47,8 @@ | |||||||
|                             [message]="'addon.messages.nocontactsgetstarted' | translate"> |                             [message]="'addon.messages.nocontactsgetstarted' | translate"> | ||||||
|                         </core-empty-box> |                         </core-empty-box> | ||||||
| 
 | 
 | ||||||
|                         <core-infinite-loading [enabled]="confirmedCanLoadMore" (action)="loadMore($event)" |                         <core-infinite-loading [enabled]="confirmedCanLoadMore" (action)="loadMore($event)" [error]="confirmedLoadMoreError" | ||||||
|                             [error]="confirmedLoadMoreError" position="bottom"> |                             position="bottom"> | ||||||
|                         </core-infinite-loading> |                         </core-infinite-loading> | ||||||
|                     </core-loading> |                     </core-loading> | ||||||
|                 </ng-template> |                 </ng-template> | ||||||
| @ -77,8 +79,8 @@ | |||||||
|                         <core-empty-box *ngIf="!requests.length" icon="far-address-book" |                         <core-empty-box *ngIf="!requests.length" icon="far-address-book" | ||||||
|                             [message]="'addon.messages.nocontactrequests' | translate"> |                             [message]="'addon.messages.nocontactrequests' | translate"> | ||||||
|                         </core-empty-box> |                         </core-empty-box> | ||||||
|                         <core-infinite-loading [enabled]="requestsCanLoadMore" (action)="loadMore($event)" |                         <core-infinite-loading [enabled]="requestsCanLoadMore" (action)="loadMore($event)" [error]="requestsLoadMoreError" | ||||||
|                             [error]="requestsLoadMoreError" position="bottom"> |                             position="bottom"> | ||||||
|                         </core-infinite-loading> |                         </core-infinite-loading> | ||||||
|                     </core-loading> |                     </core-loading> | ||||||
|                 </ng-template> |                 </ng-template> | ||||||
|  | |||||||
| @ -3,12 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|             <img *ngIf="loaded && !otherMember && conversationImage" class="core-bar-button-image" [src]="conversationImage" |                 <img *ngIf="loaded && !otherMember && conversationImage" class="core-bar-button-image" [src]="conversationImage" alt="" | ||||||
|                 alt="" onError="this.src='assets/img/group-avatar.png'" core-external-content role="presentation" |                     onError="this.src='assets/img/group-avatar.png'" core-external-content role="presentation" [siteId]="siteId || null"> | ||||||
|                 [siteId]="siteId || null"> |                 <core-user-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" [user]="otherMember" [linkProfile]="false" | ||||||
|             <core-user-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" [user]="otherMember" |                     [checkOnline]="otherMember.showonlinestatus"> | ||||||
|                 [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus"> |  | ||||||
|                 </core-user-avatar> |                 </core-user-avatar> | ||||||
|                 <core-format-text [text]="title" contextLevel="system" [contextInstanceId]="0"></core-format-text> |                 <core-format-text [text]="title" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|                 <ion-icon *ngIf="conversation && conversation.isfavourite" name="fas-star" |                 <ion-icon *ngIf="conversation && conversation.isfavourite" name="fas-star" | ||||||
| @ -18,44 +18,41 @@ | |||||||
|                     [attr.aria-label]="'addon.messages.mutedconversation' | translate"> |                     [attr.aria-label]="'addon.messages.mutedconversation' | translate"> | ||||||
|                 </ion-icon> |                 </ion-icon> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"></ion-buttons> |         <ion-buttons slot="end"></ion-buttons> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
|     <core-navbar-buttons slot="end"> |     <core-navbar-buttons slot="end"> | ||||||
|         <core-context-menu [attr.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" |             <core-context-menu-item [hidden]="isSelf || !showInfo || isGroup" [priority]="1000" | ||||||
|                 [content]="'addon.messages.info' | translate" (action)="viewInfo()" |                 [content]="'addon.messages.info' | translate" (action)="viewInfo()" iconAction="fas-info-circle"></core-context-menu-item> | ||||||
|                 iconAction="fas-info-circle"></core-context-menu-item> |  | ||||||
|             <core-context-menu-item [hidden]="isSelf || !showInfo || !isGroup" [priority]="1000" |             <core-context-menu-item [hidden]="isSelf || !showInfo || !isGroup" [priority]="1000" | ||||||
|                 [content]="'addon.messages.groupinfo' | translate" (action)="viewInfo()" |                 [content]="'addon.messages.groupinfo' | translate" (action)="viewInfo()" iconAction="fas-info-circle"> | ||||||
|                 iconAction="fas-info-circle"></core-context-menu-item> |             </core-context-menu-item> | ||||||
|             <core-context-menu-item [hidden]="!groupMessagingEnabled || !conversation" [priority]="800" |             <core-context-menu-item [hidden]="!groupMessagingEnabled || !conversation" [priority]="800" [content]="(conversation && conversation.isfavourite ? 'addon.messages.removefromfavourites' : | ||||||
|                 [content]="(conversation && conversation.isfavourite ? 'addon.messages.removefromfavourites' : |                 'addon.messages.addtofavourites') | translate" (action)="changeFavourite($event)" [closeOnClick]="false" | ||||||
|                 'addon.messages.addtofavourites') | translate" |                 [iconAction]="favouriteIcon" [iconSlash]="favouriteIconSlash"></core-context-menu-item> | ||||||
|                 (action)="changeFavourite($event)" [closeOnClick]="false" [iconAction]="favouriteIcon" |  | ||||||
|                 [iconSlash]="favouriteIconSlash"></core-context-menu-item> |  | ||||||
|             <core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.isblocked" [priority]="700" |             <core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.isblocked" [priority]="700" | ||||||
|                 [content]="'addon.messages.blockuser' | translate" (action)="blockUser()" [iconAction]="blockIcon"> |                 [content]="'addon.messages.blockuser' | translate" (action)="blockUser()" [iconAction]="blockIcon"> | ||||||
|             </core-context-menu-item> |             </core-context-menu-item> | ||||||
|             <core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.isblocked" [priority]="700" |             <core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.isblocked" [priority]="700" | ||||||
|                 [content]="'addon.messages.unblockuser' | translate" (action)="unblockUser()" [iconAction]="blockIcon"> |                 [content]="'addon.messages.unblockuser' | translate" (action)="unblockUser()" [iconAction]="blockIcon"> | ||||||
|             </core-context-menu-item> |             </core-context-menu-item> | ||||||
|             <core-context-menu-item [hidden]="isSelf || !muteEnabled || !conversation" [priority]="600" |             <core-context-menu-item [hidden]="isSelf || !muteEnabled || !conversation" [priority]="600" [content]="(conversation && conversation.ismuted ? 'addon.messages.unmuteconversation' : | ||||||
|                 [content]="(conversation && conversation.ismuted ? 'addon.messages.unmuteconversation' : |  | ||||||
|                 'addon.messages.muteconversation') | translate" (action)="changeMute($event)" [closeOnClick]="false" |                 'addon.messages.muteconversation') | translate" (action)="changeMute($event)" [closeOnClick]="false" | ||||||
|                 [iconAction]="muteIcon"></core-context-menu-item> |                 [iconAction]="muteIcon"></core-context-menu-item> | ||||||
|             <core-context-menu-item [hidden]="!canDelete || !messages || !messages.length" [priority]="400" |             <core-context-menu-item [hidden]="!canDelete || !messages || !messages.length" [priority]="400" | ||||||
|                 [content]="'addon.messages.showdeletemessages' | translate" |                 [content]="'addon.messages.showdeletemessages' | translate" iconAction="toggle" [(toggle)]="showDelete"> | ||||||
|                 iconAction="toggle" [(toggle)]="showDelete"></core-context-menu-item> |             </core-context-menu-item> | ||||||
|             <core-context-menu-item [hidden]="!groupMessagingEnabled || !conversationId || isGroup || !messages || !messages.length" |             <core-context-menu-item [hidden]="!groupMessagingEnabled || !conversationId || isGroup || !messages || !messages.length" | ||||||
|                 [priority]="200" [content]="'addon.messages.deleteconversation' | translate" (action)="deleteConversation($event)" |                 [priority]="200" [content]="'addon.messages.deleteconversation' | translate" (action)="deleteConversation($event)" | ||||||
|                 [closeOnClick]="false" [iconAction]="deleteIcon"></core-context-menu-item> |                 [closeOnClick]="false" [iconAction]="deleteIcon"></core-context-menu-item> | ||||||
|             <core-context-menu-item |             <core-context-menu-item | ||||||
|                 [hidden]="isSelf || !otherMember || otherMember.iscontact || requestContactSent || requestContactReceived" |                 [hidden]="isSelf || !otherMember || otherMember.iscontact || requestContactSent || requestContactReceived" [priority]="100" | ||||||
|                 [priority]="100" [content]="'addon.messages.addtoyourcontacts' | translate" (action)="createContactRequest()" |                 [content]="'addon.messages.addtoyourcontacts' | translate" (action)="createContactRequest()" [iconAction]="addRemoveIcon"> | ||||||
|                 [iconAction]="addRemoveIcon"></core-context-menu-item> |             </core-context-menu-item> | ||||||
|             <core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.iscontact" [priority]="100" |             <core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.iscontact" [priority]="100" | ||||||
|                 [content]="'addon.messages.removefromyourcontacts' | translate" (action)="removeContact()" |                 [content]="'addon.messages.removefromyourcontacts' | translate" (action)="removeContact()" [iconAction]="addRemoveIcon" | ||||||
|                 [iconAction]="addRemoveIcon" [iconSlash]="true"></core-context-menu-item> |                 [iconSlash]="true"></core-context-menu-item> | ||||||
|         </core-context-menu> |         </core-context-menu> | ||||||
|     </core-navbar-buttons> |     </core-navbar-buttons> | ||||||
| </ion-header> | </ion-header> | ||||||
| @ -72,15 +69,13 @@ | |||||||
| 
 | 
 | ||||||
|         <h2 class="sr-only">{{ title }}</h2> |         <h2 class="sr-only">{{ title }}</h2> | ||||||
| 
 | 
 | ||||||
|         <ion-list class="addon-messages-discussion-container" [class.addon-messages-discussion-group]="isGroup" |         <ion-list class="addon-messages-discussion-container" [class.addon-messages-discussion-group]="isGroup" [attr.aria-live]="'polite'"> | ||||||
|             [attr.aria-live]="'polite'"> |  | ||||||
|             <ng-container *ngFor="let message of messages; index as index; last as last"> |             <ng-container *ngFor="let message of messages; index as index; last as last"> | ||||||
|                 <h3 class="ion-text-center addon-messages-date" *ngIf="message.showDate"> |                 <h3 class="ion-text-center addon-messages-date" *ngIf="message.showDate"> | ||||||
|                     {{ message.timecreated | coreFormatDate: "strftimedayshort" }} |                     {{ message.timecreated | coreFormatDate: "strftimedayshort" }} | ||||||
|                 </h3> |                 </h3> | ||||||
| 
 | 
 | ||||||
|                 <ion-chip class="addon-messages-unreadfrom" *ngIf="unreadMessageFrom && message.id == unreadMessageFrom" |                 <ion-chip class="addon-messages-unreadfrom" *ngIf="unreadMessageFrom && message.id == unreadMessageFrom" color="light"> | ||||||
|                     color="light"> |  | ||||||
|                     <ion-label>{{ 'addon.messages.newmessages' | translate }}</ion-label> |                     <ion-label>{{ 'addon.messages.newmessages' | translate }}</ion-label> | ||||||
|                     <ion-icon name="fas-arrow-down" aria-hidden="true"></ion-icon> |                     <ion-icon name="fas-arrow-down" aria-hidden="true"></ion-icon> | ||||||
|                 </ion-chip> |                 </ion-chip> | ||||||
| @ -93,8 +88,7 @@ | |||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <!-- User data. --> |                         <!-- User data. --> | ||||||
|                         <div *ngIf="message.showUserData" class="item-heading addon-message-user"> |                         <div *ngIf="message.showUserData" class="item-heading addon-message-user"> | ||||||
|                             <core-user-avatar slot="start" [user]="members[message.useridfrom]" [linkProfile]="false" |                             <core-user-avatar slot="start" [user]="members[message.useridfrom]" [linkProfile]="false" aria-hidden="true"> | ||||||
|                                 aria-hidden="true"> |  | ||||||
|                             </core-user-avatar> |                             </core-user-avatar> | ||||||
|                             <div>{{ members[message.useridfrom].fullname }}</div> |                             <div>{{ members[message.useridfrom].fullname }}</div> | ||||||
|                         </div> |                         </div> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.messages.messages' | translate }}</h1> |             <h1>{{ 'addon.messages.messages' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <core-user-menu-button></core-user-menu-button> |             <core-user-menu-button></core-user-menu-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
| @ -15,9 +17,9 @@ | |||||||
|             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |             <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|         </ion-refresher> |         </ion-refresher> | ||||||
| 
 | 
 | ||||||
|         <core-search-box (onSubmit)="searchMessage($event)" (onClear)="clearSearch()" |         <core-search-box (onSubmit)="searchMessage($event)" (onClear)="clearSearch()" [placeholder]=" 'addon.messages.message' | translate" | ||||||
|             [placeholder]=" 'addon.messages.message' | translate" autocorrect="off" spellcheck="false" lengthCheck="2" |             autocorrect="off" spellcheck="false" lengthCheck="2" [disabled]="!loaded" searchArea="AddonMessagesDiscussions" | ||||||
|             [disabled]="!loaded" searchArea="AddonMessagesDiscussions" [autoFocus]="false"></core-search-box> |             [autoFocus]="false"></core-search-box> | ||||||
| 
 | 
 | ||||||
|         <core-loading [hideUntil]="loaded" [message]="loadingMessage"> |         <core-loading [hideUntil]="loaded" [message]="loadingMessage"> | ||||||
| 
 | 
 | ||||||
| @ -26,7 +28,9 @@ | |||||||
|                 <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()" |                 <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()" | ||||||
|                     [attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button> |                     [attr.aria-label]="'addon.messages.contacts' | translate" detail="true" button> | ||||||
|                     <ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon> |                     <ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                     <ion-label><h2>{{ 'addon.messages.contacts' | translate }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.messages.contacts' | translate }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|                 <ng-container *ngIf="search.showResults"> |                 <ng-container *ngIf="search.showResults"> | ||||||
| @ -34,7 +38,9 @@ | |||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2>{{ 'core.searchresults' | translate }}</h2> |                             <h2>{{ 'core.searchresults' | translate }}</h2> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|                         <ion-note slot="end" class="ion-padding-end"><ion-badge>{{ search.results.length }}</ion-badge></ion-note> |                         <ion-note slot="end" class="ion-padding-end"> | ||||||
|  |                             <ion-badge>{{ search.results.length }}</ion-badge> | ||||||
|  |                         </ion-note> | ||||||
|                     </ion-item-divider> |                     </ion-item-divider> | ||||||
|                     <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button |                     <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button | ||||||
|                         [attr.aria-label]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" |                         [attr.aria-label]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" | ||||||
| @ -42,8 +48,10 @@ | |||||||
|                         <core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar> |                         <core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <p class="item-heading">{{ result.fullname }}</p> |                             <p class="item-heading">{{ result.fullname }}</p> | ||||||
|                             <p><core-format-text clean="true" singleLine="true" [text]="result.lastmessage" contextLevel="system" |                             <p> | ||||||
|                                 [contextInstanceId]="0"></core-format-text></p> |                                 <core-format-text clean="true" singleLine="true" [text]="result.lastmessage" contextLevel="system" | ||||||
|  |                                     [contextInstanceId]="0"></core-format-text> | ||||||
|  |                             </p> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ng-container> |                 </ng-container> | ||||||
| @ -67,8 +75,8 @@ | |||||||
|                                 </ion-note> |                                 </ion-note> | ||||||
|                             </div> |                             </div> | ||||||
|                             <p> |                             <p> | ||||||
|                                 <core-format-text clean="true" singleLine="true" [text]="discussion.message!.message" |                                 <core-format-text clean="true" singleLine="true" [text]="discussion.message!.message" contextLevel="system" | ||||||
|                                     contextLevel="system" [contextInstanceId]="0"> |                                     [contextInstanceId]="0"> | ||||||
|                                 </core-format-text> |                                 </core-format-text> | ||||||
|                             </p> |                             </p> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.messages.messages' | translate }}</h1> |             <h1>{{ 'addon.messages.messages' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate"> |             <ion-button fill="clear" (click)="gotoSearch()" [attr.aria-label]="'addon.messages.searchcombined' | translate"> | ||||||
|                 <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
| @ -25,28 +27,25 @@ | |||||||
|             <ion-list> |             <ion-list> | ||||||
|                 <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()" detail="true" button> |                 <ion-item class="ion-text-wrap addon-message-discussion" (click)="gotoContacts()" detail="true" button> | ||||||
|                     <ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon> |                     <ion-icon name="fas-address-book" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                     <ion-label><h2>{{ 'addon.messages.contacts' | translate }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.messages.contacts' | translate }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                     <ion-badge *ngIf="contactRequestsCount > 0" slot="end" aria-hidden="true">{{contactRequestsCount}}</ion-badge> |                     <ion-badge *ngIf="contactRequestsCount > 0" slot="end" aria-hidden="true">{{contactRequestsCount}}</ion-badge> | ||||||
|                     <span *ngIf="contactRequestsCount > 0" class="sr-only"> |                     <span *ngIf="contactRequestsCount > 0" class="sr-only"> | ||||||
|                         {{ 'addon.messages.pendingcontactrequests' | translate:{$a: contactRequestsCount} }} |                         {{ 'addon.messages.pendingcontactrequests' | translate:{$a: contactRequestsCount} }} | ||||||
|                     </span> |                     </span> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <!-- Favourite conversations. --> |                 <!-- Favourite conversations. --> | ||||||
|                 <ion-item |                 <ion-item button class="ion-text-wrap divider" (click)="toggle(favourites)" sticky="true" | ||||||
|                     button |  | ||||||
|                     class="ion-text-wrap divider" |  | ||||||
|                     (click)="toggle(favourites)" |  | ||||||
|                     sticky="true" |  | ||||||
|                     [attr.aria-label]="(favourites.expanded ? 'core.collapse' : 'core.expand') | translate" |                     [attr.aria-label]="(favourites.expanded ? 'core.collapse' : 'core.expand') | translate" | ||||||
|                     [attr.aria-expanded]="favourites.expanded" |                     [attr.aria-expanded]="favourites.expanded" aria-controls="addon-messages-groupconversations-favourite" role="heading" | ||||||
|                     aria-controls="addon-messages-groupconversations-favourite" |                     detail="false"> | ||||||
|                     role="heading" |  | ||||||
|                     detail="false" |  | ||||||
|                 > |  | ||||||
|                     <ion-icon *ngIf="!favourites.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"> |                     <ion-icon *ngIf="!favourites.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"> | ||||||
|                     </ion-icon> |                     </ion-icon> | ||||||
|                     <ion-icon *ngIf="favourites.expanded" name="fas-caret-down" 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><h2>{{ 'core.favourites' | translate }} ({{ favourites.count }})</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'core.favourites' | translate }} ({{ favourites.count }})</h2> | ||||||
|  |                     </ion-label> | ||||||
|                     <ion-badge slot="end" *ngIf="favourites.unread" aria-hidden="true">{{ favourites.unread }}</ion-badge> |                     <ion-badge slot="end" *ngIf="favourites.unread" aria-hidden="true">{{ favourites.unread }}</ion-badge> | ||||||
|                     <span *ngIf="favourites.unread" class="sr-only"> |                     <span *ngIf="favourites.unread" class="sr-only"> | ||||||
|                         {{ 'addon.messages.unreadconversations' | translate:{$a: favourites.unread} }} |                         {{ 'addon.messages.unreadconversations' | translate:{$a: favourites.unread} }} | ||||||
| @ -60,28 +59,26 @@ | |||||||
|                     <core-infinite-loading [enabled]="favourites.canLoadMore" (action)="loadMoreConversations(favourites, $event)" |                     <core-infinite-loading [enabled]="favourites.canLoadMore" (action)="loadMoreConversations(favourites, $event)" | ||||||
|                         [error]="favourites.loadMoreError"></core-infinite-loading> |                         [error]="favourites.loadMoreError"></core-infinite-loading> | ||||||
|                     <ion-item class="ion-text-wrap" *ngIf="favourites.conversations && favourites.conversations.length == 0"> |                     <ion-item class="ion-text-wrap" *ngIf="favourites.conversations && favourites.conversations.length == 0"> | ||||||
|                         <ion-label><p>{{ 'addon.messages.nofavourites' | translate }}</p></ion-label> |                         <ion-label> | ||||||
|  |                             <p>{{ 'addon.messages.nofavourites' | translate }}</p> | ||||||
|  |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </div> |                 </div> | ||||||
|                 <ion-item class="ion-text-center" *ngIf="favourites.loading"> |                 <ion-item class="ion-text-center" *ngIf="favourites.loading"> | ||||||
|                     <ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label> |                     <ion-label> | ||||||
|  |                         <ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|                 <!-- Group conversations. --> |                 <!-- Group conversations. --> | ||||||
|                 <ion-item |                 <ion-item button class="divider ion-text-wrap" (click)="toggle(group)" sticky="true" | ||||||
|                     button |                     [attr.aria-label]="(group.expanded ? 'core.collapse' : 'core.expand') | translate" [attr.aria-expanded]="group.expanded" | ||||||
|                     class="divider ion-text-wrap" |                     aria-controls="addon-messages-groupconversations-group" role="heading" detail="false"> | ||||||
|                     (click)="toggle(group)" |  | ||||||
|                     sticky="true" |  | ||||||
|                     [attr.aria-label]="(group.expanded ? 'core.collapse' : 'core.expand') | translate" |  | ||||||
|                     [attr.aria-expanded]="group.expanded" |  | ||||||
|                     aria-controls="addon-messages-groupconversations-group" |  | ||||||
|                     role="heading" |  | ||||||
|                     detail="false" |  | ||||||
|                 > |  | ||||||
|                     <ion-icon *ngIf="!group.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"></ion-icon> |                     <ion-icon *ngIf="!group.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"></ion-icon> | ||||||
|                     <ion-icon *ngIf="group.expanded" name="fas-caret-down" 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><h2>{{ 'addon.messages.groupconversations' | translate }} ({{ group.count }})</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.messages.groupconversations' | translate }} ({{ group.count }})</h2> | ||||||
|  |                     </ion-label> | ||||||
|                     <ion-badge slot="end" *ngIf="group.unread" aria-hidden="true">{{ group.unread }}</ion-badge> |                     <ion-badge slot="end" *ngIf="group.unread" aria-hidden="true">{{ group.unread }}</ion-badge> | ||||||
|                     <span *ngIf="group.unread" class="sr-only"> |                     <span *ngIf="group.unread" class="sr-only"> | ||||||
|                         {{ 'addon.messages.unreadconversations' | translate:{$a: group.unread} }} |                         {{ 'addon.messages.unreadconversations' | translate:{$a: group.unread} }} | ||||||
| @ -95,24 +92,21 @@ | |||||||
|                     <core-infinite-loading [enabled]="group.canLoadMore" (action)="loadMoreConversations(group, $event)" |                     <core-infinite-loading [enabled]="group.canLoadMore" (action)="loadMoreConversations(group, $event)" | ||||||
|                         [error]="group.loadMoreError"></core-infinite-loading> |                         [error]="group.loadMoreError"></core-infinite-loading> | ||||||
|                     <ion-item class="ion-text-wrap" *ngIf="group.conversations && group.conversations.length == 0"> |                     <ion-item class="ion-text-wrap" *ngIf="group.conversations && group.conversations.length == 0"> | ||||||
|                         <ion-label><p>{{ 'addon.messages.nogroupconversations' | translate }}</p></ion-label> |                         <ion-label> | ||||||
|  |                             <p>{{ 'addon.messages.nogroupconversations' | translate }}</p> | ||||||
|  |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </div> |                 </div> | ||||||
|                 <ion-item class="ion-text-center" *ngIf="group.loading"> |                 <ion-item class="ion-text-center" *ngIf="group.loading"> | ||||||
|                     <ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label> |                     <ion-label> | ||||||
|  |                         <ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|                 <ion-item |                 <ion-item button class="divider ion-text-wrap" (click)="toggle(individual)" sticky="true" | ||||||
|                     button |  | ||||||
|                     class="divider ion-text-wrap" |  | ||||||
|                     (click)="toggle(individual)" |  | ||||||
|                     sticky="true" |  | ||||||
|                     [attr.aria-label]="(individual.expanded ? 'core.collapse' : 'core.expand') | translate" |                     [attr.aria-label]="(individual.expanded ? 'core.collapse' : 'core.expand') | translate" | ||||||
|                     [attr.aria-expanded]="individual.expanded" |                     [attr.aria-expanded]="individual.expanded" aria-controls="addon-messages-groupconversations-individual" role="heading" | ||||||
|                     aria-controls="addon-messages-groupconversations-individual" |                     detail="false"> | ||||||
|                     role="heading" |  | ||||||
|                     detail="false" |  | ||||||
|                 > |  | ||||||
|                     <ion-icon *ngIf="!individual.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"> |                     <ion-icon *ngIf="!individual.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"> | ||||||
|                     </ion-icon> |                     </ion-icon> | ||||||
|                     <ion-icon *ngIf="individual.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon> |                     <ion-icon *ngIf="individual.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon> | ||||||
| @ -132,11 +126,15 @@ | |||||||
|                     <core-infinite-loading [enabled]="individual.canLoadMore" (action)="loadMoreConversations(individual, $event)" |                     <core-infinite-loading [enabled]="individual.canLoadMore" (action)="loadMoreConversations(individual, $event)" | ||||||
|                         [error]="individual.loadMoreError"></core-infinite-loading> |                         [error]="individual.loadMoreError"></core-infinite-loading> | ||||||
|                     <ion-item class="ion-text-wrap" *ngIf="individual.conversations && individual.conversations.length == 0"> |                     <ion-item class="ion-text-wrap" *ngIf="individual.conversations && individual.conversations.length == 0"> | ||||||
|                         <ion-label><p>{{ 'addon.messages.noindividualconversations' | translate }}</p></ion-label> |                         <ion-label> | ||||||
|  |                             <p>{{ 'addon.messages.noindividualconversations' | translate }}</p> | ||||||
|  |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </div> |                 </div> | ||||||
|                 <ion-item class="ion-text-center" *ngIf="individual.loading"> |                 <ion-item class="ion-text-center" *ngIf="individual.loading"> | ||||||
|                     <ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label> |                     <ion-label> | ||||||
|  |                         <ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|             </ion-list> |             </ion-list> | ||||||
| @ -147,8 +145,7 @@ | |||||||
| <!-- Template to render a list of conversations. --> | <!-- Template to render a list of conversations. --> | ||||||
| <ng-template #conversationsTemplate let-conversations="conversations"> | <ng-template #conversationsTemplate let-conversations="conversations"> | ||||||
|     <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let conversation of conversations" button detail="false" |     <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let conversation of conversations" button detail="false" | ||||||
|         [attr.aria-label]="conversation.name" (click)="gotoConversation(conversation.id, conversation.userid)" |         [attr.aria-label]="conversation.name" (click)="gotoConversation(conversation.id, conversation.userid)" [attr.aria-current]="((conversation.id && conversation.id == selectedConversationId) || | ||||||
|         [attr.aria-current]="((conversation.id && conversation.id == selectedConversationId) || |  | ||||||
|             (conversation.userid && conversation.userid == selectedUserId)) ? 'page': 'false'" |             (conversation.userid && conversation.userid == selectedUserId)) ? 'page': 'false'" | ||||||
|         id="addon-message-conversation-{{ conversation.id ? conversation.id : 'user-' + conversation.userid }}"> |         id="addon-message-conversation-{{ conversation.id ? conversation.id : 'user-' + conversation.userid }}"> | ||||||
|         <!-- Group conversation image. --> |         <!-- Group conversation image. --> | ||||||
| @ -158,17 +155,17 @@ | |||||||
|         </ion-avatar> |         </ion-avatar> | ||||||
| 
 | 
 | ||||||
|         <!-- Avatar for individual conversations. --> |         <!-- Avatar for individual conversations. --> | ||||||
|         <core-user-avatar *ngIf="conversation.type != typeGroup" core-user-avatar [user]="conversation.otherUser" |         <core-user-avatar *ngIf="conversation.type != typeGroup" core-user-avatar [user]="conversation.otherUser" [linkProfile]="false" | ||||||
|             [linkProfile]="false" [checkOnline]="conversation.showonlinestatus" slot="start"></core-user-avatar> |             [checkOnline]="conversation.showonlinestatus" slot="start"></core-user-avatar> | ||||||
| 
 | 
 | ||||||
|         <ion-label> |         <ion-label> | ||||||
|             <div class="flex-row ion-justify-content-between"> |             <div class="flex-row ion-justify-content-between"> | ||||||
|                 <p class="item-heading"> |                 <p class="item-heading"> | ||||||
|                     <core-format-text [text]="conversation.name" contextLevel="system" [contextInstanceId]="0"></core-format-text> |                     <core-format-text [text]="conversation.name" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|                     <ion-icon name="fas-user-slash" *ngIf="conversation.isblocked" |                     <ion-icon name="fas-user-slash" *ngIf="conversation.isblocked" [title]="'addon.messages.contactblocked' | translate"> | ||||||
|                         [title]="'addon.messages.contactblocked' | translate"></ion-icon> |                     </ion-icon> | ||||||
|                     <ion-icon *ngIf="conversation.ismuted" name="fas-volume-mute" |                     <ion-icon *ngIf="conversation.ismuted" name="fas-volume-mute" [title]="'addon.messages.mutedconversation' | translate"> | ||||||
|                         [title]="'addon.messages.mutedconversation' | translate"></ion-icon> |                     </ion-icon> | ||||||
|                 </p> |                 </p> | ||||||
|                 <ion-note *ngIf="conversation.lastmessagedate > 0 || conversation.unreadcount"> |                 <ion-note *ngIf="conversation.lastmessagedate > 0 || conversation.unreadcount"> | ||||||
|                     <span *ngIf="conversation.lastmessagedate > 0" class="addon-message-last-message-date"> |                     <span *ngIf="conversation.lastmessagedate > 0" class="addon-message-last-message-date"> | ||||||
| @ -180,16 +177,17 @@ | |||||||
|                     </span> |                     </span> | ||||||
|                 </ion-note> |                 </ion-note> | ||||||
|             </div> |             </div> | ||||||
|             <p *ngIf="conversation.subname"><core-format-text [text]="conversation.subname" contextLevel="system" |             <p *ngIf="conversation.subname"> | ||||||
|                 [contextInstanceId]="0"></core-format-text></p> |                 <core-format-text [text]="conversation.subname" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|  |             </p> | ||||||
|             <p class="addon-message-last-message"> |             <p class="addon-message-last-message"> | ||||||
|                 <span *ngIf="conversation.sentfromcurrentuser" class="addon-message-last-message-user"> |                 <span *ngIf="conversation.sentfromcurrentuser" class="addon-message-last-message-user"> | ||||||
|                     {{ 'addon.messages.you' | translate }} |                     {{ 'addon.messages.you' | translate }} | ||||||
|                 </span> |                 </span> | ||||||
|                 <span *ngIf="!conversation.sentfromcurrentuser && conversation.type == typeGroup && conversation.members[0]" |                 <span *ngIf="!conversation.sentfromcurrentuser && conversation.type == typeGroup && conversation.members[0]" | ||||||
|                     class="addon-message-last-message-user">{{ conversation.members[0].fullname + ':' }}</span> |                     class="addon-message-last-message-user">{{ conversation.members[0].fullname + ':' }}</span> | ||||||
|                 <core-format-text clean="true" singleLine="true" [text]="conversation.lastmessage" |                 <core-format-text clean="true" singleLine="true" [text]="conversation.lastmessage" class="addon-message-last-message-text" | ||||||
|                     class="addon-message-last-message-text" contextLevel="system" [contextInstanceId]="0"></core-format-text> |                     contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|             </p> |             </p> | ||||||
|         </ion-label> |         </ion-label> | ||||||
|     </ion-item> |     </ion-item> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.messages.searchcombined' | translate }}</h1> |             <h1>{{ 'addon.messages.searchcombined' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| @ -23,8 +25,7 @@ | |||||||
|                     [error]="messages.loadMoreError"></core-infinite-loading> |                     [error]="messages.loadMoreError"></core-infinite-loading> | ||||||
|             </ion-list> |             </ion-list> | ||||||
| 
 | 
 | ||||||
|             <core-empty-box |             <core-empty-box *ngIf="displayResults && !contacts.results.length && !nonContacts.results.length && !messages.results.length" | ||||||
|                 *ngIf="displayResults && !contacts.results.length && !nonContacts.results.length && !messages.results.length" |  | ||||||
|                 icon="fas-search" [message]="'core.noresults' | translate"> |                 icon="fas-search" [message]="'core.noresults' | translate"> | ||||||
|             </core-empty-box> |             </core-empty-box> | ||||||
|         </core-loading> |         </core-loading> | ||||||
| @ -35,20 +36,20 @@ | |||||||
| <ng-template #resultsTemplate let-item="item"> | <ng-template #resultsTemplate let-item="item"> | ||||||
|     <ng-container *ngIf="item.results.length > 0"> |     <ng-container *ngIf="item.results.length > 0"> | ||||||
|         <ion-item-divider class="ion-text-wrap"> |         <ion-item-divider class="ion-text-wrap"> | ||||||
|             <ion-label><h2>{{ item.titleString | translate }}</h2></ion-label> |             <ion-label> | ||||||
|  |                 <h2>{{ item.titleString | translate }}</h2> | ||||||
|  |             </ion-label> | ||||||
|         </ion-item-divider> |         </ion-item-divider> | ||||||
| 
 | 
 | ||||||
|         <!-- List of results --> |         <!-- List of results --> | ||||||
|         <ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [attr.aria-label]="result.fullname" |         <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" |             (click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' : 'false'" detail="true" button> | ||||||
|             button> |  | ||||||
|             <core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar> |             <core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar> | ||||||
|             <ion-label> |             <ion-label> | ||||||
|                 <p class="item-heading"> |                 <p class="item-heading"> | ||||||
|                     <core-format-text [text]="result.fullname" [highlight]="result.highlightName" [filter]="false"> |                     <core-format-text [text]="result.fullname" [highlight]="result.highlightName" [filter]="false"> | ||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                     <ion-icon name="fas-ban" *ngIf="result.isblocked" |                     <ion-icon name="fas-ban" *ngIf="result.isblocked" [attr.aria-label]="'addon.messages.contactblocked' | translate"> | ||||||
|                         [attr.aria-label]="'addon.messages.contactblocked' | translate"> |  | ||||||
|                     </ion-icon> |                     </ion-icon> | ||||||
|                 </p> |                 </p> | ||||||
|                 <ion-note *ngIf="result.lastmessagedate > 0"> |                 <ion-note *ngIf="result.lastmessagedate > 0"> | ||||||
| @ -58,9 +59,8 @@ | |||||||
|                     <span *ngIf="result.sentfromcurrentuser" class="addon-message-last-message-user"> |                     <span *ngIf="result.sentfromcurrentuser" class="addon-message-last-message-user"> | ||||||
|                         {{ 'addon.messages.you' | translate }} |                         {{ 'addon.messages.you' | translate }} | ||||||
|                     </span> |                     </span> | ||||||
|                     <core-format-text clean="true" singleLine="true" [text]="result.lastmessage" |                     <core-format-text clean="true" singleLine="true" [text]="result.lastmessage" [highlight]="result.highlightMessage" | ||||||
|                         [highlight]="result.highlightMessage" contextLevel="system" [contextInstanceId]="0" |                         contextLevel="system" [contextInstanceId]="0" class="addon-message-last-message-text"></core-format-text> | ||||||
|                         class="addon-message-last-message-text"></core-format-text> |  | ||||||
|                 </p> |                 </p> | ||||||
|             </ion-label> |             </ion-label> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.messages.messages' | translate }}</h1> |             <h1>{{ 'addon.messages.messages' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -22,7 +24,9 @@ | |||||||
|             <ion-list *ngIf="advancedContactable" class="ion-text-wrap"> |             <ion-list *ngIf="advancedContactable" class="ion-text-wrap"> | ||||||
|                 <ion-radio-group [(ngModel)]="contactablePrivacy" (ionChange)="saveContactablePrivacy(contactablePrivacy)"> |                 <ion-radio-group [(ngModel)]="contactablePrivacy" (ionChange)="saveContactablePrivacy(contactablePrivacy)"> | ||||||
|                     <ion-item-divider> |                     <ion-item-divider> | ||||||
|                         <ion-label><h2>{{ 'addon.messages.contactableprivacy' | translate }}</h2></ion-label> |                         <ion-label> | ||||||
|  |                             <h2>{{ 'addon.messages.contactableprivacy' | translate }}</h2> | ||||||
|  |                         </ion-label> | ||||||
|                     </ion-item-divider> |                     </ion-item-divider> | ||||||
|                     <ion-item> |                     <ion-item> | ||||||
|                         <ion-label>{{ 'addon.messages.contactableprivacy_onlycontacts' | translate }}</ion-label> |                         <ion-label>{{ 'addon.messages.contactableprivacy_onlycontacts' | translate }}</ion-label> | ||||||
| @ -66,16 +70,9 @@ | |||||||
|                         <ng-container *ngIf="groupMessagingEnabled"> |                         <ng-container *ngIf="groupMessagingEnabled"> | ||||||
|                             <ion-item class="ion-text-wrap"> |                             <ion-item class="ion-text-wrap"> | ||||||
|                                 <ion-label>{{ processor.displayname }}</ion-label> |                                 <ion-label>{{ processor.displayname }}</ion-label> | ||||||
|                                 <core-button-with-spinner |                                 <core-button-with-spinner *ngIf="!preferences.disableall" [loading]="!!notification.updating" slot="end"> | ||||||
|                                     *ngIf="!preferences.disableall" |                                     <ion-toggle *ngIf="!processor.locked" [(ngModel)]="processor.checked" | ||||||
|                                     [loading]="!!notification.updating" |                                         (ngModelChange)="changePreference(notification, '', processor)"> | ||||||
|                                     slot="end" |  | ||||||
|                                 > |  | ||||||
|                                     <ion-toggle |  | ||||||
|                                         *ngIf="!processor.locked" |  | ||||||
|                                         [(ngModel)]="processor.checked" |  | ||||||
|                                         (ngModelChange)="changePreference(notification, '', processor)" |  | ||||||
|                                     > |  | ||||||
|                                     </ion-toggle> |                                     </ion-toggle> | ||||||
|                                     <ion-note *ngIf="processor.locked"> |                                     <ion-note *ngIf="processor.locked"> | ||||||
|                                         {{ processor.lockedmessage }} |                                         {{ processor.lockedmessage }} | ||||||
| @ -92,15 +89,11 @@ | |||||||
|                             <ion-row class="ion-text-wrap ion-hide-md-down ion-align-items-center"> |                             <ion-row class="ion-text-wrap ion-hide-md-down ion-align-items-center"> | ||||||
|                                 <ion-col class="ion-margin-horizontal">{{ processor.displayname }}</ion-col> |                                 <ion-col class="ion-margin-horizontal">{{ processor.displayname }}</ion-col> | ||||||
|                                 <ion-col size="2" class="ion-text-center" *ngFor="let state of ['loggedin', 'loggedoff']"> |                                 <ion-col size="2" class="ion-text-center" *ngFor="let state of ['loggedin', 'loggedoff']"> | ||||||
|                                     <core-button-with-spinner |                                     <core-button-with-spinner *ngIf="!preferences.disableall" | ||||||
|                                         *ngIf="!preferences.disableall" |                                         [loading]="notification.updating && notification.updating[state]"> | ||||||
|                                         [loading]="notification.updating && notification.updating[state]" |  | ||||||
|                                     > |  | ||||||
|                                         <!-- If notifications not disabled, show toggle. --> |                                         <!-- If notifications not disabled, show toggle. --> | ||||||
|                                         <ion-toggle *ngIf="!processor.locked" |                                         <ion-toggle *ngIf="!processor.locked" [(ngModel)]="processor[state].checked" | ||||||
|                                             [(ngModel)]="processor[state].checked" |                                             (ngModelChange)="changePreference(notification, state, processor)"> | ||||||
|                                             (ngModelChange)="changePreference(notification, state, processor)" |  | ||||||
|                                         > |  | ||||||
|                                         </ion-toggle> |                                         </ion-toggle> | ||||||
|                                         <div class="ion-padding text-gray" *ngIf="processor.locked"> |                                         <div class="ion-padding text-gray" *ngIf="processor.locked"> | ||||||
|                                             {{'core.settings.locked' | translate }} |                                             {{'core.settings.locked' | translate }} | ||||||
| @ -118,14 +111,10 @@ | |||||||
|                                 If notifications are disabled, show "Disabled" instead of toggle. --> |                                 If notifications are disabled, show "Disabled" instead of toggle. --> | ||||||
|                             <ion-item *ngFor="let state of ['loggedin', 'loggedoff']" class="ion-text-wrap ion-hide-md-up"> |                             <ion-item *ngFor="let state of ['loggedin', 'loggedoff']" class="ion-text-wrap ion-hide-md-up"> | ||||||
|                                 <ion-label>{{ 'core.settings.' + state | translate }}</ion-label> |                                 <ion-label>{{ 'core.settings.' + state | translate }}</ion-label> | ||||||
|                                 <core-button-with-spinner slot="end" |                                 <core-button-with-spinner slot="end" *ngIf="!preferences.disableall" | ||||||
|                                     *ngIf="!preferences.disableall" |                                     [loading]="notification.updating && notification.updating[state]"> | ||||||
|                                     [loading]="notification.updating && notification.updating[state]" |                                     <ion-toggle *ngIf="!processor.locked" [(ngModel)]="processor[state].checked" | ||||||
|                                 > |                                         (ngModelChange)="changePreference(notification, state, processor)"> | ||||||
|                                     <ion-toggle *ngIf="!processor.locked" |  | ||||||
|                                         [(ngModel)]="processor[state].checked" |  | ||||||
|                                         (ngModelChange)="changePreference(notification, state, processor)" |  | ||||||
|                                     > |  | ||||||
|                                     </ion-toggle> |                                     </ion-toggle> | ||||||
|                                     <ion-note *ngIf="processor.locked"> |                                     <ion-note *ngIf="processor.locked"> | ||||||
|                                         {{'core.settings.locked' | translate }} |                                         {{'core.settings.locked' | translate }} | ||||||
| @ -144,7 +133,11 @@ | |||||||
|         <!-- General settings. --> |         <!-- General settings. --> | ||||||
|         <ion-card> |         <ion-card> | ||||||
|             <ion-list class="ion-text-wrap"> |             <ion-list class="ion-text-wrap"> | ||||||
|                 <ion-item-divider><ion-label><h2>{{ 'core.settings.general' | translate }}</h2></ion-label></ion-item-divider> |                 <ion-item-divider> | ||||||
|  |                     <ion-label> | ||||||
|  |                         <h2>{{ 'core.settings.general' | translate }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|  |                 </ion-item-divider> | ||||||
|                 <ion-item class="ion-text-wrap"> |                 <ion-item class="ion-text-wrap"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading">{{ 'addon.messages.useentertosend' | translate }}</p> |                         <p class="item-heading">{{ 'addon.messages.useentertosend' | translate }}</p> | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2>{{ plugin.name }}</h2> |             <h2>{{ plugin.name }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
| @ -10,8 +12,7 @@ | |||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|     <form name="addon-mod_assign-edit-feedback-form" *ngIf="userId && plugin" #editFeedbackForm> |     <form name="addon-mod_assign-edit-feedback-form" *ngIf="userId && plugin" #editFeedbackForm> | ||||||
|         <addon-mod-assign-feedback-plugin [assign]="assign" [submission]="submission" [userId]="userId" |         <addon-mod-assign-feedback-plugin [assign]="assign" [submission]="submission" [userId]="userId" [plugin]="plugin" [edit]="true"> | ||||||
|             [plugin]="plugin" [edit]="true"> |  | ||||||
|         </addon-mod-assign-feedback-plugin> |         </addon-mod-assign-feedback-plugin> | ||||||
|         <ion-button expand="block" (click)="done($event)">{{ 'core.done' | translate }}</ion-button> |         <ion-button expand="block" (click)="done($event)">{{ 'core.done' | translate }}</ion-button> | ||||||
|     </form> |     </form> | ||||||
|  | |||||||
| @ -1,4 +1,3 @@ | |||||||
| 
 |  | ||||||
| <core-dynamic-component [component]="pluginComponent" [data]="data"> | <core-dynamic-component [component]="pluginComponent" [data]="data"> | ||||||
|     <!-- This content will be replaced by the component if found. --> |     <!-- This content will be replaced by the component if found. --> | ||||||
|     <core-loading [hideUntil]="pluginLoaded"> |     <core-loading [hideUntil]="pluginLoaded"> | ||||||
| @ -9,9 +8,8 @@ | |||||||
|                     {{ 'addon.mod_assign.feedbacknotsupported' | translate }} |                     {{ 'addon.mod_assign.feedbacknotsupported' | translate }} | ||||||
|                 </ion-badge> |                 </ion-badge> | ||||||
|                 <p *ngIf="text"> |                 <p *ngIf="text"> | ||||||
|                     <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" |                     <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="120" [text]="text" | ||||||
|                         [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" |                         contextLevel="module" [contextInstanceId]="assign.cmid" [courseId]="assign.course"> | ||||||
|                         [courseId]="assign.course"> |  | ||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                 </p> |                 </p> | ||||||
|                 <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" |                 <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" | ||||||
|  | |||||||
| @ -1,15 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="assign && (description || (assign.introattachments && assign.introattachments.length))" |         <core-context-menu-item *ngIf="assign && (description || (assign.introattachments && assign.introattachments.length))" | ||||||
|             [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" |             [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|             iconAction="fas-arrow-right"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -31,34 +30,13 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline"> | ||||||
|     </core-course-module-info> |         <ion-list inset="true" description *ngIf="assign && assign.introattachments && assign.introattachments.length"> | ||||||
| 
 |  | ||||||
|     <!-- Description and intro attachments. --> |  | ||||||
|     <ion-card *ngIf="description"> |  | ||||||
|         <ion-item class="ion-text-wrap"> |  | ||||||
|             <ion-label> |  | ||||||
|                 <core-format-text [text]="description" [component]="component" [componentId]="componentId" maxHeight="120" |  | ||||||
|                     contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId" |  | ||||||
|                     (onClick)="expandDescription($event)"> |  | ||||||
|                 </core-format-text> |  | ||||||
|             </ion-label> |  | ||||||
|         </ion-item> |  | ||||||
|     </ion-card> |  | ||||||
| 
 |  | ||||||
|     <ion-card *ngIf="assign && assign.introattachments && assign.introattachments.length"> |  | ||||||
|             <core-file *ngFor="let file of assign.introattachments" [file]="file" [component]="component" [componentId]="componentId"> |             <core-file *ngFor="let file of assign.introattachments" [file]="file" [component]="component" [componentId]="componentId"> | ||||||
|             </core-file> |             </core-file> | ||||||
|     </ion-card> |         </ion-list> | ||||||
| 
 |     </core-course-module-info> | ||||||
|     <!-- Assign has something offline. --> |  | ||||||
|     <ion-card class="core-warning-card" *ngIf="hasOffline"> |  | ||||||
|         <ion-item> |  | ||||||
|             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |  | ||||||
|             <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label> |  | ||||||
|         </ion-item> |  | ||||||
|     </ion-card> |  | ||||||
| 
 | 
 | ||||||
|     <!-- User can view all submissions (teacher). --> |     <!-- User can view all submissions (teacher). --> | ||||||
|     <ng-container *ngIf="assign && canViewAllSubmissions"> |     <ng-container *ngIf="assign && canViewAllSubmissions"> | ||||||
| @ -90,8 +68,7 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <!-- Summary of all submissions. --> |             <!-- Summary of all submissions. --> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="summary && summary.participantcount" (click)="goToSubmissionList()" detail="true" |             <ion-item class="ion-text-wrap" *ngIf="summary && summary.participantcount" (click)="goToSubmissionList()" detail="true" button> | ||||||
|                 button> |  | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <h2 *ngIf="assign.teamsubmission">{{ 'addon.mod_assign.numberofteams' | translate }}</h2> |                     <h2 *ngIf="assign.teamsubmission">{{ 'addon.mod_assign.numberofteams' | translate }}</h2> | ||||||
|                     <h2 *ngIf="!assign.teamsubmission">{{ 'addon.mod_assign.numberofparticipants' | translate }}</h2> |                     <h2 *ngIf="!assign.teamsubmission">{{ 'addon.mod_assign.numberofparticipants' | translate }}</h2> | ||||||
| @ -109,11 +86,11 @@ | |||||||
| 
 | 
 | ||||||
|             <!-- Summary of submissions with draft status. --> |             <!-- Summary of submissions with draft status. --> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="assign.submissiondrafts && summary && summary.submissionsenabled" |             <ion-item class="ion-text-wrap" *ngIf="assign.submissiondrafts && summary && summary.submissionsenabled" | ||||||
|                 [class.hide-detail]="!summary.submissiondraftscount" |                 [class.hide-detail]="!summary.submissiondraftscount" detail="true" [button]="summary.submissiondraftscount" | ||||||
|                 detail="true" |  | ||||||
|                 [button]="summary.submissiondraftscount" |  | ||||||
|                 (click)="goToSubmissionList(submissionStatusDraft, !!summary.submissiondraftscount)"> |                 (click)="goToSubmissionList(submissionStatusDraft, !!summary.submissiondraftscount)"> | ||||||
|                 <ion-label><h2>{{ 'addon.mod_assign.numberofdraftsubmissions' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.mod_assign.numberofdraftsubmissions' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|                 <ion-badge slot="end" color="primary"> |                 <ion-badge slot="end" color="primary"> | ||||||
|                     <span aria-hidden="true">{{ summary.submissiondraftscount }}</span> |                     <span aria-hidden="true">{{ summary.submissiondraftscount }}</span> | ||||||
|                     <span class="sr-only"> |                     <span class="sr-only"> | ||||||
| @ -125,11 +102,11 @@ | |||||||
| 
 | 
 | ||||||
|             <!-- Summary of submissions with submitted status. --> |             <!-- Summary of submissions with submitted status. --> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled" |             <ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled" | ||||||
|                 [class.hide-detail]="!summary.submissionssubmittedcount" |                 [class.hide-detail]="!summary.submissionssubmittedcount" detail="true" [button]="summary.submissionssubmittedcount" | ||||||
|                 detail="true" |  | ||||||
|                 [button]="summary.submissionssubmittedcount" |  | ||||||
|                 (click)="goToSubmissionList(submissionStatusSubmitted, !!summary.submissionssubmittedcount)"> |                 (click)="goToSubmissionList(submissionStatusSubmitted, !!summary.submissionssubmittedcount)"> | ||||||
|                 <ion-label><h2>{{ 'addon.mod_assign.numberofsubmittedassignments' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.mod_assign.numberofsubmittedassignments' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|                 <ion-badge slot="end" color="primary"> |                 <ion-badge slot="end" color="primary"> | ||||||
|                     <span aria-hidden="true">{{ summary.submissionssubmittedcount }}</span> |                     <span aria-hidden="true">{{ summary.submissionssubmittedcount }}</span> | ||||||
|                     <span class="sr-only"> |                     <span class="sr-only"> | ||||||
| @ -141,11 +118,11 @@ | |||||||
| 
 | 
 | ||||||
|             <!-- Summary of submissions that need grading. --> |             <!-- Summary of submissions that need grading. --> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled && !assign.teamsubmission" |             <ion-item class="ion-text-wrap" *ngIf="summary && summary.submissionsenabled && !assign.teamsubmission" | ||||||
|                 [class.hide-detail]="!needsGradingAvailable" |                 [class.hide-detail]="!needsGradingAvailable" detail="true" [button]="needsGradingAvailable" | ||||||
|                 detail="true" |  | ||||||
|                 [button]="needsGradingAvailable" |  | ||||||
|                 (click)="goToSubmissionList(needGrading, needsGradingAvailable)"> |                 (click)="goToSubmissionList(needGrading, needsGradingAvailable)"> | ||||||
|                 <ion-label><h2>{{ 'addon.mod_assign.numberofsubmissionsneedgrading' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.mod_assign.numberofsubmissionsneedgrading' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|                 <ion-badge slot="end" color="primary"> |                 <ion-badge slot="end" color="primary"> | ||||||
|                     <span aria-hidden="true">{{ summary.submissionsneedgradingcount }}</span> |                     <span aria-hidden="true">{{ summary.submissionsneedgradingcount }}</span> | ||||||
|                     <span class="sr-only"> |                     <span class="sr-only"> | ||||||
|  | |||||||
| @ -1,4 +1,3 @@ | |||||||
| 
 |  | ||||||
| <core-dynamic-component [component]="pluginComponent" [data]="data"> | <core-dynamic-component [component]="pluginComponent" [data]="data"> | ||||||
|     <!-- This content will be replaced by the component if found. --> |     <!-- This content will be replaced by the component if found. --> | ||||||
|     <core-loading [hideUntil]="pluginLoaded"> |     <core-loading [hideUntil]="pluginLoaded"> | ||||||
| @ -9,9 +8,8 @@ | |||||||
|                     {{ 'addon.mod_assign.submissionnotsupported' | translate }} |                     {{ 'addon.mod_assign.submissionnotsupported' | translate }} | ||||||
|                 </ion-badge> |                 </ion-badge> | ||||||
|                 <p *ngIf="text"> |                 <p *ngIf="text"> | ||||||
|                     <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" |                     <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="120" [text]="text" | ||||||
|                         [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" |                         contextLevel="module" [contextInstanceId]="assign.cmid" [courseId]="assign.course"> | ||||||
|                         [courseId]="assign.course"> |  | ||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                 </p> |                 </p> | ||||||
|                 <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" |                 <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" | ||||||
|  | |||||||
| @ -3,16 +3,14 @@ | |||||||
|     <ion-label> |     <ion-label> | ||||||
|         <h2>{{ plugin.name }}</h2> |         <h2>{{ plugin.name }}</h2> | ||||||
|         <p> |         <p> | ||||||
|             <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" |             <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="120" [text]="text" contextLevel="module" | ||||||
|                 [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" |                 [contextInstanceId]="assign.cmid" [courseId]="assign.course"> | ||||||
|                 [courseId]="assign.course"> |  | ||||||
|             </core-format-text> |             </core-format-text> | ||||||
|         </p> |         </p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
|     <div slot="end"> |     <div slot="end"> | ||||||
|         <div class="ion-text-end"> |         <div class="ion-text-end"> | ||||||
|             <ion-button fill="clear" *ngIf="canEdit" (click)="editComment()" color="dark" |             <ion-button fill="clear" *ngIf="canEdit" (click)="editComment()" color="dark" [attr.aria-label]="'core.edit' | translate"> | ||||||
|                 [attr.aria-label]="'core.edit' | translate"> |  | ||||||
|                 <ion-icon name="fas-pen" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-pen" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
|         </div> |         </div> | ||||||
| @ -25,9 +23,8 @@ | |||||||
| <!-- Edit --> | <!-- Edit --> | ||||||
| <ion-item class="ion-text-wrap" *ngIf="edit && loaded"> | <ion-item class="ion-text-wrap" *ngIf="edit && loaded"> | ||||||
|     <ion-label class="sr-only">{{ plugin.name }}</ion-label> |     <ion-label class="sr-only">{{ plugin.name }}</ion-label> | ||||||
|     <core-rich-text-editor [control]="control" [placeholder]="plugin.name" |     <core-rich-text-editor [control]="control" [placeholder]="plugin.name" name="assignfeedbackcomments_editor" [component]="component" | ||||||
|         name="assignfeedbackcomments_editor" [component]="component" [componentId]="assign.cmid" [autoSave]="true" |         [componentId]="assign.cmid" [autoSave]="true" contextLevel="module" [contextInstanceId]="assign.cmid" | ||||||
|         contextLevel="module" [contextInstanceId]="assign.cmid" elementId="assignfeedbackcomments_editor" |         elementId="assignfeedbackcomments_editor" [draftExtraParams]="{userid: userId, action: 'grade'}"> | ||||||
|         [draftExtraParams]="{userid: userId, action: 'grade'}"> |  | ||||||
|     </core-rich-text-editor> |     </core-rich-text-editor> | ||||||
| </ion-item> | </ion-item> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="save()"> |             <ion-button fill="clear" (click)="save()"> | ||||||
|                 {{ 'core.save' | translate }} |                 {{ 'core.save' | translate }} | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"></ion-buttons> |         <ion-buttons slot="end"></ion-buttons> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"></ion-buttons> |         <ion-buttons slot="end"></ion-buttons> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
|  | |||||||
| @ -4,9 +4,8 @@ | |||||||
|         <h2>{{ plugin.name }}</h2> |         <h2>{{ plugin.name }}</h2> | ||||||
|         <p *ngIf="words">{{ 'addon.mod_assign.numwords' | translate: {'$a': words} }}</p> |         <p *ngIf="words">{{ 'addon.mod_assign.numwords' | translate: {'$a': words} }}</p> | ||||||
|         <p> |         <p> | ||||||
|             <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" |             <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="120" [text]="text" contextLevel="module" | ||||||
|                 [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" |                 [contextInstanceId]="assign.cmid" [courseId]="assign.course"> | ||||||
|                 [courseId]="assign.course"> |  | ||||||
|             </core-format-text> |             </core-format-text> | ||||||
|         </p> |         </p> | ||||||
|     </ion-label> |     </ion-label> | ||||||
| @ -15,7 +14,9 @@ | |||||||
| <!-- Edit --> | <!-- Edit --> | ||||||
| <div *ngIf="edit && loaded"> | <div *ngIf="edit && loaded"> | ||||||
|     <ion-item-divider class="ion-text-wrap" sticky="true"> |     <ion-item-divider class="ion-text-wrap" sticky="true"> | ||||||
|         <ion-label><h2>{{ plugin.name }}</h2></ion-label> |         <ion-label> | ||||||
|  |             <h2>{{ plugin.name }}</h2> | ||||||
|  |         </ion-label> | ||||||
|     </ion-item-divider> |     </ion-item-divider> | ||||||
|     <ion-item class="ion-text-wrap" *ngIf="wordLimitEnabled && words >= 0"> |     <ion-item class="ion-text-wrap" *ngIf="wordLimitEnabled && words >= 0"> | ||||||
|         <ion-label> |         <ion-label> | ||||||
| @ -25,10 +26,10 @@ | |||||||
|     </ion-item> |     </ion-item> | ||||||
|     <ion-item class="ion-text-wrap"> |     <ion-item class="ion-text-wrap"> | ||||||
|         <ion-label class="sr-only">{{ plugin.name }}</ion-label> |         <ion-label class="sr-only">{{ plugin.name }}</ion-label> | ||||||
|         <core-rich-text-editor [control]="control" [placeholder]="plugin.name" |         <core-rich-text-editor [control]="control" [placeholder]="plugin.name" name="onlinetext_editor_text" | ||||||
|             name="onlinetext_editor_text" (contentChanged)="onChange($event)" [component]="component" |             (contentChanged)="onChange($event)" [component]="component" [componentId]="assign.cmid" [autoSave]="true" contextLevel="module" | ||||||
|             [componentId]="assign.cmid" [autoSave]="true" contextLevel="module" [contextInstanceId]="assign.cmid" |             [contextInstanceId]="assign.cmid" elementId="onlinetext_editor" | ||||||
|             elementId="onlinetext_editor" [draftExtraParams]="{userid: currentUserId, action: 'editsubmission'}"> |             [draftExtraParams]="{userid: currentUserId, action: 'editsubmission'}"> | ||||||
|         </core-rich-text-editor> |         </core-rich-text-editor> | ||||||
|     </ion-item> |     </ion-item> | ||||||
| </div> | </div> | ||||||
|  | |||||||
| @ -4,12 +4,12 @@ | |||||||
|         <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|     </ion-button> |     </ion-button> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"></core-context-menu-item> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> |             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"></core-context-menu-item> |             (action)="gotoBlog()"></core-context-menu-item> | ||||||
|         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" |         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" | ||||||
|             [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> |             [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" |         <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" | ||||||
| @ -24,13 +24,10 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <ion-card class="core-warning-card" *ngIf="warning"> |     <ion-card class="core-warning-card" *ngIf="warning"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
|             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> | ||||||
| @ -39,9 +36,8 @@ | |||||||
|     </ion-card> |     </ion-card> | ||||||
| 
 | 
 | ||||||
|     <div class="ion-padding safe-area-padding-horizontal"> |     <div class="ion-padding safe-area-padding-horizontal"> | ||||||
|         <core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter?.id" |         <core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter?.id" [previousTitle]="previousNavBarTitle" | ||||||
|             [previousTitle]="previousNavBarTitle" [next]="nextChapter?.id" [nextTitle]="nextNavBarTitle" |             [next]="nextChapter?.id" [nextTitle]="nextNavBarTitle" (action)="changeChapter($event)"> | ||||||
|             (action)="changeChapter($event)"> |  | ||||||
|         </core-navigation-bar> |         </core-navigation-bar> | ||||||
| 
 | 
 | ||||||
|         <core-format-text [component]="component" [componentId]="componentId" [text]="chapterContent" contextLevel="module" |         <core-format-text [component]="component" [componentId]="componentId" [text]="chapterContent" contextLevel="module" | ||||||
| @ -51,9 +47,8 @@ | |||||||
|             <core-tag-list [tags]="tags"></core-tag-list> |             <core-tag-list [tags]="tags"></core-tag-list> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter?.id" |         <core-navigation-bar *ngIf="displayNavBar" [previous]="previousChapter?.id" [previousTitle]="previousNavBarTitle" | ||||||
|             [previousTitle]="previousNavBarTitle" [next]="nextChapter?.id" [nextTitle]="nextNavBarTitle" |             [next]="nextChapter?.id" [nextTitle]="nextNavBarTitle" (action)="changeChapter($event)"></core-navigation-bar> | ||||||
|             (action)="changeChapter($event)"></core-navigation-bar> |  | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
| </core-loading> | </core-loading> | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <h1>{{ 'addon.mod_book.toc' | translate }}</h1> |         <ion-title> | ||||||
|  |             <h2>{{ 'addon.mod_book.toc' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon> |                 <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon> | ||||||
| @ -12,14 +14,12 @@ | |||||||
|     <nav> |     <nav> | ||||||
|         <ion-list> |         <ion-list> | ||||||
|             <ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)" |             <ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)" | ||||||
|                 [attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button |                 [attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button [class.item-dimmed]="chapter.hidden" detail="false"> | ||||||
|                 [class.item-dimmed]="chapter.hidden" detail="false"> |  | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <p [class.ion-padding-start]="addPadding && chapter.level == 1 ? true : null" class="item-heading"> |                     <p [class.ion-padding-start]="addPadding && chapter.level == 1 ? true : null" class="item-heading"> | ||||||
|                         <span *ngIf="showNumbers" class="addon-mod-book-number">{{chapter.indexNumber}} </span> |                         <span *ngIf="showNumbers" class="addon-mod-book-number">{{chapter.indexNumber}} </span> | ||||||
|                         <span *ngIf="showBullets" class="addon-mod-book-bullet">• </span> |                         <span *ngIf="showBullets" class="addon-mod-book-bullet">• </span> | ||||||
|                         <core-format-text [text]="chapter.title" contextLevel="module" [contextInstanceId]="moduleId" |                         <core-format-text [text]="chapter.title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> | ||||||
|                             [courseId]="courseId"> |  | ||||||
|                         </core-format-text> |                         </core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
| @ -17,7 +19,6 @@ | |||||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|     </ion-refresher> |     </ion-refresher> | ||||||
| 
 | 
 | ||||||
|     <addon-mod-book-index [module]="module" [courseId]="courseId" [initialChapterId]="chapterId" |     <addon-mod-book-index [module]="module" [courseId]="courseId" [initialChapterId]="chapterId" (dataRetrieved)="updateData($event)"> | ||||||
|         (dataRetrieved)="updateData($event)"> |  | ||||||
|     </addon-mod-book-index> |     </addon-mod-book-index> | ||||||
| </ion-content> | </ion-content> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -27,14 +27,10 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="safe-area-padding"> | <core-loading [hideUntil]="loaded" class="safe-area-padding"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <ion-card *ngIf="chatInfo" class="core-info-card"> |     <ion-card *ngIf="chatInfo" class="core-info-card"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
|             <ion-icon name="fas-clock" slot="start" aria-hidden="true"></ion-icon> |             <ion-icon name="fas-clock" slot="start" aria-hidden="true"></ion-icon> | ||||||
|  | |||||||
| @ -1,9 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-title> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |  | ||||||
|         </ion-buttons> |  | ||||||
|             <h2>{{ 'addon.mod_chat.currentusers' | translate }}</h2> |             <h2>{{ 'addon.mod_chat.currentusers' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
| @ -13,8 +12,7 @@ | |||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|     <core-loading [hideUntil]="usersLoaded"> |     <core-loading [hideUntil]="usersLoaded"> | ||||||
|         <ion-item class="ion-text-wrap" *ngFor="let user of users" |         <ion-item class="ion-text-wrap" *ngFor="let user of users" [class.addon-mod-chat-user]="currentUserId != user.id && isOnline"> | ||||||
|             [class.addon-mod-chat-user]="currentUserId != user.id && isOnline"> |  | ||||||
| 
 | 
 | ||||||
|             <core-user-avatar [user]="user" slot="start" [linkProfile]="false"></core-user-avatar> |             <core-user-avatar [user]="user" slot="start" [linkProfile]="false"></core-user-avatar> | ||||||
|             <ion-label> |             <ion-label> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" *ngIf="loaded" (click)="showChatUsers()" [attr.aria-label]="'core.users' | translate"> |             <ion-button fill="clear" *ngIf="loaded" (click)="showChatUsers()" [attr.aria-label]="'core.users' | translate"> | ||||||
|                 <ion-icon name="fas-users" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-users" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
| @ -81,8 +83,7 @@ | |||||||
| 
 | 
 | ||||||
|                 <ion-item *ngIf="!message.special" class="ion-text-wrap addon-message" |                 <ion-item *ngIf="!message.special" class="ion-text-wrap addon-message" | ||||||
|                     [class.addon-message-mine]="message.userid == currentUserId" |                     [class.addon-message-mine]="message.userid == currentUserId" | ||||||
|                     [class.addon-message-not-mine]="message.userid != currentUserId" |                     [class.addon-message-not-mine]="message.userid != currentUserId" [class.addon-message-no-user]="!message.showUserData" | ||||||
|                     [class.addon-message-no-user]="!message.showUserData" |  | ||||||
|                     [@coreSlideInOut]="message.userid == currentUserId ? '' : 'fromLeft'"> |                     [@coreSlideInOut]="message.userid == currentUserId ? '' : 'fromLeft'"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <!-- User data. --> |                         <!-- User data. --> | ||||||
| @ -104,8 +105,7 @@ | |||||||
|             </ng-container> |             </ng-container> | ||||||
|         </ion-list> |         </ion-list> | ||||||
| 
 | 
 | ||||||
|         <core-empty-box *ngIf="!messages || messages.length <= 0" icon="far-comments" |         <core-empty-box *ngIf="!messages || messages.length <= 0" icon="far-comments" [message]="'addon.mod_chat.nomessages' | translate"> | ||||||
|             [message]="'addon.mod_chat.nomessages' | translate"> |  | ||||||
|         </core-empty-box> |         </core-empty-box> | ||||||
|     </core-loading> |     </core-loading> | ||||||
| </ion-content> | </ion-content> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.mod_chat.messages' | translate }}</h1> |             <h1>{{ 'addon.mod_chat.messages' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -75,8 +77,7 @@ | |||||||
| 
 | 
 | ||||||
|                 <ion-item *ngIf="!message.special" class="ion-text-wrap addon-message" |                 <ion-item *ngIf="!message.special" class="ion-text-wrap addon-message" | ||||||
|                     [class.addon-message-mine]="message.userid == currentUserId" |                     [class.addon-message-mine]="message.userid == currentUserId" | ||||||
|                     [class.addon-message-not-mine]="message.userid != currentUserId" |                     [class.addon-message-not-mine]="message.userid != currentUserId" [class.addon-message-no-user]="!message.showUserData"> | ||||||
|                     [class.addon-message-no-user]="!message.showUserData"> |  | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <!-- User data. --> |                         <!-- User data. --> | ||||||
|                         <h2 class="addon-message-user"> |                         <h2 class="addon-message-user"> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.mod_chat.chatreport' | translate }}</h1> |             <h1>{{ 'addon.mod_chat.chatreport' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -29,14 +29,10 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <!-- Activity availability messages --> |     <!-- Activity availability messages --> | ||||||
|     <ion-card class="core-info-card" *ngIf="choiceNotOpenYet"> |     <ion-card class="core-info-card" *ngIf="choiceNotOpenYet"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
| @ -54,8 +50,7 @@ | |||||||
|             <ion-label> |             <ion-label> | ||||||
|                 <p *ngIf="options.length"> |                 <p *ngIf="options.length"> | ||||||
|                     {{ 'addon.mod_choice.yourselection' | translate }} |                     {{ 'addon.mod_choice.yourselection' | translate }} | ||||||
|                     <core-format-text [text]="options[0].text" contextLevel="module" [contextInstanceId]="module.id" |                     <core-format-text [text]="options[0].text" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                         [courseId]="courseId"> |  | ||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                 </p> |                 </p> | ||||||
|                 <p>{{ 'addon.mod_choice.expired' | translate:{$a: closeTimeReadable} }}</p> |                 <p>{{ 'addon.mod_choice.expired' | translate:{$a: closeTimeReadable} }}</p> | ||||||
| @ -63,14 +58,6 @@ | |||||||
|         </ion-item> |         </ion-item> | ||||||
|     </ion-card> |     </ion-card> | ||||||
| 
 | 
 | ||||||
|     <!-- 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" aria-hidden="true"></ion-icon> |  | ||||||
|             <ion-label>{{ 'core.hasdatatosync' | translate:{$a: moduleName} }}</ion-label> |  | ||||||
|         </ion-item> |  | ||||||
|     </ion-card> |  | ||||||
| 
 |  | ||||||
|     <!-- Inform what will happen with the choices. --> |     <!-- Inform what will happen with the choices. --> | ||||||
|     <ion-card class="core-info-card" *ngIf="canEdit && publishInfo && options.length"> |     <ion-card class="core-info-card" *ngIf="canEdit && publishInfo && options.length"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
| @ -145,10 +132,12 @@ | |||||||
|                                 </p> |                                 </p> | ||||||
|                             </ion-label> |                             </ion-label> | ||||||
|                         </ion-item-divider> |                         </ion-item-divider> | ||||||
|                         <ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseId" |                         <ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseId" [userId]="user.userid" | ||||||
|                             [userId]="user.userid" [attr.aria-label]="user.fullname" class="ion-text-wrap"> |                             [attr.aria-label]="user.fullname" class="ion-text-wrap"> | ||||||
|                             <core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar> |                             <core-user-avatar [user]="user" slot="start" [courseId]="courseId"></core-user-avatar> | ||||||
|                             <ion-label><p>{{user.fullname}}</p></ion-label> |                             <ion-label> | ||||||
|  |                                 <p>{{user.fullname}}</p> | ||||||
|  |                             </ion-label> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                     </ion-item-group> |                     </ion-item-group> | ||||||
|                 </ion-col> |                 </ion-col> | ||||||
| @ -159,7 +148,9 @@ | |||||||
|     <ion-card class="core-info-card" *ngIf="!canSeeResults && !choiceNotOpenYet"> |     <ion-card class="core-info-card" *ngIf="!canSeeResults && !choiceNotOpenYet"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
|             <ion-icon name="fas-info-circle" slot="start" aria-hidden="true"></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-label> | ||||||
|  |                 <p>{{ 'addon.mod_choice.noresultsviewable' | translate }}</p> | ||||||
|  |             </ion-label> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|     </ion-card> |     </ion-card> | ||||||
| </core-loading> | </core-loading> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -4,28 +4,27 @@ | |||||||
|         <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|     </ion-button> |     </ion-button> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !(hasOffline || hasOfflineRatings) && isOnline" [priority]="700" |         <core-context-menu-item *ngIf="loaded && !(hasOffline || hasOfflineRatings) && isOnline" [priority]="700" | ||||||
|             [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" |             [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
|             [closeOnClick]="false"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600" |         <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600" | ||||||
|             [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" |             [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" | ||||||
|             [closeOnClick]="false"> |             [closeOnClick]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [priority]="500" *ngIf="canAdd" [content]="'addon.mod_data.addentries' | translate" |         <core-context-menu-item [priority]="500" *ngIf="canAdd" [content]="'addon.mod_data.addentries' | translate" iconAction="fas-plus" | ||||||
|             iconAction="fas-plus" (action)="gotoAddEntries()"> |             (action)="gotoAddEntries()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [priority]="400" *ngIf="firstEntry" [content]="'addon.mod_data.single' | translate" |         <core-context-menu-item [priority]="400" *ngIf="firstEntry" [content]="'addon.mod_data.single' | translate" iconAction="fas-file" | ||||||
|             iconAction="fas-file" (action)="gotoEntry(firstEntry)"> |             (action)="gotoEntry(firstEntry)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="300" [content]="prefetchText" (action)="prefetch($event)" |         <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="300" [content]="prefetchText" (action)="prefetch($event)" | ||||||
|             [iconAction]="prefetchStatusIcon" [closeOnClick]="false"> |             [iconAction]="prefetchStatusIcon" [closeOnClick]="false"> | ||||||
| @ -40,22 +39,10 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <!-- 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" aria-hidden="true"></ion-icon> |  | ||||||
|             <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label> |  | ||||||
|         </ion-item> |  | ||||||
|     </ion-card> |  | ||||||
| 
 |  | ||||||
|     <ion-item class="ion-text-wrap" *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)"> |     <ion-item class="ion-text-wrap" *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)"> | ||||||
|         <ion-label id="addon-data-groupslabel"> |         <ion-label id="addon-data-groupslabel"> | ||||||
|             <ng-container *ngIf="groupInfo.separateGroups">{{'core.groupsseparate' | translate }}</ng-container> |             <ng-container *ngIf="groupInfo.separateGroups">{{'core.groupsseparate' | translate }}</ng-container> | ||||||
|  | |||||||
| @ -1,9 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-title> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |  | ||||||
|         </ion-buttons> |  | ||||||
|             <h2>{{ 'addon.mod_data.search' | translate }}</h2> |             <h2>{{ 'addon.mod_data.search' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon> |                 <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon> | ||||||
| @ -20,14 +19,14 @@ | |||||||
|         <ion-list class="ion-no-margin"> |         <ion-list class="ion-no-margin"> | ||||||
|             <ion-item [hidden]="search.searchingAdvanced"> |             <ion-item [hidden]="search.searchingAdvanced"> | ||||||
|                 <ion-label class="sr-only">{{ 'addon.mod_data.search' | translate}}</ion-label> |                 <ion-label class="sr-only">{{ 'addon.mod_data.search' | translate}}</ion-label> | ||||||
|                 <ion-input type="text" placeholder="{{ 'addon.mod_data.search' | translate}}" |                 <ion-input type="text" placeholder="{{ 'addon.mod_data.search' | translate}}" [(ngModel)]="search.text" name="text" | ||||||
|                     [(ngModel)]="search.text" name="text" formControlName="text"> |                     formControlName="text"> | ||||||
|                 </ion-input> |                 </ion-input> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap"> | ||||||
|                 <ion-label position="stacked">{{ 'core.sortby' | translate }}</ion-label> |                 <ion-label position="stacked">{{ 'core.sortby' | translate }}</ion-label> | ||||||
|                 <ion-select interface="action-sheet" name="sortBy" formControlName="sortBy" |                 <ion-select interface="action-sheet" name="sortBy" formControlName="sortBy" [placeholder]="'core.sortby' | translate" | ||||||
|                     [placeholder]="'core.sortby' | translate" [interfaceOptions]="{header: 'core.sortby' | translate}"> |                     [interfaceOptions]="{header: 'core.sortby' | translate}"> | ||||||
|                     <optgroup *ngIf="fieldsArray.length" label="{{ 'addon.mod_data.fields' | translate }}"> |                     <optgroup *ngIf="fieldsArray.length" label="{{ 'addon.mod_data.fields' | translate }}"> | ||||||
|                         <ion-select-option *ngFor="let field of fieldsArray" [value]="field.id">{{field.name}}</ion-select-option> |                         <ion-select-option *ngFor="let field of fieldsArray" [value]="field.id">{{field.name}}</ion-select-option> | ||||||
|                     </optgroup> |                     </optgroup> | ||||||
| @ -42,7 +41,7 @@ | |||||||
|                     </optgroup> |                     </optgroup> | ||||||
|                 </ion-select> |                 </ion-select> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-list > |             <ion-list> | ||||||
|                 <ion-radio-group [(ngModel)]="search.sortDirection" name="sortDirection" formControlName="sortDirection"> |                 <ion-radio-group [(ngModel)]="search.sortDirection" name="sortDirection" formControlName="sortDirection"> | ||||||
|                     <ion-item> |                     <ion-item> | ||||||
|                         <ion-label>{{ 'addon.mod_data.ascending' | translate }}</ion-label> |                         <ion-label>{{ 'addon.mod_data.ascending' | translate }}</ion-label> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button *ngIf="entry" fill="clear" (click)="save($event)"> |             <ion-button *ngIf="entry" fill="clear" (click)="save($event)"> | ||||||
|                 {{ 'core.save' | translate }} |                 {{ 'core.save' | translate }} | ||||||
|  | |||||||
| @ -3,15 +3,16 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|     <ion-refresher slot="fixed" |     <ion-refresher slot="fixed" [disabled]="!entryLoaded || !(isPullingToRefresh || !renderingEntry && !loadingRating && !loadingComments)" | ||||||
|         [disabled]="!entryLoaded || !(isPullingToRefresh || !renderingEntry && !loadingRating && !loadingComments)" |  | ||||||
|         (ionRefresh)="refreshDatabase($event.target)"> |         (ionRefresh)="refreshDatabase($event.target)"> | ||||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|     </ion-refresher> |     </ion-refresher> | ||||||
| @ -40,23 +41,23 @@ | |||||||
|         <div class="addon-data-contents addon-data-entry addon-data-entries-{{database.id}}" *ngIf="database && entry"> |         <div class="addon-data-contents addon-data-entry addon-data-entries-{{database.id}}" *ngIf="database && entry"> | ||||||
|             <core-style [css]="database.csstemplate" prefix=".addon-data-entries-{{database.id}}"></core-style> |             <core-style [css]="database.csstemplate" prefix=".addon-data-entries-{{database.id}}"></core-style> | ||||||
| 
 | 
 | ||||||
|             <core-compile-html [text]="entryHtml" [jsData]="jsData" [extraImports]="extraImports" |             <core-compile-html [text]="entryHtml" [jsData]="jsData" [extraImports]="extraImports" (compiling)="setRenderingEntry($event)"> | ||||||
|                 (compiling)="setRenderingEntry($event)"></core-compile-html> |             </core-compile-html> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <core-rating-rate *ngIf="database && entry && ratingInfo && (!database.approval || entry.approved)" |         <core-rating-rate *ngIf="database && entry && ratingInfo && (!database.approval || entry.approved)" [ratingInfo]="ratingInfo" | ||||||
|             [ratingInfo]="ratingInfo" contextLevel="module" [instanceId]="database.coursemodule" [itemId]="entry.id" [itemSetId]="0" |             contextLevel="module" [instanceId]="database.coursemodule" [itemId]="entry.id" [itemSetId]="0" [courseId]="courseId" | ||||||
|             [courseId]="courseId" [aggregateMethod]="database.assessed" [scaleId]="database.scale" [userId]="entry.userid" |             [aggregateMethod]="database.assessed" [scaleId]="database.scale" [userId]="entry.userid" (onLoading)="setLoadingRating($event)" | ||||||
|             (onLoading)="setLoadingRating($event)" (onUpdate)="ratingUpdated()"> |             (onUpdate)="ratingUpdated()"> | ||||||
|         </core-rating-rate> |         </core-rating-rate> | ||||||
|         <core-rating-aggregate *ngIf="database && entry && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" |         <core-rating-aggregate *ngIf="database && entry && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" | ||||||
|             [instanceId]="database.coursemodule" [itemId]="entry.id" [courseId]="courseId" [aggregateMethod]="database.assessed" |             [instanceId]="database.coursemodule" [itemId]="entry.id" [courseId]="courseId" [aggregateMethod]="database.assessed" | ||||||
|             [scaleId]="database.scale"> |             [scaleId]="database.scale"> | ||||||
|         </core-rating-aggregate> |         </core-rating-aggregate> | ||||||
| 
 | 
 | ||||||
|         <core-comments *ngIf="database && database.comments && entry && entry.id > 0 && commentsEnabled" |         <core-comments *ngIf="database && database.comments && entry && entry.id > 0 && commentsEnabled" contextLevel="module" | ||||||
|             contextLevel="module" [instanceId]="database.coursemodule" component="mod_data" [itemId]="entry.id" |             [instanceId]="database.coursemodule" component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="courseId" | ||||||
|             area="database_entry" [courseId]="courseId" (onLoading)="setLoadingComments($event)" [showItem]="true"> |             (onLoading)="setLoadingComments($event)" [showItem]="true"> | ||||||
|         </core-comments> |         </core-comments> | ||||||
| 
 | 
 | ||||||
|         <ion-grid *ngIf="hasPrevious || hasNext"> |         <ion-grid *ngIf="hasPrevious || hasNext"> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -29,22 +29,18 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <core-tabs [hideUntil]="tabsReady" [selectedIndex]="firstSelectedTab"> |     <core-tabs [hideUntil]="tabsReady" [selectedIndex]="firstSelectedTab"> | ||||||
|         <core-tab [title]="'addon.mod_feedback.overview' | translate" id="overview" (ionSelect)="tabChanged('overview')"> |         <core-tab [title]="'addon.mod_feedback.overview' | translate" id="overview" (ionSelect)="tabChanged('overview')"> | ||||||
|             <ng-template> |             <ng-template> | ||||||
|                 <ng-container *ngTemplateOutlet="tabOverview"></ng-container> |                 <ng-container *ngTemplateOutlet="tabOverview"></ng-container> | ||||||
|             </ng-template> |             </ng-template> | ||||||
|         </core-tab> |         </core-tab> | ||||||
|         <core-tab *ngIf="showAnalysis && access && access.canviewreports" id="analysis" |         <core-tab *ngIf="showAnalysis && access && access.canviewreports" id="analysis" [title]="'addon.mod_feedback.analysis' | translate" | ||||||
|             [title]="'addon.mod_feedback.analysis' | translate" (ionSelect)="tabChanged('analysis')"> |             (ionSelect)="tabChanged('analysis')"> | ||||||
|             <ng-template> |             <ng-template> | ||||||
|                 <ng-container *ngTemplateOutlet="tabAnalysis"></ng-container> |                 <ng-container *ngTemplateOutlet="tabAnalysis"></ng-container> | ||||||
|             </ng-template> |             </ng-template> | ||||||
| @ -73,10 +69,8 @@ | |||||||
|                 </ion-select-option> |                 </ion-select-option> | ||||||
|             </ion-select> |             </ion-select> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|         <ion-item class="ion-text-wrap" (click)="openRespondents()" |         <ion-item class="ion-text-wrap" (click)="openRespondents()" [class.hide-detail]="!(access.canviewreports && completedCount > 0)" | ||||||
|             [class.hide-detail]="!(access.canviewreports && completedCount > 0)" |             detail="true" [button]="access.canviewreports && completedCount > 0"> | ||||||
|             detail="true" |  | ||||||
|             [button]="access.canviewreports && completedCount > 0"> |  | ||||||
|             <ion-label> |             <ion-label> | ||||||
|                 <h2>{{ 'addon.mod_feedback.completed_feedbacks' | translate }}</h2> |                 <h2>{{ 'addon.mod_feedback.completed_feedbacks' | translate }}</h2> | ||||||
|             </ion-label> |             </ion-label> | ||||||
| @ -87,8 +81,8 @@ | |||||||
|                 </span> |                 </span> | ||||||
|             </ion-badge> |             </ion-badge> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|         <ion-item class="ion-text-wrap" *ngIf="!access.isanonymous && access.canviewreports" (click)="openNonRespondents()" |         <ion-item class="ion-text-wrap" *ngIf="!access.isanonymous && access.canviewreports" (click)="openNonRespondents()" detail="true" | ||||||
|             detail="true" button> |             button> | ||||||
|             <ion-label> |             <ion-label> | ||||||
|                 <h2>{{ 'addon.mod_feedback.show_nonrespondents' | translate }}</h2> |                 <h2>{{ 'addon.mod_feedback.show_nonrespondents' | translate }}</h2> | ||||||
|             </ion-label> |             </ion-label> | ||||||
| @ -112,14 +106,6 @@ | |||||||
|     <core-loading [hideUntil]="tabsLoaded.overview"> |     <core-loading [hideUntil]="tabsLoaded.overview"> | ||||||
|         <ng-container *ngTemplateOutlet="basicInfo"></ng-container> |         <ng-container *ngTemplateOutlet="basicInfo"></ng-container> | ||||||
| 
 | 
 | ||||||
|         <!-- 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" 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-card class="core-info-card" *ngIf="access && access.cancomplete && !access.isopen"> | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-icon name="fas-question-circle" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-question-circle" slot="start" aria-hidden="true"></ion-icon> | ||||||
| @ -212,8 +198,8 @@ | |||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </p> |                         </p> | ||||||
|                         <p> |                         <p> | ||||||
|                             <core-format-text [component]="component" [componentId]="componentId" [text]="item.label" |                             <core-format-text [component]="component" [componentId]="componentId" [text]="item.label" contextLevel="module" | ||||||
|                                 contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                                 [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </p> |                         </p> | ||||||
|                         <ng-container [ngSwitch]="item.templateName"> |                         <ng-container [ngSwitch]="item.templateName"> | ||||||
| @ -232,8 +218,7 @@ | |||||||
|                             </ng-container> |                             </ng-container> | ||||||
|                             <ng-container *ngSwitchCase="'chart'"> |                             <ng-container *ngSwitchCase="'chart'"> | ||||||
|                                 <core-chart [type]="item.chartType" [data]="item.chartData" [labels]="item.labels" height="300" |                                 <core-chart [type]="item.chartType" [data]="item.chartData" [labels]="item.labels" height="300" | ||||||
|                                     contextLevel="module" [contextInstanceId]="module.id" [wsNotFiltered]="true" |                                     contextLevel="module" [contextInstanceId]="module.id" [wsNotFiltered]="true" [courseId]="courseId"> | ||||||
|                                     [courseId]="courseId"> |  | ||||||
|                                 </core-chart> |                                 </core-chart> | ||||||
|                                 <p *ngIf="item.average"> |                                 <p *ngIf="item.average"> | ||||||
|                                     {{ 'addon.mod_feedback.average' | translate }}: {{item.average | number : '1.2-2'}} |                                     {{ 'addon.mod_feedback.average' | translate }}: {{item.average | number : '1.2-2'}} | ||||||
|  | |||||||
| @ -3,12 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|         <h1> |         <ion-title> | ||||||
|             <ng-container *ngIf="attempt">{{ attempt.fullname }}</ng-container> |             <h1 *ngIf="attempt">{{ attempt.fullname }}</h1> | ||||||
|             <ng-container *ngIf="anonAttempt"> |             <h1 *ngIf="anonAttempt"> | ||||||
|                 {{ 'addon.mod_feedback.response_nr' |translate }}: {{anonAttempt.number}} |                 {{ 'addon.mod_feedback.response_nr' |translate }}: {{anonAttempt.number}} | ||||||
|             </ng-container> |  | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -30,7 +30,7 @@ | |||||||
|                         ({{ 'addon.mod_feedback.anonymous' |translate }}) |                         ({{ 'addon.mod_feedback.anonymous' |translate }}) | ||||||
|                     </h2> |                     </h2> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item > |             </ion-item> | ||||||
|             <ng-container *ngIf="items && items.length"> |             <ng-container *ngIf="items && items.length"> | ||||||
|                 <ng-container *ngFor="let item of items"> |                 <ng-container *ngFor="let item of items"> | ||||||
|                     <core-spacer *ngIf="item.typ == 'pagebreak'"></core-spacer> |                     <core-spacer *ngIf="item.typ == 'pagebreak'"></core-spacer> | ||||||
| @ -38,8 +38,8 @@ | |||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2 *ngIf="item.name" [core-mark-required]="item.required"> |                             <h2 *ngIf="item.name" [core-mark-required]="item.required"> | ||||||
|                                 <span *ngIf="feedback!.autonumbering && item.itemnumber">{{item.itemnumber}}. </span> |                                 <span *ngIf="feedback!.autonumbering && item.itemnumber">{{item.itemnumber}}. </span> | ||||||
|                                 <core-format-text [component]="component" [componentId]="cmId" [text]="item.name" |                                 <core-format-text [component]="component" [componentId]="cmId" [text]="item.name" contextLevel="module" | ||||||
|                                     contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                                     [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                                 </core-format-text> |                                 </core-format-text> | ||||||
|                             </h2> |                             </h2> | ||||||
|                             <p *ngIf="item.submittedValue"> |                             <p *ngIf="item.submittedValue"> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -28,22 +30,20 @@ | |||||||
|                             <ion-label [position]="item.hasTextInput ? 'stacked' : undefined"> |                             <ion-label [position]="item.hasTextInput ? 'stacked' : undefined"> | ||||||
|                                 <p *ngIf="item.name" [core-mark-required]="item.required"> |                                 <p *ngIf="item.name" [core-mark-required]="item.required"> | ||||||
|                                     <span *ngIf="feedback!.autonumbering && item.itemnumber">{{item.itemnumber}}. </span> |                                     <span *ngIf="feedback!.autonumbering && item.itemnumber">{{item.itemnumber}}. </span> | ||||||
|                                     <core-format-text [component]="component" [componentId]="cmId" [text]="item.name" |                                     <core-format-text [component]="component" [componentId]="cmId" [text]="item.name" contextLevel="module" | ||||||
|                                         contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId" [wsNotFiltered]="true"> |                                         [contextInstanceId]="cmId" [courseId]="courseId" [wsNotFiltered]="true"> | ||||||
|                                     </core-format-text> |                                     </core-format-text> | ||||||
|                                     <span *ngIf="item.postfix" class="addon-mod_feedback-postfix">{{item.postfix}}</span> |                                     <span *ngIf="item.postfix" class="addon-mod_feedback-postfix">{{item.postfix}}</span> | ||||||
|                                 </p> |                                 </p> | ||||||
|                                 <p *ngIf="item.templateName == 'label'"> |                                 <p *ngIf="item.templateName == 'label'"> | ||||||
|                                     <core-format-text [component]="component" [componentId]="cmId" |                                     <core-format-text [component]="component" [componentId]="cmId" [text]="item.presentation" | ||||||
|                                         [text]="item.presentation" contextLevel="module" [contextInstanceId]="cmId" |                                         contextLevel="module" [contextInstanceId]="cmId" [wsNotFiltered]="true" [courseId]="courseId"> | ||||||
|                                         [wsNotFiltered]="true" [courseId]="courseId"> |  | ||||||
|                                     </core-format-text> |                                     </core-format-text> | ||||||
|                                 </p> |                                 </p> | ||||||
|                             </ion-label> |                             </ion-label> | ||||||
| 
 | 
 | ||||||
|                             <ion-input *ngIf="item.templateName == 'textfield'" type="text" [(ngModel)]="item.value" |                             <ion-input *ngIf="item.templateName == 'textfield'" type="text" [(ngModel)]="item.value" autocorrect="off" | ||||||
|                                 autocorrect="off" name="{{item.typ}}_{{item.id}}" maxlength="{{item.length}}" |                                 name="{{item.typ}}_{{item.id}}" maxlength="{{item.length}}" [required]="item.required"> | ||||||
|                                 [required]="item.required"> |  | ||||||
|                             </ion-input> |                             </ion-input> | ||||||
| 
 | 
 | ||||||
|                             <ng-container *ngIf="item.templateName == 'numeric'"> |                             <ng-container *ngIf="item.templateName == 'numeric'"> | ||||||
| @ -56,8 +56,8 @@ | |||||||
|                                 </ion-text> |                                 </ion-text> | ||||||
|                             </ng-container> |                             </ng-container> | ||||||
| 
 | 
 | ||||||
|                             <ion-textarea *ngIf="item.templateName == 'textarea'" [required]="item.required" |                             <ion-textarea *ngIf="item.templateName == 'textarea'" [required]="item.required" name="{{item.typ}}_{{item.id}}" | ||||||
|                                 name="{{item.typ}}_{{item.id}}" [(ngModel)]="item.value"> |                                 [(ngModel)]="item.value"> | ||||||
|                             </ion-textarea> |                             </ion-textarea> | ||||||
| 
 | 
 | ||||||
|                             <ion-select *ngIf="item.templateName == 'multichoice-d'" [required]="item.required" |                             <ion-select *ngIf="item.templateName == 'multichoice-d'" [required]="item.required" | ||||||
| @ -65,20 +65,18 @@ | |||||||
|                                 [interfaceOptions]="{header: item.name}"> |                                 [interfaceOptions]="{header: item.name}"> | ||||||
|                                 <ion-select-option *ngFor="let option of item.choices" [value]="option.value"> |                                 <ion-select-option *ngFor="let option of item.choices" [value]="option.value"> | ||||||
|                                     <core-format-text [component]="component" [componentId]="cmId" [text]="option.label" |                                     <core-format-text [component]="component" [componentId]="cmId" [text]="option.label" | ||||||
|                                         contextLevel="module" [contextInstanceId]="cmId" [wsNotFiltered]="true" |                                         contextLevel="module" [contextInstanceId]="cmId" [wsNotFiltered]="true" [courseId]="courseId"> | ||||||
|                                         [courseId]="courseId"> |  | ||||||
|                                     </core-format-text> |                                     </core-format-text> | ||||||
|                                 </ion-select-option> |                                 </ion-select-option> | ||||||
|                             </ion-select> |                             </ion-select> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
| 
 | 
 | ||||||
|                         <ion-radio-group *ngIf="item.templateName == 'multichoice-r'" [(ngModel)]="item.value" |                         <ion-radio-group *ngIf="item.templateName == 'multichoice-r'" [(ngModel)]="item.value" [required]="item.required" | ||||||
|                             [required]="item.required" name="{{item.typ}}_{{item.id}}"> |                             name="{{item.typ}}_{{item.id}}"> | ||||||
|                             <ion-item *ngFor="let option of item.choices"> |                             <ion-item *ngFor="let option of item.choices"> | ||||||
|                                 <ion-label> |                                 <ion-label> | ||||||
|                                     <core-format-text [component]="component" [componentId]="cmId" |                                     <core-format-text [component]="component" [componentId]="cmId" [text]="option.label" | ||||||
|                                         [text]="option.label" contextLevel="module" [contextInstanceId]="cmId" |                                         contextLevel="module" [contextInstanceId]="cmId" [wsNotFiltered]="true" [courseId]="courseId"> | ||||||
|                                         [wsNotFiltered]="true" [courseId]="courseId"> |  | ||||||
|                                     </core-format-text> |                                     </core-format-text> | ||||||
|                                 </ion-label> |                                 </ion-label> | ||||||
|                                 <ion-radio slot="start" [value]="option.value"></ion-radio> |                                 <ion-radio slot="start" [value]="option.value"></ion-radio> | ||||||
| @ -89,19 +87,18 @@ | |||||||
|                             <ion-item *ngFor="let option of item.choices"> |                             <ion-item *ngFor="let option of item.choices"> | ||||||
|                                 <ion-label> |                                 <ion-label> | ||||||
|                                     <core-format-text [component]="component" [componentId]="cmId" [text]="option.label" |                                     <core-format-text [component]="component" [componentId]="cmId" [text]="option.label" | ||||||
|                                         contextLevel="module" [contextInstanceId]="cmId" [wsNotFiltered]="true" |                                         contextLevel="module" [contextInstanceId]="cmId" [wsNotFiltered]="true" [courseId]="courseId"> | ||||||
|                                         [courseId]="courseId"> |  | ||||||
|                                     </core-format-text> |                                     </core-format-text> | ||||||
|                                 </ion-label> |                                 </ion-label> | ||||||
|                                 <ion-checkbox [required]="item.required" name="{{item.typ}}_{{item.id}}" |                                 <ion-checkbox [required]="item.required" name="{{item.typ}}_{{item.id}}" [(ngModel)]="option.checked" | ||||||
|                                     [(ngModel)]="option.checked" value="option.value"> |                                     value="option.value"> | ||||||
|                                 </ion-checkbox> |                                 </ion-checkbox> | ||||||
|                             </ion-item> |                             </ion-item> | ||||||
|                         </ng-container> |                         </ng-container> | ||||||
| 
 | 
 | ||||||
|                         <ng-container *ngIf="item.templateName == 'captcha'"> |                         <ng-container *ngIf="item.templateName == 'captcha'"> | ||||||
|                             <core-recaptcha *ngIf="!preview && !offline" [publicKey]="item.captcha.recaptchapublickey" |                             <core-recaptcha *ngIf="!preview && !offline" [publicKey]="item.captcha.recaptchapublickey" [model]="item" | ||||||
|                                 [model]="item" modelValueName="value"> |                                 modelValueName="value"> | ||||||
|                             </core-recaptcha> |                             </core-recaptcha> | ||||||
|                             <div *ngIf="!preview && (!item.captcha || offline)" class="core-warning-card"> |                             <div *ngIf="!preview && (!item.captcha || offline)" class="core-warning-card"> | ||||||
|                                 <ion-item> |                                 <ion-item> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.mod_feedback.responses' |translate }}</h1> |             <h1>{{ 'addon.mod_feedback.responses' |translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -27,7 +29,9 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <ion-item-divider> |             <ion-item-divider> | ||||||
|                 <ion-label><h2>{{ 'addon.mod_feedback.non_respondents_students' | translate : {$a: total } }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.mod_feedback.non_respondents_students' | translate : {$a: total } }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ng-container *ngIf="total > 0"> |             <ng-container *ngIf="total > 0"> | ||||||
|                 <ion-item *ngFor="let user of users" class="ion-text-wrap"> |                 <ion-item *ngFor="let user of users" class="ion-text-wrap"> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.mod_feedback.responses' |translate }}</h1> |             <h1>{{ 'addon.mod_feedback.responses' |translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -48,7 +50,9 @@ | |||||||
|                         {{ 'core.loadmore' | translate }} |                         {{ 'core.loadmore' | translate }} | ||||||
|                     </ion-button> |                     </ion-button> | ||||||
|                     <ion-item *ngIf="responses.responses.canLoadMore && loadingMore" class="ion-text-center"> |                     <ion-item *ngIf="responses.responses.canLoadMore && loadingMore" class="ion-text-center"> | ||||||
|                         <ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label> |                         <ion-label> | ||||||
|  |                             <ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||||
|  |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ng-container> |                 </ng-container> | ||||||
| 
 | 
 | ||||||
| @ -71,7 +75,9 @@ | |||||||
|                         {{ 'core.loadmore' | translate }} |                         {{ 'core.loadmore' | translate }} | ||||||
|                     </ion-button> |                     </ion-button> | ||||||
|                     <ion-item *ngIf="responses.anonResponses.canLoadMore && loadingMore" class="ion-text-center"> |                     <ion-item *ngIf="responses.anonResponses.canLoadMore && loadingMore" class="ion-text-center"> | ||||||
|                         <ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label> |                         <ion-label> | ||||||
|  |                             <ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||||
|  |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ng-container> |                 </ng-container> | ||||||
|             </ion-list> |             </ion-list> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|              iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="!subfolder" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="!subfolder" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -26,14 +26,10 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info *ngIf="!subfolder" [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <ion-list *ngIf="contents && (contents.files.length + contents.folders.length > 0)"> |     <ion-list *ngIf="contents && (contents.files.length + contents.folders.length > 0)"> | ||||||
|         <ng-container *ngFor="let folder of contents.folders"> |         <ng-container *ngFor="let folder of contents.folders"> | ||||||
|             <ion-item class="item-file" (click)="openFolder(folder)" detail="true" button> |             <ion-item class="item-file" (click)="openFolder(folder)" detail="true" button> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -1,38 +1,30 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" iconAction="fas-external-link-alt" |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|             [showBrowserWarning]="false"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item |         <core-context-menu-item *ngIf="discussions.loaded && !(hasOffline || hasOfflineRatings) && isOnline" [priority]="700" | ||||||
|             *ngIf="discussions.loaded && !(hasOffline || hasOfflineRatings) && isOnline" |             [content]="'addon.mod_forum.refreshdiscussions' | translate" [iconAction]="refreshIcon" [closeOnClick]="false" | ||||||
|             [priority]="700" [content]="'addon.mod_forum.refreshdiscussions' | translate" [iconAction]="refreshIcon" [closeOnClick]="false" |  | ||||||
|             (action)="doRefresh(null, $event)"> |             (action)="doRefresh(null, $event)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item |         <core-context-menu-item *ngIf="discussions.loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600" | ||||||
|             *ngIf="discussions.loaded && (hasOffline || hasOfflineRatings) && isOnline" |             [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false" | ||||||
|             [priority]="600" [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false" |  | ||||||
|             (action)="doRefresh(null, $event, true)"> |             (action)="doRefresh(null, $event, true)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="prefetchStatusIcon" |         <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" [iconAction]="prefetchStatusIcon" | ||||||
|             [priority]="500" [content]="prefetchText" [iconAction]="prefetchStatusIcon" [closeOnClick]="false" |             [closeOnClick]="false" (action)="prefetch($event)"> | ||||||
|             (action)="prefetch($event)"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="size" |         <core-context-menu-item *ngIf="size" iconDescription="fas-archive" iconAction="fas-trash" [priority]="400" | ||||||
|             iconDescription="fas-archive" iconAction="fas-trash" |             [content]="'core.clearstoreddata' | translate:{$a: size}" [closeOnClick]="false" (action)="removeFiles($event)"> | ||||||
|             [priority]="400" [content]="'core.clearstoreddata' | translate:{$a: size}" [closeOnClick]="false" |  | ||||||
|             (action)="removeFiles($event)"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="sortingAvailable" |         <core-context-menu-item *ngIf="sortingAvailable" iconAction="fas-sort" [priority]="300" [content]="'core.sort' | translate" | ||||||
|             iconAction="fas-sort" |  | ||||||
|             [priority]="300" [content]="'core.sort' | translate" |  | ||||||
|             (action)="showSortOrderSelector()"> |             (action)="showSortOrderSelector()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|     </core-context-menu> |     </core-context-menu> | ||||||
| @ -46,22 +38,15 @@ | |||||||
| 
 | 
 | ||||||
|     <core-loading [hideUntil]="discussions.loaded"> |     <core-loading [hideUntil]="discussions.loaded"> | ||||||
|         <!-- Activity info. --> |         <!-- Activity info. --> | ||||||
|         <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |         <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" | ||||||
|             (completionChanged)="onCompletionChange()"> |             [description]="forum && forum.type != 'single' && description" [component]="component" [componentId]="componentId" | ||||||
|         </core-course-module-info> |             [courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings"> | ||||||
| 
 |  | ||||||
|         <core-course-module-description *ngIf="forum && forum.type != 'single'" |  | ||||||
|             [description]="description" [component]="component" [componentId]="componentId" [note]="descriptionNote" |  | ||||||
|             contextLevel="module" [contextInstanceId]="module && module.id" [courseId]="courseId"> |  | ||||||
|         </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|         <!-- Forum discussions found to be synchronized --> |  | ||||||
|         <ion-card class="core-warning-card" *ngIf="hasOffline || hasOfflineRatings"> |  | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |                 <ion-label> | ||||||
|                 <ion-label>{{ 'core.hasdatatosync' | translate:{$a: moduleName} }}</ion-label> |                     {{descriptionNote}} | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|         <!-- Cut-off date or due date message --> |         <!-- Cut-off date or due date message --> | ||||||
|         <ion-card class="core-info-card" *ngIf="availabilityMessage"> |         <ion-card class="core-info-card" *ngIf="availabilityMessage"> | ||||||
| @ -72,23 +57,17 @@ | |||||||
|         </ion-card> |         </ion-card> | ||||||
| 
 | 
 | ||||||
|         <ng-container *ngIf="forum"> |         <ng-container *ngIf="forum"> | ||||||
|             <core-empty-box *ngIf="discussions.empty" icon="far-comments" |             <core-empty-box *ngIf="discussions.empty" icon="far-comments" [message]="'addon.mod_forum.forumnodiscussionsyet' | translate"> | ||||||
|                 [message]="'addon.mod_forum.forumnodiscussionsyet' | translate"> |  | ||||||
|             </core-empty-box> |             </core-empty-box> | ||||||
| 
 | 
 | ||||||
|             <div *ngIf="!discussions.empty && sortingAvailable && selectedSortOrder" class="ion-text-wrap"> |             <div *ngIf="!discussions.empty && sortingAvailable && selectedSortOrder" class="ion-text-wrap"> | ||||||
|                 <core-combobox |                 <core-combobox [modalOptions]="sortOrderSelectorModalOptions" listboxId="addon-mod-forum-sort-selector" | ||||||
|                     [modalOptions]="sortOrderSelectorModalOptions" |                     [label]="('core.sort' | translate)" (onChange)="setSortOrder($event)" [selection]="selectedSortOrder.label | translate" | ||||||
|                     listboxId="addon-mod-forum-sort-selector" |  | ||||||
|                     [label]="('core.sort' | translate)" |  | ||||||
|                     (onChange)="setSortOrder($event)" |  | ||||||
|                     [selection]="selectedSortOrder.label | translate" |  | ||||||
|                     interface="modal"> |                     interface="modal"> | ||||||
|                 </core-combobox> |                 </core-combobox> | ||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
|             <ion-item *ngFor="let discussion of discussions.items" |             <ion-item *ngFor="let discussion of discussions.items" class="addon-mod-forum-discussion" detail="true" | ||||||
|                 class="addon-mod-forum-discussion" detail="true" |  | ||||||
|                 [lines]="discussion.groupname && 'none'" [attr.aria-current]="discussions.getItemAriaCurrent(discussion)" |                 [lines]="discussion.groupname && 'none'" [attr.aria-current]="discussions.getItemAriaCurrent(discussion)" | ||||||
|                 (click)="discussions.select(discussion)" button> |                 (click)="discussions.select(discussion)" button> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
| @ -98,15 +77,12 @@ | |||||||
|                                 [attr.aria-label]="'addon.mod_forum.discussionpinned' | translate"></ion-icon> |                                 [attr.aria-label]="'addon.mod_forum.discussionpinned' | translate"></ion-icon> | ||||||
|                             <ion-icon name="fas-star" class="addon-forum-star" *ngIf="!discussion.pinned && discussion.starred" |                             <ion-icon name="fas-star" class="addon-forum-star" *ngIf="!discussion.pinned && discussion.starred" | ||||||
|                                 [attr.aria-label]="'addon.mod_forum.favourites' | translate"></ion-icon> |                                 [attr.aria-label]="'addon.mod_forum.favourites' | translate"></ion-icon> | ||||||
|                             <core-format-text |                             <core-format-text [text]="discussion.subject" contextLevel="module" [contextInstanceId]="module && module.id" | ||||||
|                                 [text]="discussion.subject" |                                 [courseId]="courseId"> | ||||||
|                                 contextLevel="module" [contextInstanceId]="module && module.id" [courseId]="courseId"> |  | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </p> |                         </p> | ||||||
|                         <ion-button *ngIf="canPin || discussion.canlock || discussion.canfavourite" |                         <ion-button *ngIf="canPin || discussion.canlock || discussion.canfavourite" fill="clear" color="dark" | ||||||
|                             fill="clear" color="dark" |                             [attr.aria-label]="('core.displayoptions' | translate)" (click)="showOptionsMenu($event, discussion)"> | ||||||
|                             [attr.aria-label]="('core.displayoptions' | translate)" |  | ||||||
|                             (click)="showOptionsMenu($event, discussion)"> |  | ||||||
|                             <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"> |                             <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"> | ||||||
|                             </ion-icon> |                             </ion-icon> | ||||||
|                         </ion-button> |                         </ion-button> | ||||||
| @ -158,8 +134,7 @@ | |||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <core-infinite-loading |             <core-infinite-loading [enabled]="discussions.onlineLoaded && !discussions.completed" [error]="discussions.fetchFailed" | ||||||
|                 [enabled]="discussions.onlineLoaded && !discussions.completed" [error]="discussions.fetchFailed" |  | ||||||
|                 (action)="fetchMoreDiscussions($event)"> |                 (action)="fetchMoreDiscussions($event)"> | ||||||
|             </core-infinite-loading> |             </core-infinite-loading> | ||||||
|         </ng-container> |         </ng-container> | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2 id="addon-mod-forum-sort-order-label">{{ 'core.sort' | translate }}</h2> |             <h2 id="addon-mod-forum-sort-order-label">{{ 'core.sort' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-times" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="startingPost"> |             <h1 *ngIf="startingPost"> | ||||||
|                 <core-format-text contextLevel="module" [text]="startingPost.subject" [contextInstanceId]="cmId" [courseId]="courseId"> |                 <core-format-text contextLevel="module" [text]="startingPost.subject" [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The context menu will be added in here. --> |             <!-- The context menu will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
| @ -14,48 +16,41 @@ | |||||||
| </ion-header> | </ion-header> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="discussionLoaded && !postHasOffline && isOnline" |         <core-context-menu-item *ngIf="discussionLoaded && !postHasOffline && isOnline" [priority]="650" | ||||||
|             [priority]="650" [content]="'addon.mod_forum.refreshposts' | translate" [iconAction]="refreshIcon" [closeOnClick]="false" |             [content]="'addon.mod_forum.refreshposts' | translate" [iconAction]="refreshIcon" [closeOnClick]="false" | ||||||
|             (action)="doRefresh(null, $event)"> |             (action)="doRefresh(null, $event)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="discussionLoaded && isMobile && postHasOffline && isOnline" |         <core-context-menu-item *ngIf="discussionLoaded && isMobile && postHasOffline && isOnline" [priority]="550" | ||||||
|             [priority]="550" [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false" |             [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false" | ||||||
|             (action)="doRefresh(null, $event, true)"> |             (action)="doRefresh(null, $event, true)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="sort == 'flat-oldest'" |         <core-context-menu-item [hidden]="sort == 'flat-oldest'" [priority]="500" | ||||||
|             [priority]="500" [content]="'addon.mod_forum.modeflatoldestfirst' | translate" iconAction="fas-arrow-down" |             [content]="'addon.mod_forum.modeflatoldestfirst' | translate" iconAction="fas-arrow-down" (action)="changeSort('flat-oldest')"> | ||||||
|             (action)="changeSort('flat-oldest')"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="sort == 'flat-newest'" |         <core-context-menu-item [hidden]="sort == 'flat-newest'" [priority]="450" | ||||||
|             [priority]="450" [content]="'addon.mod_forum.modeflatnewestfirst' | translate" iconAction="fas-arrow-up" |             [content]="'addon.mod_forum.modeflatnewestfirst' | translate" iconAction="fas-arrow-up" (action)="changeSort('flat-newest')"> | ||||||
|             (action)="changeSort('flat-newest')"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="sort == 'nested'" |         <core-context-menu-item [hidden]="sort == 'nested'" [priority]="400" [content]="'addon.mod_forum.modenested' | translate" | ||||||
|             [priority]="400" [content]="'addon.mod_forum.modenested' | translate" iconAction="fas-exchange-alt" |             iconAction="fas-exchange-alt" (action)="changeSort('nested')"> | ||||||
|             (action)="changeSort('nested')"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="!discussion || !discussion.canlock || discussion.locked" |         <core-context-menu-item [hidden]="!discussion || !discussion.canlock || discussion.locked" [priority]="300" | ||||||
|             [priority]="300" [content]="'addon.mod_forum.lockdiscussion' | translate" iconAction="fas-lock" |             [content]="'addon.mod_forum.lockdiscussion' | translate" iconAction="fas-lock" (action)="setLockState(true)"> | ||||||
|             (action)="setLockState(true)"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="!discussion || !discussion.canlock || !discussion.locked" |         <core-context-menu-item [hidden]="!discussion || !discussion.canlock || !discussion.locked" [priority]="300" | ||||||
|             [priority]="300" [content]="'addon.mod_forum.unlockdiscussion' | translate" iconAction="fas-unlock" |             [content]="'addon.mod_forum.unlockdiscussion' | translate" iconAction="fas-unlock" (action)="setLockState(false)"> | ||||||
|             (action)="setLockState(false)"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="!discussion || !canPin || discussion.pinned" |         <core-context-menu-item [hidden]="!discussion || !canPin || discussion.pinned" [priority]="250" | ||||||
|             [priority]="250" [content]="'addon.mod_forum.pindiscussion' | translate" iconAction="fas-map-pin" |             [content]="'addon.mod_forum.pindiscussion' | translate" iconAction="fas-map-pin" (action)="setPinState(true)"> | ||||||
|             (action)="setPinState(true)"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="!discussion || !canPin || !discussion.pinned" |         <core-context-menu-item [hidden]="!discussion || !canPin || !discussion.pinned" [priority]="250" | ||||||
|             [priority]="250" [content]="'addon.mod_forum.unpindiscussion' | translate" [iconSlash]="true" iconAction="fas-map-pin" |             [content]="'addon.mod_forum.unpindiscussion' | translate" [iconSlash]="true" iconAction="fas-map-pin" | ||||||
|             (action)="setPinState(false)"> |             (action)="setPinState(false)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="!discussion || !discussion.canfavourite || discussion.starred" |         <core-context-menu-item [hidden]="!discussion || !discussion.canfavourite || discussion.starred" [priority]="200" | ||||||
|             [priority]="200" [content]="'addon.mod_forum.addtofavourites' | translate" iconAction="fas-star" |             [content]="'addon.mod_forum.addtofavourites' | translate" iconAction="fas-star" (action)="toggleFavouriteState(true)"> | ||||||
|             (action)="toggleFavouriteState(true)"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [hidden]="!discussion || !discussion.canfavourite || !discussion.starred" |         <core-context-menu-item [hidden]="!discussion || !discussion.canfavourite || !discussion.starred" [priority]="200" | ||||||
|             [priority]="200" [content]="'addon.mod_forum.removefromfavourites' | translate" iconAction="fas-star" [iconSlash]="true" |             [content]="'addon.mod_forum.removefromfavourites' | translate" iconAction="fas-star" [iconSlash]="true" | ||||||
|             (action)="toggleFavouriteState(false)"> |             (action)="toggleFavouriteState(false)"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|     </core-context-menu> |     </core-context-menu> | ||||||
| @ -90,25 +85,20 @@ | |||||||
|         </ion-card> |         </ion-card> | ||||||
| 
 | 
 | ||||||
|         <div *ngIf="startingPost" class="ion-margin-bottom"> |         <div *ngIf="startingPost" class="ion-margin-bottom"> | ||||||
|             <addon-mod-forum-post |             <addon-mod-forum-post [post]="startingPost" [discussion]="discussion" [courseId]="courseId" [highlight]="true" | ||||||
|                 [post]="startingPost" [discussion]="discussion" [courseId]="courseId" [highlight]="true" |                 [discussionId]="discussionId" [component]="component" [componentId]="cmId" [formData]="formData" | ||||||
|                 [discussionId]="discussionId" [component]="component" [componentId]="cmId" |                 [originalData]="originalData" [forum]="forum" [accessInfo]="accessInfo" [trackPosts]="trackPosts" [ratingInfo]="ratingInfo" | ||||||
|                 [formData]="formData" [originalData]="originalData" [forum]="forum" [accessInfo]="accessInfo" |                 [leavingPage]="leavingPage" (onPostChange)="postListChanged()"> | ||||||
|                 [trackPosts]="trackPosts" [ratingInfo]="ratingInfo" [leavingPage]="leavingPage" |  | ||||||
|                 (onPostChange)="postListChanged()"> |  | ||||||
|             </addon-mod-forum-post> |             </addon-mod-forum-post> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <ion-card *ngIf="sort != 'nested'"> |         <ion-card *ngIf="sort != 'nested'"> | ||||||
|             <ng-container *ngFor="let post of posts; first as first"> |             <ng-container *ngFor="let post of posts; first as first"> | ||||||
|                 <core-spacer *ngIf="!first"></core-spacer> |                 <core-spacer *ngIf="!first"></core-spacer> | ||||||
|                 <addon-mod-forum-post |                 <addon-mod-forum-post [post]="post" [courseId]="courseId" [discussionId]="discussionId" [component]="component" | ||||||
|                     [post]="post" [courseId]="courseId" [discussionId]="discussionId" |                     [componentId]="cmId" [formData]="formData" [originalData]="originalData" [parentSubject]="postSubjects[post.parentid]" | ||||||
|                     [component]="component" [componentId]="cmId" [formData]="formData" |  | ||||||
|                     [originalData]="originalData" [parentSubject]="postSubjects[post.parentid]" |  | ||||||
|                     [forum]="forum" [accessInfo]="accessInfo" [trackPosts]="trackPosts" [ratingInfo]="ratingInfo" |                     [forum]="forum" [accessInfo]="accessInfo" [trackPosts]="trackPosts" [ratingInfo]="ratingInfo" | ||||||
|                     [leavingPage]="leavingPage" |                     [leavingPage]="leavingPage" (onPostChange)="postListChanged()"> | ||||||
|                     (onPostChange)="postListChanged()"> |  | ||||||
|                 </addon-mod-forum-post> |                 </addon-mod-forum-post> | ||||||
|             </ng-container> |             </ng-container> | ||||||
|         </ion-card> |         </ion-card> | ||||||
| @ -121,12 +111,10 @@ | |||||||
| 
 | 
 | ||||||
|         <ng-template #nestedPosts let-post="post"> |         <ng-template #nestedPosts let-post="post"> | ||||||
|             <ion-card> |             <ion-card> | ||||||
|                 <addon-mod-forum-post |                 <addon-mod-forum-post [post]="post" [courseId]="courseId" [discussionId]="discussionId" [component]="component" | ||||||
|                     [post]="post" [courseId]="courseId" [discussionId]="discussionId" [component]="component" |                     [componentId]="cmId" [formData]="formData" [originalData]="originalData" [parentSubject]="postSubjects[post.parentid]" | ||||||
|                     [componentId]="cmId" [formData]="formData" [originalData]="originalData" |                     [forum]="forum" [accessInfo]="accessInfo" [trackPosts]="trackPosts" [ratingInfo]="ratingInfo" | ||||||
|                     [parentSubject]="postSubjects[post.parentid]" [forum]="forum" [accessInfo]="accessInfo" |                     [leavingPage]="leavingPage" (onPostChange)="postListChanged()"> | ||||||
|                     [trackPosts]="trackPosts" [ratingInfo]="ratingInfo" [leavingPage]="leavingPage" |  | ||||||
|                     (onPostChange)="postListChanged()"> |  | ||||||
|                 </addon-mod-forum-post> |                 </addon-mod-forum-post> | ||||||
|             </ion-card> |             </ion-card> | ||||||
|             <div class="ion-padding-start" *ngIf="post.children && post.children.length && post.children[0].subject"> |             <div class="ion-padding-start" *ngIf="post.children && post.children.length && post.children[0].subject"> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.mod_forum.addanewdiscussion' | translate }}</h1> |             <h1>{{ 'addon.mod_forum.addanewdiscussion' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The context menu will be added in here. --> |             <!-- The context menu will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
| @ -18,9 +20,8 @@ | |||||||
|         <form *ngIf="showForm" #newDiscFormEl> |         <form *ngIf="showForm" #newDiscFormEl> | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-label position="stacked">{{ 'addon.mod_forum.subject' | translate }}</ion-label> |                 <ion-label position="stacked">{{ 'addon.mod_forum.subject' | translate }}</ion-label> | ||||||
|                 <ion-input |                 <ion-input [(ngModel)]="newDiscussion.subject" type="text" [placeholder]="'addon.mod_forum.subject' | translate" | ||||||
|                     [(ngModel)]="newDiscussion.subject" |                     name="subject"> | ||||||
|                     type="text" [placeholder]="'addon.mod_forum.subject' | translate" name="subject"> |  | ||||||
|                 </ion-input> |                 </ion-input> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item> |             <ion-item> | ||||||
| @ -31,19 +32,14 @@ | |||||||
|                     (contentChanged)="onMessageChange($event)"> |                     (contentChanged)="onMessageChange($event)"> | ||||||
|                 </core-rich-text-editor> |                 </core-rich-text-editor> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item |             <ion-item button class="divider ion-text-wrap" (click)="toggleAdvanced()" detail="false" [attr.aria-expanded]="advanced" | ||||||
|                 button |                 [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate" role="heading" | ||||||
|                 class="divider ion-text-wrap" |                 aria-controls="addon-mod-forum-new-discussion-advanced"> | ||||||
|                 (click)="toggleAdvanced()" |  | ||||||
|                 detail="false" |  | ||||||
|                 [attr.aria-expanded]="advanced" |  | ||||||
|                 [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate" |  | ||||||
|                 role="heading" |  | ||||||
|                 aria-controls="addon-mod-forum-new-discussion-advanced" |  | ||||||
|             > |  | ||||||
|                 <ion-icon *ngIf="!advanced" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon *ngIf="!advanced" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-icon *ngIf="advanced" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon *ngIf="advanced" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label><h2>{{ 'addon.mod_forum.advanced' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.mod_forum.advanced' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <div *ngIf="advanced" id="addon-mod-forum-new-discussion-advanced"> |             <div *ngIf="advanced" id="addon-mod-forum-new-discussion-advanced"> | ||||||
|                 <ion-item *ngIf="showGroups && groupIds.length > 1 && accessInfo.cancanposttomygroups"> |                 <ion-item *ngIf="showGroups && groupIds.length > 1 && accessInfo.cancanposttomygroups"> | ||||||
| @ -66,17 +62,16 @@ | |||||||
|                     <ion-label>{{ 'addon.mod_forum.discussionpinned' | translate }}</ion-label> |                     <ion-label>{{ 'addon.mod_forum.discussionpinned' | translate }}</ion-label> | ||||||
|                     <ion-toggle [(ngModel)]="newDiscussion.pin" name="pin"></ion-toggle> |                     <ion-toggle [(ngModel)]="newDiscussion.pin" name="pin"></ion-toggle> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <core-attachments *ngIf="canCreateAttachments && forum && forum.maxattachments > 0" |                 <core-attachments *ngIf="canCreateAttachments && forum && forum.maxattachments > 0" [files]="newDiscussion.files" | ||||||
|                     [files]="newDiscussion.files" [maxSize]="forum.maxbytes" [maxSubmissions]="forum.maxattachments" |                     [maxSize]="forum.maxbytes" [maxSubmissions]="forum.maxattachments" [component]="component" [componentId]="forum.cmid" | ||||||
|                     [component]="component" [componentId]="forum.cmid" [allowOffline]="true" [courseId]="courseId"> |                     [allowOffline]="true" [courseId]="courseId"> | ||||||
|                 </core-attachments> |                 </core-attachments> | ||||||
|             </div> |             </div> | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <ion-row> |                     <ion-row> | ||||||
|                         <ion-col> |                         <ion-col> | ||||||
|                             <ion-button |                             <ion-button expand="block" [disabled]="newDiscussion.subject == '' || newDiscussion.message == null" | ||||||
|                                 expand="block" [disabled]="newDiscussion.subject == '' || newDiscussion.message == null" |  | ||||||
|                                 (click)="add()"> |                                 (click)="add()"> | ||||||
|                                 {{ 'addon.mod_forum.posttoforum' | translate }} |                                 {{ 'addon.mod_forum.posttoforum' | translate }} | ||||||
|                             </ion-button> |                             </ion-button> | ||||||
|  | |||||||
| @ -10,18 +10,17 @@ | |||||||
|     </ion-button> |     </ion-button> | ||||||
| 
 | 
 | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !(hasOffline || hasOfflineRatings) && isOnline" [priority]="700" |         <core-context-menu-item *ngIf="loaded && !(hasOffline || hasOfflineRatings) && isOnline" [priority]="700" | ||||||
|             [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" |             [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
|             [closeOnClick]="false"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600" |         <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600" | ||||||
|             (action)="doRefresh(null, $event, true)" [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" |             (action)="doRefresh(null, $event, true)" [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" | ||||||
| @ -51,25 +50,15 @@ | |||||||
| 
 | 
 | ||||||
|     <core-loading [hideUntil]="loaded"> |     <core-loading [hideUntil]="loaded"> | ||||||
|         <!-- Activity info. --> |         <!-- Activity info. --> | ||||||
|         <core-course-module-info *ngIf="showCompletion && !isSearch" [module]="module" [showManualCompletion]="true" |         <core-course-module-info *ngIf="!isSearch" [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|             (completionChanged)="onCompletionChange()"> |             [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings"> | ||||||
|         </core-course-module-info> |         </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|         <core-course-module-description *ngIf="!isSearch" [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|             contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|         </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|         <!-- 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" aria-hidden="true"></ion-icon> |  | ||||||
|                 <ion-label>{{ 'core.hasdatatosync' | translate:{$a: moduleName} }}</ion-label> |  | ||||||
|             </ion-item> |  | ||||||
|         </ion-card> |  | ||||||
| 
 |  | ||||||
|         <ion-list *ngIf="!isSearch && entries.offlineEntries.length > 0"> |         <ion-list *ngIf="!isSearch && entries.offlineEntries.length > 0"> | ||||||
|             <ion-item-divider> |             <ion-item-divider> | ||||||
|                 <ion-label><h2>{{ 'addon.mod_glossary.entriestobesynced' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.mod_glossary.entriestobesynced' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ion-item *ngFor="let entry of entries.offlineEntries" (click)="entries.select(entry)" detail="false" button |             <ion-item *ngFor="let entry of entries.offlineEntries" (click)="entries.select(entry)" detail="false" button | ||||||
|                 [attr.aria-current]="entries.getItemAriaCurrent(entry)"> |                 [attr.aria-current]="entries.getItemAriaCurrent(entry)"> | ||||||
| @ -84,11 +73,12 @@ | |||||||
|         <ion-list *ngIf="entries.onlineEntries.length > 0"> |         <ion-list *ngIf="entries.onlineEntries.length > 0"> | ||||||
|             <ng-container *ngFor="let entry of entries.onlineEntries; let index = index"> |             <ng-container *ngFor="let entry of entries.onlineEntries; let index = index"> | ||||||
|                 <ion-item-divider *ngIf="getDivider && showDivider(entry, entries.onlineEntries[index - 1])"> |                 <ion-item-divider *ngIf="getDivider && showDivider(entry, entries.onlineEntries[index - 1])"> | ||||||
|                     <ion-label><h2>{{ getDivider!(entry) }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ getDivider!(entry) }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
| 
 | 
 | ||||||
|                 <ion-item button (click)="entries.select(entry)" [attr.aria-current]="entries.getItemAriaCurrent(entry)" |                 <ion-item button (click)="entries.select(entry)" [attr.aria-current]="entries.getItemAriaCurrent(entry)" detail="false"> | ||||||
|                     detail="false"> |  | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="glossary!.coursemodule" |                         <core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="glossary!.coursemodule" | ||||||
|                             [courseId]="courseId"> |                             [courseId]="courseId"> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="glossary"> |             <h1 *ngIf="glossary"> | ||||||
|                 <core-format-text [text]="glossary.name" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                 <core-format-text [text]="glossary.name" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -14,16 +16,15 @@ | |||||||
|         <form #editFormEl *ngIf="glossary"> |         <form #editFormEl *ngIf="glossary"> | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-label position="stacked">{{ 'addon.mod_glossary.concept' | translate }}</ion-label> |                 <ion-label position="stacked">{{ 'addon.mod_glossary.concept' | translate }}</ion-label> | ||||||
|                 <ion-input type="text" [placeholder]="'addon.mod_glossary.concept' | translate" [(ngModel)]="entry.concept" |                 <ion-input type="text" [placeholder]="'addon.mod_glossary.concept' | translate" [(ngModel)]="entry.concept" name="concept"> | ||||||
|                     name="concept"> |  | ||||||
|                 </ion-input> |                 </ion-input> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item> |             <ion-item> | ||||||
|                 <ion-label position="stacked">{{ 'addon.mod_glossary.definition' | translate }}</ion-label> |                 <ion-label position="stacked">{{ 'addon.mod_glossary.definition' | translate }}</ion-label> | ||||||
|                 <core-rich-text-editor [control]="definitionControl" (contentChanged)="onDefinitionChange($event)" |                 <core-rich-text-editor [control]="definitionControl" (contentChanged)="onDefinitionChange($event)" | ||||||
|                     [placeholder]="'addon.mod_glossary.definition' | translate" name="addon_mod_glossary_edit" |                     [placeholder]="'addon.mod_glossary.definition' | translate" name="addon_mod_glossary_edit" [component]="component" | ||||||
|                     [component]="component" [componentId]="cmId" [autoSave]="true" contextLevel="module" |                     [componentId]="cmId" [autoSave]="true" contextLevel="module" [contextInstanceId]="cmId" elementId="definition_editor" | ||||||
|                     [contextInstanceId]="cmId" elementId="definition_editor" [draftExtraParams]="editorExtraParams"> |                     [draftExtraParams]="editorExtraParams"> | ||||||
|                 </core-rich-text-editor> |                 </core-rich-text-editor> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item *ngIf="categories.length > 0"> |             <ion-item *ngIf="categories.length > 0"> | ||||||
| @ -47,14 +48,18 @@ | |||||||
|                 </ion-textarea> |                 </ion-textarea> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item-divider> |             <ion-item-divider> | ||||||
|                 <ion-label><h2>{{ 'addon.mod_glossary.attachment' | translate }}</h2></ion-label> |                 <ion-label> | ||||||
|  |                     <h2>{{ 'addon.mod_glossary.attachment' | translate }}</h2> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <core-attachments [files]="attachments" [component]="component" [componentId]="glossary.coursemodule" |             <core-attachments [files]="attachments" [component]="component" [componentId]="glossary.coursemodule" [allowOffline]="true" | ||||||
|                 [allowOffline]="true" [courseId]="courseId"> |                 [courseId]="courseId"> | ||||||
|             </core-attachments> |             </core-attachments> | ||||||
|             <ng-container *ngIf="glossary.usedynalink"> |             <ng-container *ngIf="glossary.usedynalink"> | ||||||
|                 <ion-item-divider> |                 <ion-item-divider> | ||||||
|                     <ion-label><h2>{{ 'addon.mod_glossary.linking' | translate }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.mod_glossary.linking' | translate }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
|                 <ion-item class="ion-text-wrap"> |                 <ion-item class="ion-text-wrap"> | ||||||
|                     <ion-label>{{ 'addon.mod_glossary.entryusedynalink' | translate }}</ion-label> |                     <ion-label>{{ 'addon.mod_glossary.entryusedynalink' | translate }}</ion-label> | ||||||
|  | |||||||
| @ -3,10 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1 *ngIf="entry"> |             <h1 *ngIf="entry"> | ||||||
|                 <core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="componentId" [courseId]="courseId"> |                 <core-format-text [text]="entry.concept" contextLevel="module" [contextInstanceId]="componentId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -39,14 +41,13 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <core-format-text [component]="component" [componentId]="componentId" [text]="entry.definition" |                     <core-format-text [component]="component" [componentId]="componentId" [text]="entry.definition" contextLevel="module" | ||||||
|                         contextLevel="module" [contextInstanceId]="componentId" [courseId]="courseId"> |                         [contextInstanceId]="componentId" [courseId]="courseId"> | ||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <div *ngIf="entry.attachment" lines="none"> |             <div *ngIf="entry.attachment" lines="none"> | ||||||
|                 <core-file *ngFor="let file of entry.attachments" [file]="file" [component]="component" |                 <core-file *ngFor="let file of entry.attachments" [file]="file" [component]="component" [componentId]="componentId"> | ||||||
|                     [componentId]="componentId"> |  | ||||||
|                 </core-file> |                 </core-file> | ||||||
|             </div> |             </div> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="tagsEnabled && entry && entry.tags && entry.tags.length > 0"> |             <ion-item class="ion-text-wrap" *ngIf="tagsEnabled && entry && entry.tags && entry.tags.length > 0"> | ||||||
| @ -56,20 +57,21 @@ | |||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="!entry.approved"> |             <ion-item class="ion-text-wrap" *ngIf="!entry.approved"> | ||||||
|                 <ion-label><p><em>{{ 'addon.mod_glossary.entrypendingapproval' | translate }}</em></p></ion-label> |                 <ion-label> | ||||||
|  |                     <p><em>{{ 'addon.mod_glossary.entrypendingapproval' | translate }}</em></p> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <core-comments *ngIf="glossary && glossary.allowcomments && entry && entry.id > 0 && commentsEnabled" |             <core-comments *ngIf="glossary && glossary.allowcomments && entry && entry.id > 0 && commentsEnabled" contextLevel="module" | ||||||
|                 contextLevel="module" [instanceId]="glossary.coursemodule" component="mod_glossary" |                 [instanceId]="glossary.coursemodule" component="mod_glossary" [itemId]="entry.id" area="glossary_entry" | ||||||
|                 [itemId]="entry.id" area="glossary_entry" [courseId]="glossary.course" [showItem]="true"> |                 [courseId]="glossary.course" [showItem]="true"> | ||||||
|             </core-comments> |             </core-comments> | ||||||
|             <core-rating-rate *ngIf="glossary && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" |             <core-rating-rate *ngIf="glossary && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" | ||||||
|                 [instanceId]="glossary.coursemodule" [itemId]="entry.id" [itemSetId]="0" [courseId]="glossary.course" |                 [instanceId]="glossary.coursemodule" [itemId]="entry.id" [itemSetId]="0" [courseId]="glossary.course" | ||||||
|                 [aggregateMethod]="glossary.assessed" [scaleId]="glossary.scale" [userId]="entry.userid" |                 [aggregateMethod]="glossary.assessed" [scaleId]="glossary.scale" [userId]="entry.userid" (onUpdate)="ratingUpdated()"> | ||||||
|                 (onUpdate)="ratingUpdated()"> |  | ||||||
|             </core-rating-rate> |             </core-rating-rate> | ||||||
|             <core-rating-aggregate *ngIf="glossary && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" |             <core-rating-aggregate *ngIf="glossary && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" | ||||||
|                 [instanceId]="glossary.coursemodule" [itemId]="entry.id" [courseId]="glossary.course" |                 [instanceId]="glossary.coursemodule" [itemId]="entry.id" [courseId]="glossary.course" [aggregateMethod]="glossary.assessed" | ||||||
|                 [aggregateMethod]="glossary.assessed" [scaleId]="glossary.scale"> |                 [scaleId]="glossary.scale"> | ||||||
|             </core-rating-aggregate> |             </core-rating-aggregate> | ||||||
|         </ng-container> |         </ng-container> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -5,18 +5,17 @@ | |||||||
|             [priority]="1000" [content]="'addon.mod_h5pactivity.review_my_attempts' | translate" (action)="viewMyAttempts()" |             [priority]="1000" [content]="'addon.mod_h5pactivity.review_my_attempts' | translate" (action)="viewMyAttempts()" | ||||||
|             iconAction="stats-chart"> |             iconAction="stats-chart"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="canViewAllAttempts" |         <core-context-menu-item *ngIf="canViewAllAttempts" [priority]="1000" [content]="'addon.mod_h5pactivity.review_attempts' | translate" | ||||||
|             [priority]="1000" [content]="'addon.mod_h5pactivity.review_attempts' | translate" (action)="viewAllAttempts()" |             (action)="viewAllAttempts()" iconAction="stats-chart"> | ||||||
|             iconAction="stats-chart"> |  | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -37,22 +36,10 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="safe-area-padding"> | <core-loading [hideUntil]="loaded" class="safe-area-padding"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <!-- Offline data stored. --> |  | ||||||
|     <ion-card class="core-warning-card" *ngIf="hasOffline"> |  | ||||||
|         <ion-item> |  | ||||||
|             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |  | ||||||
|             <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label> |  | ||||||
|         </ion-item> |  | ||||||
|     </ion-card> |  | ||||||
| 
 |  | ||||||
|     <!-- Offline disabled. --> |     <!-- Offline disabled. --> | ||||||
|     <ion-card class="core-warning-card" *ngIf="!siteCanDownload && playing"> |     <ion-card class="core-warning-card" *ngIf="!siteCanDownload && playing"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
| @ -79,8 +66,7 @@ | |||||||
|         </ion-item> |         </ion-item> | ||||||
| 
 | 
 | ||||||
|         <!-- Button to download the package. --> |         <!-- Button to download the package. --> | ||||||
|         <ion-button *ngIf="!downloading && needsDownload" class="ion-text-wrap ion-margin" expand="block" |         <ion-button *ngIf="!downloading && needsDownload" class="ion-text-wrap ion-margin" expand="block" (click)="downloadAndPlay($event)"> | ||||||
|             (click)="downloadAndPlay($event)"> |  | ||||||
|             {{ 'addon.mod_h5pactivity.downloadh5pfile' | translate }} |             {{ 'addon.mod_h5pactivity.downloadh5pfile' | translate }} | ||||||
|         </ion-button> |         </ion-button> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,11 +3,13 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module" |                 <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module" | ||||||
|                     [contextInstanceId]="h5pActivity.coursemodule" [courseId]="courseId"> |                     [contextInstanceId]="h5pActivity.coursemodule" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -62,15 +64,15 @@ | |||||||
|                     <ion-item class="ion-text-wrap" lines="none"> |                     <ion-item class="ion-text-wrap" lines="none"> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <h2>{{ 'addon.mod_h5pactivity.outcome' | translate }}</h2> |                             <h2>{{ 'addon.mod_h5pactivity.outcome' | translate }}</h2> | ||||||
|                             <p *ngIf="attempt.success !== null && attempt.success" > |                             <p *ngIf="attempt.success !== null && attempt.success"> | ||||||
|                                 <ion-icon name="fas-check-circle" aria-hidden="true"></ion-icon> |                                 <ion-icon name="fas-check-circle" aria-hidden="true"></ion-icon> | ||||||
|                                 {{ 'addon.mod_h5pactivity.attempt_success_pass' | translate }} |                                 {{ 'addon.mod_h5pactivity.attempt_success_pass' | translate }} | ||||||
|                             </p> |                             </p> | ||||||
|                             <p *ngIf="attempt.success !== null && !attempt.success" > |                             <p *ngIf="attempt.success !== null && !attempt.success"> | ||||||
|                                 <ion-icon name="far-circle" aria-hidden="true"></ion-icon> |                                 <ion-icon name="far-circle" aria-hidden="true"></ion-icon> | ||||||
|                                 {{ 'addon.mod_h5pactivity.attempt_success_fail' | translate }} |                                 {{ 'addon.mod_h5pactivity.attempt_success_fail' | translate }} | ||||||
|                             </p> |                             </p> | ||||||
|                             <p *ngIf="attempt.success === null" > |                             <p *ngIf="attempt.success === null"> | ||||||
|                                 {{ 'addon.mod_h5pactivity.attempt_success_unknown' | translate }} |                                 {{ 'addon.mod_h5pactivity.attempt_success_unknown' | translate }} | ||||||
|                             </p> |                             </p> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
| @ -89,15 +91,15 @@ | |||||||
|                 <ion-card *ngFor="let result of attempt.results"> |                 <ion-card *ngFor="let result of attempt.results"> | ||||||
|                     <ion-card-header class="ion-text-wrap"> |                     <ion-card-header class="ion-text-wrap"> | ||||||
|                         <ion-card-title> |                         <ion-card-title> | ||||||
|                             <core-format-text [text]="result.description" [component]="component" [componentId]="cmId" |                             <core-format-text [text]="result.description" [component]="component" [componentId]="cmId" contextLevel="module" | ||||||
|                                 contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                                 [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </ion-card-title> |                         </ion-card-title> | ||||||
|                     </ion-card-header> |                     </ion-card-header> | ||||||
|                     <ion-item *ngIf="result.content" class="ion-text-wrap"> |                     <ion-item *ngIf="result.content" class="ion-text-wrap"> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <core-format-text [text]="result.content" [component]="component" [componentId]="cmId" |                             <core-format-text [text]="result.content" [component]="component" [componentId]="cmId" contextLevel="module" | ||||||
|                                 contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                                 [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </ion-label> |                         </ion-label> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
| @ -113,8 +115,7 @@ | |||||||
|                                 </ion-row> |                                 </ion-row> | ||||||
|                             </ion-label> |                             </ion-label> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                         <ion-item *ngFor="let option of result.options" |                         <ion-item *ngFor="let option of result.options" class="ion-text-wrap addon-mod_h5pactivity-result-table-row"> | ||||||
|                             class="ion-text-wrap addon-mod_h5pactivity-result-table-row"> |  | ||||||
|                             <ion-label> |                             <ion-label> | ||||||
|                                 <ion-row class="ion-align-items-center"> |                                 <ion-row class="ion-align-items-center"> | ||||||
|                                     <ion-col class="ion-text-center"> |                                     <ion-col class="ion-text-center"> | ||||||
| @ -124,8 +125,7 @@ | |||||||
|                                     </ion-col> |                                     </ion-col> | ||||||
|                                     <ion-col class="ion-text-center"> |                                     <ion-col class="ion-text-center"> | ||||||
|                                         <ng-container *ngIf="option.correctanswer"> |                                         <ng-container *ngIf="option.correctanswer"> | ||||||
|                                             <ng-container |                                             <ng-container *ngTemplateOutlet="answerTemplate; context: {answer: option.correctanswer}"> | ||||||
|                                                 *ngTemplateOutlet="answerTemplate; context: {answer: option.correctanswer}"> |  | ||||||
|                                             </ng-container> |                                             </ng-container> | ||||||
|                                         </ng-container> |                                         </ng-container> | ||||||
|                                     </ion-col> |                                     </ion-col> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -3,11 +3,13 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module" |                 <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module" | ||||||
|                     [contextInstanceId]="h5pActivity.coursemodule" [courseId]="courseId"> |                     [contextInstanceId]="h5pActivity.coursemodule" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  | |||||||
| @ -3,11 +3,13 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module" |                 <core-format-text *ngIf="h5pActivity" [text]="h5pActivity.name" contextLevel="module" | ||||||
|                     [contextInstanceId]="h5pActivity.coursemodule" [courseId]="courseId"> |                     [contextInstanceId]="h5pActivity.coursemodule" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  | |||||||
| @ -4,14 +4,14 @@ | |||||||
|         <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|     </ion-button> |     </ion-button> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" |         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" | ||||||
|             [iconAction]="refreshIcon" [closeOnClick]="false"> |             [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -29,8 +29,7 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="safe-area-padding"> | <core-loading [hideUntil]="loaded" class="safe-area-padding"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()"> | ||||||
|         (completionChanged)="onCompletionChange()"> |  | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <ion-card class="core-warning-card" *ngIf="warning"> |     <ion-card class="core-warning-card" *ngIf="warning"> | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <h1>{{ 'addon.mod_imscp.toc' | translate }}</h1> |         <ion-title> | ||||||
|  |             <h2>{{ 'addon.mod_imscp.toc' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon> |                 <ion-icon name="fas-times" slot="icon-only" aria-hidden=true></ion-icon> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -33,14 +33,10 @@ | |||||||
|             <ng-template> |             <ng-template> | ||||||
| 
 | 
 | ||||||
|                 <!-- Activity info. --> |                 <!-- Activity info. --> | ||||||
|                 <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |                 <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|                     (completionChanged)="onCompletionChange()"> |                     [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline"> | ||||||
|                 </core-course-module-info> |                 </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|                 <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|                     contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|                 </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|                 <!-- Prevent access messages. Only show the first one. --> |                 <!-- Prevent access messages. Only show the first one. --> | ||||||
|                 <ion-card class="core-info-card" *ngIf="lesson && preventReasons.length"> |                 <ion-card class="core-info-card" *ngIf="lesson && preventReasons.length"> | ||||||
|                     <ion-item> |                     <ion-item> | ||||||
| @ -49,14 +45,6 @@ | |||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ion-card> |                 </ion-card> | ||||||
| 
 | 
 | ||||||
|                 <!-- Lesson has data to be synchronized --> |  | ||||||
|                 <ion-card class="core-warning-card" *ngIf="hasOffline"> |  | ||||||
|                     <ion-item> |  | ||||||
|                         <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |  | ||||||
|                         <ion-label>{{ 'core.hasdatatosync' | translate: {$a: moduleName} }}</ion-label> |  | ||||||
|                     </ion-item> |  | ||||||
|                 </ion-card> |  | ||||||
| 
 |  | ||||||
|                 <!-- Input password for protected lessons. --> |                 <!-- Input password for protected lessons. --> | ||||||
|                 <ion-card *ngIf="askPassword"> |                 <ion-card *ngIf="askPassword"> | ||||||
|                     <form (ngSubmit)="submitPassword($event, passwordinput)" #passwordForm> |                     <form (ngSubmit)="submitPassword($event, passwordinput)" #passwordForm> | ||||||
| @ -132,13 +120,11 @@ | |||||||
| 
 | 
 | ||||||
|                             <ng-container *ngIf="!leftDuringTimed && !finishedOffline"> |                             <ng-container *ngIf="!leftDuringTimed && !finishedOffline"> | ||||||
|                                 <!-- User hasn't left during the session, show a start button. --> |                                 <!-- User hasn't left during the session, show a start button. --> | ||||||
|                                 <ion-button class="ion-text-wrap ion-margin" expand="block" *ngIf="!canManage" |                                 <ion-button class="ion-text-wrap ion-margin" expand="block" *ngIf="!canManage" (click)="start(false)"> | ||||||
|                                     (click)="start(false)"> |  | ||||||
|                                     {{ 'core.start' | translate }} |                                     {{ 'core.start' | translate }} | ||||||
|                                     <ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon> |                                     <ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon> | ||||||
|                                 </ion-button> |                                 </ion-button> | ||||||
|                                 <ion-button class="ion-text-wrap ion-margin" expand="block" *ngIf="canManage" |                                 <ion-button class="ion-text-wrap ion-margin" expand="block" *ngIf="canManage" (click)="start(false)"> | ||||||
|                                     (click)="start(false)"> |  | ||||||
|                                     {{ 'addon.mod_lesson.preview' | translate }} |                                     {{ 'addon.mod_lesson.preview' | translate }} | ||||||
|                                     <ion-icon name="fas-search" slot="end" aria-hidden="true"></ion-icon> |                                     <ion-icon name="fas-search" slot="end" aria-hidden="true"></ion-icon> | ||||||
|                                 </ion-button> |                                 </ion-button> | ||||||
| @ -295,8 +281,8 @@ | |||||||
|                             <ion-card-title>{{ 'addon.mod_lesson.overview' | translate }}</ion-card-title> |                             <ion-card-title>{{ 'addon.mod_lesson.overview' | translate }}</ion-card-title> | ||||||
|                         </ion-card-header> |                         </ion-card-header> | ||||||
| 
 | 
 | ||||||
|                         <ion-item class="ion-text-wrap" *ngFor="let student of overview.students" button |                         <ion-item class="ion-text-wrap" *ngFor="let student of overview.students" button (click)="openRetake(student.id)" | ||||||
|                             (click)="openRetake(student.id)" detail="true"> |                             detail="true"> | ||||||
|                             <core-user-avatar [user]="student" slot="start" [userId]="student.id" [courseId]="courseId"> |                             <core-user-avatar [user]="student" slot="start" [userId]="student.id" [courseId]="courseId"> | ||||||
|                             </core-user-avatar> |                             </core-user-avatar> | ||||||
|                             <ion-label> |                             <ion-label> | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2>{{ pageInstance?.lesson?.name }}</h2> |             <h2>{{ pageInstance?.lesson?.name }}</h2> | ||||||
| 
 |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
| @ -15,7 +16,9 @@ | |||||||
|             <!-- Media file. --> |             <!-- Media file. --> | ||||||
|             <ng-container *ngIf="pageInstance.mediaFile"> |             <ng-container *ngIf="pageInstance.mediaFile"> | ||||||
|                 <ion-item-divider> |                 <ion-item-divider> | ||||||
|                     <ion-label><h2>{{ 'addon.mod_lesson.linkedmedia' | translate }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.mod_lesson.linkedmedia' | translate }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
|                 <core-file [file]="pageInstance.mediaFile" [component]="pageInstance.component" |                 <core-file [file]="pageInstance.mediaFile" [component]="pageInstance.component" | ||||||
|                     [componentId]="pageInstance.lesson?.coursemodule"> |                     [componentId]="pageInstance.lesson?.coursemodule"> | ||||||
| @ -25,16 +28,20 @@ | |||||||
|             <!-- Lesson menu. --> |             <!-- Lesson menu. --> | ||||||
|             <ng-container *ngIf="pageInstance.displayMenu"> |             <ng-container *ngIf="pageInstance.displayMenu"> | ||||||
|                 <ion-item-divider> |                 <ion-item-divider> | ||||||
|                     <ion-label><h2>{{ 'addon.mod_lesson.lessonmenu' | translate }}</h2></ion-label> |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.mod_lesson.lessonmenu' | translate }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item-divider> |                 </ion-item-divider> | ||||||
|                 <ion-item class="ion-text-center" *ngIf="pageInstance.loadingMenu"> |                 <ion-item class="ion-text-center" *ngIf="pageInstance.loadingMenu"> | ||||||
|                     <ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label> |                     <ion-label> | ||||||
|  |                         <ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||||
|  |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <div *ngIf="!pageInstance.loadingMenu"> |                 <div *ngIf="!pageInstance.loadingMenu"> | ||||||
|                     <ng-container *ngFor="let page of pageInstance.lessonPages"> |                     <ng-container *ngFor="let page of pageInstance.lessonPages"> | ||||||
|                         <ion-item class="ion-text-wrap" *ngIf="page.display && page.displayinmenublock" (click)="loadPage(page.id)" |                         <ion-item class="ion-text-wrap" *ngIf="page.display && page.displayinmenublock" (click)="loadPage(page.id)" | ||||||
|                             [attr.aria-current]="!pageInstance.eolData && pageInstance.currentPage == page.id ? 'page' : 'false'" |                             [attr.aria-current]="!pageInstance.eolData && pageInstance.currentPage == page.id ? 'page' : 'false'" button | ||||||
|                             button detail="true"> |                             detail="true"> | ||||||
|                             <ion-label> |                             <ion-label> | ||||||
|                                 <core-format-text [text]="page.title" contextLevel="module" [courseId]="pageInstance.courseId" |                                 <core-format-text [text]="page.title" contextLevel="module" [courseId]="pageInstance.courseId" | ||||||
|                                     [contextInstanceId]="pageInstance.lesson?.coursemodule"> |                                     [contextInstanceId]="pageInstance.lesson?.coursemodule"> | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2>{{ 'core.login.password' | translate }}</h2> |             <h2>{{ 'core.login.password' | translate }}</h2> | ||||||
| 
 |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
| @ -14,8 +15,8 @@ | |||||||
|         <ion-item> |         <ion-item> | ||||||
|             <ion-label>{{ 'addon.mod_lesson.enterpassword' | translate }}</ion-label> |             <ion-label>{{ 'addon.mod_lesson.enterpassword' | translate }}</ion-label> | ||||||
|             <core-show-password name="password"> |             <core-show-password name="password"> | ||||||
|                 <ion-input name="password" type="password" placeholder="{{ 'core.login.password' | translate }}" |                 <ion-input name="password" type="password" placeholder="{{ 'core.login.password' | translate }}" core-auto-focus | ||||||
|                     core-auto-focus #passwordinput [clearOnEdit]="false"> |                     #passwordinput [clearOnEdit]="false"> | ||||||
|                 </ion-input> |                 </ion-input> | ||||||
|             </core-show-password> |             </core-show-password> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
| @ -17,7 +19,6 @@ | |||||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|     </ion-refresher> |     </ion-refresher> | ||||||
| 
 | 
 | ||||||
|     <addon-mod-lesson-index [module]="module" [courseId]="courseId" [group]="group" [action]="action" |     <addon-mod-lesson-index [module]="module" [courseId]="courseId" [group]="group" [action]="action" (dataRetrieved)="updateData($event)"> | ||||||
|         (dataRetrieved)="updateData($event)"> |  | ||||||
|     </addon-mod-lesson-index> |     </addon-mod-lesson-index> | ||||||
| </ion-content> | </ion-content> | ||||||
|  | |||||||
| @ -3,11 +3,12 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|             <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> | ||||||
|                 [courseId]="courseId"> |  | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" *ngIf="displayMenu || mediaFile" [attr.aria-label]="'addon.mod_lesson.lessonmenu' | translate" |             <ion-button fill="clear" *ngIf="displayMenu || mediaFile" [attr.aria-label]="'addon.mod_lesson.lessonmenu' | translate" | ||||||
|                 (click)="showMenu()"> |                 (click)="showMenu()"> | ||||||
| @ -46,15 +47,14 @@ | |||||||
|             <ion-card *ngIf="!eolData && !processData"> |             <ion-card *ngIf="!eolData && !processData"> | ||||||
|                 <!-- Content page. --> |                 <!-- Content page. --> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="!question && pageContent"> |                 <ion-item class="ion-text-wrap" *ngIf="!question && pageContent"> | ||||||
|                     <core-format-text [component]="component" [componentId]="lesson.coursemodule" [text]="pageContent" |                     <core-format-text [component]="component" [componentId]="lesson.coursemodule" [text]="pageContent" contextLevel="module" | ||||||
|                         contextLevel="module" [contextInstanceId]="lesson.coursemodule" [courseId]="courseId"> |                         [contextInstanceId]="lesson.coursemodule" [courseId]="courseId"> | ||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|                 <!-- Question page. --> |                 <!-- Question page. --> | ||||||
|                 <!-- We need to set ngIf loaded to make formGroup directive restart every time a page changes, see MOBILE-2540. --> |                 <!-- We need to set ngIf loaded to make formGroup directive restart every time a page changes, see MOBILE-2540. --> | ||||||
|                 <form *ngIf="question && loaded" [formGroup]="questionForm" #questionFormEl |                 <form *ngIf="question && loaded" [formGroup]="questionForm" #questionFormEl (ngSubmit)="submitQuestion($event)"> | ||||||
|                     (ngSubmit)="submitQuestion($event)"> |  | ||||||
| 
 | 
 | ||||||
|                     <ion-item-divider class="ion-text-wrap" *ngIf="pageContent"> |                     <ion-item-divider class="ion-text-wrap" *ngIf="pageContent"> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
| @ -91,8 +91,8 @@ | |||||||
|                                     <h3 class="item-heading">{{ 'addon.mod_lesson.youranswer' | translate }}</h3> |                                     <h3 class="item-heading">{{ 'addon.mod_lesson.youranswer' | translate }}</h3> | ||||||
|                                     <p> |                                     <p> | ||||||
|                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" |                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" | ||||||
|                                             [text]="question.useranswer" contextLevel="module" |                                             [text]="question.useranswer" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" | ||||||
|                                             [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> |                                             [courseId]="courseId"> | ||||||
|                                         </core-format-text> |                                         </core-format-text> | ||||||
|                                     </p> |                                     </p> | ||||||
|                                 </ion-label> |                                 </ion-label> | ||||||
| @ -105,9 +105,8 @@ | |||||||
|                             <ion-radio-group *ngIf="!question.multi" [formControlName]="question.controlName"> |                             <ion-radio-group *ngIf="!question.multi" [formControlName]="question.controlName"> | ||||||
|                                 <ion-item class="ion-text-wrap" *ngFor="let option of question.options"> |                                 <ion-item class="ion-text-wrap" *ngFor="let option of question.options"> | ||||||
|                                     <ion-label> |                                     <ion-label> | ||||||
|                                         <core-format-text [component]="component" [componentId]="lesson.coursemodule" |                                         <core-format-text [component]="component" [componentId]="lesson.coursemodule" [text]="option.text" | ||||||
|                                             [text]="option.text" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" |                                             contextLevel="module" [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> | ||||||
|                                             [courseId]="courseId"> |  | ||||||
|                                         </core-format-text> |                                         </core-format-text> | ||||||
|                                     </ion-label> |                                     </ion-label> | ||||||
|                                     <ion-radio slot="end" [id]="option.id" [value]="option.value" [disabled]="option.disabled"> |                                     <ion-radio slot="end" [id]="option.id" [value]="option.value" [disabled]="option.disabled"> | ||||||
| @ -119,9 +118,8 @@ | |||||||
|                             <ng-container *ngIf="question.multi"> |                             <ng-container *ngIf="question.multi"> | ||||||
|                                 <ion-item class="ion-text-wrap" *ngFor="let option of question.options"> |                                 <ion-item class="ion-text-wrap" *ngFor="let option of question.options"> | ||||||
|                                     <ion-label> |                                     <ion-label> | ||||||
|                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" |                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" [text]="option.text" | ||||||
|                                             [text]="option.text" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" |                                             contextLevel="module" [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> | ||||||
|                                             [courseId]="courseId"> |  | ||||||
|                                         </core-format-text> |                                         </core-format-text> | ||||||
|                                     </ion-label> |                                     </ion-label> | ||||||
|                                     <ion-checkbox [id]="option.id" [formControlName]="option.name" slot="end"></ion-checkbox> |                                     <ion-checkbox [id]="option.id" [formControlName]="option.name" slot="end"></ion-checkbox> | ||||||
| @ -133,10 +131,12 @@ | |||||||
|                         <ng-container *ngSwitchCase="'matching'"> |                         <ng-container *ngSwitchCase="'matching'"> | ||||||
|                             <ion-item class="ion-text-wrap" *ngFor="let row of question.rows"> |                             <ion-item class="ion-text-wrap" *ngFor="let row of question.rows"> | ||||||
|                                 <ion-label> |                                 <ion-label> | ||||||
|                                     <p><core-format-text id="addon-mod_lesson-matching-{{row.id}}" [component]="component" |                                     <p> | ||||||
|  |                                         <core-format-text id="addon-mod_lesson-matching-{{row.id}}" [component]="component" | ||||||
|                                             [componentId]="lesson?.coursemodule" [text]="row.text" contextLevel="module" |                                             [componentId]="lesson?.coursemodule" [text]="row.text" contextLevel="module" | ||||||
|                                             [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> |                                             [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> | ||||||
|                                     </core-format-text></p> |                                         </core-format-text> | ||||||
|  |                                     </p> | ||||||
|                                 </ion-label> |                                 </ion-label> | ||||||
|                                 <ion-select [id]="row.id" [formControlName]="row.name" interface="action-sheet" |                                 <ion-select [id]="row.id" [formControlName]="row.name" interface="action-sheet" | ||||||
|                                     [attr.aria-labelledby]="'addon-mod_lesson-matching-' + row.id"> |                                     [attr.aria-labelledby]="'addon-mod_lesson-matching-' + row.id"> | ||||||
| @ -161,8 +161,8 @@ | |||||||
|                 <ion-grid *ngIf="pageButtons?.length" class="ion-text-wrap addon-mod_lesson-pagebuttons"> |                 <ion-grid *ngIf="pageButtons?.length" class="ion-text-wrap addon-mod_lesson-pagebuttons"> | ||||||
|                     <ion-row class="ion-align-items-center"> |                     <ion-row class="ion-align-items-center"> | ||||||
|                         <ion-col *ngFor="let button of pageButtons" size="12" size-md="6" size-lg="3" col-xl> |                         <ion-col *ngFor="let button of pageButtons" size="12" size-md="6" size-lg="3" col-xl> | ||||||
|                             <ion-button expand="block" fill="outline" [id]="button.id" |                             <ion-button expand="block" fill="outline" [id]="button.id" (click)="buttonClicked(button.data)" | ||||||
|                                 (click)="buttonClicked(button.data)" class="ion-text-wrap button-no-uppercase"> |                                 class="ion-text-wrap button-no-uppercase"> | ||||||
|                                 {{ button.content }} |                                 {{ button.content }} | ||||||
|                             </ion-button> |                             </ion-button> | ||||||
|                         </ion-col> |                         </ion-col> | ||||||
| @ -213,8 +213,7 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="eolData.displayscorewithessays" lines="none"> |                 <ion-item class="ion-text-wrap" *ngIf="eolData.displayscorewithessays" lines="none"> | ||||||
|                     <ion-label [innerHTML]="eolData.displayscorewithessays.message"></ion-label> |                     <ion-label [innerHTML]="eolData.displayscorewithessays.message"></ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="!eolData.displayscorewithessays && eolData.displayscorewithoutessays" |                 <ion-item class="ion-text-wrap" *ngIf="!eolData.displayscorewithessays && eolData.displayscorewithoutessays" lines="none"> | ||||||
|                     lines="none"> |  | ||||||
|                     <ion-label>{{ eolData.displayscorewithoutessays.message }}</ion-label> |                     <ion-label>{{ eolData.displayscorewithoutessays.message }}</ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="eolData.yourcurrentgradeisoutof" lines="none"> |                 <ion-item class="ion-text-wrap" *ngIf="eolData.yourcurrentgradeisoutof" lines="none"> | ||||||
| @ -247,19 +246,17 @@ | |||||||
|                     <ion-label>{{ eolData.modattemptsnoteacher.message }}</ion-label> |                     <ion-label>{{ eolData.modattemptsnoteacher.message }}</ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <!-- If activity link was successfully formatted, render the button. --> |                 <!-- If activity link was successfully formatted, render the button. --> | ||||||
|                 <ion-button *ngIf="activityLink && activityLink.formatted" |                 <ion-button *ngIf="activityLink && activityLink.formatted" expand="block" color="light" [href]="activityLink.href" core-link | ||||||
|                     expand="block" color="light" [href]="activityLink.href" core-link [capture]="true" |                     [capture]="true" class="ion-text-wrap ion-margin button-no-uppercase"> | ||||||
|                     class="ion-text-wrap ion-margin button-no-uppercase"> |                     <core-format-text [text]="activityLink.label" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" | ||||||
|                     <core-format-text [text]="activityLink.label" contextLevel="module" |                         [courseId]="courseId"> | ||||||
|                         [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> |  | ||||||
|                     </core-format-text> |                     </core-format-text> | ||||||
|                 </ion-button> |                 </ion-button> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="activityLink && !activityLink.formatted" |                 <ion-item class="ion-text-wrap" *ngIf="activityLink && !activityLink.formatted" lines="none"> | ||||||
|                     lines="none"> |  | ||||||
|                     <!-- Activity link wasn't formatted, render the original link. --> |                     <!-- Activity link wasn't formatted, render the original link. --> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <core-format-text [text]="activityLink.label" contextLevel="module" |                         <core-format-text [text]="activityLink.label" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" | ||||||
|                             [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> |                             [courseId]="courseId"> | ||||||
|                         </core-format-text> |                         </core-format-text> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| @ -267,15 +264,14 @@ | |||||||
| 
 | 
 | ||||||
|             <!-- Feedback returned when processing an action. --> |             <!-- Feedback returned when processing an action. --> | ||||||
|             <ion-list *ngIf="processData"> |             <ion-list *ngIf="processData"> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="processData.ongoingscore && !processData.reviewmode" > |                 <ion-item class="ion-text-wrap" *ngIf="processData.ongoingscore && !processData.reviewmode"> | ||||||
|                     <ion-label>{{ processData.ongoingscore }}</ion-label> |                     <ion-label>{{ processData.ongoingscore }}</ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="!processData.reviewmode || review"> |                 <ion-item class="ion-text-wrap" *ngIf="!processData.reviewmode || review"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <div *ngIf="!processData.reviewmode"> |                         <div *ngIf="!processData.reviewmode"> | ||||||
|                             <core-format-text [component]="component" [componentId]="lesson?.coursemodule" |                             <core-format-text [component]="component" [componentId]="lesson?.coursemodule" [text]="processData.feedback" | ||||||
|                                 [text]="processData.feedback" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" |                                 contextLevel="module" [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> | ||||||
|                                 [courseId]="courseId"> |  | ||||||
|                             </core-format-text> |                             </core-format-text> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div *ngIf="review"> |                         <div *ngIf="review"> | ||||||
| @ -286,8 +282,7 @@ | |||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|                 <ion-button expand="block" class="ion-text-wrap ion-margin" color="light" *ngIf="review" |                 <ion-button expand="block" class="ion-text-wrap ion-margin" color="light" *ngIf="review" (click)="changePage(LESSON_EOL)"> | ||||||
|                     (click)="changePage(LESSON_EOL)"> |  | ||||||
|                     {{ 'addon.mod_lesson.finish' | translate }} |                     {{ 'addon.mod_lesson.finish' | translate }} | ||||||
|                 </ion-button> |                 </ion-button> | ||||||
|                 <ion-button expand="block" class="ion-text-wrap ion-margin" color="light" *ngFor="let button of processDataButtons" |                 <ion-button expand="block" class="ion-text-wrap ion-margin" color="light" *ngFor="let button of processDataButtons" | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.mod_lesson.detailedstats' | translate }}</h1> |             <h1>{{ 'addon.mod_lesson.detailedstats' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -133,8 +135,8 @@ | |||||||
|                                     <ion-label> |                                     <ion-label> | ||||||
|                                         <p> |                                         <p> | ||||||
|                                             <core-format-text [component]="component" [componentId]="lesson?.coursemodule" |                                             <core-format-text [component]="component" [componentId]="lesson?.coursemodule" | ||||||
|                                                 [text]="answer[0].content" contextLevel="module" |                                                 [text]="answer[0].content" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" | ||||||
|                                                 [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> |                                                 [courseId]="courseId"> | ||||||
|                                             </core-format-text> |                                             </core-format-text> | ||||||
|                                         </p> |                                         </p> | ||||||
|                                         <ion-badge *ngIf="answer[1]" color="dark"> |                                         <ion-badge *ngIf="answer[1]" color="dark"> | ||||||
| @ -144,8 +146,7 @@ | |||||||
|                                             </core-format-text> |                                             </core-format-text> | ||||||
|                                         </ion-badge> |                                         </ion-badge> | ||||||
|                                     </ion-label> |                                     </ion-label> | ||||||
|                                     <ion-checkbox [attr.name]="answer[0].name" [ngModel]="answer[0].checked" [disabled]="true" |                                     <ion-checkbox [attr.name]="answer[0].name" [ngModel]="answer[0].checked" [disabled]="true" slot="end"> | ||||||
|                                         slot="end"> |  | ||||||
|                                     </ion-checkbox> |                                     </ion-checkbox> | ||||||
|                                 </ion-item> |                                 </ion-item> | ||||||
| 
 | 
 | ||||||
| @ -213,15 +214,13 @@ | |||||||
|                                 <!-- Another page (end of branch, ...). --> |                                 <!-- Another page (end of branch, ...). --> | ||||||
|                                 <ion-label> |                                 <ion-label> | ||||||
|                                     <p> |                                     <p> | ||||||
|                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" |                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" [text]="answer[0]" | ||||||
|                                             [text]="answer[0]" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" |                                             contextLevel="module" [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> | ||||||
|                                             [courseId]="courseId"> |  | ||||||
|                                         </core-format-text> |                                         </core-format-text> | ||||||
|                                     </p> |                                     </p> | ||||||
|                                     <ion-badge *ngIf="answer[1]" color="dark"> |                                     <ion-badge *ngIf="answer[1]" color="dark"> | ||||||
|                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" |                                         <core-format-text [component]="component" [componentId]="lesson?.coursemodule" [text]="answer[1]" | ||||||
|                                             [text]="answer[1]" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" |                                             contextLevel="module" [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> | ||||||
|                                             [courseId]="courseId"> |  | ||||||
|                                         </core-format-text> |                                         </core-format-text> | ||||||
|                                     </ion-badge> |                                     </ion-badge> | ||||||
|                                 </ion-label> |                                 </ion-label> | ||||||
| @ -233,14 +232,16 @@ | |||||||
|                                 <h3 class="item-heading">{{ 'addon.mod_lesson.response' | translate }}</h3> |                                 <h3 class="item-heading">{{ 'addon.mod_lesson.response' | translate }}</h3> | ||||||
|                                 <p> |                                 <p> | ||||||
|                                     <core-format-text [component]="component" [componentId]="lesson?.coursemodule" |                                     <core-format-text [component]="component" [componentId]="lesson?.coursemodule" | ||||||
|                                         [text]="page.answerdata.response" contextLevel="module" |                                         [text]="page.answerdata.response" contextLevel="module" [contextInstanceId]="lesson?.coursemodule" | ||||||
|                                         [contextInstanceId]="lesson?.coursemodule" [courseId]="courseId"> |                                         [courseId]="courseId"> | ||||||
|                                     </core-format-text> |                                     </core-format-text> | ||||||
|                                 </p> |                                 </p> | ||||||
|                             </ion-label> |                             </ion-label> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                         <ion-item class="ion-text-wrap" *ngIf="page.answerdata.score"> |                         <ion-item class="ion-text-wrap" *ngIf="page.answerdata.score"> | ||||||
|                             <ion-label><p>{{page.answerdata.score}}</p></ion-label> |                             <ion-label> | ||||||
|  |                                 <p>{{page.answerdata.score}}</p> | ||||||
|  |                             </ion-label> | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                     </div> |                     </div> | ||||||
|                 </ion-card> |                 </ion-card> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -20,14 +20,11 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="safe-area-padding"> | <core-loading [hideUntil]="loaded" class="safe-area-padding"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [description]="lti && lti.showdescriptionlaunch && description" [component]="component" [componentId]="componentId" | ||||||
|  |         [courseId]="courseId"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description *ngIf="lti && lti.showdescriptionlaunch" [description]="description" [component]="component" |  | ||||||
|         [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <div class="ion-padding"> |     <div class="ion-padding"> | ||||||
|         <ion-button expand="block" (click)="launch()"> |         <ion-button expand="block" (click)="launch()"> | ||||||
|             <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> |             <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" |         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" | ||||||
|             [iconAction]="refreshIcon" [closeOnClick]="false"> |             [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -26,14 +26,10 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="safe-area-padding"> | <core-loading [hideUntil]="loaded" class="safe-area-padding"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="displayDescription && description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description *ngIf="displayDescription" [description]="description" [component]="component" |  | ||||||
|         [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <ion-card class="core-warning-card" *ngIf="warning"> |     <ion-card class="core-warning-card" *ngIf="warning"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
|             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'far-newspaper'" | ||||||
|             [iconAction]="'far-newspaper'" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -29,19 +29,18 @@ | |||||||
| <core-loading [hideUntil]="loaded"> | <core-loading [hideUntil]="loaded"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId" | ||||||
|  |         [hasDataToSync]="buttonText && hasOffline && !showStatusSpinner"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <!-- Access rules description messages. --> |     <!-- Access rules description messages. --> | ||||||
|     <ion-card *ngIf="gradeMethodReadable || accessRules.length || syncTime"> |     <ion-card *ngIf="gradeMethodReadable || accessRules.length || syncTime"> | ||||||
|         <ion-list> |         <ion-list> | ||||||
|             <ion-item class="ion-text-wrap" *ngFor="let rule of accessRules"> |             <ion-item class="ion-text-wrap" *ngFor="let rule of accessRules"> | ||||||
|                 <ion-label><p>{{ rule }}</p></ion-label> |                 <ion-label> | ||||||
|  |                     <p>{{ rule }}</p> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="gradeMethodReadable"> |             <ion-item class="ion-text-wrap" *ngIf="gradeMethodReadable"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
| @ -96,15 +95,9 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
|             <div role="rowgroup"> |             <div role="rowgroup"> | ||||||
|                 <!-- List of attempts. --> |                 <!-- List of attempts. --> | ||||||
|                 <ion-item |                 <ion-item button detail="true" *ngFor="let attempt of attempts" class="ion-text-wrap" | ||||||
|                     button |                     [ngClass]='{"addon-mod_quiz-highlighted": attempt.highlightGrade}' [attr.aria-label]="'core.seemoredetail' | translate" | ||||||
|                     detail="true" |                     (click)="viewAttempt(attempt.id)"> | ||||||
|                     *ngFor="let attempt of attempts" |  | ||||||
|                     class="ion-text-wrap" |  | ||||||
|                     [ngClass]='{"addon-mod_quiz-highlighted": attempt.highlightGrade}' |  | ||||||
|                     [attr.aria-label]="'core.seemoredetail' | translate" |  | ||||||
|                     (click)="viewAttempt(attempt.id)" |  | ||||||
|                 > |  | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <ion-row class="ion-align-items-center" role="row"> |                         <ion-row class="ion-align-items-center" role="row"> | ||||||
|                             <ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && attempt.preview" role="cell"> |                             <ion-col class="ion-text-center" *ngIf="quiz.showAttemptColumn && attempt.preview" role="cell"> | ||||||
| @ -142,17 +135,21 @@ | |||||||
|             <ion-item class="ion-text-wrap" *ngIf="gradebookFeedback"> |             <ion-item class="ion-text-wrap" *ngIf="gradebookFeedback"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <p class="item-heading">{{ 'addon.mod_quiz.comment' | translate }}</p> |                     <p class="item-heading">{{ 'addon.mod_quiz.comment' | translate }}</p> | ||||||
|                     <p><core-format-text [component]="component" [componentId]="componentId" [text]="gradebookFeedback" |                     <p> | ||||||
|  |                         <core-format-text [component]="component" [componentId]="componentId" [text]="gradebookFeedback" | ||||||
|                             contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                             contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|                     </core-format-text></p> |                         </core-format-text> | ||||||
|  |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap" *ngIf="quiz.showFeedbackColumn && overallFeedback"> |             <ion-item class="ion-text-wrap" *ngIf="quiz.showFeedbackColumn && overallFeedback"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <p class="item-heading">{{ 'addon.mod_quiz.overallfeedback' | translate }}</p> |                     <p class="item-heading">{{ 'addon.mod_quiz.overallfeedback' | translate }}</p> | ||||||
|                     <p><core-format-text [component]="component" [componentId]="componentId" [text]="overallFeedback" |                     <p> | ||||||
|                         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |                         <core-format-text [component]="component" [componentId]="componentId" [text]="overallFeedback" contextLevel="module" | ||||||
|                     </core-format-text></p> |                             [contextInstanceId]="module.id" [courseId]="courseId"> | ||||||
|  |                         </core-format-text> | ||||||
|  |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-list> |         </ion-list> | ||||||
| @ -163,10 +160,14 @@ | |||||||
|         <ion-list> |         <ion-list> | ||||||
|             <!-- Error messages. --> |             <!-- Error messages. --> | ||||||
|             <ion-item class="ion-text-wrap core-danger-item addon-mod_quiz-prevent-messages" *ngFor="let message of preventMessages"> |             <ion-item class="ion-text-wrap core-danger-item addon-mod_quiz-prevent-messages" *ngFor="let message of preventMessages"> | ||||||
|                 <ion-label><p>{{ message }}</p></ion-label> |                 <ion-label> | ||||||
|  |                     <p>{{ message }}</p> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap core-danger-item addon-mod_quiz-no-questions" *ngIf="quiz.hasquestions === 0"> |             <ion-item class="ion-text-wrap core-danger-item addon-mod_quiz-no-questions" *ngIf="quiz.hasquestions === 0"> | ||||||
|                 <ion-label><p>{{ 'addon.mod_quiz.noquestions' | translate }}</p></ion-label> |                 <ion-label> | ||||||
|  |                     <p>{{ 'addon.mod_quiz.noquestions' | translate }}</p> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="ion-text-wrap core-danger-item addon-mod_quiz-unsupported-questions" |             <ion-item class="ion-text-wrap core-danger-item addon-mod_quiz-unsupported-questions" | ||||||
|                 *ngIf="!hasSupportedQuestions && unsupportedQuestions.length"> |                 *ngIf="!hasSupportedQuestions && unsupportedQuestions.length"> | ||||||
| @ -194,14 +195,6 @@ | |||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <!-- Quiz has data to be synchronized --> |  | ||||||
|             <ion-card class="core-warning-card" *ngIf="buttonText && hasOffline && !showStatusSpinner"> |  | ||||||
|                 <ion-item class="ion-text-wrap"> |  | ||||||
|                     <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> |  | ||||||
| 
 |  | ||||||
|             <!-- Other warnings. --> |             <!-- Other warnings. --> | ||||||
|             <ion-item class="core-warning-item ion-text-wrap" *ngIf="hasSupportedQuestions && unsupportedQuestions.length"> |             <ion-item class="core-warning-item ion-text-wrap" *ngIf="hasSupportedQuestions && unsupportedQuestions.length"> | ||||||
|                 <ion-label> |                 <ion-label> | ||||||
| @ -226,7 +219,9 @@ | |||||||
| 
 | 
 | ||||||
|             <!-- Spinner shown while downloading or calculating. --> |             <!-- Spinner shown while downloading or calculating. --> | ||||||
|             <ion-item class="ion-text-center" *ngIf="showStatusSpinner"> |             <ion-item class="ion-text-center" *ngIf="showStatusSpinner"> | ||||||
|                 <ion-label><ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner></ion-label> |                 <ion-label> | ||||||
|  |                     <ion-spinner [attr.aria-label]="'core.loading' | translate"></ion-spinner> | ||||||
|  |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-list> |         </ion-list> | ||||||
|     </ion-card> |     </ion-card> | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2>{{ 'addon.mod_quiz.quiznavigation' | translate }}</h2> |             <h2>{{ 'addon.mod_quiz.quiznavigation' | translate }}</h2> | ||||||
| 
 |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
| @ -41,12 +42,12 @@ | |||||||
|                 <ion-icon *ngIf="question.stateClass == 'core-question-correct'" name="fas-check" color="success" |                 <ion-icon *ngIf="question.stateClass == 'core-question-correct'" name="fas-check" color="success" | ||||||
|                     [attr.aria-label]="question.status" slot="end"> |                     [attr.aria-label]="question.status" slot="end"> | ||||||
|                 </ion-icon> |                 </ion-icon> | ||||||
|                 <ion-icon *ngIf="question.stateClass == 'core-question-partiallycorrect'" name="fas-check-square" |                 <ion-icon *ngIf="question.stateClass == 'core-question-partiallycorrect'" name="fas-check-square" color="warning" | ||||||
|                     color="warning" [attr.aria-label]="question.status" slot="end"> |                     [attr.aria-label]="question.status" slot="end"> | ||||||
|                 </ion-icon> |                 </ion-icon> | ||||||
|                 <ion-icon *ngIf="question.stateClass == 'core-question-incorrect' || |                 <ion-icon *ngIf="question.stateClass == 'core-question-incorrect' || | ||||||
|                     question.stateClass == 'core-question-notanswered'" name="fas-times" color="danger" |                     question.stateClass == 'core-question-notanswered'" name="fas-times" color="danger" [attr.aria-label]="question.status" | ||||||
|                     [attr.aria-label]="question.status" slot="end"> |                     slot="end"> | ||||||
|                 </ion-icon> |                 </ion-icon> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,7 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|  |         <ion-title> | ||||||
|             <h2>{{ title | translate }}</h2> |             <h2>{{ title | translate }}</h2> | ||||||
| 
 |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
|  | |||||||
| @ -3,11 +3,13 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text *ngIf="quiz" [text]="quiz.name" contextLevel="module" [contextInstanceId]="quiz.coursemodule" |                 <core-format-text *ngIf="quiz" [text]="quiz.name" contextLevel="module" [contextInstanceId]="quiz.coursemodule" | ||||||
|                     [courseId]="courseId"> |                     [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
| @ -45,8 +47,8 @@ | |||||||
|                 <ion-label> |                 <ion-label> | ||||||
|                     <h2>{{ 'addon.mod_quiz.feedback' | translate }}</h2> |                     <h2>{{ 'addon.mod_quiz.feedback' | translate }}</h2> | ||||||
|                     <p> |                     <p> | ||||||
|                         <core-format-text [component]="component" [componentId]="componentId" [text]="feedback" |                         <core-format-text [component]="component" [componentId]="componentId" [text]="feedback" contextLevel="module" | ||||||
|                             contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                             [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                         </core-format-text> |                         </core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -3,11 +3,13 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text *ngIf="quiz" [text]="quiz.name" contextLevel="module" [contextInstanceId]="quiz.coursemodule" |                 <core-format-text *ngIf="quiz" [text]="quiz.name" contextLevel="module" [contextInstanceId]="quiz.coursemodule" | ||||||
|                     [courseId]="courseId"> |                     [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" id="addon-mod_quiz-connection-error-button" [hidden]="!autoSaveError" |             <ion-button fill="clear" id="addon-mod_quiz-connection-error-button" [hidden]="!autoSaveError" | ||||||
| @ -15,8 +17,7 @@ | |||||||
|                 aria-haspopup="dialog"> |                 aria-haspopup="dialog"> | ||||||
|                 <ion-icon name="fas-exclamation-circle" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-exclamation-circle" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
|             <ion-button *ngIf="navigation.length" [attr.aria-label]="'addon.mod_quiz.opentoc' | translate" |             <ion-button *ngIf="navigation.length" [attr.aria-label]="'addon.mod_quiz.opentoc' | translate" (click)="openNavigation()"> | ||||||
|                 (click)="openNavigation()"> |  | ||||||
|                 <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
| @ -24,8 +25,7 @@ | |||||||
|     <!-- Navigation arrows and time left. --> |     <!-- Navigation arrows and time left. --> | ||||||
|     <ion-toolbar *ngIf="loaded && endTime && questions.length && !quizAborted && !showSummary" color="light"> |     <ion-toolbar *ngIf="loaded && endTime && questions.length && !quizAborted && !showSummary" color="light"> | ||||||
|         <ion-title> |         <ion-title> | ||||||
|             <core-timer [endTime]="endTime" (finished)="timeUp()" [timerText]="'addon.mod_quiz.timeleft' | translate" |             <core-timer [endTime]="endTime" (finished)="timeUp()" [timerText]="'addon.mod_quiz.timeleft' | translate" [align]="'center'"> | ||||||
|                 [align]="'center'"> |  | ||||||
|             </core-timer> |             </core-timer> | ||||||
|         </ion-title> |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
| @ -79,10 +79,9 @@ | |||||||
|                     </ion-item-divider> |                     </ion-item-divider> | ||||||
| 
 | 
 | ||||||
|                     <!-- Body of the question. --> |                     <!-- Body of the question. --> | ||||||
|                     <core-question class="ion-text-wrap" [question]="question" [component]="component" |                     <core-question class="ion-text-wrap" [question]="question" [component]="component" [componentId]="cmId" | ||||||
|                         [componentId]="cmId" [attemptId]="attempt!.id" [usageId]="attempt!.uniqueid" |                         [attemptId]="attempt!.id" [usageId]="attempt!.uniqueid" [offlineEnabled]="offline" contextLevel="module" | ||||||
|                         [offlineEnabled]="offline" contextLevel="module" [contextInstanceId]="cmId" |                         [contextInstanceId]="cmId" [courseId]="courseId" [preferredBehaviour]="quiz!.preferredbehaviour" [review]="false" | ||||||
|                         [courseId]="courseId" [preferredBehaviour]="quiz!.preferredbehaviour" [review]="false" |  | ||||||
|                         (onAbort)="abortQuiz()" (buttonClicked)="behaviourButtonClicked($event)"> |                         (onAbort)="abortQuiz()" (buttonClicked)="behaviourButtonClicked($event)"> | ||||||
|                     </core-question> |                     </core-question> | ||||||
|                 </ion-card> |                 </ion-card> | ||||||
| @ -92,7 +91,7 @@ | |||||||
|         <!-- Go to next or previous page. --> |         <!-- Go to next or previous page. --> | ||||||
|         <ion-grid class="ion-text-wrap" *ngIf="questions.length && !quizAborted && !showSummary"> |         <ion-grid class="ion-text-wrap" *ngIf="questions.length && !quizAborted && !showSummary"> | ||||||
|             <ion-row> |             <ion-row> | ||||||
|                 <ion-col *ngIf="previousPage >= 0" > |                 <ion-col *ngIf="previousPage >= 0"> | ||||||
|                     <ion-button expand="block" color="light" (click)="changePage(previousPage)"> |                     <ion-button expand="block" color="light" (click)="changePage(previousPage)"> | ||||||
|                         <ion-icon name="fas-chevron-left" slot="start" aria-hidden="true"></ion-icon> |                         <ion-icon name="fas-chevron-left" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                         {{ 'core.previous' | translate }} |                         {{ 'core.previous' | translate }} | ||||||
| @ -131,8 +130,8 @@ | |||||||
|             <!-- List of questions of the summary table. --> |             <!-- List of questions of the summary table. --> | ||||||
|             <ng-container *ngFor="let question of summaryQuestions"> |             <ng-container *ngFor="let question of summaryQuestions"> | ||||||
|                 <ion-item *ngIf="question.number" (click)="changePage(question.page, false, question.slot)" |                 <ion-item *ngIf="question.number" (click)="changePage(question.page, false, question.slot)" | ||||||
|                     [attr.aria-label]="'core.question.questionno' | translate:{$a: question.number}" |                     [attr.aria-label]="'core.question.questionno' | translate:{$a: question.number}" [detail]="!isSequential && canReturn" | ||||||
|                     [detail]="!isSequential && canReturn" [button]="!isSequential && canReturn"> |                     [button]="!isSequential && canReturn"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <ion-row class="ion-align-items-center"> |                         <ion-row class="ion-align-items-center"> | ||||||
|                             <ion-col size="3" class="ion-text-center">{{ question.number }}</ion-col> |                             <ion-col size="3" class="ion-text-center">{{ question.number }}</ion-col> | ||||||
| @ -153,8 +152,7 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <!-- Time left (if quiz is timed). --> |             <!-- Time left (if quiz is timed). --> | ||||||
|             <core-timer *ngIf="endTime" [endTime]="endTime" (finished)="timeUp()" |             <core-timer *ngIf="endTime" [endTime]="endTime" (finished)="timeUp()" [timerText]="'addon.mod_quiz.timeleft' | translate"> | ||||||
|                 [timerText]="'addon.mod_quiz.timeleft' | translate"> |  | ||||||
|             </core-timer> |             </core-timer> | ||||||
| 
 | 
 | ||||||
|             <!-- List of messages explaining why the quiz cannot be submitted. --> |             <!-- List of messages explaining why the quiz cannot be submitted. --> | ||||||
| @ -165,15 +163,14 @@ | |||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <ion-button *ngIf="preventSubmitMessages.length" expand="block" [href]="moduleUrl" core-link |             <ion-button *ngIf="preventSubmitMessages.length" expand="block" [href]="moduleUrl" core-link [showBrowserWarning]="false"> | ||||||
|                 [showBrowserWarning]="false"> |  | ||||||
|                 {{ 'core.openinbrowser' | translate }} |                 {{ 'core.openinbrowser' | translate }} | ||||||
|                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
| 
 | 
 | ||||||
|             <!-- Button to submit the quiz. --> |             <!-- Button to submit the quiz. --> | ||||||
|             <ion-button *ngIf="!attempt!.finishedOffline && !preventSubmitMessages.length" expand="block" |             <ion-button *ngIf="!attempt!.finishedOffline && !preventSubmitMessages.length" expand="block" class="ion-margin" | ||||||
|                 class="ion-margin" (click)="finishAttempt(true)"> |                 (click)="finishAttempt(true)"> | ||||||
|                 {{ 'addon.mod_quiz.submitallandfinish' | translate }} |                 {{ 'addon.mod_quiz.submitallandfinish' | translate }} | ||||||
|             </ion-button> |             </ion-button> | ||||||
|         </ion-card> |         </ion-card> | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1>{{ 'addon.mod_quiz.review' | translate }}</h1> |             <h1>{{ 'addon.mod_quiz.review' | translate }}</h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" *ngIf="navigation.length" [attr.aria-label]="'addon.mod_quiz.opentoc' | translate" |             <ion-button fill="clear" *ngIf="navigation.length" [attr.aria-label]="'addon.mod_quiz.opentoc' | translate" | ||||||
| @ -75,8 +77,8 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngFor="let data of additionalData"> |                 <ion-item class="ion-text-wrap" *ngFor="let data of additionalData"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <p class="item-heading">{{ data.title }}</p> |                         <p class="item-heading">{{ data.title }}</p> | ||||||
|                         <core-format-text [component]="component" [componentId]="cmId" [text]="data.content" |                         <core-format-text [component]="component" [componentId]="cmId" [text]="data.content" contextLevel="module" | ||||||
|                             contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                             [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                         </core-format-text> |                         </core-format-text> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| @ -107,8 +109,7 @@ | |||||||
|                     <!-- Body of the question. --> |                     <!-- Body of the question. --> | ||||||
|                     <core-question class="ion-text-wrap" [question]="question" [component]="component" [componentId]="cmId" |                     <core-question class="ion-text-wrap" [question]="question" [component]="component" [componentId]="cmId" | ||||||
|                         [attemptId]="attempt.id" [usageId]="attempt.uniqueid" [offlineEnabled]="false" contextLevel="module" |                         [attemptId]="attempt.id" [usageId]="attempt.uniqueid" [offlineEnabled]="false" contextLevel="module" | ||||||
|                         [contextInstanceId]="cmId" [courseId]="courseId" [review]="true" |                         [contextInstanceId]="cmId" [courseId]="courseId" [review]="true" [preferredBehaviour]="quiz?.preferredbehaviour"> | ||||||
|                         [preferredBehaviour]="quiz?.preferredbehaviour"> |  | ||||||
|                     </core-question> |                     </core-question> | ||||||
|                 </ion-card> |                 </ion-card> | ||||||
|             </div> |             </div> | ||||||
| @ -130,8 +131,7 @@ | |||||||
|                 </ion-button> |                 </ion-button> | ||||||
|             </ion-col> |             </ion-col> | ||||||
|             <ion-col class="ion-text-end"> |             <ion-col class="ion-text-end"> | ||||||
|                 <ion-button color="light" *ngIf="nextPage >= -1" (click)="changePage(nextPage)" |                 <ion-button color="light" *ngIf="nextPage >= -1" (click)="changePage(nextPage)" [attr.aria-label]="'core.next' | translate"> | ||||||
|                     [attr.aria-label]="'core.next' | translate"> |  | ||||||
|                     <ion-icon name="fas-chevron-right" slot="icon-only" aria-hidden="true"></ion-icon> |                     <ion-icon name="fas-chevron-right" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|                 </ion-button> |                 </ion-button> | ||||||
|             </ion-col> |             </ion-col> | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"></core-context-menu-item> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> |             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"></core-context-menu-item> |             (action)="gotoBlog()"></core-context-menu-item> | ||||||
|         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" |         <core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" | ||||||
|             [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> |             [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" |         <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)" | ||||||
| @ -21,15 +21,11 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="safe-area-padding core-loading-fullheight"> | <core-loading [hideUntil]="loaded" class="safe-area-padding core-loading-fullheight"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" [courseId]="courseId" (completionChanged)="onCompletionChange()" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [description]="mode != 'iframe' && (mode != 'embedded' || displayDescription) && description" [component]="component" | ||||||
|  |         [componentId]="componentId"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description *ngIf="mode != 'iframe' && (mode != 'embedded' || displayDescription)" |  | ||||||
|         [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" |  | ||||||
|         [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <ion-card class="core-warning-card" *ngIf="warning"> |     <ion-card class="core-warning-card" *ngIf="warning"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
|             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |             <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
| @ -14,8 +16,7 @@ | |||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|     <ion-refresher slot="fixed" |     <ion-refresher slot="fixed" [disabled]="!activityComponent?.loaded || activityComponent?.mode == 'iframe'" | ||||||
|         [disabled]="!activityComponent?.loaded || activityComponent?.mode == 'iframe'" |  | ||||||
|         (ionRefresh)="activityComponent?.doRefresh($event.target)"> |         (ionRefresh)="activityComponent?.doRefresh($event.target)"> | ||||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> |         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|     </ion-refresher> |     </ion-refresher> | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
| import { CoreConstants } from '@/core/constants'; | import { CoreConstants } from '@/core/constants'; | ||||||
| import { Injectable, Type } from '@angular/core'; | import { Injectable, Type } from '@angular/core'; | ||||||
| import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler'; | import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler'; | ||||||
| import { CoreCourse } from '@features/course/services/course'; | import { CoreCourse, CoreCourseWSModule } from '@features/course/services/course'; | ||||||
| import { CoreCourseModule } from '@features/course/services/course-helper'; | import { CoreCourseModule } from '@features/course/services/course-helper'; | ||||||
| import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; | import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate'; | ||||||
| import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; | import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; | ||||||
| @ -226,6 +226,32 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase | |||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * @inheritdoc | ||||||
|  |      */ | ||||||
|  |     async getIconSrc(module?: CoreCourseWSModule): Promise<string | undefined> { | ||||||
|  |         if (!module) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         let mimetypeIcon = ''; | ||||||
|  | 
 | ||||||
|  |         if ('contentsinfo' in module && module.contentsinfo) { | ||||||
|  |             // No need to use the list of files.
 | ||||||
|  |             const mimetype = module.contentsinfo.mimetypes[0]; | ||||||
|  |             if (mimetype) { | ||||||
|  |                 mimetypeIcon = CoreMimetypeUtils.getMimetypeIcon(mimetype); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } else if (module.contents && module.contents[0]) { | ||||||
|  |             const files = module.contents; | ||||||
|  |             const file = files[0]; | ||||||
|  | 
 | ||||||
|  |             mimetypeIcon = CoreMimetypeUtils.getFileIcon(file.filename || ''); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return await CoreCourse.getModuleIconSrc(module.modname, module.modicon, mimetypeIcon); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * @inheritdoc |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -1,14 +1,14 @@ | |||||||
| <!-- Buttons to add to the header. --> | <!-- Buttons to add to the header. --> | ||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> |             iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" iconAction="far-newspaper" | ||||||
|             iconAction="far-newspaper" (action)="gotoBlog()"> |             (action)="gotoBlog()"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" |         <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate" | ||||||
|             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> |             (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"> | ||||||
| @ -29,14 +29,10 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="safe-area-padding"> | <core-loading [hideUntil]="loaded" class="safe-area-padding"> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity info. --> |     <!-- Activity info. --> | ||||||
|     <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" |     <core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description" | ||||||
|         (completionChanged)="onCompletionChange()"> |         [component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="!errorMessage && hasOffline"> | ||||||
|     </core-course-module-info> |     </core-course-module-info> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" |  | ||||||
|         contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> |  | ||||||
|     </core-course-module-description> |  | ||||||
| 
 |  | ||||||
|     <!-- Warning message. --> |     <!-- Warning message. --> | ||||||
|     <ion-card class="core-info-card" *ngIf="scorm && scorm.warningMessage"> |     <ion-card class="core-info-card" *ngIf="scorm && scorm.warningMessage"> | ||||||
|         <ion-item> |         <ion-item> | ||||||
| @ -117,14 +113,6 @@ | |||||||
|             </ion-list> |             </ion-list> | ||||||
|         </ion-card> |         </ion-card> | ||||||
| 
 | 
 | ||||||
|         <!-- Synchronization warning. --> |  | ||||||
|         <ion-card class="core-warning-card" *ngIf="!errorMessage && hasOffline"> |  | ||||||
|             <ion-item> |  | ||||||
|                 <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> |  | ||||||
| 
 |  | ||||||
|         <!-- TOC. --> |         <!-- TOC. --> | ||||||
|         <ion-card *ngIf="scorm && organizations && !skip && |         <ion-card *ngIf="scorm && organizations && !skip && | ||||||
|             ((scorm.displaycoursestructure && organizations.length) || organizations.length > 1)" class="addon-mod_scorm-toc"> |             ((scorm.displaycoursestructure && organizations.length) || organizations.length > 1)" class="addon-mod_scorm-toc"> | ||||||
| @ -134,8 +122,8 @@ | |||||||
|             <ion-list> |             <ion-list> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="organizations.length > 1"> |                 <ion-item class="ion-text-wrap" *ngIf="organizations.length > 1"> | ||||||
|                     <ion-label>{{ 'addon.mod_scorm.organizations' | translate }}</ion-label> |                     <ion-label>{{ 'addon.mod_scorm.organizations' | translate }}</ion-label> | ||||||
|                     <ion-select [(ngModel)]="currentOrganization.identifier" (ionChange)="loadOrganization()" |                     <ion-select [(ngModel)]="currentOrganization.identifier" (ionChange)="loadOrganization()" interface="action-sheet" | ||||||
|                         interface="action-sheet" [interfaceOptions]="{header: 'addon.mod_scorm.organizations' | translate}"> |                         [interfaceOptions]="{header: 'addon.mod_scorm.organizations' | translate}"> | ||||||
|                         <ion-select-option *ngFor="let org of organizations" [value]="org.identifier"> |                         <ion-select-option *ngFor="let org of organizations" [value]="org.identifier"> | ||||||
|                             {{ org.title }} |                             {{ org.title }} | ||||||
|                         </ion-select-option> |                         </ion-select-option> | ||||||
| @ -155,8 +143,7 @@ | |||||||
|                         <p>{{ currentOrganization.title }}</p> |                         <p>{{ currentOrganization.title }}</p> | ||||||
|                         <div *ngFor="let sco of toc" class="core-padding-{{sco.level}} addon-mod_scorm-type-{{sco.scormtype}}"> |                         <div *ngFor="let sco of toc" class="core-padding-{{sco.level}} addon-mod_scorm-type-{{sco.scormtype}}"> | ||||||
|                             <p *ngIf="sco.isvisible"> |                             <p *ngIf="sco.isvisible"> | ||||||
|                                 <ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" |                                 <ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" slot="start"> | ||||||
|                                     slot="start"> |  | ||||||
|                                 </ion-icon> |                                 </ion-icon> | ||||||
|                                 <button class="as-link" *ngIf="sco.prereq && sco.launch" (click)="open($event, false, sco.id)"> |                                 <button class="as-link" *ngIf="sco.prereq && sco.launch" (click)="open($event, false, sco.id)"> | ||||||
|                                     <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" |                                     <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="module.id" | ||||||
| @ -205,8 +192,7 @@ | |||||||
|             <ion-list> |             <ion-list> | ||||||
|                 <ng-container *ngIf="!downloading && !skip"> |                 <ng-container *ngIf="!downloading && !skip"> | ||||||
|                     <!-- Create new attempt --> |                     <!-- Create new attempt --> | ||||||
|                     <ion-item class="ion-text-wrap" |                     <ion-item class="ion-text-wrap" *ngIf="!scorm.forcenewattempt && numAttempts > 0 && !incomplete && attemptsLeft > 0"> | ||||||
|                         *ngIf="!scorm.forcenewattempt && numAttempts > 0 && !incomplete && attemptsLeft > 0"> |  | ||||||
|                         <ion-label>{{ 'addon.mod_scorm.newattempt' | translate }}</ion-label> |                         <ion-label>{{ 'addon.mod_scorm.newattempt' | translate }}</ion-label> | ||||||
|                         <ion-checkbox slot="end" name="newAttempt" [(ngModel)]="startNewAttempt"> |                         <ion-checkbox slot="end" name="newAttempt" [(ngModel)]="startNewAttempt"> | ||||||
|                         </ion-checkbox> |                         </ion-checkbox> | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <h1>{{ 'addon.mod_scorm.toc' | translate }}</h1> |         <ion-title> | ||||||
|  |             <h2>{{ 'addon.mod_scorm.toc' | translate }}</h2> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <ion-button fill="clear" (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> |                 <ion-icon slot="icon-only" name="fas-times" aria-hidden="true"></ion-icon> | ||||||
| @ -36,8 +38,7 @@ | |||||||
|                     <ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" slot="start"> |                     <ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" slot="start"> | ||||||
|                     </ion-icon> |                     </ion-icon> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="moduleId" |                         <core-format-text [text]="sco.title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"> | ||||||
|                             [courseId]="courseId"> |  | ||||||
|                         </core-format-text> |                         </core-format-text> | ||||||
|                         <span *ngIf="accessInfo && accessInfo.canviewscores && sco.scoreraw"> |                         <span *ngIf="accessInfo && accessInfo.canviewscores && sco.scoreraw"> | ||||||
|                             ({{ 'addon.mod_scorm.score' | translate }}: {{sco.scoreraw}}) |                             ({{ 'addon.mod_scorm.score' | translate }}: {{sco.scoreraw}}) | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| <ion-header> | <ion-header collapsible> | ||||||
|     <ion-toolbar> |     <ion-toolbar> | ||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  | |||||||
| @ -3,14 +3,16 @@ | |||||||
|         <ion-buttons slot="start"> |         <ion-buttons slot="start"> | ||||||
|             <ion-back-button [text]="'core.back' | translate"></ion-back-button> |             <ion-back-button [text]="'core.back' | translate"></ion-back-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|  |         <ion-title> | ||||||
|             <h1> |             <h1> | ||||||
|                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> |                 <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"> | ||||||
|                 </core-format-text> |                 </core-format-text> | ||||||
|             </h1> |             </h1> | ||||||
|  |         </ion-title> | ||||||
|         <ion-buttons slot="end"> |         <ion-buttons slot="end"> | ||||||
|             <core-button-with-spinner *ngIf="showToc" [loading]="loadingToc"> |             <core-button-with-spinner *ngIf="showToc" [loading]="loadingToc"> | ||||||
|                 <ion-button fill="clear" *ngIf="toc.length" (click)="openToc()" |                 <ion-button fill="clear" *ngIf="toc.length" (click)="openToc()" [attr.aria-label]="'addon.mod_scorm.toc' | translate" | ||||||
|                     [attr.aria-label]="'addon.mod_scorm.toc' | translate" aria-haspopup="true"> |                     aria-haspopup="true"> | ||||||
|                     <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> |                     <ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon> | ||||||
|                 </ion-button> |                 </ion-button> | ||||||
|             </core-button-with-spinner> |             </core-button-with-spinner> | ||||||
|  | |||||||
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