MOBILE-2481 course: Add section navigation
parent
8a2160db17
commit
9b3bd3012e
|
@ -67,7 +67,7 @@
|
||||||
<ion-grid text-wrap *ngIf="questions && questions.length && !quizAborted && !showSummary">
|
<ion-grid text-wrap *ngIf="questions && questions.length && !quizAborted && !showSummary">
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col *ngIf="previousPage >= 0" >
|
<ion-col *ngIf="previousPage >= 0" >
|
||||||
<button ion-button block icon-start (click)="changePage(previousPage)">
|
<button ion-button block icon-start color="light" (click)="changePage(previousPage)">
|
||||||
<ion-icon name="arrow-back" md="ios-arrow-back"></ion-icon>
|
<ion-icon name="arrow-back" md="ios-arrow-back"></ion-icon>
|
||||||
{{ 'core.previous' | translate }}
|
{{ 'core.previous' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -416,7 +416,7 @@ ion-col ion-select {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
:not(.item) ion-select,
|
:not(.item) > * > * > ion-select,
|
||||||
.core-button-select {
|
.core-button-select {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: $core-color;
|
color: $core-color;
|
||||||
|
@ -447,7 +447,7 @@ ion-col ion-select {
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-inner {
|
.button-inner {
|
||||||
justify-content: space-between;
|
justify-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-icon .select-icon-inner {
|
.select-icon .select-icon-inner {
|
||||||
|
@ -456,6 +456,8 @@ ion-col ion-select {
|
||||||
|
|
||||||
ion-icon:last-child {
|
ion-icon:last-child {
|
||||||
@include margin(null, null, null, 5px);
|
@include margin(null, null, null, 5px);
|
||||||
|
text-align: right;
|
||||||
|
flex-grow: 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="core-tabs-bar" #topTabs [hidden]="!tabs || tabs.length < 2">
|
<div class="core-tabs-bar" #topTabs [hidden]="!tabs || tabs.length < 2">
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col class="col-with-arrow" (click)="slidePrev()" no-padding col-1>
|
<ion-col class="col-with-arrow" (click)="slidePrev()" no-padding col-1>
|
||||||
<ion-icon *ngIf="showPrevButton" name="arrow-back"></ion-icon>
|
<ion-icon *ngIf="showPrevButton" name="arrow-back" md="ios-arrow-back"></ion-icon>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
<ion-col no-padding col-10>
|
<ion-col no-padding col-10>
|
||||||
<ion-slides (ionSlideDidChange)="slideChanged()" [slidesPerView]="slidesShown">
|
<ion-slides (ionSlideDidChange)="slideChanged()" [slidesPerView]="slidesShown">
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
</ion-slides>
|
</ion-slides>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
<ion-col class="col-with-arrow" (click)="slideNext()" no-padding col-1>
|
<ion-col class="col-with-arrow" (click)="slideNext()" no-padding col-1>
|
||||||
<ion-icon *ngIf="showNextButton" name="arrow-forward"></ion-icon>
|
<ion-icon *ngIf="showNextButton" name="arrow-forward" md="ios-arrow-forward"></ion-icon>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<div *ngIf="course.imageThumb" class="core-course-thumb">
|
<div *ngIf="course.imageThumb" class="core-course-thumb">
|
||||||
<img [src]="course.imageThumb" core-external-content alt=""/>
|
<img [src]="course.imageThumb" core-external-content alt=""/>
|
||||||
</div>
|
</div>
|
||||||
<ion-item *ngIf="course.progress != null && course.progress >= 0">
|
<ion-item *ngIf="course.progress != null && course.progress >= 0" class="core-course-progress">
|
||||||
<core-progress-bar [progress]="course.progress"></core-progress-bar>
|
<core-progress-bar [progress]="course.progress"></core-progress-bar>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
@ -22,8 +22,9 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<!-- Section selector. -->
|
<!-- Section selector. -->
|
||||||
<core-dynamic-component [component]="sectionSelectorComponent" [data]="data">
|
<core-dynamic-component [component]="sectionSelectorComponent" [data]="data">
|
||||||
<div text-wrap *ngIf="displaySectionSelector && sections && sections.length" no-padding class="clearfix">
|
<div text-wrap *ngIf="displaySectionSelector && sections && sections.length" padding class="clearfix" ion-row justify-content-between>
|
||||||
<button float-start ion-button (click)="showSectionSelector($event)" clear class="core-button-select button-no-uppercase">
|
<button float-start ion-button icon-start (click)="showSectionSelector($event)" color="light" class="core-button-select button-no-uppercase" ion-col>
|
||||||
|
<core-icon name="fa-folder"></core-icon>
|
||||||
{{selectedSection && (selectedSection.formattedName || selectedSection.name) || 'core.course.sections' | translate }}
|
{{selectedSection && (selectedSection.formattedName || selectedSection.name) || 'core.course.sections' | translate }}
|
||||||
<ion-icon name="arrow-dropdown" ios="md-arrow-dropdown"></ion-icon>
|
<ion-icon name="arrow-dropdown" ios="md-arrow-dropdown"></ion-icon>
|
||||||
</button>
|
</button>
|
||||||
|
@ -49,6 +50,17 @@
|
||||||
</core-dynamic-component>
|
</core-dynamic-component>
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
<ion-buttons padding end class="core-course-section-nav-buttons" *ngIf="displaySectionSelector && sections && sections.length">
|
||||||
|
<button *ngIf="previousSection" ion-button color="light" icon-only (click)="sectionChanged(previousSection)" title="{{ 'core.previous' | translate }}">
|
||||||
|
<ion-icon name="arrow-back" md="ios-arrow-back"></ion-icon>
|
||||||
|
<core-format-text class="accesshide" [text]="previousSection.formattedName || previousSection.name"></core-format-text>
|
||||||
|
</button>
|
||||||
|
<button *ngIf="nextSection" ion-button icon-only (click)="sectionChanged(nextSection)" title="{{ 'core.next' | translate }}">
|
||||||
|
<core-format-text class="accesshide" [text]="nextSection.formattedName || nextSection.name"></core-format-text>
|
||||||
|
<ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
|
||||||
|
</button>
|
||||||
|
</ion-buttons>
|
||||||
|
|
||||||
</core-dynamic-component>
|
</core-dynamic-component>
|
||||||
|
|
||||||
<!-- Template to render a section. -->
|
<!-- Template to render a section. -->
|
||||||
|
|
|
@ -55,4 +55,13 @@ core-course-format {
|
||||||
line-height: 44px;
|
line-height: 44px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.core-course-section-nav-buttons {
|
||||||
|
.button-inner core-format-text {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
displaySectionSelector: boolean;
|
displaySectionSelector: boolean;
|
||||||
selectedSection: any;
|
selectedSection: any;
|
||||||
|
previousSection: any;
|
||||||
|
nextSection: any;
|
||||||
allSectionsId: number = CoreCourseProvider.ALL_SECTIONS_ID;
|
allSectionsId: number = CoreCourseProvider.ALL_SECTIONS_ID;
|
||||||
selectOptions: any = {};
|
selectOptions: any = {};
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
|
@ -248,6 +250,26 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
this.selectedSection = newSection;
|
this.selectedSection = newSection;
|
||||||
this.data.section = this.selectedSection;
|
this.data.section = this.selectedSection;
|
||||||
|
|
||||||
|
// Select next and previous sections to show the arrows.
|
||||||
|
const i = this.sections.findIndex((value, index) => {
|
||||||
|
return this.compareSections(value, this.selectedSection);
|
||||||
|
});
|
||||||
|
|
||||||
|
let j;
|
||||||
|
for (j = i - 1; j >= 1; j--) {
|
||||||
|
if (!(this.sections[j].visible === 0 || this.sections[j].uservisible === false) && this.sections[j].hasContent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.previousSection = j >= 1 ? this.sections[j] : null;
|
||||||
|
|
||||||
|
for (j = i + 1; j < this.sections.length; j++) {
|
||||||
|
if (!(this.sections[j].visible === 0 || this.sections[j].uservisible === false) && this.sections[j].hasContent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.nextSection = j < this.sections.length ? this.sections[j] : null;
|
||||||
|
|
||||||
if (this.moduleId && typeof previousValue == 'undefined') {
|
if (this.moduleId && typeof previousValue == 'undefined') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.domUtils.scrollToElementBySelector(this.content, '#core-course-module-' + this.moduleId);
|
this.domUtils.scrollToElementBySelector(this.content, '#core-course-module-' + this.moduleId);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ng-container *ngFor="let section of sections">
|
<ng-container *ngFor="let section of sections">
|
||||||
<a ion-item *ngIf="section.hasContent" text-wrap (click)="selectSection(section)" [class.core-primary-item]="selected.id == section.id" [class.item-dimmed]="section.visible === 0 || section.uservisible === false" detail-none>
|
<a ion-item *ngIf="section.hasContent" text-wrap (click)="selectSection(section)" [class.core-primary-item]="selected.id == section.id" [class.item-dimmed]="section.visible === 0 || section.uservisible === false" detail-none>
|
||||||
|
<core-icon name="fa-folder" item-start></core-icon>
|
||||||
<h2><core-format-text [text]="section.formattedName || section.name"></core-format-text></h2>
|
<h2><core-format-text [text]="section.formattedName || section.name"></core-format-text></h2>
|
||||||
<ion-badge color="secondary" *ngIf="section.visible === 0">{{ 'core.course.nocontentavailable' | translate }}</ion-badge>
|
<ion-badge color="secondary" *ngIf="section.visible === 0">{{ 'core.course.nocontentavailable' | translate }}</ion-badge>
|
||||||
<ion-badge color="secondary" *ngIf="section.availabilityinfo"><core-format-text [text]=" section.availabilityinfo"></core-format-text></ion-badge>
|
<ion-badge color="secondary" *ngIf="section.availabilityinfo"><core-format-text [text]=" section.availabilityinfo"></core-format-text></ion-badge>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<ion-content class="core-center-view">
|
<ion-content class="core-center-view">
|
||||||
<core-loading [hideUntil]="pageLoaded">
|
<core-loading [hideUntil]="pageLoaded">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div text-wrap text-center>
|
<div text-wrap text-center margin-bottom>
|
||||||
<!-- Show site logo or a default image. -->
|
<!-- Show site logo or a default image. -->
|
||||||
<img *ngIf="logoUrl" [src]="logoUrl" role="presentation">
|
<img *ngIf="logoUrl" [src]="logoUrl" role="presentation">
|
||||||
<img *ngIf="!logoUrl" src="assets/img/login_logo.png" class="login-logo" role="presentation">
|
<img *ngIf="!logoUrl" src="assets/img/login_logo.png" class="login-logo" role="presentation">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content padding class="core-center-view">
|
<ion-content padding class="core-center-view">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div *ngIf="site" text-wrap text-center [ngClass]="{'item-avatar-center': site.avatar}">
|
<div *ngIf="site" text-wrap text-center margin-bottom [ngClass]="{'item-avatar-center': site.avatar}">
|
||||||
<ion-avatar *ngIf="site.avatar">
|
<ion-avatar *ngIf="site.avatar">
|
||||||
<!-- Show user avatar. -->
|
<!-- Show user avatar. -->
|
||||||
<img [src]="site.avatar" class="avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullname} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'">
|
<img [src]="site.avatar" class="avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullname} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'">
|
||||||
|
|
Loading…
Reference in New Issue