Merge pull request #3011 from NoelDeMartin/MOBILE-3833
MOBILE-3833: Configure formatting & implement privacy provider for behat
This commit is contained in:
		
						commit
						683c5f4e5a
					
				
							
								
								
									
										18
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@ -1,5 +1,23 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Formatting.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    "editor.defaultFormatter": "dbaeumer.vscode-eslint",
 | 
				
			||||||
 | 
					    "[html]": {
 | 
				
			||||||
 | 
					        "editor.defaultFormatter": "vscode.html-language-features",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "editor.formatOnSave": true,
 | 
				
			||||||
 | 
					    "eslint.format.enable": true,
 | 
				
			||||||
 | 
					    "html.format.endWithNewline": true,
 | 
				
			||||||
 | 
					    "html.format.wrapLineLength": 140,
 | 
				
			||||||
 | 
					    "files.trimFinalNewlines": true,
 | 
				
			||||||
 | 
					    "files.insertFinalNewline": true,
 | 
				
			||||||
 | 
					    "files.trimTrailingWhitespace": true,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Config files.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    "files.associations": {
 | 
					    "files.associations": {
 | 
				
			||||||
        "moodle.config.json": "jsonc",
 | 
					        "moodle.config.json": "jsonc",
 | 
				
			||||||
        "moodle.config.*.json": "jsonc",
 | 
					        "moodle.config.*.json": "jsonc",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										32
									
								
								scripts/templates/behat-plugin/classes/privacy/provider.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								scripts/templates/behat-plugin/classes/privacy/provider.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					// This file is part of Moodle - http://moodle.org/
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Moodle is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Moodle is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace local_moodleappbehat\privacy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use core_privacy\local\metadata\null_provider;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defined('MOODLE_INTERNAL') || die();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class provider implements null_provider {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @inheritdoc
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function get_reason() : string {
 | 
				
			||||||
 | 
					        return 'privacy_metadata';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$string['pluginname'] = 'Moodle App Behat (auto-generated)';
 | 
					$string['pluginname'] = 'Moodle App Behat (auto-generated)';
 | 
				
			||||||
 | 
					$string['privacy_metadata'] = 'This plugin should only be used in development environments, and it does not store any user data.';
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,7 @@
 | 
				
			|||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item-divider>
 | 
					</ion-item-divider>
 | 
				
			||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false">
 | 
					<core-loading [hideUntil]="loaded" [fullscreen]="false">
 | 
				
			||||||
    <ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="true" button
 | 
					    <ion-item class="ion-text-wrap item-media" *ngFor="let entry of entries" detail="true" button (click)="gotoCoureListModType(entry)">
 | 
				
			||||||
        (click)="gotoCoureListModType(entry)">
 | 
					 | 
				
			||||||
        <core-mod-icon slot="start" [modicon]="entry.icon" [modname]="entry.modName" [showAlt]="false">
 | 
					        <core-mod-icon slot="start" [modicon]="entry.icon" [modname]="entry.modName" [showAlt]="false">
 | 
				
			||||||
        </core-mod-icon>
 | 
					        </core-mod-icon>
 | 
				
			||||||
        <ion-label>{{ entry.name }}</ion-label>
 | 
					        <ion-label>{{ entry.name }}</ion-label>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,25 +1,23 @@
 | 
				
			|||||||
<ion-item-divider sticky="true">
 | 
					<ion-item-divider sticky="true">
 | 
				
			||||||
    <ion-label><h2>{{ 'addon.block_recentlyaccesseditems.pluginname' | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ 'addon.block_recentlyaccesseditems.pluginname' | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
    <div slot="end">
 | 
					    <div slot="end">
 | 
				
			||||||
        <core-horizontal-scroll-controls #scrollControls [aria-controls]="scrollElementId">
 | 
					        <core-horizontal-scroll-controls #scrollControls [aria-controls]="scrollElementId">
 | 
				
			||||||
        </core-horizontal-scroll-controls>
 | 
					        </core-horizontal-scroll-controls>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</ion-item-divider>
 | 
					</ion-item-divider>
 | 
				
			||||||
<core-loading [hideUntil]="loaded" [fullscreen]="false">
 | 
					<core-loading [hideUntil]="loaded" [fullscreen]="false">
 | 
				
			||||||
    <div
 | 
					    <div [id]="scrollElementId" [hidden]="!items || items.length === 0" class="core-horizontal-scroll"
 | 
				
			||||||
        [id]="scrollElementId"
 | 
					        (scroll)="scrollControls.updateScrollPosition()">
 | 
				
			||||||
        [hidden]="!items || items.length === 0"
 | 
					 | 
				
			||||||
        class="core-horizontal-scroll"
 | 
					 | 
				
			||||||
        (scroll)="scrollControls.updateScrollPosition()"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
        <div *ngIf="items" (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
 | 
					        <div *ngIf="items" (onResize)="scrollControls.updateScrollPosition()" class="flex-row">
 | 
				
			||||||
            <div class="safe-area-pseudo-padding-start"></div>
 | 
					            <div class="safe-area-pseudo-padding-start"></div>
 | 
				
			||||||
            <div *ngFor="let item of items" class="core-horizontal-scroll-item">
 | 
					            <div *ngFor="let item of items" class="core-horizontal-scroll-item">
 | 
				
			||||||
                <ion-card>
 | 
					                <ion-card>
 | 
				
			||||||
                    <ion-item class="core-course-module-handler item-media ion-text-wrap" detail="false" (click)="action($event, item)"
 | 
					                    <ion-item class="core-course-module-handler item-media ion-text-wrap" detail="false" (click)="action($event, item)"
 | 
				
			||||||
                        button>
 | 
					                        button>
 | 
				
			||||||
                        <core-mod-icon slot="start" *ngIf="item.iconUrl" [modicon]="item.iconUrl"
 | 
					                        <core-mod-icon slot="start" *ngIf="item.iconUrl" [modicon]="item.iconUrl" [modname]="item.modname"
 | 
				
			||||||
                            [modname]="item.modname" [componentId]="item.cmid" [showAlt]="false">
 | 
					                            [componentId]="item.cmid" [showAlt]="false">
 | 
				
			||||||
                        </core-mod-icon>
 | 
					                        </core-mod-icon>
 | 
				
			||||||
                        <ion-label>
 | 
					                        <ion-label>
 | 
				
			||||||
                            <!-- Add the icon title so accessibility tools read it. -->
 | 
					                            <!-- Add the icon title so accessibility tools read it. -->
 | 
				
			||||||
 | 
				
			|||||||
@ -7,8 +7,8 @@
 | 
				
			|||||||
    <ng-container *ngIf="mainMenuBlock">
 | 
					    <ng-container *ngIf="mainMenuBlock">
 | 
				
			||||||
        <ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary">
 | 
					        <ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary">
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <core-format-text [text]="mainMenuBlock.summary" [component]="component" [componentId]="siteHomeId"
 | 
					                <core-format-text [text]="mainMenuBlock.summary" [component]="component" [componentId]="siteHomeId" contextLevel="course"
 | 
				
			||||||
                    contextLevel="course" [contextInstanceId]="siteHomeId"></core-format-text>
 | 
					                    [contextInstanceId]="siteHomeId"></core-format-text>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,9 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
<!-- Add buttons to the nav bar. -->
 | 
					<!-- Add buttons to the nav bar. -->
 | 
				
			||||||
<core-navbar-buttons slot="end" prepend>
 | 
					<core-navbar-buttons slot="end" prepend>
 | 
				
			||||||
    <core-context-menu>
 | 
					    <core-context-menu>
 | 
				
			||||||
        <core-context-menu-item *ngIf="canNavigate && !isCurrentMonth && displayNavButtons" [priority]="900"
 | 
					        <core-context-menu-item *ngIf="canNavigate && !isCurrentMonth && displayNavButtons" [priority]="900"
 | 
				
			||||||
        [content]="'addon.calendar.currentmonth' | translate" iconAction="fas-calendar-day"
 | 
					            [content]="'addon.calendar.currentmonth' | translate" iconAction="fas-calendar-day" (action)="goToCurrentMonth()">
 | 
				
			||||||
        (action)="goToCurrentMonth()"></core-context-menu-item>
 | 
					        </core-context-menu-item>
 | 
				
			||||||
    </core-context-menu>
 | 
					    </core-context-menu>
 | 
				
			||||||
</core-navbar-buttons>
 | 
					</core-navbar-buttons>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,20 +45,13 @@
 | 
				
			|||||||
            <ion-row *ngFor="let week of weeks" class="addon-calendar-week" role="row">
 | 
					            <ion-row *ngFor="let week of weeks" class="addon-calendar-week" role="row">
 | 
				
			||||||
                <!-- Empty slots (first week). -->
 | 
					                <!-- Empty slots (first week). -->
 | 
				
			||||||
                <ion-col *ngFor="let value of week.prepadding" class="dayblank addon-calendar-day" role="cell"></ion-col>
 | 
					                <ion-col *ngFor="let value of week.prepadding" class="dayblank addon-calendar-day" role="cell"></ion-col>
 | 
				
			||||||
                <ion-col
 | 
					                <ion-col *ngFor="let day of week.days" class="addon-calendar-day ion-text-center" [ngClass]='{
 | 
				
			||||||
                    *ngFor="let day of week.days"
 | 
					 | 
				
			||||||
                    class="addon-calendar-day ion-text-center"
 | 
					 | 
				
			||||||
                    [ngClass]='{
 | 
					 | 
				
			||||||
                        "hasevents": day.hasevents,
 | 
					                        "hasevents": day.hasevents,
 | 
				
			||||||
                        "today": isCurrentMonth && day.istoday,
 | 
					                        "today": isCurrentMonth && day.istoday,
 | 
				
			||||||
                        "weekend": day.isweekend,
 | 
					                        "weekend": day.isweekend,
 | 
				
			||||||
                        "duration_finish": day.haslastdayofevent
 | 
					                        "duration_finish": day.haslastdayofevent
 | 
				
			||||||
                    }'
 | 
					                    }' [class.addon-calendar-event-past-day]="isPastMonth || day.ispast" role="cell" tabindex="0"
 | 
				
			||||||
                    [class.addon-calendar-event-past-day]="isPastMonth || day.ispast"
 | 
					                    (ariaButtonClick)="dayClicked(day.mday)">
 | 
				
			||||||
                    role="cell"
 | 
					 | 
				
			||||||
                    tabindex="0"
 | 
					 | 
				
			||||||
                    (ariaButtonClick)="dayClicked(day.mday)"
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                    <p class="addon-calendar-day-number" role="button">
 | 
					                    <p class="addon-calendar-day-number" role="button">
 | 
				
			||||||
                        <span aria-hidden="true">{{ day.mday }}</span>
 | 
					                        <span aria-hidden="true">{{ day.mday }}</span>
 | 
				
			||||||
                        <span class="sr-only">{{ day.periodName | translate }}</span>
 | 
					                        <span class="sr-only">{{ day.periodName | translate }}</span>
 | 
				
			||||||
@ -67,24 +59,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <!-- In phone, display some dots to indicate the type of events. -->
 | 
					                    <!-- In phone, display some dots to indicate the type of events. -->
 | 
				
			||||||
                    <p class="ion-hide-md-up addon-calendar-dot-types"><span *ngFor="let type of day.calendareventtypes"
 | 
					                    <p class="ion-hide-md-up addon-calendar-dot-types"><span *ngFor="let type of day.calendareventtypes"
 | 
				
			||||||
                        class="calendar_event_type calendar_event_{{type}}"></span></p>
 | 
					                            class="calendar_event_type calendar_event_{{type}}"></span></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <!-- In tablet, display list of events. -->
 | 
					                    <!-- In tablet, display list of events. -->
 | 
				
			||||||
                    <div class="ion-hide-md-down addon-calendar-day-events">
 | 
					                    <div class="ion-hide-md-down addon-calendar-day-events">
 | 
				
			||||||
                        <ng-container *ngFor="let event of day.filteredEvents | slice:0:4; let index = index">
 | 
					                        <ng-container *ngFor="let event of day.filteredEvents | slice:0:4; let index = index">
 | 
				
			||||||
                            <div
 | 
					                            <div *ngIf="index < 3 || day.filteredEvents.length == 4" class="addon-calendar-event"
 | 
				
			||||||
                                *ngIf="index < 3 || day.filteredEvents.length == 4"
 | 
					                                [class.addon-calendar-event-past]="event.ispast" role="button" tabindex="0"
 | 
				
			||||||
                                class="addon-calendar-event"
 | 
					                                (ariaButtonClick)="eventClicked(event, $event)">
 | 
				
			||||||
                                [class.addon-calendar-event-past]="event.ispast"
 | 
					 | 
				
			||||||
                                role="button"
 | 
					 | 
				
			||||||
                                tabindex="0"
 | 
					 | 
				
			||||||
                                (ariaButtonClick)="eventClicked(event, $event)"
 | 
					 | 
				
			||||||
                            >
 | 
					 | 
				
			||||||
                                <span class="calendar_event_type calendar_event_{{event.formattedType}}"></span>
 | 
					                                <span class="calendar_event_type calendar_event_{{event.formattedType}}"></span>
 | 
				
			||||||
                                <ion-icon *ngIf="event.offline && !event.deleted" name="fas-clock"
 | 
					                                <ion-icon *ngIf="event.offline && !event.deleted" name="fas-clock"
 | 
				
			||||||
                                    [attr.aria-label]="'core.notsent' | translate"></ion-icon>
 | 
					                                    [attr.aria-label]="'core.notsent' | translate"></ion-icon>
 | 
				
			||||||
                                <ion-icon *ngIf="event.deleted" name="fas-trash"
 | 
					                                <ion-icon *ngIf="event.deleted" name="fas-trash" [attr.aria-label]="'core.deletedoffline' | translate">
 | 
				
			||||||
                                    [attr.aria-label]="'core.deletedoffline' | translate"></ion-icon>
 | 
					                                </ion-icon>
 | 
				
			||||||
                                <span class="addon-calendar-event-time">
 | 
					                                <span class="addon-calendar-event-time">
 | 
				
			||||||
                                    {{ event.timestart * 1000 | coreFormatDate: timeFormat }}
 | 
					                                    {{ event.timestart * 1000 | coreFormatDate: timeFormat }}
 | 
				
			||||||
                                </span>
 | 
					                                </span>
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,9 @@
 | 
				
			|||||||
    <ng-container *ngIf="filter.course || filter.category || filter.group">
 | 
					    <ng-container *ngIf="filter.course || filter.category || filter.group">
 | 
				
			||||||
        <ion-radio-group [(ngModel)]="courseId" (ionChange)="onChange()">
 | 
					        <ion-radio-group [(ngModel)]="courseId" (ionChange)="onChange()">
 | 
				
			||||||
            <ion-item class="ion-text-wrap" *ngFor="let course of courses">
 | 
					            <ion-item class="ion-text-wrap" *ngFor="let course of courses">
 | 
				
			||||||
                <ion-label><core-format-text [text]="course.fullname"></core-format-text></ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
 | 
					                    <core-format-text [text]="course.fullname"></core-format-text>
 | 
				
			||||||
 | 
					                </ion-label>
 | 
				
			||||||
                <ion-radio slot="end" [value]="course.id"></ion-radio>
 | 
					                <ion-radio slot="end" [value]="course.id"></ion-radio>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
        </ion-radio-group>
 | 
					        </ion-radio-group>
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@
 | 
				
			|||||||
                    </span>
 | 
					                    </span>
 | 
				
			||||||
                    <p class="item-heading">
 | 
					                    <p class="item-heading">
 | 
				
			||||||
                        <core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
 | 
					                        <core-format-text [text]="event.name" [contextLevel]="event.contextLevel"
 | 
				
			||||||
                        [contextInstanceId]="event.contextInstanceId"></core-format-text>
 | 
					                            [contextInstanceId]="event.contextInstanceId"></core-format-text>
 | 
				
			||||||
                    </p>
 | 
					                    </p>
 | 
				
			||||||
                    <p [innerHTML]="event.formattedtime"></p>
 | 
					                    <p [innerHTML]="event.formattedtime"></p>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
 | 
				
			|||||||
@ -31,8 +31,8 @@
 | 
				
			|||||||
        <!-- View the submission tab. -->
 | 
					        <!-- View the submission tab. -->
 | 
				
			||||||
        <core-tab [title]="'addon.mod_assign.submission' | translate" id="submission">
 | 
					        <core-tab [title]="'addon.mod_assign.submission' | translate" id="submission">
 | 
				
			||||||
            <ng-template>
 | 
					            <ng-template>
 | 
				
			||||||
                <addon-mod-assign-submission-plugin *ngFor="let plugin of submissionPlugins"
 | 
					                <addon-mod-assign-submission-plugin *ngFor="let plugin of submissionPlugins" [assign]="assign" [submission]="userSubmission"
 | 
				
			||||||
                    [assign]="assign" [submission]="userSubmission" [plugin]="plugin">
 | 
					                    [plugin]="plugin">
 | 
				
			||||||
                </addon-mod-assign-submission-plugin>
 | 
					                </addon-mod-assign-submission-plugin>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <!-- Render some data about the submission. -->
 | 
					                <!-- Render some data about the submission. -->
 | 
				
			||||||
@ -56,8 +56,7 @@
 | 
				
			|||||||
                        <p *ngIf="assign!.intro"
 | 
					                        <p *ngIf="assign!.intro"
 | 
				
			||||||
                            [innerHTML]="'addon.mod_assign.allowsubmissionsfromdatesummary' | translate: {'$a': fromDate}">
 | 
					                            [innerHTML]="'addon.mod_assign.allowsubmissionsfromdatesummary' | translate: {'$a': fromDate}">
 | 
				
			||||||
                        </p>
 | 
					                        </p>
 | 
				
			||||||
                        <p *ngIf="!assign!.intro"
 | 
					                        <p *ngIf="!assign!.intro" [innerHTML]="'addon.mod_assign.allowsubmissionsanddescriptionfromdatesummary' | translate:
 | 
				
			||||||
                            [innerHTML]="'addon.mod_assign.allowsubmissionsanddescriptionfromdatesummary' | translate:
 | 
					 | 
				
			||||||
                                {'$a': fromDate}">
 | 
					                                {'$a': fromDate}">
 | 
				
			||||||
                        </p>
 | 
					                        </p>
 | 
				
			||||||
                    </ion-label>
 | 
					                    </ion-label>
 | 
				
			||||||
@ -66,8 +65,8 @@
 | 
				
			|||||||
                <ion-item class="ion-text-wrap" *ngIf="showDates && assign!.duedate && !isSubmittedForGrading">
 | 
					                <ion-item class="ion-text-wrap" *ngIf="showDates && assign!.duedate && !isSubmittedForGrading">
 | 
				
			||||||
                    <ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
                        <h2>{{ 'addon.mod_assign.duedate' | translate }}</h2>
 | 
					                        <h2>{{ 'addon.mod_assign.duedate' | translate }}</h2>
 | 
				
			||||||
                        <p *ngIf="assign!.duedate" >{{ assign!.duedate * 1000 | coreFormatDate }}</p>
 | 
					                        <p *ngIf="assign!.duedate">{{ assign!.duedate * 1000 | coreFormatDate }}</p>
 | 
				
			||||||
                        <p *ngIf="!assign!.duedate" >{{ 'addon.mod_assign.duedateno' | translate }}</p>
 | 
					                        <p *ngIf="!assign!.duedate">{{ 'addon.mod_assign.duedateno' | translate }}</p>
 | 
				
			||||||
                    </ion-label>
 | 
					                    </ion-label>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,8 +77,7 @@
 | 
				
			|||||||
                    </ion-label>
 | 
					                    </ion-label>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <ion-item class="ion-text-wrap"
 | 
					                <ion-item class="ion-text-wrap" *ngIf="assign!.duedate && lastAttempt?.extensionduedate && !isSubmittedForGrading">
 | 
				
			||||||
                    *ngIf="assign!.duedate && lastAttempt?.extensionduedate && !isSubmittedForGrading">
 | 
					 | 
				
			||||||
                    <ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
                        <h2>{{ 'addon.mod_assign.extensionduedate' | translate }}</h2>
 | 
					                        <h2>{{ 'addon.mod_assign.extensionduedate' | translate }}</h2>
 | 
				
			||||||
                        <p>{{ lastAttempt!.extensionduedate * 1000 | coreFormatDate }}</p>
 | 
					                        <p>{{ lastAttempt!.extensionduedate * 1000 | coreFormatDate }}</p>
 | 
				
			||||||
@ -91,11 +89,11 @@
 | 
				
			|||||||
                        <h2>{{ 'addon.mod_assign.attemptnumber' | translate }}</h2>
 | 
					                        <h2>{{ 'addon.mod_assign.attemptnumber' | translate }}</h2>
 | 
				
			||||||
                        <p *ngIf="assign!.maxattempts == unlimitedAttempts">
 | 
					                        <p *ngIf="assign!.maxattempts == unlimitedAttempts">
 | 
				
			||||||
                            {{ 'addon.mod_assign.outof' | translate :
 | 
					                            {{ 'addon.mod_assign.outof' | translate :
 | 
				
			||||||
                                {'$a': {'current': currentAttempt, 'total': maxAttemptsText} } }}
 | 
					                            {'$a': {'current': currentAttempt, 'total': maxAttemptsText} } }}
 | 
				
			||||||
                        </p>
 | 
					                        </p>
 | 
				
			||||||
                        <p *ngIf="assign!.maxattempts != unlimitedAttempts">
 | 
					                        <p *ngIf="assign!.maxattempts != unlimitedAttempts">
 | 
				
			||||||
                            {{ 'addon.mod_assign.outof' | translate :
 | 
					                            {{ 'addon.mod_assign.outof' | translate :
 | 
				
			||||||
                                {'$a': {'current': currentAttempt, 'total': assign!.maxattempts} } }}
 | 
					                            {'$a': {'current': currentAttempt, 'total': assign!.maxattempts} } }}
 | 
				
			||||||
                        </p>
 | 
					                        </p>
 | 
				
			||||||
                    </ion-label>
 | 
					                    </ion-label>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
@ -105,13 +103,11 @@
 | 
				
			|||||||
                    <ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
                        <div *ngIf="!unsupportedEditPlugins.length && !showErrorStatementEdit">
 | 
					                        <div *ngIf="!unsupportedEditPlugins.length && !showErrorStatementEdit">
 | 
				
			||||||
                            <!-- If has offline data, show edit. -->
 | 
					                            <!-- If has offline data, show edit. -->
 | 
				
			||||||
                            <ion-button expand="block" class="ion-text-wrap" color="primary" *ngIf="hasOffline"
 | 
					                            <ion-button expand="block" class="ion-text-wrap" color="primary" *ngIf="hasOffline" (click)="goToEdit()">
 | 
				
			||||||
                                (click)="goToEdit()">
 | 
					 | 
				
			||||||
                                {{ 'addon.mod_assign.editsubmission' | translate }}
 | 
					                                {{ 'addon.mod_assign.editsubmission' | translate }}
 | 
				
			||||||
                            </ion-button>
 | 
					                            </ion-button>
 | 
				
			||||||
                            <!-- If no submission or is new, show add submission. -->
 | 
					                            <!-- If no submission or is new, show add submission. -->
 | 
				
			||||||
                            <ion-button expand="block" class="ion-text-wrap" color="primary"
 | 
					                            <ion-button expand="block" class="ion-text-wrap" color="primary" *ngIf="!hasOffline &&
 | 
				
			||||||
                                *ngIf="!hasOffline &&
 | 
					 | 
				
			||||||
                                    (!userSubmission || !userSubmission!.status || userSubmission!.status == statusNew)"
 | 
					                                    (!userSubmission || !userSubmission!.status || userSubmission!.status == statusNew)"
 | 
				
			||||||
                                (click)="goToEdit()">
 | 
					                                (click)="goToEdit()">
 | 
				
			||||||
                                {{ 'addon.mod_assign.addsubmission' | translate }}
 | 
					                                {{ 'addon.mod_assign.addsubmission' | translate }}
 | 
				
			||||||
@ -127,8 +123,7 @@
 | 
				
			|||||||
                                </ion-button>
 | 
					                                </ion-button>
 | 
				
			||||||
                            </ng-container>
 | 
					                            </ng-container>
 | 
				
			||||||
                            <!-- Else show editsubmission. -->
 | 
					                            <!-- Else show editsubmission. -->
 | 
				
			||||||
                            <ion-button expand="block" class="ion-text-wrap" color="primary"
 | 
					                            <ion-button expand="block" class="ion-text-wrap" color="primary" *ngIf="!hasOffline && userSubmission && userSubmission!.status &&
 | 
				
			||||||
                                *ngIf="!hasOffline && userSubmission && userSubmission!.status &&
 | 
					 | 
				
			||||||
                                    userSubmission!.status != statusNew &&
 | 
					                                    userSubmission!.status != statusNew &&
 | 
				
			||||||
                                    userSubmission!.status != statusReopened" (click)="goToEdit()">
 | 
					                                    userSubmission!.status != statusReopened" (click)="goToEdit()">
 | 
				
			||||||
                                {{ 'addon.mod_assign.editsubmission' | translate }}
 | 
					                                {{ 'addon.mod_assign.editsubmission' | translate }}
 | 
				
			||||||
@ -156,8 +151,7 @@
 | 
				
			|||||||
                    <!-- Submit button. -->
 | 
					                    <!-- Submit button. -->
 | 
				
			||||||
                    <ion-item class="ion-text-wrap" *ngIf="!showErrorStatementSubmit">
 | 
					                    <ion-item class="ion-text-wrap" *ngIf="!showErrorStatementSubmit">
 | 
				
			||||||
                        <ion-label>
 | 
					                        <ion-label>
 | 
				
			||||||
                            <ion-button expand="block" class="ion-text-wrap"
 | 
					                            <ion-button expand="block" class="ion-text-wrap" (click)="submitForGrading(acceptStatement)">
 | 
				
			||||||
                                (click)="submitForGrading(acceptStatement)">
 | 
					 | 
				
			||||||
                                {{ 'addon.mod_assign.submitassignment' | translate }}
 | 
					                                {{ 'addon.mod_assign.submitassignment' | translate }}
 | 
				
			||||||
                            </ion-button>
 | 
					                            </ion-button>
 | 
				
			||||||
                            <p>{{ 'addon.mod_assign.submitassignment_help' | translate }}</p>
 | 
					                            <p>{{ 'addon.mod_assign.submitassignment_help' | translate }}</p>
 | 
				
			||||||
@ -175,14 +169,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                <!-- Team members that need to submit it too. -->
 | 
					                <!-- Team members that need to submit it too. -->
 | 
				
			||||||
                <ion-item-divider class="ion-text-wrap" *ngIf="membersToSubmit && membersToSubmit.length > 0">
 | 
					                <ion-item-divider class="ion-text-wrap" *ngIf="membersToSubmit && membersToSubmit.length > 0">
 | 
				
			||||||
                    <ion-label><h2>{{ 'addon.mod_assign.userswhoneedtosubmit' | translate: {$a: ''} }}</h2></ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
 | 
					                        <h2>{{ 'addon.mod_assign.userswhoneedtosubmit' | translate: {$a: ''} }}</h2>
 | 
				
			||||||
 | 
					                    </ion-label>
 | 
				
			||||||
                </ion-item-divider>
 | 
					                </ion-item-divider>
 | 
				
			||||||
                <ng-container *ngIf="membersToSubmit && membersToSubmit.length > 0 && !blindMarking">
 | 
					                <ng-container *ngIf="membersToSubmit && membersToSubmit.length > 0 && !blindMarking">
 | 
				
			||||||
                    <ng-container *ngFor="let user of membersToSubmit">
 | 
					                    <ng-container *ngFor="let user of membersToSubmit">
 | 
				
			||||||
                        <ion-item class="ion-text-wrap" core-user-link [userId]="user.id"
 | 
					                        <ion-item class="ion-text-wrap" core-user-link [userId]="user.id" [courseId]="courseId"
 | 
				
			||||||
                            [courseId]="courseId" [attr.aria-label]="user.fullname">
 | 
					                            [attr.aria-label]="user.fullname">
 | 
				
			||||||
                            <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>
 | 
				
			||||||
                    </ng-container>
 | 
					                    </ng-container>
 | 
				
			||||||
                </ng-container>
 | 
					                </ng-container>
 | 
				
			||||||
@ -196,12 +194,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                <!-- Submission is locked. -->
 | 
					                <!-- Submission is locked. -->
 | 
				
			||||||
                <ion-item class="ion-text-wrap" *ngIf="lastAttempt?.locked">
 | 
					                <ion-item class="ion-text-wrap" *ngIf="lastAttempt?.locked">
 | 
				
			||||||
                    <ion-label><h2>{{ 'addon.mod_assign.submissionslocked' | translate }}</h2></ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
 | 
					                        <h2>{{ 'addon.mod_assign.submissionslocked' | translate }}</h2>
 | 
				
			||||||
 | 
					                    </ion-label>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <!-- Editing status. -->
 | 
					                <!-- Editing status. -->
 | 
				
			||||||
                <ion-item class="ion-text-wrap"
 | 
					                <ion-item class="ion-text-wrap" *ngIf="lastAttempt && isSubmittedForGrading && lastAttempt!.caneditowner !== undefined"
 | 
				
			||||||
                    *ngIf="lastAttempt && isSubmittedForGrading && lastAttempt!.caneditowner !== undefined"
 | 
					 | 
				
			||||||
                    [ngClass]="{submissioneditable: lastAttempt!.caneditowner, submissionnoteditable: !lastAttempt!.caneditowner}">
 | 
					                    [ngClass]="{submissioneditable: lastAttempt!.caneditowner, submissionnoteditable: !lastAttempt!.caneditowner}">
 | 
				
			||||||
                    <ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
                        <h2>{{ 'addon.mod_assign.editingstatus' | translate }}</h2>
 | 
					                        <h2>{{ 'addon.mod_assign.editingstatus' | translate }}</h2>
 | 
				
			||||||
@ -220,7 +219,9 @@
 | 
				
			|||||||
                    *ngIf="feedback?.gradefordisplay && (!isGrading || grade.method != 'simple')">
 | 
					                    *ngIf="feedback?.gradefordisplay && (!isGrading || grade.method != 'simple')">
 | 
				
			||||||
                    <ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
                        <h2>{{ 'addon.mod_assign.currentgrade' | translate }}</h2>
 | 
					                        <h2>{{ 'addon.mod_assign.currentgrade' | translate }}</h2>
 | 
				
			||||||
                        <p><core-format-text [text]="feedback!.gradefordisplay" [filter]="false"></core-format-text></p>
 | 
					                        <p>
 | 
				
			||||||
 | 
					                            <core-format-text [text]="feedback!.gradefordisplay" [filter]="false"></core-format-text>
 | 
				
			||||||
 | 
					                        </p>
 | 
				
			||||||
                    </ion-label>
 | 
					                    </ion-label>
 | 
				
			||||||
                    <ion-button slot="end" *ngIf="feedback!.advancedgrade" (click)="showAdvancedGrade()"
 | 
					                    <ion-button slot="end" *ngIf="feedback!.advancedgrade" (click)="showAdvancedGrade()"
 | 
				
			||||||
                        [attr.aria-label]="'core.showadvanced' |translate">
 | 
					                        [attr.aria-label]="'core.showadvanced' |translate">
 | 
				
			||||||
@ -243,7 +244,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <!-- Grade using a scale. -->
 | 
					                    <!-- Grade using a scale. -->
 | 
				
			||||||
                    <ion-item class="ion-text-wrap" *ngIf="grade.method == 'simple' && grade.scale">
 | 
					                    <ion-item class="ion-text-wrap" *ngIf="grade.method == 'simple' && grade.scale">
 | 
				
			||||||
                        <ion-label><h2>{{ 'addon.mod_assign.grade' | translate }}</h2></ion-label>
 | 
					                        <ion-label>
 | 
				
			||||||
 | 
					                            <h2>{{ 'addon.mod_assign.grade' | translate }}</h2>
 | 
				
			||||||
 | 
					                        </ion-label>
 | 
				
			||||||
                        <ion-select [(ngModel)]="grade.grade" interface="action-sheet" [disabled]="grade.disabled"
 | 
					                        <ion-select [(ngModel)]="grade.grade" interface="action-sheet" [disabled]="grade.disabled"
 | 
				
			||||||
                            [interfaceOptions]="{header: 'addon.mod_assign.grade' | translate}">
 | 
					                            [interfaceOptions]="{header: 'addon.mod_assign.grade' | translate}">
 | 
				
			||||||
                            <ion-select-option *ngFor="let grade of grade.scale" [value]="grade.value">
 | 
					                            <ion-select-option *ngFor="let grade of grade.scale" [value]="grade.value">
 | 
				
			||||||
@ -254,10 +257,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <!-- Outcomes. -->
 | 
					                    <!-- Outcomes. -->
 | 
				
			||||||
                    <ion-item class="ion-text-wrap" *ngFor="let outcome of gradeInfo!.outcomes">
 | 
					                    <ion-item class="ion-text-wrap" *ngFor="let outcome of gradeInfo!.outcomes">
 | 
				
			||||||
                        <ion-label><h2>{{ outcome.name }}</h2></ion-label>
 | 
					                        <ion-label>
 | 
				
			||||||
                        <ion-select *ngIf="canSaveGrades && outcome.itemNumber" [(ngModel)]="outcome.selectedId"
 | 
					                            <h2>{{ outcome.name }}</h2>
 | 
				
			||||||
                            interface="action-sheet" [disabled]="gradeInfo!.disabled"
 | 
					                        </ion-label>
 | 
				
			||||||
                            [interfaceOptions]="{header: outcome.name }">
 | 
					                        <ion-select *ngIf="canSaveGrades && outcome.itemNumber" [(ngModel)]="outcome.selectedId" interface="action-sheet"
 | 
				
			||||||
 | 
					                            [disabled]="gradeInfo!.disabled" [interfaceOptions]="{header: outcome.name }">
 | 
				
			||||||
                            <ion-select-option *ngFor="let grade of outcome.options" [value]="grade.value">
 | 
					                            <ion-select-option *ngFor="let grade of outcome.options" [value]="grade.value">
 | 
				
			||||||
                                {{grade.label}}
 | 
					                                {{grade.label}}
 | 
				
			||||||
                            </ion-select-option>
 | 
					                            </ion-select-option>
 | 
				
			||||||
@ -310,11 +314,11 @@
 | 
				
			|||||||
                            <h2>{{ 'addon.mod_assign.attemptsettings' | translate }}</h2>
 | 
					                            <h2>{{ 'addon.mod_assign.attemptsettings' | translate }}</h2>
 | 
				
			||||||
                            <p *ngIf="assign!.maxattempts == unlimitedAttempts">
 | 
					                            <p *ngIf="assign!.maxattempts == unlimitedAttempts">
 | 
				
			||||||
                                {{ 'addon.mod_assign.outof' | translate :
 | 
					                                {{ 'addon.mod_assign.outof' | translate :
 | 
				
			||||||
                                    {'$a': {'current': currentAttempt, 'total': maxAttemptsText} } }}
 | 
					                                {'$a': {'current': currentAttempt, 'total': maxAttemptsText} } }}
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                            <p *ngIf="assign!.maxattempts != unlimitedAttempts">
 | 
					                            <p *ngIf="assign!.maxattempts != unlimitedAttempts">
 | 
				
			||||||
                                {{ 'addon.mod_assign.outof' | translate :
 | 
					                                {{ 'addon.mod_assign.outof' | translate :
 | 
				
			||||||
                                    {'$a': {'current': currentAttempt, 'total': assign!.maxattempts} } }}
 | 
					                                {'$a': {'current': currentAttempt, 'total': assign!.maxattempts} } }}
 | 
				
			||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                            <p>
 | 
					                            <p>
 | 
				
			||||||
                                {{ 'addon.mod_assign.attemptreopenmethod' | translate }}:
 | 
					                                {{ 'addon.mod_assign.attemptreopenmethod' | translate }}:
 | 
				
			||||||
@ -322,7 +326,7 @@
 | 
				
			|||||||
                            </p>
 | 
					                            </p>
 | 
				
			||||||
                        </ion-label>
 | 
					                        </ion-label>
 | 
				
			||||||
                    </ion-item>
 | 
					                    </ion-item>
 | 
				
			||||||
                    <ion-item *ngIf="canSaveGrades && allowAddAttempt" >
 | 
					                    <ion-item *ngIf="canSaveGrades && allowAddAttempt">
 | 
				
			||||||
                        <ion-label>{{ 'addon.mod_assign.addattempt' | translate }}</ion-label>
 | 
					                        <ion-label>{{ 'addon.mod_assign.addattempt' | translate }}</ion-label>
 | 
				
			||||||
                        <ion-toggle [(ngModel)]="grade.addAttempt"></ion-toggle>
 | 
					                        <ion-toggle [(ngModel)]="grade.addAttempt"></ion-toggle>
 | 
				
			||||||
                    </ion-item>
 | 
					                    </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,8 +3,7 @@
 | 
				
			|||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <h2>{{plugin.name}}</h2>
 | 
					        <h2>{{plugin.name}}</h2>
 | 
				
			||||||
        <ng-container>
 | 
					        <ng-container>
 | 
				
			||||||
            <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" [alwaysDownload]="true">
 | 
				
			||||||
                [alwaysDownload]="true">
 | 
					 | 
				
			||||||
            </core-file>
 | 
					            </core-file>
 | 
				
			||||||
        </ng-container>
 | 
					        </ng-container>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,8 +3,7 @@
 | 
				
			|||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <h2>{{plugin.name}}</h2>
 | 
					        <h2>{{plugin.name}}</h2>
 | 
				
			||||||
        <ng-container>
 | 
					        <ng-container>
 | 
				
			||||||
            <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" [alwaysDownload]="true">
 | 
				
			||||||
                [alwaysDownload]="true">
 | 
					 | 
				
			||||||
            </core-file>
 | 
					            </core-file>
 | 
				
			||||||
        </ng-container>
 | 
					        </ng-container>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="true" button>
 | 
					<ion-item *ngIf="commentsEnabled" class="ion-text-wrap" (click)="showComments($event)" detail="true" button>
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <h2>{{plugin.name}}</h2>
 | 
					        <h2>{{plugin.name}}</h2>
 | 
				
			||||||
        <core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments"
 | 
					        <core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments" [itemId]="submission.id"
 | 
				
			||||||
            [itemId]="submission.id" area="submission_comments" [title]="plugin.name" [courseId]="assign.course">
 | 
					            area="submission_comments" [title]="plugin.name" [courseId]="assign.course">
 | 
				
			||||||
        </core-comments>
 | 
					        </core-comments>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,9 @@
 | 
				
			|||||||
<!-- Edit -->
 | 
					<!-- Edit -->
 | 
				
			||||||
<div *ngIf="edit">
 | 
					<div *ngIf="edit">
 | 
				
			||||||
    <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>
 | 
				
			||||||
    <core-attachments [files]="files" [maxSize]="maxSize" [maxSubmissions]="maxSubmissions" [courseId]="assign.course"
 | 
					    <core-attachments [files]="files" [maxSize]="maxSize" [maxSubmissions]="maxSubmissions" [courseId]="assign.course"
 | 
				
			||||||
        [component]="component" [componentId]="assign.cmid" [acceptedTypes]="acceptedTypes" [allowOffline]="allowOffline">
 | 
					        [component]="component" [componentId]="assign.cmid" [acceptedTypes]="acceptedTypes" [allowOffline]="allowOffline">
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@
 | 
				
			|||||||
</ion-button>
 | 
					</ion-button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<core-comments *ngIf="action == 'comments' && mode == 'list'" contextLevel="module" [instanceId]="database.coursemodule"
 | 
					<core-comments *ngIf="action == 'comments' && mode == 'list'" contextLevel="module" [instanceId]="database.coursemodule"
 | 
				
			||||||
component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="database.course">
 | 
					    component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="database.course">
 | 
				
			||||||
</core-comments>
 | 
					</core-comments>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 | coreFormatDate }}</span>
 | 
					<span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 | coreFormatDate }}</span>
 | 
				
			||||||
@ -32,7 +32,7 @@ component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="datab
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<a *ngIf="action == 'userpicture'" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">
 | 
					<a *ngIf="action == 'userpicture'" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">
 | 
				
			||||||
    <img class="avatar-round" [src]="userPicture" [alt]="'core.pictureof' | translate:{$a: entry.fullname}" core-external-content
 | 
					    <img class="avatar-round" [src]="userPicture" [alt]="'core.pictureof' | translate:{$a: entry.fullname}" core-external-content
 | 
				
			||||||
    onError="this.src='assets/img/user-avatar.png'">
 | 
					        onError="this.src='assets/img/user-avatar.png'">
 | 
				
			||||||
</a>
 | 
					</a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<a *ngIf="action == 'user' && entry" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">
 | 
					<a *ngIf="action == 'user' && entry" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<span *ngIf="editMode && form">
 | 
					<span *ngIf="editMode && form">
 | 
				
			||||||
    <span [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
					    <span [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
				
			||||||
    <core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component"
 | 
					    <core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component" [componentId]="componentId"
 | 
				
			||||||
        [componentId]="componentId" [allowOffline]="true" [courseId]="database?.course">
 | 
					        [allowOffline]="true" [courseId]="database?.course">
 | 
				
			||||||
    </core-attachments>
 | 
					    </core-attachments>
 | 
				
			||||||
    <core-input-errors *ngIf="error" [errorText]="error"></core-input-errors>
 | 
					    <core-input-errors *ngIf="error" [errorText]="error"></core-input-errors>
 | 
				
			||||||
</span>
 | 
					</span>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,12 @@
 | 
				
			|||||||
<span *ngIf="editMode && form" [formGroup]="form">
 | 
					<span *ngIf="editMode && form" [formGroup]="form">
 | 
				
			||||||
    <span [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
					    <span [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
				
			||||||
    <core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component"
 | 
					    <core-attachments [files]="files" [maxSize]="maxSizeBytes" maxSubmissions="1" [component]="component" [componentId]="componentId"
 | 
				
			||||||
        [componentId]="componentId" [allowOffline]="true" acceptedTypes="image" [courseId]="database?.course">
 | 
					        [allowOffline]="true" acceptedTypes="image" [courseId]="database?.course">
 | 
				
			||||||
    </core-attachments>
 | 
					    </core-attachments>
 | 
				
			||||||
    <core-input-errors *ngIf="error" [errorText]="error"></core-input-errors>
 | 
					    <core-input-errors *ngIf="error" [errorText]="error"></core-input-errors>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <ion-label position="stacked">{{ 'addon.mod_data.alttext' | translate }}</ion-label>
 | 
					    <ion-label position="stacked">{{ 'addon.mod_data.alttext' | translate }}</ion-label>
 | 
				
			||||||
    <ion-input type="text" [formControlName]="'f_'+field.id+'_alttext'" [placeholder]=" 'addon.mod_data.alttext' | translate" >
 | 
					    <ion-input type="text" [formControlName]="'f_'+field.id+'_alttext'" [placeholder]=" 'addon.mod_data.alttext' | translate">
 | 
				
			||||||
    </ion-input>
 | 
					    </ion-input>
 | 
				
			||||||
</span>
 | 
					</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,8 +15,8 @@
 | 
				
			|||||||
</span>
 | 
					</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<button class="as-link" *ngIf="listMode && imageUrl" (click)="navigateEntry()">
 | 
					<button class="as-link" *ngIf="listMode && imageUrl" (click)="navigateEntry()">
 | 
				
			||||||
    <img [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" core-external-content/>
 | 
					    <img [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" core-external-content />
 | 
				
			||||||
</button>
 | 
					</button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<img *ngIf="showMode && imageUrl" [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture"
 | 
					<img *ngIf="showMode && imageUrl" [src]="imageUrl" [alt]="title" class="core-media-adapt-width listMode_picture" [attr.width]="width"
 | 
				
			||||||
    [attr.width]="width" [attr.height]="height" core-external-content/>
 | 
					    [attr.height]="height" core-external-content />
 | 
				
			||||||
 | 
				
			|||||||
@ -2,9 +2,9 @@
 | 
				
			|||||||
    <ion-input *ngIf="searchMode" type="text" [placeholder]="field.name" [formControlName]="'f_'+field.id"></ion-input>
 | 
					    <ion-input *ngIf="searchMode" type="text" [placeholder]="field.name" [formControlName]="'f_'+field.id"></ion-input>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
					    <span *ngIf="editMode" [core-mark-required]="field.required" class="core-mark-required"></span>
 | 
				
			||||||
    <core-rich-text-editor *ngIf="editMode" [control]="form.controls['f_'+field.id]" [placeholder]="field.name"
 | 
					    <core-rich-text-editor *ngIf="editMode" [control]="form.controls['f_'+field.id]" [placeholder]="field.name" [name]="'f_'+field.id"
 | 
				
			||||||
        [name]="'f_'+field.id" [component]="component" [componentId]="componentId" [autoSave]="true"
 | 
					        [component]="component" [componentId]="componentId" [autoSave]="true" contextLevel="module" [contextInstanceId]="componentId"
 | 
				
			||||||
        contextLevel="module" [contextInstanceId]="componentId" [elementId]="'field_'+field.id" ngDefaultControl>
 | 
					        [elementId]="'field_'+field.id" ngDefaultControl>
 | 
				
			||||||
    </core-rich-text-editor>
 | 
					    </core-rich-text-editor>
 | 
				
			||||||
    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
					    <core-input-errors *ngIf="error && editMode" [control]="form.controls['f_'+field.id]" [errorText]="error"></core-input-errors>
 | 
				
			||||||
</span>
 | 
					</span>
 | 
				
			||||||
 | 
				
			|||||||
@ -8,20 +8,19 @@
 | 
				
			|||||||
    <ion-item button class="ion-text-wrap" (click)="deletePost()" *ngIf="offlinePost || (canDelete && isOnline)" detail="false">
 | 
					    <ion-item button class="ion-text-wrap" (click)="deletePost()" *ngIf="offlinePost || (canDelete && isOnline)" detail="false">
 | 
				
			||||||
        <ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon>
 | 
					        <ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <p  class="item-heading" *ngIf="!offlinePost">{{ 'addon.mod_forum.delete' | translate }}</p>
 | 
					            <p class="item-heading" *ngIf="!offlinePost">{{ 'addon.mod_forum.delete' | translate }}</p>
 | 
				
			||||||
            <p  class="item-heading" *ngIf="offlinePost">{{ 'core.discard' | translate }}</p>
 | 
					            <p class="item-heading" *ngIf="offlinePost">{{ 'core.discard' | translate }}</p>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
    <ion-item class="ion-text-wrap" *ngIf="wordCount">
 | 
					    <ion-item class="ion-text-wrap" *ngIf="wordCount">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <p  class="item-heading">{{ 'core.numwords' | translate: {'$a': wordCount} }}</p>
 | 
					            <p class="item-heading">{{ 'core.numwords' | translate: {'$a': wordCount} }}</p>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
    <ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false" button detail="false"
 | 
					    <ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false" button detail="false" [showBrowserWarning]="false">
 | 
				
			||||||
        [showBrowserWarning]="false">
 | 
					 | 
				
			||||||
        <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon>
 | 
					        <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <p  class="item-heading">{{ 'core.openinbrowser' | translate }}</p>
 | 
					            <p class="item-heading">{{ 'core.openinbrowser' | translate }}</p>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
</core-loading>
 | 
					</core-loading>
 | 
				
			||||||
 | 
				
			|||||||
@ -8,22 +8,19 @@
 | 
				
			|||||||
                            <ion-icon name="fas-map-pin" *ngIf="discussion && !post.parentid && discussion.pinned"
 | 
					                            <ion-icon name="fas-map-pin" *ngIf="discussion && !post.parentid && discussion.pinned"
 | 
				
			||||||
                                [attr.aria-label]="'addon.mod_forum.discussionpinned' | translate">
 | 
					                                [attr.aria-label]="'addon.mod_forum.discussionpinned' | translate">
 | 
				
			||||||
                            </ion-icon>
 | 
					                            </ion-icon>
 | 
				
			||||||
                            <ion-icon name="fas-star" class="addon-forum-star"
 | 
					                            <ion-icon name="fas-star" class="addon-forum-star" [attr.aria-label]="'addon.mod_forum.favourites' | translate"
 | 
				
			||||||
                                [attr.aria-label]="'addon.mod_forum.favourites' | translate"
 | 
					 | 
				
			||||||
                                *ngIf="discussion && !post.parentid && !discussion.pinned && discussion.starred">
 | 
					                                *ngIf="discussion && !post.parentid && !discussion.pinned && discussion.starred">
 | 
				
			||||||
                            </ion-icon>
 | 
					                            </ion-icon>
 | 
				
			||||||
                            <core-format-text
 | 
					                            <core-format-text [text]="post.subject" contextLevel="module" [contextInstanceId]="forum && forum.cmid"
 | 
				
			||||||
                                [text]="post.subject"
 | 
					                                [courseId]="courseId">
 | 
				
			||||||
                                contextLevel="module" [contextInstanceId]="forum && forum.cmid" [courseId]="courseId">
 | 
					 | 
				
			||||||
                            </core-format-text>
 | 
					                            </core-format-text>
 | 
				
			||||||
                        </h2>
 | 
					                        </h2>
 | 
				
			||||||
                        <ion-note *ngIf="trackPosts && post.unread" class="ion-float-end ion-padding-start ion-text-end"
 | 
					                        <ion-note *ngIf="trackPosts && post.unread" class="ion-float-end ion-padding-start ion-text-end"
 | 
				
			||||||
                            [attr.aria-label]="'addon.mod_forum.unread' | translate">
 | 
					                            [attr.aria-label]="'addon.mod_forum.unread' | translate">
 | 
				
			||||||
                            <ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
 | 
					                            <ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                        </ion-note>
 | 
					                        </ion-note>
 | 
				
			||||||
                        <ion-button *ngIf="optionsMenuEnabled"
 | 
					                        <ion-button *ngIf="optionsMenuEnabled" fill="clear" color="dark"
 | 
				
			||||||
                            fill="clear" color="dark" [attr.aria-label]="('core.displayoptions' | translate)"
 | 
					                            [attr.aria-label]="('core.displayoptions' | translate)" (click)="showOptionsMenu($event)">
 | 
				
			||||||
                            (click)="showOptionsMenu($event)">
 | 
					 | 
				
			||||||
                            <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>
 | 
				
			||||||
@ -50,9 +47,8 @@
 | 
				
			|||||||
                                [attr.aria-label]="'addon.mod_forum.unread' | translate">
 | 
					                                [attr.aria-label]="'addon.mod_forum.unread' | translate">
 | 
				
			||||||
                                <ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
 | 
					                                <ion-icon name="fas-circle" color="primary" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                            </ion-note>
 | 
					                            </ion-note>
 | 
				
			||||||
                            <ion-button *ngIf="optionsMenuEnabled"
 | 
					                            <ion-button *ngIf="optionsMenuEnabled" fill="clear" color="dark"
 | 
				
			||||||
                                fill="clear" color="dark" [attr.aria-label]="('core.displayoptions' | translate)"
 | 
					                                [attr.aria-label]="('core.displayoptions' | translate)" (click)="showOptionsMenu($event)">
 | 
				
			||||||
                                (click)="showOptionsMenu($event)">
 | 
					 | 
				
			||||||
                                <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					                                <ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                            </ion-button>
 | 
					                            </ion-button>
 | 
				
			||||||
                        </ng-container>
 | 
					                        </ng-container>
 | 
				
			||||||
@ -64,8 +60,8 @@
 | 
				
			|||||||
            <div class="ion-padding-bottom" *ngIf="post.isprivatereply">
 | 
					            <div class="ion-padding-bottom" *ngIf="post.isprivatereply">
 | 
				
			||||||
                <ion-note color="danger">{{ 'addon.mod_forum.postisprivatereply' | translate }}</ion-note>
 | 
					                <ion-note color="danger">{{ 'addon.mod_forum.postisprivatereply' | translate }}</ion-note>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="post.message"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="post.message" contextLevel="module"
 | 
				
			||||||
                contextLevel="module" [contextInstanceId]="forum && forum.cmid" [courseId]="courseId">
 | 
					                [contextInstanceId]="forum && forum.cmid" [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
            <div lines="none" *ngIf="post.attachments && post.attachments.length > 0">
 | 
					            <div lines="none" *ngIf="post.attachments && post.attachments.length > 0">
 | 
				
			||||||
                <core-files [files]="post.attachments" [component]="component" [componentId]="componentId" showInline="true">
 | 
					                <core-files [files]="post.attachments" [component]="component" [componentId]="componentId" showInline="true">
 | 
				
			||||||
@ -79,23 +75,19 @@
 | 
				
			|||||||
                    <core-tag-list [tags]="post.tags"></core-tag-list>
 | 
					                    <core-tag-list [tags]="post.tags"></core-tag-list>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
            <core-rating-rate *ngIf="forum && ratingInfo"
 | 
					            <core-rating-rate *ngIf="forum && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" [instanceId]="componentId"
 | 
				
			||||||
                [ratingInfo]="ratingInfo" contextLevel="module" [instanceId]="componentId" [itemId]="post.id"
 | 
					                [itemId]="post.id" [itemSetId]="discussionId" [courseId]="courseId" [aggregateMethod]="forum.assessed"
 | 
				
			||||||
                [itemSetId]="discussionId" [courseId]="courseId" [aggregateMethod]="forum.assessed" [scaleId]="forum.scale"
 | 
					                [scaleId]="forum.scale" [userId]="post.author.id" (onUpdate)="ratingUpdated()">
 | 
				
			||||||
                [userId]="post.author.id" (onUpdate)="ratingUpdated()">
 | 
					 | 
				
			||||||
            </core-rating-rate>
 | 
					            </core-rating-rate>
 | 
				
			||||||
            <core-rating-aggregate *ngIf="forum && ratingInfo"
 | 
					            <core-rating-aggregate *ngIf="forum && ratingInfo" [ratingInfo]="ratingInfo" contextLevel="module" [instanceId]="componentId"
 | 
				
			||||||
                [ratingInfo]="ratingInfo" contextLevel="module" [instanceId]="componentId" [itemId]="post.id"
 | 
					                [itemId]="post.id" [courseId]="courseId" [aggregateMethod]="forum.assessed" [scaleId]="forum.scale">
 | 
				
			||||||
                [courseId]="courseId" [aggregateMethod]="forum.assessed" [scaleId]="forum.scale">
 | 
					 | 
				
			||||||
            </core-rating-aggregate>
 | 
					            </core-rating-aggregate>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ion-item *ngIf="post.id > 0 && post.capabilities.reply && !post.isprivatereply"
 | 
					            <ion-item *ngIf="post.id > 0 && post.capabilities.reply && !post.isprivatereply"
 | 
				
			||||||
                class="ion-no-padding ion-text-end addon-forum-reply-button">
 | 
					                class="ion-no-padding ion-text-end addon-forum-reply-button">
 | 
				
			||||||
                <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
                    <ion-button fill="clear" size="small"
 | 
					                    <ion-button fill="clear" size="small" [attr.aria-controls]="'addon-forum-reply-edit-form-' + uniqueId"
 | 
				
			||||||
                        [attr.aria-controls]="'addon-forum-reply-edit-form-' + uniqueId"
 | 
					                        [attr.aria-expanded]="formData.replyingTo === post.id" (click)="showReplyForm($event)">
 | 
				
			||||||
                        [attr.aria-expanded]="formData.replyingTo === post.id"
 | 
					 | 
				
			||||||
                        (click)="showReplyForm($event)">
 | 
					 | 
				
			||||||
                        <ion-icon name="fas-reply" slot="start" aria-hidden="true"></ion-icon>
 | 
					                        <ion-icon name="fas-reply" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                        {{ 'addon.mod_forum.reply' | translate }}
 | 
					                        {{ 'addon.mod_forum.reply' | translate }}
 | 
				
			||||||
                    </ion-button>
 | 
					                    </ion-button>
 | 
				
			||||||
@ -104,21 +96,18 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </ng-container>
 | 
					    </ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <form *ngIf="showForm"
 | 
					    <form *ngIf="showForm" [id]="'addon-forum-reply-edit-form-' + uniqueId" #replyFormEl>
 | 
				
			||||||
        [id]="'addon-forum-reply-edit-form-' + uniqueId" #replyFormEl>
 | 
					 | 
				
			||||||
        <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 type="text" [placeholder]="'addon.mod_forum.subject' | translate" [(ngModel)]="formData.subject"
 | 
					            <ion-input type="text" [placeholder]="'addon.mod_forum.subject' | translate" [(ngModel)]="formData.subject" name="subject">
 | 
				
			||||||
                name="subject">
 | 
					 | 
				
			||||||
            </ion-input>
 | 
					            </ion-input>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ion-item>
 | 
					        <ion-item>
 | 
				
			||||||
            <ion-label position="stacked">{{ 'addon.mod_forum.message' | translate }}</ion-label>
 | 
					            <ion-label position="stacked">{{ 'addon.mod_forum.message' | translate }}</ion-label>
 | 
				
			||||||
            <core-rich-text-editor elementId="message" contextLevel="module"
 | 
					            <core-rich-text-editor elementId="message" contextLevel="module" [control]="messageControl"
 | 
				
			||||||
                [control]="messageControl" [placeholder]="'addon.mod_forum.replyplaceholder' | translate"
 | 
					                [placeholder]="'addon.mod_forum.replyplaceholder' | translate" [name]="'mod_forum_reply_' + post.id" [component]="component"
 | 
				
			||||||
                [name]="'mod_forum_reply_' + post.id" [component]="component" [componentId]="componentId" [autoSave]="true"
 | 
					                [componentId]="componentId" [autoSave]="true" [contextInstanceId]="forum && forum.cmid"
 | 
				
			||||||
                [contextInstanceId]="forum && forum.cmid" [draftExtraParams]="{reply: post.id}"
 | 
					                [draftExtraParams]="{reply: post.id}" (contentChanged)="onMessageChange($event)">
 | 
				
			||||||
                (contentChanged)="onMessageChange($event)">
 | 
					 | 
				
			||||||
            </core-rich-text-editor>
 | 
					            </core-rich-text-editor>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ion-item class="ion-text-wrap" *ngIf="accessInfo.canpostprivatereply">
 | 
					        <ion-item class="ion-text-wrap" *ngIf="accessInfo.canpostprivatereply">
 | 
				
			||||||
@ -126,14 +115,9 @@
 | 
				
			|||||||
            <ion-checkbox slot="end" [(ngModel)]="formData.isprivatereply" name="isprivatereply"></ion-checkbox>
 | 
					            <ion-checkbox slot="end" [(ngModel)]="formData.isprivatereply" name="isprivatereply"></ion-checkbox>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ng-container *ngIf="forum.id && forum.maxattachments > 0">
 | 
					        <ng-container *ngIf="forum.id && forum.maxattachments > 0">
 | 
				
			||||||
            <ion-item
 | 
					            <ion-item button class="divider ion-text-wrap" (click)="toggleAdvanced()" detail="false" [attr.aria-expanded]="advanced"
 | 
				
			||||||
                button
 | 
					 | 
				
			||||||
                class="divider ion-text-wrap"
 | 
					 | 
				
			||||||
                (click)="toggleAdvanced()" detail="false"
 | 
					 | 
				
			||||||
                [attr.aria-expanded]="advanced"
 | 
					 | 
				
			||||||
                [attr.aria-controls]="'addon-forum-reply-edit-form-advanced-' + uniqueId"
 | 
					                [attr.aria-controls]="'addon-forum-reply-edit-form-advanced-' + uniqueId"
 | 
				
			||||||
                [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate"
 | 
					                [attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate">
 | 
				
			||||||
            >
 | 
					 | 
				
			||||||
                <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>
 | 
					                <ion-label>
 | 
				
			||||||
@ -141,8 +125,7 @@
 | 
				
			|||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
            <div *ngIf="advanced" [id]="'addon-forum-reply-edit-form-advanced-' + uniqueId">
 | 
					            <div *ngIf="advanced" [id]="'addon-forum-reply-edit-form-advanced-' + uniqueId">
 | 
				
			||||||
                <core-attachments
 | 
					                <core-attachments [files]="formData.files" [maxSize]="forum.maxbytes" [maxSubmissions]="forum.maxattachments"
 | 
				
			||||||
                    [files]="formData.files" [maxSize]="forum.maxbytes" [maxSubmissions]="forum.maxattachments"
 | 
					 | 
				
			||||||
                    [component]="component" [componentId]="forum.cmid" [allowOffline]="true" [courseId]="courseId">
 | 
					                    [component]="component" [componentId]="forum.cmid" [allowOffline]="true" [courseId]="courseId">
 | 
				
			||||||
                </core-attachments>
 | 
					                </core-attachments>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,12 @@
 | 
				
			|||||||
<ion-list>
 | 
					<ion-list>
 | 
				
			||||||
    <ng-container *ngFor="let group of subwikis">
 | 
					    <ng-container *ngFor="let group of subwikis">
 | 
				
			||||||
        <ion-item-divider *ngIf="group.label">
 | 
					        <ion-item-divider *ngIf="group.label">
 | 
				
			||||||
            <ion-label><h2>{{ group.label }}</h2></ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
 | 
					                <h2>{{ group.label }}</h2>
 | 
				
			||||||
 | 
					            </ion-label>
 | 
				
			||||||
        </ion-item-divider>
 | 
					        </ion-item-divider>
 | 
				
			||||||
        <ion-item class="ion-text-wrap" *ngFor="let subwiki of group.subwikis" (click)="openSubwiki(subwiki)"
 | 
					        <ion-item class="ion-text-wrap" *ngFor="let subwiki of group.subwikis" (click)="openSubwiki(subwiki)"
 | 
				
			||||||
            [attr.disabled]="!subwiki.canedit && subwiki.id <= 0"
 | 
					            [attr.disabled]="!subwiki.canedit && subwiki.id <= 0" [button]="subwiki.canedit || subwiki.id > 0"
 | 
				
			||||||
            [button]="subwiki.canedit || subwiki.id > 0"
 | 
					 | 
				
			||||||
            [attr.aria-current]="isSubwikiSelected(subwiki) ? 'page' : 'false'" detail="false">
 | 
					            [attr.aria-current]="isSubwikiSelected(subwiki) ? 'page' : 'false'" detail="false">
 | 
				
			||||||
            <ion-label>{{ subwiki.name }}</ion-label>
 | 
					            <ion-label>{{ subwiki.name }}</ion-label>
 | 
				
			||||||
            <ion-icon *ngIf="isSubwikiSelected(subwiki)" name="fas-check" slot="end" aria-hidden="true"></ion-icon>
 | 
					            <ion-icon *ngIf="isSubwikiSelected(subwiki)" name="fas-check" slot="end" aria-hidden="true"></ion-icon>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,19 +3,17 @@
 | 
				
			|||||||
        <ion-item class="ion-text-wrap">
 | 
					        <ion-item class="ion-text-wrap">
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <h2>{{ field.dimtitle }}</h2>
 | 
					                <h2>{{ field.dimtitle }}</h2>
 | 
				
			||||||
                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId"
 | 
					                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
				
			||||||
                    [courseId]="courseId">
 | 
					 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ion-item *ngIf="edit && field.grades">
 | 
					        <ion-item *ngIf="edit && field.grades">
 | 
				
			||||||
            <ion-label position="stacked">
 | 
					            <ion-label position="stacked">
 | 
				
			||||||
                <span [core-mark-required]="true">
 | 
					                <span [core-mark-required]="true">
 | 
				
			||||||
                {{ 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' | translate : {'$a': field.dimtitle } }}
 | 
					                    {{ 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' | translate : {'$a': field.dimtitle } }}
 | 
				
			||||||
                </span>
 | 
					                </span>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
            <ion-select [(ngModel)]="selectedValues[n].grade" interface="action-sheet"
 | 
					            <ion-select [(ngModel)]="selectedValues[n].grade" interface="action-sheet" [interfaceOptions]="{header: 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' |
 | 
				
			||||||
                [interfaceOptions]="{header: 'addon.mod_workshop_assessment_accumulative.dimensiongradefor' |
 | 
					 | 
				
			||||||
                    translate : {'$a': field.dimtitle }}">
 | 
					                    translate : {'$a': field.dimtitle }}">
 | 
				
			||||||
                <ion-select-option *ngFor="let grade of field.grades" [value]="grade.value">{{grade.label}}</ion-select-option>
 | 
					                <ion-select-option *ngFor="let grade of field.grades" [value]="grade.value">{{grade.label}}</ion-select-option>
 | 
				
			||||||
            </ion-select>
 | 
					            </ion-select>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,8 +3,7 @@
 | 
				
			|||||||
        <ion-item class="ion-text-wrap">
 | 
					        <ion-item class="ion-text-wrap">
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <h2>{{ field.dimtitle }}</h2>
 | 
					                <h2>{{ field.dimtitle }}</h2>
 | 
				
			||||||
                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId"
 | 
					                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
				
			||||||
                    [courseId]="courseId">
 | 
					 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
@ -22,9 +21,11 @@
 | 
				
			|||||||
        <ion-item *ngIf="!edit" class="ion-text-wrap">
 | 
					        <ion-item *ngIf="!edit" class="ion-text-wrap">
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <h2>{{ 'addon.mod_workshop_assessment_comments.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</h2>
 | 
					                <h2>{{ 'addon.mod_workshop_assessment_comments.dimensioncommentfor' | translate : {'$a': field.dimtitle } }}</h2>
 | 
				
			||||||
                <p><core-format-text [text]="selectedValues[n].peercomment" contextLevel="module" [contextInstanceId]="moduleId"
 | 
					                <p>
 | 
				
			||||||
                    [courseId]="courseId">
 | 
					                    <core-format-text [text]="selectedValues[n].peercomment" contextLevel="module" [contextInstanceId]="moduleId"
 | 
				
			||||||
                </core-format-text></p>
 | 
					                        [courseId]="courseId">
 | 
				
			||||||
 | 
					                    </core-format-text>
 | 
				
			||||||
 | 
					                </p>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
    </ion-card>
 | 
					    </ion-card>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,8 +3,7 @@
 | 
				
			|||||||
        <ion-item class="ion-text-wrap">
 | 
					        <ion-item class="ion-text-wrap">
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <h2>{{ field.dimtitle }}</h2>
 | 
					                <h2>{{ field.dimtitle }}</h2>
 | 
				
			||||||
                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId"
 | 
					                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
				
			||||||
                    [courseId]="courseId">
 | 
					 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
@ -26,7 +25,9 @@
 | 
				
			|||||||
                    <ion-radio slot="start" [value]="-1" [disabled]="!edit"></ion-radio>
 | 
					                    <ion-radio slot="start" [value]="-1" [disabled]="!edit"></ion-radio>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
                <ion-item>
 | 
					                <ion-item>
 | 
				
			||||||
                    <ion-label><core-format-text [text]="field.grade1" [filter]="false"></core-format-text></ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
 | 
					                        <core-format-text [text]="field.grade1" [filter]="false"></core-format-text>
 | 
				
			||||||
 | 
					                    </ion-label>
 | 
				
			||||||
                    <ion-radio slot="start" [value]="1" [disabled]="!edit"></ion-radio>
 | 
					                    <ion-radio slot="start" [value]="1" [disabled]="!edit"></ion-radio>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
            </ion-radio-group>
 | 
					            </ion-radio-group>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,20 +3,21 @@
 | 
				
			|||||||
        <ion-item class="ion-text-wrap">
 | 
					        <ion-item class="ion-text-wrap">
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <h2 [core-mark-required]="edit">{{ field.dimtitle }}</h2>
 | 
					                <h2 [core-mark-required]="edit">{{ field.dimtitle }}</h2>
 | 
				
			||||||
                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId"
 | 
					                <core-format-text [text]="field.description" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
				
			||||||
                    [courseId]="courseId">
 | 
					 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
            <core-input-errors *ngIf="edit && fieldErrors['chosenlevelid_' + n]" [errorText]="fieldErrors['chosenlevelid_' + n]">
 | 
					            <core-input-errors *ngIf="edit && fieldErrors['chosenlevelid_' + n]" [errorText]="fieldErrors['chosenlevelid_' + n]">
 | 
				
			||||||
                </core-input-errors>
 | 
					            </core-input-errors>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ion-list>
 | 
					        <ion-list>
 | 
				
			||||||
            <ion-radio-group [(ngModel)]="selectedValues[n].chosenlevelid" [name]="'chosenlevelid_' + n">
 | 
					            <ion-radio-group [(ngModel)]="selectedValues[n].chosenlevelid" [name]="'chosenlevelid_' + n">
 | 
				
			||||||
                <ion-item *ngFor="let subfield of field.fields">
 | 
					                <ion-item *ngFor="let subfield of field.fields">
 | 
				
			||||||
                    <ion-label>
 | 
					                    <ion-label>
 | 
				
			||||||
                        <p><core-format-text [text]="subfield.definition" contextLevel="module"
 | 
					                        <p>
 | 
				
			||||||
                            [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
					                            <core-format-text [text]="subfield.definition" contextLevel="module" [contextInstanceId]="moduleId"
 | 
				
			||||||
                        </core-format-text></p>
 | 
					                                [courseId]="courseId">
 | 
				
			||||||
 | 
					                            </core-format-text>
 | 
				
			||||||
 | 
					                        </p>
 | 
				
			||||||
                    </ion-label>
 | 
					                    </ion-label>
 | 
				
			||||||
                    <ion-radio slot="start" [value]="subfield.levelid" [disabled]="!edit"></ion-radio>
 | 
					                    <ion-radio slot="start" [value]="subfield.levelid" [disabled]="!edit"></ion-radio>
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,9 @@
 | 
				
			|||||||
        <ion-card *ngIf="assessmentStrategyLoaded && overallFeedkback &&
 | 
					        <ion-card *ngIf="assessmentStrategyLoaded && overallFeedkback &&
 | 
				
			||||||
            (edit || data.assessment?.feedbackauthor || data.assessment?.feedbackattachmentfiles?.length) ">
 | 
					            (edit || data.assessment?.feedbackauthor || data.assessment?.feedbackattachmentfiles?.length) ">
 | 
				
			||||||
            <ion-item class="ion-text-wrap">
 | 
					            <ion-item class="ion-text-wrap">
 | 
				
			||||||
                <ion-label><h2>{{ 'addon.mod_workshop.overallfeedback' | translate }}</h2></ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
 | 
					                    <h2>{{ 'addon.mod_workshop.overallfeedback' | translate }}</h2>
 | 
				
			||||||
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
            <ion-item position="stacked" *ngIf="edit">
 | 
					            <ion-item position="stacked" *ngIf="edit">
 | 
				
			||||||
                <ion-label position="stacked">
 | 
					                <ion-label position="stacked">
 | 
				
			||||||
@ -25,19 +27,17 @@
 | 
				
			|||||||
                        {{ 'addon.mod_workshop.feedbackauthor' | translate }}
 | 
					                        {{ 'addon.mod_workshop.feedbackauthor' | translate }}
 | 
				
			||||||
                    </span>
 | 
					                    </span>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
                <core-rich-text-editor [control]="feedbackControl" [component]="component"
 | 
					                <core-rich-text-editor [control]="feedbackControl" [component]="component" [componentId]="workshop.coursemodule"
 | 
				
			||||||
                    [componentId]="workshop.coursemodule" [autoSave]="true" contextLevel="module"
 | 
					                    [autoSave]="true" contextLevel="module" [contextInstanceId]="workshop.coursemodule" elementId="feedbackauthor_editor"
 | 
				
			||||||
                    [contextInstanceId]="workshop.coursemodule" elementId="feedbackauthor_editor"
 | 
					 | 
				
			||||||
                    [draftExtraParams]="{asid: assessmentId}" (contentChanged)="onFeedbackChange($event)">
 | 
					                    [draftExtraParams]="{asid: assessmentId}" (contentChanged)="onFeedbackChange($event)">
 | 
				
			||||||
                </core-rich-text-editor>
 | 
					                </core-rich-text-editor>
 | 
				
			||||||
                <core-input-errors
 | 
					                <core-input-errors *ngIf="overallFeedkbackRequired && data.fieldErrors && data.fieldErrors['feedbackauthor']"
 | 
				
			||||||
                    *ngIf="overallFeedkbackRequired && data.fieldErrors && data.fieldErrors['feedbackauthor']"
 | 
					 | 
				
			||||||
                    [errorText]="data.fieldErrors['feedbackauthor']">
 | 
					                    [errorText]="data.fieldErrors['feedbackauthor']">
 | 
				
			||||||
                </core-input-errors>
 | 
					                </core-input-errors>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
            <core-attachments *ngIf="edit && workshop.overallfeedbackfiles" [files]="data.assessment?.feedbackattachmentfiles"
 | 
					            <core-attachments *ngIf="edit && workshop.overallfeedbackfiles" [files]="data.assessment?.feedbackattachmentfiles"
 | 
				
			||||||
                [maxSize]="workshop.overallfeedbackmaxbytes" [maxSubmissions]="workshop.overallfeedbackfiles"
 | 
					                [maxSize]="workshop.overallfeedbackmaxbytes" [maxSubmissions]="workshop.overallfeedbackfiles" [component]="component"
 | 
				
			||||||
                [component]="component" [componentId]="componentId" [allowOffline]="true" [courseId]="workshop.course">
 | 
					                [componentId]="componentId" [allowOffline]="true" [courseId]="workshop.course">
 | 
				
			||||||
            </core-attachments>
 | 
					            </core-attachments>
 | 
				
			||||||
            <ion-item *ngIf="edit && access && access.canallocate">
 | 
					            <ion-item *ngIf="edit && access && access.canallocate">
 | 
				
			||||||
                <ion-label position="stacked">
 | 
					                <ion-label position="stacked">
 | 
				
			||||||
@ -57,11 +57,10 @@
 | 
				
			|||||||
                    </core-format-text>
 | 
					                    </core-format-text>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
            <ion-item *ngIf="!edit && workshop.overallfeedbackfiles && data.assessment?.feedbackattachmentfiles?.length"
 | 
					            <ion-item *ngIf="!edit && workshop.overallfeedbackfiles && data.assessment?.feedbackattachmentfiles?.length" lines="none">
 | 
				
			||||||
                lines="none">
 | 
					 | 
				
			||||||
                <ion-label>
 | 
					                <ion-label>
 | 
				
			||||||
                    <core-files [files]="data.assessment?.feedbackattachmentfiles" [component]="component"
 | 
					                    <core-files [files]="data.assessment?.feedbackattachmentfiles" [component]="component" [componentId]="componentId">
 | 
				
			||||||
                        [componentId]="componentId"></core-files>
 | 
					                    </core-files>
 | 
				
			||||||
                </ion-label>
 | 
					                </ion-label>
 | 
				
			||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
        </ion-card>
 | 
					        </ion-card>
 | 
				
			||||||
 | 
				
			|||||||
@ -5,13 +5,11 @@
 | 
				
			|||||||
            </core-user-avatar>
 | 
					            </core-user-avatar>
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <h2>
 | 
					                <h2>
 | 
				
			||||||
                    <core-format-text [text]="submission.title" contextLevel="module" [contextInstanceId]="module.id"
 | 
					                    <core-format-text [text]="submission.title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
				
			||||||
                        [courseId]="courseId">
 | 
					 | 
				
			||||||
                    </core-format-text>
 | 
					                    </core-format-text>
 | 
				
			||||||
                </h2>
 | 
					                </h2>
 | 
				
			||||||
                <p *ngIf="profile && profile?.fullname">{{profile.fullname}}</p>
 | 
					                <p *ngIf="profile && profile?.fullname">{{profile.fullname}}</p>
 | 
				
			||||||
                <p *ngIf="showGrade(submission.grade)"
 | 
					                <p *ngIf="showGrade(submission.grade)" [class.addon-has-overriden-grade]="showGrade(submission.gradeover)">
 | 
				
			||||||
                    [class.addon-has-overriden-grade]="showGrade(submission.gradeover)">
 | 
					 | 
				
			||||||
                    {{ 'addon.mod_workshop.submissiongradeof' | translate:{$a: workshop.grade } }}: {{submission.grade}}
 | 
					                    {{ 'addon.mod_workshop.submissiongradeof' | translate:{$a: workshop.grade } }}: {{submission.grade}}
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
                <p *ngIf="showGrade(submission.gradeover)" class="addon-overriden-grade">
 | 
					                <p *ngIf="showGrade(submission.gradeover)" class="addon-overriden-grade">
 | 
				
			||||||
@ -36,8 +34,8 @@
 | 
				
			|||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ion-item class="ion-text-wrap" *ngIf="submission.content">
 | 
					        <ion-item class="ion-text-wrap" *ngIf="submission.content">
 | 
				
			||||||
            <ion-label>
 | 
					            <ion-label>
 | 
				
			||||||
                <core-format-text [component]="component" [componentId]="componentId" [text]="submission.content"
 | 
					                <core-format-text [component]="component" [componentId]="componentId" [text]="submission.content" contextLevel="module"
 | 
				
			||||||
                    contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
					                    [contextInstanceId]="module.id" [courseId]="courseId">
 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
            </ion-label>
 | 
					            </ion-label>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
@ -71,8 +69,7 @@
 | 
				
			|||||||
        </core-user-avatar>
 | 
					        </core-user-avatar>
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <h2>
 | 
					            <h2>
 | 
				
			||||||
                <core-format-text [text]="submission.title" contextLevel="module" [contextInstanceId]="module.id"
 | 
					                <core-format-text [text]="submission.title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
 | 
				
			||||||
                    [courseId]="courseId">
 | 
					 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
            </h2>
 | 
					            </h2>
 | 
				
			||||||
            <p *ngIf="profile && profile.fullname">{{profile.fullname}}</p>
 | 
					            <p *ngIf="profile && profile.fullname">{{profile.fullname}}</p>
 | 
				
			||||||
@ -92,19 +89,19 @@
 | 
				
			|||||||
                {{ 'addon.mod_workshop.gradinggradeof' | translate:{$a: workshop.gradinggrade } }}: {{submission.gradinggrade}}
 | 
					                {{ 'addon.mod_workshop.gradinggradeof' | translate:{$a: workshop.gradinggrade } }}: {{submission.gradinggrade}}
 | 
				
			||||||
            </p>
 | 
					            </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ion-badge *ngIf="assessment && (showGrade(assessment.grade) || assessment.offline)" color="success"
 | 
					            <ion-badge *ngIf="assessment && (showGrade(assessment.grade) || assessment.offline)" color="success" class="ion-text-wrap">
 | 
				
			||||||
                class="ion-text-wrap">
 | 
					 | 
				
			||||||
                {{ 'addon.mod_workshop.assessedsubmission' | translate }}
 | 
					                {{ 'addon.mod_workshop.assessedsubmission' | translate }}
 | 
				
			||||||
            </ion-badge>
 | 
					            </ion-badge>
 | 
				
			||||||
            <ion-badge *ngIf="assessment && !showGrade(assessment.grade) && !assessment.offline" color="danger"
 | 
					            <ion-badge *ngIf="assessment && !showGrade(assessment.grade) && !assessment.offline" color="danger" class="ion-text-wrap">
 | 
				
			||||||
                class="ion-text-wrap">
 | 
					 | 
				
			||||||
                {{ 'addon.mod_workshop.notassessed' | translate }}
 | 
					                {{ 'addon.mod_workshop.notassessed' | translate }}
 | 
				
			||||||
            </ion-badge>
 | 
					            </ion-badge>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
        <ion-note slot="end" *ngIf="submission.timemodified">
 | 
					        <ion-note slot="end" *ngIf="submission.timemodified">
 | 
				
			||||||
            {{submission.timemodified | coreDateDayOrTime}}
 | 
					            {{submission.timemodified | coreDateDayOrTime}}
 | 
				
			||||||
            <div *ngIf="offline"><ion-icon name="fas-clock" aria-hidden="true"></ion-icon> {{ 'core.notsent' | translate }}</div>
 | 
					            <div *ngIf="offline">
 | 
				
			||||||
 | 
					                <ion-icon name="fas-clock" aria-hidden="true"></ion-icon> {{ 'core.notsent' | translate }}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
            <div *ngIf="submission.deleted">
 | 
					            <div *ngIf="submission.deleted">
 | 
				
			||||||
                <ion-icon name="fas-trash" aria-hidden="true"></ion-icon> {{ 'core.deletedoffline' | translate }}
 | 
					                <ion-icon name="fas-trash" aria-hidden="true"></ion-icon> {{ 'core.deletedoffline' | translate }}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
<div *ngIf="question && question.behaviourCertaintyOptions && question.behaviourCertaintyOptions.length">
 | 
					<div *ngIf="question && question.behaviourCertaintyOptions && question.behaviourCertaintyOptions.length">
 | 
				
			||||||
    <ion-item class="ion-text-wrap addon-qbehaviour-deferredcbm-certainty-title" >
 | 
					    <ion-item class="ion-text-wrap addon-qbehaviour-deferredcbm-certainty-title">
 | 
				
			||||||
        <ion-label><p>{{ 'core.question.certainty' | translate }}</p></ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
 | 
					            <p>{{ 'core.question.certainty' | translate }}</p>
 | 
				
			||||||
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <ion-radio-group [(ngModel)]="question.behaviourCertaintySelected" [name]="question.behaviourCertaintyOptions[0].name">
 | 
					    <ion-radio-group [(ngModel)]="question.behaviourCertaintySelected" [name]="question.behaviourCertaintyOptions[0].name">
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<ion-list class="addon-qtype-calculated-container" *ngIf="calcQuestion && (calcQuestion.text || calcQuestion.text === '')">
 | 
					<ion-list class="addon-qtype-calculated-container" *ngIf="calcQuestion && (calcQuestion.text || calcQuestion.text === '')">
 | 
				
			||||||
    <ion-item class="ion-text-wrap">
 | 
					    <ion-item class="ion-text-wrap">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="calcQuestion.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="calcQuestion.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
@ -23,8 +23,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            <!-- Input to enter the answer. -->
 | 
					            <!-- Input to enter the answer. -->
 | 
				
			||||||
            <ion-input type="text" [attr.name]="calcQuestion.input.name"
 | 
					            <ion-input type="text" [attr.name]="calcQuestion.input.name"
 | 
				
			||||||
                [placeholder]="calcQuestion.input.readOnly ? '' : 'core.question.answer' | translate"
 | 
					                [placeholder]="calcQuestion.input.readOnly ? '' : 'core.question.answer' | translate" [value]="calcQuestion.input.value"
 | 
				
			||||||
                [value]="calcQuestion.input.value" [disabled]="calcQuestion.input.readOnly" autocorrect="off">
 | 
					                [disabled]="calcQuestion.input.readOnly" autocorrect="off">
 | 
				
			||||||
            </ion-input>
 | 
					            </ion-input>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <!-- Display unit select after the answer input. -->
 | 
					            <!-- Display unit select after the answer input. -->
 | 
				
			||||||
@ -48,9 +48,9 @@
 | 
				
			|||||||
    <label *ngIf="calcQuestion!.select!.accessibilityLabel" class="accesshide" for="{{calcQuestion!.select!.id}}">
 | 
					    <label *ngIf="calcQuestion!.select!.accessibilityLabel" class="accesshide" for="{{calcQuestion!.select!.id}}">
 | 
				
			||||||
        {{ calcQuestion!.select!.accessibilityLabel }}
 | 
					        {{ calcQuestion!.select!.accessibilityLabel }}
 | 
				
			||||||
    </label>
 | 
					    </label>
 | 
				
			||||||
    <ion-select id="{{calcQuestion!.select!.id}}" [name]="calcQuestion!.select!.name"
 | 
					    <ion-select id="{{calcQuestion!.select!.id}}" [name]="calcQuestion!.select!.name" [(ngModel)]="calcQuestion!.select!.selected"
 | 
				
			||||||
        [(ngModel)]="calcQuestion!.select!.selected" interface="action-sheet" [disabled]="calcQuestion!.select!.disabled"
 | 
					        interface="action-sheet" [disabled]="calcQuestion!.select!.disabled" [slot]="calcQuestion?.selectFirst ? 'start' : 'end'"
 | 
				
			||||||
        [slot]="calcQuestion?.selectFirst ? 'start' : 'end'" [interfaceOptions]="{header: 'addon.mod_quiz.unit' | translate}">
 | 
					        [interfaceOptions]="{header: 'addon.mod_quiz.unit' | translate}">
 | 
				
			||||||
        <ion-select-option *ngFor="let option of calcQuestion!.select!.options" [value]="option.value">
 | 
					        <ion-select-option *ngFor="let option of calcQuestion!.select!.options" [value]="option.value">
 | 
				
			||||||
            {{option.label}}
 | 
					            {{option.label}}
 | 
				
			||||||
        </ion-select-option>
 | 
					        </ion-select-option>
 | 
				
			||||||
 | 
				
			|||||||
@ -11,9 +11,8 @@
 | 
				
			|||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
            </ion-card>
 | 
					            </ion-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="ddQuestion.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="ddQuestion.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId"
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId" (afterRender)="textRendered()">
 | 
				
			||||||
                (afterRender)="textRendered()">
 | 
					 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -11,8 +11,7 @@
 | 
				
			|||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
            </ion-card>
 | 
					            </ion-card>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="ddQuestion.text" #questiontext
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="ddQuestion.text" #questiontext
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId"
 | 
					                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" (afterRender)="textRendered()">
 | 
				
			||||||
                (afterRender)="textRendered()">
 | 
					 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -10,13 +10,12 @@
 | 
				
			|||||||
            </ion-item>
 | 
					            </ion-item>
 | 
				
			||||||
        </ion-card>
 | 
					        </ion-card>
 | 
				
			||||||
        <div class="addon-qtype-ddwtos-container">
 | 
					        <div class="addon-qtype-ddwtos-container">
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="ddQuestion.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="ddQuestion.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId" #questiontext
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId" #questiontext (afterRender)="textRendered()">
 | 
				
			||||||
                (afterRender)="textRendered()">
 | 
					 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <core-format-text *ngIf="ddQuestion.answers" [component]="component" [componentId]="componentId"
 | 
					            <core-format-text *ngIf="ddQuestion.answers" [component]="component" [componentId]="componentId" [text]="ddQuestion.answers"
 | 
				
			||||||
                [text]="ddQuestion.answers" [filter]="false" (afterRender)="answersRendered()">
 | 
					                [filter]="false" (afterRender)="answersRendered()">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div class="drags"></div>
 | 
					            <div class="drags"></div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
<ion-list *ngIf="question && (question.text || question.text === '')">
 | 
					<ion-list *ngIf="question && (question.text || question.text === '')">
 | 
				
			||||||
    <!-- "Seen" hidden input -->
 | 
					    <!-- "Seen" hidden input -->
 | 
				
			||||||
    <input *ngIf="seenInput" type="hidden" [name]="seenInput.name" [value]="seenInput.value" >
 | 
					    <input *ngIf="seenInput" type="hidden" [name]="seenInput.name" [value]="seenInput.value">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <ion-item class="ion-text-wrap">
 | 
					    <ion-item class="ion-text-wrap">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="question.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="question.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,8 @@
 | 
				
			|||||||
    <!-- Question text. -->
 | 
					    <!-- Question text. -->
 | 
				
			||||||
    <ion-item class="ion-text-wrap">
 | 
					    <ion-item class="ion-text-wrap">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="essayQuestion.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="essayQuestion.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
@ -15,13 +15,12 @@
 | 
				
			|||||||
            <ion-label class="sr-only">{{ 'core.question.answer' | translate }}</ion-label>
 | 
					            <ion-label class="sr-only">{{ 'core.question.answer' | translate }}</ion-label>
 | 
				
			||||||
            <!-- "Format" and draftid hidden inputs -->
 | 
					            <!-- "Format" and draftid hidden inputs -->
 | 
				
			||||||
            <input *ngIf="essayQuestion.formatInput" type="hidden" [name]="essayQuestion.formatInput.name"
 | 
					            <input *ngIf="essayQuestion.formatInput" type="hidden" [name]="essayQuestion.formatInput.name"
 | 
				
			||||||
                [value]="essayQuestion.formatInput.value" >
 | 
					                [value]="essayQuestion.formatInput.value">
 | 
				
			||||||
            <input *ngIf="essayQuestion.answerDraftIdInput" type="hidden" [name]="essayQuestion.answerDraftIdInput.name"
 | 
					            <input *ngIf="essayQuestion.answerDraftIdInput" type="hidden" [name]="essayQuestion.answerDraftIdInput.name"
 | 
				
			||||||
                [value]="essayQuestion.answerDraftIdInput.value" >
 | 
					                [value]="essayQuestion.answerDraftIdInput.value">
 | 
				
			||||||
            <!-- Plain text textarea. -->
 | 
					            <!-- Plain text textarea. -->
 | 
				
			||||||
            <ion-textarea *ngIf="essayQuestion.isPlainText" class="core-question-textarea"
 | 
					            <ion-textarea *ngIf="essayQuestion.isPlainText" class="core-question-textarea"
 | 
				
			||||||
                [ngClass]='{"core-monospaced": essayQuestion.isMonospaced}'
 | 
					                [ngClass]='{"core-monospaced": essayQuestion.isMonospaced}' placeholder="{{ 'core.question.answer' | translate }}"
 | 
				
			||||||
                placeholder="{{ 'core.question.answer' | translate }}"
 | 
					 | 
				
			||||||
                [attr.name]="essayQuestion.textarea.name" [ngModel]="essayQuestion.textarea.text">
 | 
					                [attr.name]="essayQuestion.textarea.name" [ngModel]="essayQuestion.textarea.text">
 | 
				
			||||||
            </ion-textarea>
 | 
					            </ion-textarea>
 | 
				
			||||||
            <!-- Rich text editor. -->
 | 
					            <!-- Rich text editor. -->
 | 
				
			||||||
@ -56,7 +55,7 @@
 | 
				
			|||||||
            </core-attachments>
 | 
					            </core-attachments>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <input *ngIf="essayQuestion.attachmentsDraftIdInput" type="hidden" [name]="essayQuestion.attachmentsDraftIdInput.name"
 | 
					            <input *ngIf="essayQuestion.attachmentsDraftIdInput" type="hidden" [name]="essayQuestion.attachmentsDraftIdInput.name"
 | 
				
			||||||
                [value]="essayQuestion.attachmentsDraftIdInput.value" >
 | 
					                [value]="essayQuestion.attachmentsDraftIdInput.value">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <!-- Attachments not supported in this site. -->
 | 
					            <!-- Attachments not supported in this site. -->
 | 
				
			||||||
            <ion-item *ngIf="!uploadFilesSupported" class="ion-text-wrap core-danger-item">
 | 
					            <ion-item *ngIf="!uploadFilesSupported" class="ion-text-wrap core-danger-item">
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,8 @@
 | 
				
			|||||||
<ion-list class="addon-qtype-gapselect-container" *ngIf="question && (question.text || question.text === '')">
 | 
					<ion-list class="addon-qtype-gapselect-container" *ngIf="question && (question.text || question.text === '')">
 | 
				
			||||||
    <ion-item class="ion-text-wrap">
 | 
					    <ion-item class="ion-text-wrap">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="question.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="question.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId"
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId" (afterRender)="questionRendered()">
 | 
				
			||||||
                (afterRender)="questionRendered()">
 | 
					 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,15 @@
 | 
				
			|||||||
<section class="addon-qtype-match-container" *ngIf="matchQuestion && matchQuestion.loaded">
 | 
					<section class="addon-qtype-match-container" *ngIf="matchQuestion && matchQuestion.loaded">
 | 
				
			||||||
    <ion-item class="ion-text-wrap">
 | 
					    <ion-item class="ion-text-wrap">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="matchQuestion.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="matchQuestion.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
    <ion-item class="ion-text-wrap" *ngFor="let row of matchQuestion.rows">
 | 
					    <ion-item class="ion-text-wrap" *ngFor="let row of matchQuestion.rows">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text id="addon-qtype-match-question-{{row.id}}" [component]="component"
 | 
					            <core-format-text id="addon-qtype-match-question-{{row.id}}" [component]="component" [componentId]="componentId"
 | 
				
			||||||
                [componentId]="componentId" [text]="row.text" [contextLevel]="contextLevel"
 | 
					                [text]="row.text" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
                [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
            <label class="accesshide" for="{{row.id}}" *ngIf="row.accessibilityLabel">
 | 
					            <label class="accesshide" for="{{row.id}}" *ngIf="row.accessibilityLabel">
 | 
				
			||||||
                {{ row.accessibilityLabel }}
 | 
					                {{ row.accessibilityLabel }}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,7 @@
 | 
				
			|||||||
<ion-list class="addon-qtype-multianswer-container" *ngIf="question && (question.text || question.text === '')">
 | 
					<ion-list class="addon-qtype-multianswer-container" *ngIf="question && (question.text || question.text === '')">
 | 
				
			||||||
    <div class="fake-ion-item ion-text-wrap">
 | 
					    <div class="fake-ion-item ion-text-wrap">
 | 
				
			||||||
        <core-format-text [component]="component" [componentId]="componentId" [text]="question.text"
 | 
					        <core-format-text [component]="component" [componentId]="componentId" [text]="question.text" [contextLevel]="contextLevel"
 | 
				
			||||||
            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId"
 | 
					            [contextInstanceId]="contextInstanceId" [courseId]="courseId" (afterRender)="questionRendered()">
 | 
				
			||||||
            (afterRender)="questionRendered()">
 | 
					 | 
				
			||||||
        </core-format-text>
 | 
					        </core-format-text>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</ion-list>
 | 
					</ion-list>
 | 
				
			||||||
 | 
				
			|||||||
@ -14,10 +14,9 @@
 | 
				
			|||||||
    <!-- Checkbox for multiple choice. -->
 | 
					    <!-- Checkbox for multiple choice. -->
 | 
				
			||||||
    <ng-container *ngIf="multiQuestion.multi">
 | 
					    <ng-container *ngIf="multiQuestion.multi">
 | 
				
			||||||
        <ion-item class="ion-text-wrap answer" *ngFor="let option of multiQuestion.options">
 | 
					        <ion-item class="ion-text-wrap answer" *ngFor="let option of multiQuestion.options">
 | 
				
			||||||
            <ion-label [color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'
 | 
					            <ion-label [color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")' [class]="option.class">
 | 
				
			||||||
                [class]="option.class">
 | 
					                <core-format-text [component]="component" [componentId]="componentId" [text]="option.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                <core-format-text [component]="component" [componentId]="componentId" [text]="option.text"
 | 
					                    [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
                    [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
                <div *ngIf="option.feedback" class="specificfeedback">
 | 
					                <div *ngIf="option.feedback" class="specificfeedback">
 | 
				
			||||||
                    <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
					                    <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
				
			||||||
@ -41,12 +40,11 @@
 | 
				
			|||||||
    </ng-container>
 | 
					    </ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Radio buttons for single choice. -->
 | 
					    <!-- Radio buttons for single choice. -->
 | 
				
			||||||
    <ion-radio-group *ngIf="!multiQuestion.multi" [(ngModel)]="multiQuestion.singleChoiceModel"
 | 
					    <ion-radio-group *ngIf="!multiQuestion.multi" [(ngModel)]="multiQuestion.singleChoiceModel" [name]="multiQuestion.optionsName">
 | 
				
			||||||
        [name]="multiQuestion.optionsName">
 | 
					 | 
				
			||||||
        <ion-item class="ion-text-wrap answer" *ngFor="let option of multiQuestion.options">
 | 
					        <ion-item class="ion-text-wrap answer" *ngFor="let option of multiQuestion.options">
 | 
				
			||||||
            <ion-label [class]="option.class">
 | 
					            <ion-label [class]="option.class">
 | 
				
			||||||
                <core-format-text [component]="component" [componentId]="componentId" [text]="option.text"
 | 
					                <core-format-text [component]="component" [componentId]="componentId" [text]="option.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                    [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					                    [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
                </core-format-text>
 | 
					                </core-format-text>
 | 
				
			||||||
                <div *ngIf="option.feedback" class="specificfeedback">
 | 
					                <div *ngIf="option.feedback" class="specificfeedback">
 | 
				
			||||||
                    <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
					                    <core-format-text [component]="component" [componentId]="componentId" [text]="option.feedback"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<ion-list *ngIf="textQuestion && (textQuestion.text || textQuestion.text === '')">
 | 
					<ion-list *ngIf="textQuestion && (textQuestion.text || textQuestion.text === '')">
 | 
				
			||||||
    <ion-item class="ion-text-wrap addon-qtype-shortanswer-text">
 | 
					    <ion-item class="ion-text-wrap addon-qtype-shortanswer-text">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="textQuestion.text"
 | 
					            <core-format-text [component]="component" [componentId]="componentId" [text]="textQuestion.text" [contextLevel]="contextLevel"
 | 
				
			||||||
                [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					                [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
@ -13,8 +13,8 @@
 | 
				
			|||||||
            [attr.name]="textQuestion.input.name" [value]="textQuestion.input.value" autocorrect="off"
 | 
					            [attr.name]="textQuestion.input.name" [value]="textQuestion.input.value" autocorrect="off"
 | 
				
			||||||
            [disabled]="textQuestion.input.readOnly">
 | 
					            [disabled]="textQuestion.input.readOnly">
 | 
				
			||||||
        </ion-input>
 | 
					        </ion-input>
 | 
				
			||||||
        <ion-icon *ngIf="textQuestion.input.correctIcon" class="core-correct-icon" slot="end"
 | 
					        <ion-icon *ngIf="textQuestion.input.correctIcon" class="core-correct-icon" slot="end" [name]="textQuestion.input.correctIcon"
 | 
				
			||||||
            [name]="textQuestion.input.correctIcon" [color]="[textQuestion.input.correctIconColor]">
 | 
					            [color]="[textQuestion.input.correctIconColor]">
 | 
				
			||||||
        </ion-icon>
 | 
					        </ion-icon>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
</ion-list>
 | 
					</ion-list>
 | 
				
			||||||
 | 
				
			|||||||
@ -11,8 +11,8 @@
 | 
				
			|||||||
    <ion-label position="stacked">
 | 
					    <ion-label position="stacked">
 | 
				
			||||||
        <span [core-mark-required]="required">{{ field.name }}</span>
 | 
					        <span [core-mark-required]="required">{{ field.name }}</span>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
    <ion-datetime [formControlName]="modelName" [placeholder]="'core.choosedots' | translate" [displayFormat]="format"
 | 
					    <ion-datetime [formControlName]="modelName" [placeholder]="'core.choosedots' | translate" [displayFormat]="format" [max]="max"
 | 
				
			||||||
        [max]="max" [min]="min" [monthNames]="monthNames">
 | 
					        [min]="min" [monthNames]="monthNames">
 | 
				
			||||||
    </ion-datetime>
 | 
					    </ion-datetime>
 | 
				
			||||||
    <core-input-errors [control]="form.controls[modelName]"></core-input-errors>
 | 
					    <core-input-errors [control]="form.controls[modelName]"></core-input-errors>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -2,9 +2,10 @@
 | 
				
			|||||||
<ion-item *ngIf="!edit && field && field.name">
 | 
					<ion-item *ngIf="!edit && field && field.name">
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <h2>{{ field.name }}</h2>
 | 
					        <h2>{{ field.name }}</h2>
 | 
				
			||||||
        <p><core-format-text [text]="value" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"
 | 
					        <p>
 | 
				
			||||||
            [courseId]="courseId">
 | 
					            <core-format-text [text]="value" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
        </core-format-text></p>
 | 
					            </core-format-text>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,9 +2,10 @@
 | 
				
			|||||||
<ion-item *ngIf="!edit && field && field.name">
 | 
					<ion-item *ngIf="!edit && field && field.name">
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <h2>{{ field.name }}</h2>
 | 
					        <h2>{{ field.name }}</h2>
 | 
				
			||||||
        <p><core-format-text [text]="value" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"
 | 
					        <p>
 | 
				
			||||||
            [courseId]="courseId">
 | 
					            <core-format-text [text]="value" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
        </core-format-text></p>
 | 
					            </core-format-text>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,9 +2,10 @@
 | 
				
			|||||||
<ion-item *ngIf="!edit && field && field.name">
 | 
					<ion-item *ngIf="!edit && field && field.name">
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <h2>{{ field.name }}</h2>
 | 
					        <h2>{{ field.name }}</h2>
 | 
				
			||||||
        <p><core-format-text [text]="value" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"
 | 
					        <p>
 | 
				
			||||||
            [courseId]="courseId">
 | 
					            <core-format-text [text]="value" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
        </core-format-text></p>
 | 
					            </core-format-text>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -14,7 +15,7 @@
 | 
				
			|||||||
        <span [core-mark-required]="required">{{ field.name }}</span>
 | 
					        <span [core-mark-required]="required">{{ field.name }}</span>
 | 
				
			||||||
        <core-input-errors [control]="control"></core-input-errors>
 | 
					        <core-input-errors [control]="control"></core-input-errors>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
    <core-rich-text-editor [control]="control" [placeholder]="field.name" [autoSave]="true"
 | 
					    <core-rich-text-editor [control]="control" [placeholder]="field.name" [autoSave]="true" [contextLevel]="contextLevel"
 | 
				
			||||||
        [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [elementId]="modelName">
 | 
					        [contextInstanceId]="contextInstanceId" [elementId]="modelName">
 | 
				
			||||||
    </core-rich-text-editor>
 | 
					    </core-rich-text-editor>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -19,13 +19,12 @@
 | 
				
			|||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
<div *ngFor="let file of files; let index=index">
 | 
					<div *ngFor="let file of files; let index=index">
 | 
				
			||||||
    <!-- Files already attached to the submission, either in online or in offline. -->
 | 
					    <!-- Files already attached to the submission, either in online or in offline. -->
 | 
				
			||||||
    <core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="componentId"
 | 
					    <core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="componentId" [canDelete]="true"
 | 
				
			||||||
        [canDelete]="true" (onDelete)="delete(index, true)" [canDownload]="!file.offline">
 | 
					        (onDelete)="delete(index, true)" [canDownload]="!file.offline">
 | 
				
			||||||
    </core-file>
 | 
					    </core-file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Files added to draft but not attached to submission yet. -->
 | 
					    <!-- Files added to draft but not attached to submission yet. -->
 | 
				
			||||||
    <core-local-file *ngIf="file.name" [file]="file" [manage]="true" (onDelete)="delete(index, false)"
 | 
					    <core-local-file *ngIf="file.name" [file]="file" [manage]="true" (onDelete)="delete(index, false)" (onRename)="renamed(index, $event)">
 | 
				
			||||||
        (onRename)="renamed(index, $event)">
 | 
					 | 
				
			||||||
    </core-local-file>
 | 
					    </core-local-file>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,16 +9,17 @@
 | 
				
			|||||||
        <ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" aria-hidden="true" slot="start">
 | 
					        <ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" aria-hidden="true" slot="start">
 | 
				
			||||||
        </ion-icon>
 | 
					        </ion-icon>
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <p class="item-heading"><core-format-text [clean]="true" [text]="item.content" [filter]="false"></core-format-text></p>
 | 
					            <p class="item-heading">
 | 
				
			||||||
 | 
					                <core-format-text [clean]="true" [text]="item.content" [filter]="false"></core-format-text>
 | 
				
			||||||
 | 
					            </p>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
        <ng-container *ngIf="(item.href || item.action) && item.iconAction">
 | 
					        <ng-container *ngIf="(item.href || item.action) && item.iconAction">
 | 
				
			||||||
            <ion-icon *ngIf="item.iconAction != 'spinner' && item.iconAction != 'toggle'" [name]="item.iconAction"
 | 
					            <ion-icon *ngIf="item.iconAction != 'spinner' && item.iconAction != 'toggle'" [name]="item.iconAction"
 | 
				
			||||||
                [class.icon-slash]="item.iconSlash" slot="end" aria-hidden="true">
 | 
					                [class.icon-slash]="item.iconSlash" slot="end" aria-hidden="true">
 | 
				
			||||||
            </ion-icon>
 | 
					            </ion-icon>
 | 
				
			||||||
            <ion-spinner *ngIf="item.iconAction == 'spinner'" slot="end"
 | 
					            <ion-spinner *ngIf="item.iconAction == 'spinner'" slot="end" [attr.aria-label]="'core.loading' | translate">
 | 
				
			||||||
                [attr.aria-label]="'core.loading' | translate">
 | 
					 | 
				
			||||||
            </ion-spinner>
 | 
					            </ion-spinner>
 | 
				
			||||||
            <ion-toggle  *ngIf="item.iconAction == 'toggle'" [(ngModel)]="item.toggle" (ionChange)="item.toggleChanged($event)" slot="end">
 | 
					            <ion-toggle *ngIf="item.iconAction == 'toggle'" [(ngModel)]="item.toggle" (ionChange)="item.toggleChanged($event)" slot="end">
 | 
				
			||||||
            </ion-toggle>
 | 
					            </ion-toggle>
 | 
				
			||||||
        </ng-container>
 | 
					        </ng-container>
 | 
				
			||||||
        <ion-badge class="{{item.badgeClass}}" slot="end" *ngIf="item.badge">
 | 
					        <ion-badge class="{{item.badgeClass}}" slot="end" *ngIf="item.badge">
 | 
				
			||||||
 | 
				
			|||||||
@ -8,8 +8,8 @@
 | 
				
			|||||||
        <p *ngIf="showTime">{{ timemodified * 1000 | coreFormatDate }}</p>
 | 
					        <p *ngIf="showTime">{{ timemodified * 1000 | coreFormatDate }}</p>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
    <div slot="end" class="flex-row">
 | 
					    <div slot="end" class="flex-row">
 | 
				
			||||||
        <core-download-refresh [status]="state" [enabled]="canDownload" [loading]="isDownloading"
 | 
					        <core-download-refresh [status]="state" [enabled]="canDownload" [loading]="isDownloading" [canTrustDownload]="!alwaysDownload"
 | 
				
			||||||
            [canTrustDownload]="!alwaysDownload" (action)="download()" size="small">
 | 
					            (action)="download()" size="small">
 | 
				
			||||||
        </core-download-refresh>
 | 
					        </core-download-refresh>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <ion-button fill="clear" *ngIf="isDownloaded && isIOS" (click)="openFile($event, true)" color="dark"
 | 
					        <ion-button fill="clear" *ngIf="isDownloaded && isIOS" (click)="openFile($event, true)" color="dark"
 | 
				
			||||||
@ -17,8 +17,8 @@
 | 
				
			|||||||
            <ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true"></ion-icon>
 | 
					            <ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true"></ion-icon>
 | 
				
			||||||
        </ion-button>
 | 
					        </ion-button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <ion-button fill="clear" *ngIf="!isDownloading && canDelete" (click)="delete($event)"
 | 
					        <ion-button fill="clear" *ngIf="!isDownloading && canDelete" (click)="delete($event)" [attr.aria-label]="'core.delete' | translate"
 | 
				
			||||||
            [attr.aria-label]="'core.delete' | translate" color="danger" size="small">
 | 
					            color="danger" size="small">
 | 
				
			||||||
            <ion-icon slot="icon-only" name="fas-trash" aria-hidden="true"></ion-icon>
 | 
					            <ion-icon slot="icon-only" name="fas-trash" aria-hidden="true"></ion-icon>
 | 
				
			||||||
        </ion-button>
 | 
					        </ion-button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -2,25 +2,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <core-navbar-buttons slot="end" append *ngIf="initialized && showFullscreenOnToolbar">
 | 
					    <core-navbar-buttons slot="end" append *ngIf="initialized && showFullscreenOnToolbar">
 | 
				
			||||||
        <ion-button fill="clear" (click)="toggleFullscreen()"
 | 
					        <ion-button fill="clear" (click)="toggleFullscreen()"
 | 
				
			||||||
            [attr.aria-label]="(fullscreen ? 'core.disablefullscreen' : 'core.fullscreen') | translate" >
 | 
					            [attr.aria-label]="(fullscreen ? 'core.disablefullscreen' : 'core.fullscreen') | translate">
 | 
				
			||||||
            <ion-icon *ngIf="!fullscreen" name="fas-expand" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					            <ion-icon *ngIf="!fullscreen" name="fas-expand" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            <ion-icon *ngIf="fullscreen" name="fas-compress" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					            <ion-icon *ngIf="fullscreen" name="fas-compress" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
        </ion-button>
 | 
					        </ion-button>
 | 
				
			||||||
    </core-navbar-buttons>
 | 
					    </core-navbar-buttons>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Don't add the iframe until safeUrl is set, adding an iframe with null as src causes the iframe to load the whole app. -->
 | 
					    <!-- Don't add the iframe until safeUrl is set, adding an iframe with null as src causes the iframe to load the whole app. -->
 | 
				
			||||||
    <iframe #iframe *ngIf="safeUrl" [hidden]="loading" class="core-iframe"
 | 
					    <iframe #iframe *ngIf="safeUrl" [hidden]="loading" class="core-iframe" [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}"
 | 
				
			||||||
        [ngStyle]="{'width': iframeWidth, 'height': iframeHeight}" [src]="safeUrl"
 | 
					        [src]="safeUrl" [attr.allowfullscreen]="allowFullscreen ? 'allowfullscreen' : null">
 | 
				
			||||||
        [attr.allowfullscreen]="allowFullscreen ? 'allowfullscreen' : null">
 | 
					 | 
				
			||||||
    </iframe>
 | 
					    </iframe>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <ion-button
 | 
					    <ion-button *ngIf="!loading && displayHelp" color="dark" expand="block" fill="clear" (click)="openIframeHelpModal()"
 | 
				
			||||||
        *ngIf="!loading && displayHelp"
 | 
					        aria-haspopup="dialog" class="core-button-as-link core-iframe-help">
 | 
				
			||||||
        color="dark" expand="block" fill="clear"
 | 
					 | 
				
			||||||
        (click)="openIframeHelpModal()"
 | 
					 | 
				
			||||||
        aria-haspopup="dialog"
 | 
					 | 
				
			||||||
        class="core-button-as-link core-iframe-help"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
        {{ 'core.iframehelp' | translate }}
 | 
					        {{ 'core.iframehelp' | translate }}
 | 
				
			||||||
    </ion-button>
 | 
					    </ion-button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -18,8 +18,7 @@
 | 
				
			|||||||
        </ion-input>
 | 
					        </ion-input>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="buttons" slot="end">
 | 
					        <div class="buttons" slot="end">
 | 
				
			||||||
            <ion-button fill="clear" *ngIf="isIOS" (click)="openFile($event, true)"
 | 
					            <ion-button fill="clear" *ngIf="isIOS" (click)="openFile($event, true)" [attr.aria-label]="openButtonLabel | translate">
 | 
				
			||||||
                [attr.aria-label]="openButtonLabel | translate">
 | 
					 | 
				
			||||||
                <ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </ion-button>
 | 
					            </ion-button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,5 @@
 | 
				
			|||||||
<img
 | 
					<img *ngIf="!isLocalUrl" [src]="icon" [alt]="showAlt ? modNameTranslated : ''" [attr.role]="!showAlt ? 'presentation' : null"
 | 
				
			||||||
    *ngIf="!isLocalUrl"
 | 
					    class="core-module-icon" core-external-content [component]="linkIconWithComponent ? modname : null"
 | 
				
			||||||
    [src]="icon"
 | 
					    [componentId]="linkIconWithComponent ? componentId : null" (error)="loadFallbackIcon()">
 | 
				
			||||||
    [alt]="showAlt ? modNameTranslated : ''"
 | 
					<img *ngIf="isLocalUrl" [src]="icon" [alt]="showAlt ? modNameTranslated : ''" [attr.role]="!showAlt ? 'presentation' : null"
 | 
				
			||||||
    [attr.role]="!showAlt ? 'presentation' : null" 
 | 
					    class="core-module-icon" (error)="loadFallbackIcon()">
 | 
				
			||||||
    class="core-module-icon"
 | 
					 | 
				
			||||||
    core-external-content
 | 
					 | 
				
			||||||
    [component]="linkIconWithComponent ? modname : null"
 | 
					 | 
				
			||||||
    [componentId]="linkIconWithComponent ? componentId : null"
 | 
					 | 
				
			||||||
    (error)="loadFallbackIcon()"
 | 
					 | 
				
			||||||
>
 | 
					 | 
				
			||||||
<img
 | 
					 | 
				
			||||||
    *ngIf="isLocalUrl"
 | 
					 | 
				
			||||||
    [src]="icon"
 | 
					 | 
				
			||||||
    [alt]="showAlt ? modNameTranslated : ''"
 | 
					 | 
				
			||||||
    [attr.role]="!showAlt ? 'presentation' : null" 
 | 
					 | 
				
			||||||
    class="core-module-icon"
 | 
					 | 
				
			||||||
    (error)="loadFallbackIcon()"
 | 
					 | 
				
			||||||
>
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
<ng-container *ngIf="progress >= 0">
 | 
					<ng-container *ngIf="progress >= 0">
 | 
				
			||||||
    <progress max="100" [value]="progress" role="progressbar" [attr.aria-valuenow]="progress"
 | 
					    <progress max="100" [value]="progress" role="progressbar" [attr.aria-valuenow]="progress" [attr.aria-valuetext]="progressBarValueText"
 | 
				
			||||||
        [attr.aria-valuetext]="progressBarValueText" [attr.aria-describedby]="ariaDescribedBy">
 | 
					        [attr.aria-describedby]="ariaDescribedBy">
 | 
				
			||||||
    </progress>
 | 
					    </progress>
 | 
				
			||||||
    <div class="core-progress-text">
 | 
					    <div class="core-progress-text">
 | 
				
			||||||
        <span class="sr-only" *ngIf="a11yText">{{ a11yText | translate }}</span>
 | 
					        <span class="sr-only" *ngIf="a11yText">{{ a11yText | translate }}</span>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,24 +1,12 @@
 | 
				
			|||||||
<form #messageForm>
 | 
					<form #messageForm>
 | 
				
			||||||
    <textarea
 | 
					    <textarea class="core-send-message-input" [attr.aria-label]="placeholder" [core-auto-focus]="showKeyboard" [placeholder]="placeholder"
 | 
				
			||||||
        class="core-send-message-input"
 | 
					        rows="1" [core-auto-rows]="message" [(ngModel)]="message" name="message" (onResize)="textareaResized()"
 | 
				
			||||||
        [attr.aria-label]="placeholder"
 | 
					        (keyup.enter)="enterKeyUp($event)" (keyup.control.enter)="enterKeyUp($event, 'control')"
 | 
				
			||||||
        [core-auto-focus]="showKeyboard"
 | 
					        (keyup.meta.enter)="enterKeyUp($event, 'meta')" (keydown.enter)="enterKeyDown($event)"
 | 
				
			||||||
        [placeholder]="placeholder"
 | 
					        (keydown.control.enter)="enterKeyDown($event, 'control')" (keydown.meta.enter)="enterKeyDown($event, 'meta')">
 | 
				
			||||||
        rows="1"
 | 
					 | 
				
			||||||
        [core-auto-rows]="message"
 | 
					 | 
				
			||||||
        [(ngModel)]="message"
 | 
					 | 
				
			||||||
        name="message"
 | 
					 | 
				
			||||||
        (onResize)="textareaResized()"
 | 
					 | 
				
			||||||
        (keyup.enter)="enterKeyUp($event)"
 | 
					 | 
				
			||||||
        (keyup.control.enter)="enterKeyUp($event, 'control')"
 | 
					 | 
				
			||||||
        (keyup.meta.enter)="enterKeyUp($event, 'meta')"
 | 
					 | 
				
			||||||
        (keydown.enter)="enterKeyDown($event)"
 | 
					 | 
				
			||||||
        (keydown.control.enter)="enterKeyDown($event, 'control')"
 | 
					 | 
				
			||||||
        (keydown.meta.enter)="enterKeyDown($event, 'meta')"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
    </textarea>
 | 
					    </textarea>
 | 
				
			||||||
    <ion-button fill="clear" size="large" type="submit" [disabled]="!message || sendDisabled"
 | 
					    <ion-button fill="clear" size="large" type="submit" [disabled]="!message || sendDisabled" [attr.aria-label]="'core.send' | translate"
 | 
				
			||||||
        [attr.aria-label]="'core.send' | translate" [core-suppress-events] (onClick)="submitForm($event)">
 | 
					        [core-suppress-events] (onClick)="submitForm($event)">
 | 
				
			||||||
        <ion-icon name="send" color="dark" slot="icon-only" aria-hidden="true" flip-rtl></ion-icon>
 | 
					        <ion-icon name="send" color="dark" slot="icon-only" aria-hidden="true" flip-rtl></ion-icon>
 | 
				
			||||||
    </ion-button>
 | 
					    </ion-button>
 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,5 @@
 | 
				
			|||||||
    <ng-content></ng-content>
 | 
					    <ng-content></ng-content>
 | 
				
			||||||
</ion-content>
 | 
					</ion-content>
 | 
				
			||||||
<ion-router-outlet class="content-outlet"></ion-router-outlet>
 | 
					<ion-router-outlet class="content-outlet"></ion-router-outlet>
 | 
				
			||||||
<core-empty-box class="content-placeholder" icon="fas-arrow-circle-left" [message]="placeholderText | translate"
 | 
					<core-empty-box class="content-placeholder" icon="fas-arrow-circle-left" [message]="placeholderText | translate" [flipIconRtl]="true">
 | 
				
			||||||
    [flipIconRtl]="true">
 | 
					 | 
				
			||||||
</core-empty-box>
 | 
					</core-empty-box>
 | 
				
			||||||
 | 
				
			|||||||
@ -9,24 +9,12 @@
 | 
				
			|||||||
                <ion-slides (ionSlideDidChange)="slideChanged()" [options]="slidesOpts" [dir]="direction" role="tablist"
 | 
					                <ion-slides (ionSlideDidChange)="slideChanged()" [options]="slidesOpts" [dir]="direction" role="tablist"
 | 
				
			||||||
                    [attr.aria-label]="description">
 | 
					                    [attr.aria-label]="description">
 | 
				
			||||||
                    <ng-container *ngFor="let tab of tabs">
 | 
					                    <ng-container *ngFor="let tab of tabs">
 | 
				
			||||||
                        <ion-slide
 | 
					                        <ion-slide role="presentation" [id]="tab.id! + '-tab'" class="tab-slide" tabindex="-1"
 | 
				
			||||||
                            role="presentation"
 | 
					 | 
				
			||||||
                            [id]="tab.id! + '-tab'"
 | 
					 | 
				
			||||||
                            class="tab-slide"
 | 
					 | 
				
			||||||
                            tabindex="-1"
 | 
					 | 
				
			||||||
                            [class.selected]="selected == tab.id">
 | 
					                            [class.selected]="selected == tab.id">
 | 
				
			||||||
                            <ion-tab-button
 | 
					                            <ion-tab-button (ionTabButtonClick)="selectTab(tab.id, $event)" (keydown)="tabAction.keyDown($event)"
 | 
				
			||||||
                                (ionTabButtonClick)="selectTab(tab.id, $event)"
 | 
					                                (keyup)="tabAction.keyUp(tab.id, $event)" [tab]="tab.page" [layout]="layout" class="{{tab.class}}"
 | 
				
			||||||
                                (keydown)="tabAction.keyDown($event)"
 | 
					                                role="tab" [attr.aria-controls]="tab.id" [attr.aria-selected]="selected == tab.id"
 | 
				
			||||||
                                (keyup)="tabAction.keyUp(tab.id, $event)"
 | 
					                                [tabindex]="selected == tab.id ? 0 : -1">
 | 
				
			||||||
                                [tab]="tab.page"
 | 
					 | 
				
			||||||
                                [layout]="layout"
 | 
					 | 
				
			||||||
                                class="{{tab.class}}"
 | 
					 | 
				
			||||||
                                role="tab"
 | 
					 | 
				
			||||||
                                [attr.aria-controls]="tab.id"
 | 
					 | 
				
			||||||
                                [attr.aria-selected]="selected == tab.id"
 | 
					 | 
				
			||||||
                                [tabindex]="selected == tab.id ? 0 : -1"
 | 
					 | 
				
			||||||
                            >
 | 
					 | 
				
			||||||
                                <ion-icon *ngIf="tab.icon" [name]="tab.icon" aria-hidden="true"></ion-icon>
 | 
					                                <ion-icon *ngIf="tab.icon" [name]="tab.icon" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                                <ion-label>
 | 
					                                <ion-label>
 | 
				
			||||||
                                    {{ tab.title | translate}}
 | 
					                                    {{ tab.title | translate}}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,24 +8,12 @@
 | 
				
			|||||||
            <ion-slides (ionSlideDidChange)="slideChanged()" [options]="slidesOpts" [dir]="direction" role="tablist"
 | 
					            <ion-slides (ionSlideDidChange)="slideChanged()" [options]="slidesOpts" [dir]="direction" role="tablist"
 | 
				
			||||||
                [attr.aria-label]="description">
 | 
					                [attr.aria-label]="description">
 | 
				
			||||||
                <ng-container *ngFor="let tab of tabs">
 | 
					                <ng-container *ngFor="let tab of tabs">
 | 
				
			||||||
                    <ion-slide
 | 
					                    <ion-slide *ngIf="tab.enabled" role="presentation" [hidden]="!hideUntil" class="tab-slide" [id]="tab.id! + '-tab'"
 | 
				
			||||||
                        *ngIf="tab.enabled"
 | 
					 | 
				
			||||||
                        role="presentation"
 | 
					 | 
				
			||||||
                        [hidden]="!hideUntil"
 | 
					 | 
				
			||||||
                        class="tab-slide"
 | 
					 | 
				
			||||||
                        [id]="tab.id! + '-tab'"
 | 
					 | 
				
			||||||
                        [class.selected]="selected == tab.id">
 | 
					                        [class.selected]="selected == tab.id">
 | 
				
			||||||
                        <ion-tab-button
 | 
					                        <ion-tab-button (click)="selectTab(tab.id, $event)" (keydown)="tabAction.keyDown($event)"
 | 
				
			||||||
                            (click)="selectTab(tab.id, $event)"
 | 
					                            (keyup)="tabAction.keyUp(tab.id, $event)" class="{{tab.class}}" [layout]="layout" role="tab"
 | 
				
			||||||
                            (keydown)="tabAction.keyDown($event)"
 | 
					                            [attr.aria-controls]="tab.id" [attr.aria-selected]="selected == tab.id"
 | 
				
			||||||
                            (keyup)="tabAction.keyUp(tab.id, $event)"
 | 
					                            [tabindex]="selected == tab.id ? 0 : -1">
 | 
				
			||||||
                            class="{{tab.class}}"
 | 
					 | 
				
			||||||
                            [layout]="layout"
 | 
					 | 
				
			||||||
                            role="tab"
 | 
					 | 
				
			||||||
                            [attr.aria-controls]="tab.id"
 | 
					 | 
				
			||||||
                            [attr.aria-selected]="selected == tab.id"
 | 
					 | 
				
			||||||
                            [tabindex]="selected == tab.id ? 0 : -1"
 | 
					 | 
				
			||||||
                        >
 | 
					 | 
				
			||||||
                            <ion-icon *ngIf="tab.icon" [name]="tab.icon" aria-hidden="true"></ion-icon>
 | 
					                            <ion-icon *ngIf="tab.icon" [name]="tab.icon" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                            <ion-label>
 | 
					                            <ion-label>
 | 
				
			||||||
                                {{ tab.title | translate}}
 | 
					                                {{ tab.title | translate}}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
<ion-item lines="none" class="core-timer" role="timer"
 | 
					<ion-item lines="none" class="core-timer" role="timer" [ngClass]="{'ion-text-center': align == 'center', 'ion-text-end': align == 'right'}">
 | 
				
			||||||
    [ngClass]="{'ion-text-center': align == 'center', 'ion-text-end': align == 'right'}">
 | 
					 | 
				
			||||||
    <ion-icon name="fas-clock" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon name="fas-clock" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <span *ngIf="timeLeft && timeLeft > 0 && timerText" class="core-timer-text">{{ timerText }}</span>
 | 
					        <span *ngIf="timeLeft && timeLeft > 0 && timerText" class="core-timer-text">{{ timerText }}</span>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,15 +1,6 @@
 | 
				
			|||||||
<img
 | 
					<img *ngIf="avatarUrl" [src]="avatarUrl" [alt]="'core.pictureof' | translate:{$a: fullname}" core-external-content
 | 
				
			||||||
    *ngIf="avatarUrl"
 | 
					    onError="this.src='assets/img/user-avatar.png'" (ariaButtonClick)="gotoProfile($event)" [attr.aria-hidden]="!linkProfile"
 | 
				
			||||||
    [src]="avatarUrl"
 | 
					    [attr.role]="linkProfile ? 'button' : null" [attr.tabindex]="linkProfile ? 0 : null" [class.clickable]="linkProfile">
 | 
				
			||||||
    [alt]="'core.pictureof' | translate:{$a: fullname}"
 | 
					 | 
				
			||||||
    core-external-content
 | 
					 | 
				
			||||||
    onError="this.src='assets/img/user-avatar.png'"
 | 
					 | 
				
			||||||
    (ariaButtonClick)="gotoProfile($event)"
 | 
					 | 
				
			||||||
    [attr.aria-hidden]="!linkProfile"
 | 
					 | 
				
			||||||
    [attr.role]="linkProfile ? 'button' : null"
 | 
					 | 
				
			||||||
    [attr.tabindex]="linkProfile ? 0 : null"
 | 
					 | 
				
			||||||
    [class.clickable]="linkProfile"
 | 
					 | 
				
			||||||
>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<img *ngIf="!avatarUrl" src="assets/img/user-avatar.png" [alt]="'core.pictureof' | translate:{$a: fullname}"
 | 
					<img *ngIf="!avatarUrl" src="assets/img/user-avatar.png" [alt]="'core.pictureof' | translate:{$a: fullname}"
 | 
				
			||||||
    (ariaButtonClick)="gotoProfile($event)" [attr.aria-hidden]="!linkProfile" [attr.role]="linkProfile ? 'button' : null"
 | 
					    (ariaButtonClick)="gotoProfile($event)" [attr.aria-hidden]="!linkProfile" [attr.role]="linkProfile ? 'button' : null"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
<ion-item button class="ion-text-wrap divider" (click)="gotoBlock()" detail="true">
 | 
					<ion-item button class="ion-text-wrap divider" (click)="gotoBlock()" detail="true">
 | 
				
			||||||
    <ion-label><h2>{{ title | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ title | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,7 @@
 | 
				
			|||||||
<ion-item-divider class="ion-text-wrap" *ngIf="title" sticky="true">
 | 
					<ion-item-divider class="ion-text-wrap" *ngIf="title" sticky="true">
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <h2>
 | 
					        <h2>
 | 
				
			||||||
            <core-format-text [text]="title | translate" contextLevel="block" [contextInstanceId]="block.instanceid"
 | 
					            <core-format-text [text]="title | translate" contextLevel="block" [contextInstanceId]="block.instanceid" [courseId]="courseId">
 | 
				
			||||||
            [courseId]="courseId">
 | 
					 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </h2>
 | 
					        </h2>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
@ -11,14 +10,14 @@
 | 
				
			|||||||
    <ion-item *ngIf="block.contents?.content" class="ion-text-wrap core-block-content">
 | 
					    <ion-item *ngIf="block.contents?.content" class="ion-text-wrap core-block-content">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [text]="block.contents?.content" contextLevel="block" [contextInstanceId]="block.instanceid"
 | 
					            <core-format-text [text]="block.contents?.content" contextLevel="block" [contextInstanceId]="block.instanceid"
 | 
				
			||||||
            [courseId]="courseId">
 | 
					                [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
    <ion-item *ngIf="block.contents?.footer" class="ion-text-wrap core-block-footer">
 | 
					    <ion-item *ngIf="block.contents?.footer" class="ion-text-wrap core-block-footer">
 | 
				
			||||||
        <ion-label>
 | 
					        <ion-label>
 | 
				
			||||||
            <core-format-text [text]="block.contents?.footer" contextLevel="block" [contextInstanceId]="block.instanceid"
 | 
					            <core-format-text [text]="block.contents?.footer" contextLevel="block" [contextInstanceId]="block.instanceid"
 | 
				
			||||||
            [courseId]="courseId">
 | 
					                [courseId]="courseId">
 | 
				
			||||||
            </core-format-text>
 | 
					            </core-format-text>
 | 
				
			||||||
        </ion-label>
 | 
					        </ion-label>
 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -7,21 +7,16 @@
 | 
				
			|||||||
            {{ 'core.comments.commentsnotworking' | translate }}
 | 
					            {{ 'core.comments.commentsnotworking' | translate }}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    </core-loading>
 | 
					    </core-loading>
 | 
				
			||||||
    <ion-item
 | 
					    <ion-item *ngIf="showItem" button [detail]="!countError && commentsLoaded" (click)="openComments($event)" [disabled]="countError">
 | 
				
			||||||
        *ngIf="showItem"
 | 
					        <ion-label>
 | 
				
			||||||
        button
 | 
					            <core-loading [hideUntil]="commentsLoaded" [fullscreen]="false">
 | 
				
			||||||
        [detail]="!countError && commentsLoaded"
 | 
					                <p *ngIf="!countError" class="item-heading">
 | 
				
			||||||
        (click)="openComments($event)"
 | 
					                    {{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
 | 
				
			||||||
        [disabled]="countError">
 | 
					                </p>
 | 
				
			||||||
            <ion-label>
 | 
					                <p *ngIf="countError">
 | 
				
			||||||
                <core-loading [hideUntil]="commentsLoaded" [fullscreen]="false">
 | 
					                    {{ 'core.comments.commentsnotworking' | translate }}
 | 
				
			||||||
                    <p *ngIf="!countError" class="item-heading">
 | 
					                </p>
 | 
				
			||||||
                        {{ 'core.comments.commentscount' | translate : {'$a': commentsCount} }}
 | 
					            </core-loading>
 | 
				
			||||||
                    </p>
 | 
					        </ion-label>
 | 
				
			||||||
                    <p *ngIf="countError">
 | 
					 | 
				
			||||||
                        {{ 'core.comments.commentsnotworking' | translate }}
 | 
					 | 
				
			||||||
                    </p>
 | 
					 | 
				
			||||||
                </core-loading>
 | 
					 | 
				
			||||||
            </ion-label>
 | 
					 | 
				
			||||||
    </ion-item>
 | 
					    </ion-item>
 | 
				
			||||||
</ng-container>
 | 
					</ng-container>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,18 +3,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <ng-container *ngIf="completion.istrackeduser">
 | 
					    <ng-container *ngIf="completion.istrackeduser">
 | 
				
			||||||
        <ng-container *ngFor="let rule of details">
 | 
					        <ng-container *ngFor="let rule of details">
 | 
				
			||||||
            <ion-badge *ngIf="rule.statuscomplete" color="success" role="listitem"
 | 
					            <ion-badge *ngIf="rule.statuscomplete" color="success" role="listitem" [attr.aria-label]="rule.accessibleDescription">
 | 
				
			||||||
                [attr.aria-label]="rule.accessibleDescription">
 | 
					 | 
				
			||||||
                <strong>{{ 'core.course.completion_automatic:done' | translate }}</strong> {{ rule.rulevalue.description }}
 | 
					                <strong>{{ 'core.course.completion_automatic:done' | translate }}</strong> {{ rule.rulevalue.description }}
 | 
				
			||||||
            </ion-badge>
 | 
					            </ion-badge>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ion-badge *ngIf="rule.statuscompletefail" color="danger" role="listitem"
 | 
					            <ion-badge *ngIf="rule.statuscompletefail" color="danger" role="listitem" [attr.aria-label]="rule.accessibleDescription">
 | 
				
			||||||
                [attr.aria-label]="rule.accessibleDescription">
 | 
					 | 
				
			||||||
                <strong>{{ 'core.course.completion_automatic:failed' | translate }}</strong> {{ rule.rulevalue.description }}
 | 
					                <strong>{{ 'core.course.completion_automatic:failed' | translate }}</strong> {{ rule.rulevalue.description }}
 | 
				
			||||||
            </ion-badge>
 | 
					            </ion-badge>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ion-badge *ngIf="rule.statusincomplete" color="medium" role="listitem"
 | 
					            <ion-badge *ngIf="rule.statusincomplete" color="medium" role="listitem" [attr.aria-label]="rule.accessibleDescription">
 | 
				
			||||||
                [attr.aria-label]="rule.accessibleDescription">
 | 
					 | 
				
			||||||
                <strong>{{ 'core.course.completion_automatic:todo' | translate }}</strong> {{ rule.rulevalue.description }}
 | 
					                <strong>{{ 'core.course.completion_automatic:todo' | translate }}</strong> {{ rule.rulevalue.description }}
 | 
				
			||||||
            </ion-badge>
 | 
					            </ion-badge>
 | 
				
			||||||
        </ng-container>
 | 
					        </ng-container>
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <ng-container *ngIf="completion.istrackeduser">
 | 
					    <ng-container *ngIf="completion.istrackeduser">
 | 
				
			||||||
        <ng-container *ngIf="completion.state">
 | 
					        <ng-container *ngIf="completion.state">
 | 
				
			||||||
            <ion-button color="success" fill="outline" [attr.aria-label]="accessibleDescription"
 | 
					            <ion-button color="success" fill="outline" [attr.aria-label]="accessibleDescription" (click)="completionClicked($event)">
 | 
				
			||||||
                (click)="completionClicked($event)">
 | 
					 | 
				
			||||||
                <ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
                {{ 'core.course.completion_manual:done' | translate }}
 | 
					                {{ 'core.course.completion_manual:done' | translate }}
 | 
				
			||||||
            </ion-button>
 | 
					            </ion-button>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<ion-item class="ion-text-wrap" *ngFor="let item of items" (click)="openCourse(item.courseId)" [attr.aria-label]="item.courseName"
 | 
					<ion-item class="ion-text-wrap" *ngFor="let item of items" (click)="openCourse(item.courseId)" [attr.aria-label]="item.courseName" button
 | 
				
			||||||
    button detail="true">
 | 
					    detail="true">
 | 
				
			||||||
    <ion-icon name="fas-graduation-cap" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon name="fas-graduation-cap" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <p class="item-heading">{{ item.courseName }}</p>
 | 
					        <p class="item-heading">{{ item.courseName }}</p>
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,8 @@
 | 
				
			|||||||
            [content]="'core.settings.showdownloadoptions' | translate" (action)="toggleDownload()">
 | 
					            [content]="'core.settings.showdownloadoptions' | translate" (action)="toggleDownload()">
 | 
				
			||||||
        </core-context-menu-item>
 | 
					        </core-context-menu-item>
 | 
				
			||||||
        <core-context-menu-item [hidden]="!downloadCourseEnabled" [priority]="1900"
 | 
					        <core-context-menu-item [hidden]="!downloadCourseEnabled" [priority]="1900"
 | 
				
			||||||
            [content]="prefetchCourseData.statusTranslatable | translate" (action)="prefetchCourse()"
 | 
					            [content]="prefetchCourseData.statusTranslatable | translate" (action)="prefetchCourse()" [iconAction]="prefetchCourseData.icon"
 | 
				
			||||||
            [iconAction]="prefetchCourseData.icon" [closeOnClick]="false">
 | 
					            [closeOnClick]="false">
 | 
				
			||||||
        </core-context-menu-item>
 | 
					        </core-context-menu-item>
 | 
				
			||||||
        <core-context-menu-item [priority]="1800" [content]="'core.course.coursesummary' | translate" (action)="openCourseSummary()"
 | 
					        <core-context-menu-item [priority]="1800" [content]="'core.course.coursesummary' | translate" (action)="openCourseSummary()"
 | 
				
			||||||
            iconAction="fas-graduation-cap">
 | 
					            iconAction="fas-graduation-cap">
 | 
				
			||||||
@ -21,9 +21,9 @@
 | 
				
			|||||||
    </ion-refresher>
 | 
					    </ion-refresher>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <core-loading [hideUntil]="dataLoaded">
 | 
					    <core-loading [hideUntil]="dataLoaded">
 | 
				
			||||||
        <core-course-format [course]="course" [sections]="sections" [initialSectionId]="sectionId"
 | 
					        <core-course-format [course]="course" [sections]="sections" [initialSectionId]="sectionId" [initialSectionNumber]="sectionNumber"
 | 
				
			||||||
            [initialSectionNumber]="sectionNumber" [downloadEnabled]="downloadEnabled" [moduleId]="moduleId"
 | 
					            [downloadEnabled]="downloadEnabled" [moduleId]="moduleId" (completionChanged)="onCompletionChange($event)"
 | 
				
			||||||
            (completionChanged)="onCompletionChange($event)" class="core-course-format-{{course.format}}">
 | 
					            class="core-course-format-{{course.format}}">
 | 
				
			||||||
        </core-course-format>
 | 
					        </core-course-format>
 | 
				
			||||||
    </core-loading>
 | 
					    </core-loading>
 | 
				
			||||||
</ion-content>
 | 
					</ion-content>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,26 +1,38 @@
 | 
				
			|||||||
<ion-item button class="ion-text-wrap" (click)="action('download')" *ngIf="downloadCourseEnabled" detail="false">
 | 
					<ion-item button class="ion-text-wrap" (click)="action('download')" *ngIf="downloadCourseEnabled" detail="false">
 | 
				
			||||||
    <ion-icon *ngIf="!prefetch.loading" [name]="prefetch.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon *ngIf="!prefetch.loading" [name]="prefetch.icon" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-spinner *ngIf="prefetch.loading" slot="start" [attr.aria-label]="'core.loading' | translate"></ion-spinner>
 | 
					    <ion-spinner *ngIf="prefetch.loading" slot="start" [attr.aria-label]="'core.loading' | translate"></ion-spinner>
 | 
				
			||||||
    <ion-label><h2>{{ prefetch.statusTranslatable | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ prefetch.statusTranslatable | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
<ion-item button class="ion-text-wrap" (click)="action('delete')" detail="false"
 | 
					<ion-item button class="ion-text-wrap" (click)="action('delete')" detail="false"
 | 
				
			||||||
    *ngIf="prefetch.status == 'downloaded' || prefetch.status == 'outdated'">
 | 
					    *ngIf="prefetch.status == 'downloaded' || prefetch.status == 'outdated'">
 | 
				
			||||||
    <ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-label><h2>{{ 'addon.storagemanager.deletecourse' | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ 'addon.storagemanager.deletecourse' | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
<ion-item button class="ion-text-wrap" (click)="action('hide')" *ngIf="!course.hidden" detail="false">
 | 
					<ion-item button class="ion-text-wrap" (click)="action('hide')" *ngIf="!course.hidden" detail="false">
 | 
				
			||||||
    <ion-icon name="fas-eye" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon name="fas-eye" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-label><h2>{{ 'core.courses.hidecourse' | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ 'core.courses.hidecourse' | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
<ion-item button class="ion-text-wrap" (click)="action('show')" *ngIf="course.hidden" detail="false">
 | 
					<ion-item button class="ion-text-wrap" (click)="action('show')" *ngIf="course.hidden" detail="false">
 | 
				
			||||||
    <ion-icon name="fas-eye-slash" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon name="fas-eye-slash" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-label><h2>{{ 'core.courses.show' | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ 'core.courses.show' | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
<ion-item button class="ion-text-wrap" (click)="action('favourite')" *ngIf="!course.isfavourite" detail="false">
 | 
					<ion-item button class="ion-text-wrap" (click)="action('favourite')" *ngIf="!course.isfavourite" detail="false">
 | 
				
			||||||
    <ion-icon name="fas-star" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon name="fas-star" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-label><h2>{{ 'core.courses.addtofavourites' | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ 'core.courses.addtofavourites' | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
<ion-item button class="ion-text-wrap" (click)="action('unfavourite')" *ngIf="course.isfavourite" detail="false">
 | 
					<ion-item button class="ion-text-wrap" (click)="action('unfavourite')" *ngIf="course.isfavourite" detail="false">
 | 
				
			||||||
    <ion-icon name="far-star" slot="start" aria-hidden="true"></ion-icon>
 | 
					    <ion-icon name="far-star" slot="start" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    <ion-label><h2>{{ 'core.courses.removefromfavourites' | translate }}</h2></ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
 | 
					        <h2>{{ 'core.courses.removefromfavourites' | translate }}</h2>
 | 
				
			||||||
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,29 +1,11 @@
 | 
				
			|||||||
<div class="core-rte-editor-container" (click)="focusRTE()" [class.toolbar-hidden]="toolbarHidden">
 | 
					<div class="core-rte-editor-container" (click)="focusRTE()" [class.toolbar-hidden]="toolbarHidden">
 | 
				
			||||||
    <div
 | 
					    <div [hidden]="!rteEnabled" #editor class="core-rte-editor" role="textbox" contenteditable="true"
 | 
				
			||||||
        [hidden]="!rteEnabled"
 | 
					        [attr.aria-labelledby]="ariaLabelledBy" [attr.data-placeholder-text]="placeholder" (focus)="showToolbar($event)"
 | 
				
			||||||
        #editor
 | 
					        (blur)="hideToolbar($event)">
 | 
				
			||||||
        class="core-rte-editor"
 | 
					 | 
				
			||||||
        role="textbox"
 | 
					 | 
				
			||||||
        contenteditable="true"
 | 
					 | 
				
			||||||
        [attr.aria-labelledby]="ariaLabelledBy"
 | 
					 | 
				
			||||||
        [attr.data-placeholder-text]="placeholder"
 | 
					 | 
				
			||||||
        (focus)="showToolbar($event)"
 | 
					 | 
				
			||||||
        (blur)="hideToolbar($event)"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <ion-textarea
 | 
					    <ion-textarea [hidden]="rteEnabled" #textarea class="core-textarea" role="textbox" [attr.name]="name" ngControl="control"
 | 
				
			||||||
        [hidden]="rteEnabled"
 | 
					        [placeholder]="placeholder" (ionChange)="onChange()" (ionFocus)="showToolbar($event)" (ionBlur)="hideToolbar($event)">
 | 
				
			||||||
        #textarea
 | 
					 | 
				
			||||||
        class="core-textarea"
 | 
					 | 
				
			||||||
        role="textbox"
 | 
					 | 
				
			||||||
        [attr.name]="name"
 | 
					 | 
				
			||||||
        ngControl="control"
 | 
					 | 
				
			||||||
        [placeholder]="placeholder"
 | 
					 | 
				
			||||||
        (ionChange)="onChange()"
 | 
					 | 
				
			||||||
        (ionFocus)="showToolbar($event)"
 | 
					 | 
				
			||||||
        (ionBlur)="hideToolbar($event)"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
    </ion-textarea>
 | 
					    </ion-textarea>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="core-rte-info-message" *ngIf="infoMessage">
 | 
					    <div class="core-rte-info-message" *ngIf="infoMessage">
 | 
				
			||||||
@ -33,9 +15,8 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div #toolbar class="core-rte-toolbar" [class.toolbar-hidden]="toolbarHidden">
 | 
					<div #toolbar class="core-rte-toolbar" [class.toolbar-hidden]="toolbarHidden">
 | 
				
			||||||
    <button *ngIf="toolbarArrows" class="toolbar-arrow" [class.toolbar-arrow-hidden]="toolbarPrevHidden"
 | 
					    <button *ngIf="toolbarArrows" class="toolbar-arrow" [class.toolbar-arrow-hidden]="toolbarPrevHidden" (click)="toolbarPrev($event)"
 | 
				
			||||||
        (click)="toolbarPrev($event)" (keyup)="toolbarPrev($event)"
 | 
					        (keyup)="toolbarPrev($event)" (mousedown)="downAction($event)" (keydown)="downAction($event)"
 | 
				
			||||||
        (mousedown)="downAction($event)" (keydown)="downAction($event)"
 | 
					 | 
				
			||||||
        [attr.aria-label]="'core.previous' | translate">
 | 
					        [attr.aria-label]="'core.previous' | translate">
 | 
				
			||||||
        <ion-icon name="fas-chevron-left" aria-hidden="true"></ion-icon>
 | 
					        <ion-icon name="fas-chevron-left" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    </button>
 | 
					    </button>
 | 
				
			||||||
@ -58,8 +39,7 @@
 | 
				
			|||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.u" [title]="'core.editor.underline' | translate"
 | 
					            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.u" [title]="'core.editor.underline' | translate"
 | 
				
			||||||
                (click)="buttonAction($event, 'underline', 'u')" (keyup)="buttonAction($event, 'underline', 'u')"
 | 
					                (click)="buttonAction($event, 'underline', 'u')" (keyup)="buttonAction($event, 'underline', 'u')"
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)"
 | 
					                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                <ion-icon name="fas-underline" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-underline" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
@ -72,35 +52,34 @@
 | 
				
			|||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.p" [title]="'core.editor.p' | translate"
 | 
					            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.p" [title]="'core.editor.p' | translate"
 | 
				
			||||||
                (click)="buttonAction($event, 'p', 'block')" (keyup)="buttonAction($event, 'p', 'block')"
 | 
					                (click)="buttonAction($event, 'p', 'block')" (keyup)="buttonAction($event, 'p', 'block')" (mousedown)="downAction($event)"
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
					                (keydown)="downAction($event)">
 | 
				
			||||||
                <ion-icon name="fas-paragraph" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-paragraph" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h3" [title]="'core.editor.h3' | translate"
 | 
					            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h3" [title]="'core.editor.h3' | translate"
 | 
				
			||||||
                (click)="buttonAction($event, 'h3', 'block')" (keyup)="buttonAction($event, 'h3', 'block')"
 | 
					                (click)="buttonAction($event, 'h3', 'block')" (keyup)="buttonAction($event, 'h3', 'block')" (mousedown)="downAction($event)"
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)" >
 | 
					                (keydown)="downAction($event)">
 | 
				
			||||||
                <ion-icon name="fas-heading" aria-hidden="true"></ion-icon><span aria-hidden="true">3</span>
 | 
					                <ion-icon name="fas-heading" aria-hidden="true"></ion-icon><span aria-hidden="true">3</span>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h4" [title]="'core.editor.h4' | translate"
 | 
					            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h4" [title]="'core.editor.h4' | translate"
 | 
				
			||||||
                (click)="buttonAction($event, 'h4', 'block')" (keyup)="buttonAction($event, 'h4', 'block')"
 | 
					                (click)="buttonAction($event, 'h4', 'block')" (keyup)="buttonAction($event, 'h4', 'block')" (mousedown)="downAction($event)"
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
					                (keydown)="downAction($event)">
 | 
				
			||||||
                <ion-icon name="fas-heading" aria-hidden="true"></ion-icon><span aria-hidden="true">4</span>
 | 
					                <ion-icon name="fas-heading" aria-hidden="true"></ion-icon><span aria-hidden="true">4</span>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h5" [title]="'core.editor.h5' | translate"
 | 
					            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h5" [title]="'core.editor.h5' | translate"
 | 
				
			||||||
                (click)="buttonAction($event, 'h5', 'block')" (keyup)="buttonAction($event, 'h5', 'block')"
 | 
					                (click)="buttonAction($event, 'h5', 'block')" (keyup)="buttonAction($event, 'h5', 'block')" (mousedown)="downAction($event)"
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
					                (keydown)="downAction($event)">
 | 
				
			||||||
                <ion-icon name="fas-heading" aria-hidden="true"></ion-icon><span aria-hidden="true">5</span>
 | 
					                <ion-icon name="fas-heading" aria-hidden="true"></ion-icon><span aria-hidden="true">5</span>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.ul"
 | 
					            <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.ul" [title]="'core.editor.unorderedlist' | translate"
 | 
				
			||||||
                [title]="'core.editor.unorderedlist' | translate"
 | 
					 | 
				
			||||||
                (click)="buttonAction($event, 'insertUnorderedList')" (click)="buttonAction($event, 'insertUnorderedList')"
 | 
					                (click)="buttonAction($event, 'insertUnorderedList')" (click)="buttonAction($event, 'insertUnorderedList')"
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
					                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
				
			||||||
                <ion-icon name="fas-list-ul" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-list-ul" aria-hidden="true"></ion-icon>
 | 
				
			||||||
@ -114,40 +93,33 @@
 | 
				
			|||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [disabled]="!rteEnabled"
 | 
					            <button [disabled]="!rteEnabled" (click)="buttonAction($event, 'removeFormat')" (keyup)="buttonAction($event, 'removeFormat')"
 | 
				
			||||||
                (click)="buttonAction($event, 'removeFormat')" (keyup)="buttonAction($event, 'removeFormat')"
 | 
					                (mousedown)="downAction($event)" (keydown)="downAction($event)" [title]="'core.editor.clear' | translate">
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)"
 | 
					 | 
				
			||||||
                [title]="'core.editor.clear' | translate">
 | 
					 | 
				
			||||||
                <ion-icon name="fas-eraser" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-eraser" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide *ngIf="canScanQR">
 | 
					        <ion-slide *ngIf="canScanQR">
 | 
				
			||||||
            <button [disabled]="!rteEnabled"
 | 
					            <button [disabled]="!rteEnabled" (click)="scanQR($event)" (keyup)="scanQR($event)" (mousedown)="stopBubble($event)"
 | 
				
			||||||
                (click)="scanQR($event)" (keyup)="scanQR($event)"
 | 
					                (keydown)="stopBubble($event)" [title]="'core.scanqr' | translate">
 | 
				
			||||||
                (mousedown)="stopBubble($event)" (keydown)="stopBubble($event)"
 | 
					 | 
				
			||||||
                [title]="'core.scanqr' | translate">
 | 
					 | 
				
			||||||
                <ion-icon name="fas-qrcode" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-qrcode" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide>
 | 
					        <ion-slide>
 | 
				
			||||||
            <button [attr.aria-pressed]="!rteEnabled" [title]="'core.editor.toggle' | translate"
 | 
					            <button [attr.aria-pressed]="!rteEnabled" [title]="'core.editor.toggle' | translate" (click)="toggleEditor($event)"
 | 
				
			||||||
                (click)="toggleEditor($event)" (keyup)="toggleEditor($event)"
 | 
					                (keyup)="toggleEditor($event)" (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
					 | 
				
			||||||
                <ion-icon name="fas-code" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-code" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
        <ion-slide *ngIf="isPhone">
 | 
					        <ion-slide *ngIf="isPhone">
 | 
				
			||||||
            <button [title]="'core.editor.hidetoolbar' | translate"
 | 
					            <button [title]="'core.editor.hidetoolbar' | translate" (click)="hideToolbar($event)" (keyup)="hideToolbar($event)"
 | 
				
			||||||
                (click)="hideToolbar($event)" (keyup)="hideToolbar($event)"
 | 
					 | 
				
			||||||
                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
					                (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
				
			||||||
                <ion-icon name="fas-times" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-times" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
        </ion-slide>
 | 
					        </ion-slide>
 | 
				
			||||||
    </ion-slides>
 | 
					    </ion-slides>
 | 
				
			||||||
    <button *ngIf="toolbarArrows" class="toolbar-arrow" [class.toolbar-arrow-hidden]="toolbarNextHidden"
 | 
					    <button *ngIf="toolbarArrows" class="toolbar-arrow" [class.toolbar-arrow-hidden]="toolbarNextHidden"
 | 
				
			||||||
        [attr.aria-label]="'core.next' | translate"
 | 
					        [attr.aria-label]="'core.next' | translate" (click)="toolbarNext($event)" (keyup)="toolbarNext($event)"
 | 
				
			||||||
        (click)="toolbarNext($event)" (keyup)="toolbarNext($event)"
 | 
					        (mousedown)="downAction($event)" (keydown)="downAction($event)">
 | 
				
			||||||
        (mousedown)="downAction($event)" (keydown)="downAction($event)" >
 | 
					 | 
				
			||||||
        <ion-icon name="fas-chevron-right" aria-hidden="true"></ion-icon>
 | 
					        <ion-icon name="fas-chevron-right" aria-hidden="true"></ion-icon>
 | 
				
			||||||
    </button>
 | 
					    </button>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
<!-- Question contents. -->
 | 
					<!-- Question contents. -->
 | 
				
			||||||
<core-dynamic-component *ngIf="loaded" [component]="componentClass" [data]="data" class="core-question-{{question?.slot}}">
 | 
					<core-dynamic-component *ngIf="loaded" [component]="componentClass" [data]="data" class="core-question-{{question?.slot}}">
 | 
				
			||||||
    <!-- This content will only be shown if there's no component to render the question. -->
 | 
					    <!-- This content will only be shown if there's no component to render the question. -->
 | 
				
			||||||
@ -6,7 +5,7 @@
 | 
				
			|||||||
</core-dynamic-component>
 | 
					</core-dynamic-component>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- Sequence check input. -->
 | 
					<!-- Sequence check input. -->
 | 
				
			||||||
<input *ngIf="seqCheck" type="hidden" name="{{seqCheck.name}}" value="{{seqCheck.value}}" >
 | 
					<input *ngIf="seqCheck" type="hidden" name="{{seqCheck.name}}" value="{{seqCheck.value}}">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- Question behaviour components. -->
 | 
					<!-- Question behaviour components. -->
 | 
				
			||||||
<core-dynamic-component *ngFor="let componentClass of behaviourComponents" [component]="componentClass" [data]="data">
 | 
					<core-dynamic-component *ngFor="let componentClass of behaviourComponents" [component]="componentClass" [data]="data">
 | 
				
			||||||
@ -15,7 +14,7 @@
 | 
				
			|||||||
<!-- Question validation error. -->
 | 
					<!-- Question validation error. -->
 | 
				
			||||||
<ion-item class="ion-text-wrap core-danger-item" *ngIf="validationError">
 | 
					<ion-item class="ion-text-wrap core-danger-item" *ngIf="validationError">
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
    	<p>{{ validationError }}</p>
 | 
					        <p>{{ validationError }}</p>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,8 +27,8 @@
 | 
				
			|||||||
<!-- Question feedback. -->
 | 
					<!-- Question feedback. -->
 | 
				
			||||||
<ion-item class="ion-text-wrap core-question-feedback-container" *ngIf="question && question.feedbackHtml">
 | 
					<ion-item class="ion-text-wrap core-question-feedback-container" *ngIf="question && question.feedbackHtml">
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <core-format-text [component]="component" [componentId]="componentId" [text]="question.feedbackHtml"
 | 
					        <core-format-text [component]="component" [componentId]="componentId" [text]="question.feedbackHtml" [contextLevel]="contextLevel"
 | 
				
			||||||
            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					            [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
        </core-format-text>
 | 
					        </core-format-text>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
@ -37,8 +36,8 @@
 | 
				
			|||||||
<!-- Question comment. -->
 | 
					<!-- Question comment. -->
 | 
				
			||||||
<ion-item class="ion-text-wrap core-question-comment" *ngIf="question && question.commentHtml">
 | 
					<ion-item class="ion-text-wrap core-question-comment" *ngIf="question && question.commentHtml">
 | 
				
			||||||
    <ion-label>
 | 
					    <ion-label>
 | 
				
			||||||
        <core-format-text [component]="component" [componentId]="componentId" [text]="question.commentHtml"
 | 
					        <core-format-text [component]="component" [componentId]="componentId" [text]="question.commentHtml" [contextLevel]="contextLevel"
 | 
				
			||||||
            [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
					            [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
				
			||||||
        </core-format-text>
 | 
					        </core-format-text>
 | 
				
			||||||
    </ion-label>
 | 
					    </ion-label>
 | 
				
			||||||
</ion-item>
 | 
					</ion-item>
 | 
				
			||||||
 | 
				
			|||||||
@ -2,23 +2,21 @@
 | 
				
			|||||||
    <form (ngSubmit)="submitForm($event)" role="search" #searchForm>
 | 
					    <form (ngSubmit)="submitForm($event)" role="search" #searchForm>
 | 
				
			||||||
        <ion-item>
 | 
					        <ion-item>
 | 
				
			||||||
            <ion-label class="sr-only">{{ placeholder }}</ion-label>
 | 
					            <ion-label class="sr-only">{{ placeholder }}</ion-label>
 | 
				
			||||||
            <ion-input type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder"
 | 
					            <ion-input type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder" [autocorrect]="autocorrect"
 | 
				
			||||||
                [autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus"
 | 
					                [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" [disabled]="disabled" role="searchbox" (ionFocus)="focus($event)">
 | 
				
			||||||
                [disabled]="disabled" role="searchbox" (ionFocus)="focus($event)">
 | 
					 | 
				
			||||||
            </ion-input>
 | 
					            </ion-input>
 | 
				
			||||||
            <ion-button slot="end" fill="clear" type="submit" [attr.aria-label]="searchLabel"
 | 
					            <ion-button slot="end" fill="clear" type="submit" [attr.aria-label]="searchLabel"
 | 
				
			||||||
                [disabled]="disabled || !searchText || (searchText.length < lengthCheck)">
 | 
					                [disabled]="disabled || !searchText || (searchText.length < lengthCheck)">
 | 
				
			||||||
                <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
					                <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
				
			||||||
            </ion-button>
 | 
					            </ion-button>
 | 
				
			||||||
            <ion-button *ngIf="showClear" slot="end" fill="clear"
 | 
					            <ion-button *ngIf="showClear" slot="end" fill="clear" [attr.aria-label]="'core.clearsearch' | translate"
 | 
				
			||||||
                [attr.aria-label]="'core.clearsearch' | translate" [disabled]="searched == '' || disabled"
 | 
					                [disabled]="searched == '' || disabled" (click)="clearForm()">
 | 
				
			||||||
                (click)="clearForm()">
 | 
					 | 
				
			||||||
                <ion-icon name="fas-backspace" slot="icon-only" aria-hidden="true" flip-rtl></ion-icon>
 | 
					                <ion-icon name="fas-backspace" slot="icon-only" aria-hidden="true" flip-rtl></ion-icon>
 | 
				
			||||||
            </ion-button>
 | 
					            </ion-button>
 | 
				
			||||||
        </ion-item>
 | 
					        </ion-item>
 | 
				
			||||||
        <ion-list class="core-search-history" [hidden]="!historyShown">
 | 
					        <ion-list class="core-search-history" [hidden]="!historyShown">
 | 
				
			||||||
            <ion-item button class="ion-text-wrap" *ngFor="let item of history"
 | 
					            <ion-item button class="ion-text-wrap" *ngFor="let item of history" (click)="historyClicked($event, item.searchedtext)"
 | 
				
			||||||
                (click)="historyClicked($event, item.searchedtext)" tabindex="0" detail="true">
 | 
					                tabindex="0" detail="true">
 | 
				
			||||||
                <ion-icon name="fas-history" slot="start" aria-hidden="true">
 | 
					                <ion-icon name="fas-history" slot="start" aria-hidden="true">
 | 
				
			||||||
                </ion-icon>
 | 
					                </ion-icon>
 | 
				
			||||||
                <ion-label>{{item.searchedtext}}</ion-label>
 | 
					                <ion-label>{{item.searchedtext}}</ion-label>
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,8 @@
 | 
				
			|||||||
<core-loading [hideUntil]="filesLoaded" [fullscreen]="false">
 | 
					<core-loading [hideUntil]="filesLoaded" [fullscreen]="false">
 | 
				
			||||||
    <ion-list *ngIf="files && files.length > 0">
 | 
					    <ion-list *ngIf="files && files.length > 0">
 | 
				
			||||||
        <ng-container *ngFor="let file of files; let idx = index">
 | 
					        <ng-container *ngFor="let file of files; let idx = index">
 | 
				
			||||||
            <core-local-file *ngIf="file.isFile" [file]="file" [manage]="manage" [overrideClick]="pick"
 | 
					            <core-local-file *ngIf="file.isFile" [file]="file" [manage]="manage" [overrideClick]="pick" (onClick)="filePicked(file)"
 | 
				
			||||||
                (onClick)="filePicked(file)" (onDelete)="fileDeleted(idx)" (onRename)="fileRenamed(idx, $event)">
 | 
					                (onDelete)="fileDeleted(idx)" (onRename)="fileRenamed(idx, $event)">
 | 
				
			||||||
            </core-local-file>
 | 
					            </core-local-file>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ion-item button *ngIf="!file.isFile" class="ion-text-wrap item-file" (click)="openFolder(file)" detail="true">
 | 
					            <ion-item button *ngIf="!file.isFile" class="ion-text-wrap item-file" (click)="openFolder(file)" detail="true">
 | 
				
			||||||
@ -22,8 +22,7 @@
 | 
				
			|||||||
        </ng-container>
 | 
					        </ng-container>
 | 
				
			||||||
    </ion-list>
 | 
					    </ion-list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <core-empty-box *ngIf="files && !files.length && manage" icon="fas-folder"
 | 
					    <core-empty-box *ngIf="files && !files.length && manage" icon="fas-folder" [message]="'core.sharedfiles.nosharedfiles' | translate">
 | 
				
			||||||
        [message]="'core.sharedfiles.nosharedfiles' | translate">
 | 
					 | 
				
			||||||
    </core-empty-box>
 | 
					    </core-empty-box>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <core-empty-box *ngIf="files && !files.length && !manage" icon="fas-folder"
 | 
					    <core-empty-box *ngIf="files && !files.length && !manage" icon="fas-folder"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,6 @@
 | 
				
			|||||||
<ion-item class="ion-text-wrap" *ngFor="let item of items" [href]="item.url" core-link [capture]="true">
 | 
					<ion-item class="ion-text-wrap" *ngFor="let item of items" [href]="item.url" core-link [capture]="true">
 | 
				
			||||||
    <ion-avatar slot="start" *ngIf="item.avatarUrl">
 | 
					    <ion-avatar slot="start" *ngIf="item.avatarUrl">
 | 
				
			||||||
        <img [src]="item.avatarUrl" core-external-content alt="" role="presentation"
 | 
					        <img [src]="item.avatarUrl" core-external-content alt="" role="presentation" onError="this.src='assets/img/user-avatar.png'">
 | 
				
			||||||
            onError="this.src='assets/img/user-avatar.png'">
 | 
					 | 
				
			||||||
    </ion-avatar>
 | 
					    </ion-avatar>
 | 
				
			||||||
    <core-mod-icon *ngIf="item.iconUrl" [modicon]="item.iconUrl" slot="start" [showAlt]="false">
 | 
					    <core-mod-icon *ngIf="item.iconUrl" [modicon]="item.iconUrl" slot="start" [showAlt]="false">
 | 
				
			||||||
    </core-mod-icon>
 | 
					    </core-mod-icon>
 | 
				
			||||||
 | 
				
			|||||||
@ -6,15 +6,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<ion-content>
 | 
					<ion-content>
 | 
				
			||||||
    <core-split-view>
 | 
					    <core-split-view>
 | 
				
			||||||
        <ion-refresher slot="fixed" [disabled]="!participants.loaded || searchInProgress"
 | 
					        <ion-refresher slot="fixed" [disabled]="!participants.loaded || searchInProgress" (ionRefresh)="refreshParticipants($event.target)">
 | 
				
			||||||
            (ionRefresh)="refreshParticipants($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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <core-search-box *ngIf="showSearchBox"
 | 
					        <core-search-box *ngIf="showSearchBox" [disabled]="searchInProgress" [spellcheck]="false" [autoFocus]="true" [lengthCheck]="1"
 | 
				
			||||||
            [disabled]="searchInProgress" [spellcheck]="false" [autoFocus]="true" [lengthCheck]="1"
 | 
					            autocorrect="off" searchArea="CoreUserParticipants" (onSubmit)="search($event)" (onClear)="clearSearch()">
 | 
				
			||||||
            autocorrect="off" searchArea="CoreUserParticipants"
 | 
					 | 
				
			||||||
            (onSubmit)="search($event)" (onClear)="clearSearch()">
 | 
					 | 
				
			||||||
        </core-search-box>
 | 
					        </core-search-box>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <core-loading [hideUntil]="participants.loaded">
 | 
					        <core-loading [hideUntil]="participants.loaded">
 | 
				
			||||||
@ -27,9 +24,9 @@
 | 
				
			|||||||
            </core-empty-box>
 | 
					            </core-empty-box>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <ion-list *ngIf="!participants.empty">
 | 
					            <ion-list *ngIf="!participants.empty">
 | 
				
			||||||
                <ion-item *ngFor="let participant of participants.items"
 | 
					                <ion-item *ngFor="let participant of participants.items" class="ion-text-wrap"
 | 
				
			||||||
                    class="ion-text-wrap" [attr.aria-current]="participants.getItemAriaCurrent(participant)"
 | 
					                    [attr.aria-current]="participants.getItemAriaCurrent(participant)" [attr.aria-label]="participant.fullname"
 | 
				
			||||||
                    [attr.aria-label]="participant.fullname" (click)="participants.select(participant)" button detail="true">
 | 
					                    (click)="participants.select(participant)" button detail="true">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <core-user-avatar [user]="participant" [linkProfile]="false" [checkOnline]="true" slot="start">
 | 
					                    <core-user-avatar [user]="participant" [linkProfile]="false" [checkOnline]="true" slot="start">
 | 
				
			||||||
                    </core-user-avatar>
 | 
					                    </core-user-avatar>
 | 
				
			||||||
@ -57,8 +54,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                </ion-item>
 | 
					                </ion-item>
 | 
				
			||||||
            </ion-list>
 | 
					            </ion-list>
 | 
				
			||||||
            <core-infinite-loading [enabled]="participants.loaded && !participants.completed"
 | 
					            <core-infinite-loading [enabled]="participants.loaded && !participants.completed" (action)="fetchMoreParticipants($event)"
 | 
				
			||||||
                (action)="fetchMoreParticipants($event)" [error]="fetchMoreParticipantsFailed">
 | 
					                [error]="fetchMoreParticipantsFailed">
 | 
				
			||||||
            </core-infinite-loading>
 | 
					            </core-infinite-loading>
 | 
				
			||||||
        </core-loading>
 | 
					        </core-loading>
 | 
				
			||||||
    </core-split-view>
 | 
					    </core-split-view>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user