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