MOBILE-3149 module: Add collapsible footer buttons on module index pages

main
Pau Ferrer Ocaña 2022-02-24 16:44:24 +01:00
parent 540141bad5
commit d4515ca74c
15 changed files with 288 additions and 271 deletions

View File

@ -94,15 +94,6 @@
</ion-item>
</ng-container>
<ion-button *ngIf="meetingInfo.canjoin" class="ion-margin" expand="block" (click)="joinRoom()">
{{ 'addon.mod_bigbluebuttonbn.view_conference_action_join' | translate }}
</ion-button>
<ion-button *ngIf="meetingInfo.statusrunning && meetingInfo.ismoderator" color="light" class="ion-margin" expand="block"
(click)="endMeeting()">
{{ 'addon.mod_bigbluebuttonbn.view_conference_action_end' | translate }}
</ion-button>
<ion-card *ngIf="!meetingInfo.canjoin" class="core-warning-card">
<ion-item class="ion-text-wrap">
<ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon>
@ -110,8 +101,20 @@
</ion-item>
</ion-card>
</ng-container>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width"
*ngIf="meetingInfo && (meetingInfo.canjoin || meetingInfo.statusrunning && meetingInfo.ismoderator)">
<ion-button *ngIf="meetingInfo.statusrunning && meetingInfo.ismoderator" fill="outline" class="ion-margin ion-text-wrap"
expand="block" (click)="endMeeting()">
{{ 'addon.mod_bigbluebuttonbn.view_conference_action_end' | translate }}
</ion-button>
<ion-button *ngIf="meetingInfo.canjoin" class="ion-margin ion-text-wrap" expand="block" (click)="joinRoom()">
{{ 'addon.mod_bigbluebuttonbn.view_conference_action_join' | translate }}
</ion-button>
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -31,16 +31,17 @@
</p>
</ion-label>
</ion-item>
</ion-list>
<ion-button class="ion-margin" expand="block" (click)="openBook()">
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width">
<ion-button expand="block" (click)="openBook()" class="ion-margin ion-text-wrap">
<span *ngIf="!hasStartedBook">{{ 'core.start' | translate }}</span>
<span *ngIf="hasStartedBook">{{ 'core.resume' | translate }}</span>
</ion-button>
</div>
</ion-list>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -20,16 +20,18 @@
</ion-item>
</ion-card>
<ng-container *ngIf="chat">
<ion-button *ngIf="chat" class="ion-margin ion-text-wrap" expand="block" fill="outline" (click)="viewSessions()">
{{ 'addon.mod_chat.viewreport' | translate }}
</ion-button>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="chat">
<ion-button class="ion-margin ion-text-wrap" expand="block" color="primary" (click)="enterChat()">
{{ 'addon.mod_chat.enterchat' | translate }}
</ion-button>
<ion-button class="ion-margin ion-text-wrap" expand="block" color="light" (click)="viewSessions()">
{{ 'addon.mod_chat.viewreport' | translate }}
</ion-button>
</ng-container>
</core-loading>
</div>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -64,12 +64,6 @@
<ion-radio slot="end" [value]="option.id" [disabled]="option.disabled || !canEdit"></ion-radio>
</ion-item>
</ion-radio-group>
<ion-button *ngIf="canEdit" expand="block" (click)="save()" [disabled]="!canSave()" class="ion-margin">
{{ 'addon.mod_choice.savemychoice' | translate }}
</ion-button>
<ion-button *ngIf="canDelete" expand="block" color="light" (click)="delete()" class="ion-margin">
{{ 'addon.mod_choice.removemychoice' | translate }}
</ion-button>
</ion-card>
<!-- Choice results -->
@ -139,11 +133,24 @@
</ion-label>
</ion-item>
</ion-card>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="options.length && choice && (canEdit || canDelete)">
<ion-button *ngIf="canDelete" expand="block" fill="outline" (click)="delete()" class="ion-margin ion-text-wrap">
{{ 'addon.mod_choice.removemychoice' | translate }}
</ion-button>
<ion-button *ngIf="canEdit" expand="block" (click)="save()" [disabled]="!canSave()" class="ion-margin ion-text-wrap">
{{ 'addon.mod_choice.savemychoice' | translate }}
</ion-button>
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
</core-course-module-navigation>
<!-- Template to render a choice option label. -->
<ng-template #optionLabelTemplate let-option="option">

View File

@ -33,11 +33,28 @@
</ng-template>
</core-tab>
</core-tabs>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="access && (access.canedititems || access.canviewreports || !access.isempty)">
<ion-button expand="block" fill="outline" (click)="gotoAnswerQuestions(true)" class="ion-margin ion-text-wrap">
<ion-icon name="fas-search" slot="start" aria-hidden="true"></ion-icon>
{{ 'addon.mod_feedback.preview' | translate }}
</ion-button>
<ion-button *ngIf="access.cancomplete && access.cansubmit && access.isopen" expand="block" (click)="gotoAnswerQuestions()"
class="ion-margin ion-text-wrap">
<ng-container *ngIf="!goPage">
{{ 'addon.mod_feedback.complete_the_form' | translate }}
</ng-container>
<ng-container *ngIf="goPage">
{{ 'addon.mod_feedback.continue_the_form' | translate }}
</ng-container>
</ion-button>
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>
<ng-template #basicInfo>
<ion-list *ngIf="access && access.canviewanalysis && !access.isempty">
@ -133,28 +150,6 @@
<p *ngIf="!access.isanonymous">{{ 'addon.mod_feedback.non_anonymous' | translate }}</p>
</ion-label>
</ion-item>
<ion-grid>
<ion-row class="ion-align-items-center">
<ion-col>
<ion-button expand="block" fill="outline" (click)="gotoAnswerQuestions(true)" class="ion-text-wrap">
<ion-icon name="fas-search" slot="start" aria-hidden="true"></ion-icon>
{{ 'addon.mod_feedback.preview' | translate }}
</ion-button>
</ion-col>
<ion-col *ngIf="access.cancomplete && access.cansubmit && access.isopen">
<ion-button expand="block" (click)="gotoAnswerQuestions()" class="ion-text-wrap">
<ng-container *ngIf="!goPage">
{{ 'addon.mod_feedback.complete_the_form' | translate }}
</ng-container>
<ng-container *ngIf="goPage">
{{ 'addon.mod_feedback.continue_the_form' | translate }}
</ng-container>
<ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ng-container>
</ion-list>
</core-loading>

View File

@ -26,12 +26,12 @@
<div class="addon-mod-imscp-container">
<core-iframe *ngIf="!showLoading" [src]="src" [showFullscreenOnToolbar]="true" [autoFullscreenOnRotate]="true"></core-iframe>
</div>
</core-loading>
<!-- TODO Add a contents page to avoid having both bars -->
<core-navigation-bar collapsible-footer *ngIf="!showLoading && navigationItems.length > 1 && false" [items]="navigationItems"
(action)="loadItem($event)">
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<!-- TODO Add a contents page to avoid having both bars. Please add here start/resume buttons. -->
<core-navigation-bar *ngIf="navigationItems.length > 1" [items]="navigationItems" (action)="loadItem($event)">
</core-navigation-bar>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -38,84 +38,15 @@
</ion-item>
<ion-button expand="block" type="submit">
{{ 'addon.mod_lesson.continue' | translate }}
<ion-icon slot="end" name="fas-chevron-right" aria-hidden="true"></ion-icon>
</ion-button>
<!-- Remove this once Ionic fixes this bug: https://github.com/ionic-team/ionic-framework/issues/19368 -->
<input type="submit" class="core-submit-hidden-enter" />
</form>
</ion-card>
<core-loading [hideUntil]="!showSpinner">
<core-loading [hideUntil]="!showSpinner" *ngIf="canViewReports">
<ion-list *ngIf="(lesson && !preventReasons.length) || retakeToReview">
<ng-container *ngIf="retakeToReview">
<!-- A retake was finished in a synchronization, allow reviewing it. -->
<ion-item class="ion-text-wrap">
<ion-label class="ion-padding-bottom">
{{ 'addon.mod_lesson.retakefinishedinsync' | translate }}
</ion-label>
</ion-item>
<ion-button class="ion-text-wrap ion-margin" expand="block" (click)="review()">
{{ 'addon.mod_lesson.review' | translate }}
</ion-button>
</ng-container>
<ng-container *ngIf="lesson && !preventReasons.length">
<ion-item class="ion-text-wrap" *ngIf="leftDuringTimed && !lesson.timelimit && !finishedOffline">
<!-- User left during the session and there is no time limit, ask to continue. -->
<ion-label>
<p [innerHTML]="'addon.mod_lesson.youhaveseen' | translate"></p>
<ion-grid>
<ion-row>
<ion-col>
<ion-button expand="block" color="light" (click)="start(false)">
{{ 'core.no' | translate }}
</ion-button>
</ion-col>
<ion-col>
<ion-button expand="block" (click)="start(true)">
{{ 'core.yes' | translate }}
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ion-label>
</ion-item>
<ng-container *ngIf="leftDuringTimed && lesson.timelimit && lesson.retake && !finishedOffline">
<ion-item class="ion-text-wrap">
<!-- User left during the session with time limit and retakes allowed, ask to continue. -->
<ion-label [innerHTML]="'addon.mod_lesson.leftduringtimed' | translate"></ion-label>
</ion-item>
<ion-button class="ion-text-wrap ion-margin" expand="block" (click)="start(false)">
{{ 'addon.mod_lesson.continue' | translate }}
<ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</ng-container>
<ion-item class="ion-text-wrap" *ngIf="leftDuringTimed && lesson.timelimit && !lesson.retake">
<!-- User left during the session with time limit and retakes not allowed.
This should be handled by preventMessages. -->
<ion-label [innerHTML]="'addon.mod_lesson.leftduringtimednoretake' | translate"></ion-label>
</ion-item>
<ng-container *ngIf="!leftDuringTimed && !finishedOffline">
<!-- User hasn't left during the session, show a start button. -->
<ion-button class="ion-text-wrap ion-margin" expand="block" *ngIf="!canManage" (click)="start(false)">
{{ 'core.start' | translate }}
<ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
<ion-button class="ion-text-wrap ion-margin" expand="block" *ngIf="canManage" (click)="start(false)">
{{ 'addon.mod_lesson.preview' | translate }}
<ion-icon name="fas-search" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</ng-container>
<ion-button class="ion-text-wrap" *ngIf="finishedOffline" expand="block" (click)="start(true)">
<!-- There's an attempt finished in offline. Let the user continue, showing the end of lesson. -->
{{ 'addon.mod_lesson.continue' | translate }}
<ion-icon name="fas-chevron-right" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</ng-container>
<ng-container *ngTemplateOutlet="buttons"></ng-container>
</ion-list>
</core-loading>
</ng-template>
@ -277,8 +208,81 @@
</ng-template>
</core-tab>
</core-tabs>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="!canViewReports && ((lesson && !preventReasons.length) || retakeToReview)">
<ng-container *ngTemplateOutlet="buttons"></ng-container>
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
</core-course-module-navigation>
<ng-template #buttons>
<ng-container *ngIf="retakeToReview">
<!-- A retake was finished in a synchronization, allow reviewing it. -->
<ion-item class="ion-text-wrap">
<ion-label class="ion-padding-bottom">
{{ 'addon.mod_lesson.retakefinishedinsync' | translate }}
</ion-label>
</ion-item>
<ion-button class="ion-text-wrap ion-margin" expand="block" (click)="review()">
{{ 'addon.mod_lesson.review' | translate }}
</ion-button>
</ng-container>
<ng-container *ngIf="lesson && !preventReasons.length">
<ion-item class="ion-text-wrap" *ngIf="leftDuringTimed && !lesson.timelimit && !finishedOffline">
<!-- User left during the session and there is no time limit, ask to continue. -->
<ion-label>
<p [innerHTML]="'addon.mod_lesson.youhaveseen' | translate"></p>
<ion-row>
<ion-col>
<ion-button expand="block" fill="outline" (click)="start(false)">
{{ 'core.no' | translate }}
</ion-button>
</ion-col>
<ion-col>
<ion-button expand="block" (click)="start(true)">
{{ 'core.yes' | translate }}
</ion-button>
</ion-col>
</ion-row>
</ion-label>
</ion-item>
<ng-container *ngIf="leftDuringTimed && lesson.timelimit && lesson.retake && !finishedOffline">
<ion-item class="ion-text-wrap">
<!-- User left during the session with time limit and retakes allowed, ask to continue. -->
<ion-label [innerHTML]="'addon.mod_lesson.leftduringtimed' | translate"></ion-label>
</ion-item>
<ion-button class="ion-text-wrap ion-margin" expand="block" (click)="start(false)">
{{ 'addon.mod_lesson.continue' | translate }}
</ion-button>
</ng-container>
<ion-item class="ion-text-wrap" *ngIf="leftDuringTimed && lesson.timelimit && !lesson.retake">
<!-- User left during the session with time limit and retakes not allowed.
This should be handled by preventMessages. -->
<ion-label [innerHTML]="'addon.mod_lesson.leftduringtimednoretake' | translate"></ion-label>
</ion-item>
<ng-container *ngIf="!leftDuringTimed && !finishedOffline">
<!-- User hasn't left during the session, show a start button. -->
<ion-button class="ion-text-wrap ion-margin" expand="block" *ngIf="!canManage" (click)="start(false)">
{{ 'core.start' | translate }}
</ion-button>
<ion-button class="ion-text-wrap ion-margin" expand="block" fill="outline" *ngIf="canManage" (click)="start(false)">
<ion-icon name="fas-search" slot="start" aria-hidden="true"></ion-icon>
{{ 'addon.mod_lesson.preview' | translate }}
</ion-button>
</ng-container>
<ion-button class="ion-text-wrap ion-margin" *ngIf="finishedOffline" expand="block" (click)="start(true)">
<!-- There's an attempt finished in offline. Let the user continue, showing the end of lesson. -->
{{ 'addon.mod_lesson.continue' | translate }}
</ion-button>
</ng-container>
</ng-template>

View File

@ -13,14 +13,15 @@
[componentId]="componentId" [courseId]="courseId">
</core-course-module-info>
<div class="ion-padding">
<ion-button expand="block" (click)="launch()">
<ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width">
<ion-button expand="block" (click)="launch()" class="ion-margin ion-text-wrap">
{{ 'addon.mod_lti.launchactivity' | translate }}
<ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</div>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -6,7 +6,7 @@
</core-navbar-buttons>
<!-- Content. -->
<core-loading [hideUntil]="!showLoading" class="safe-area-padding">
<core-loading [hideUntil]="!showLoading" class="safe-area-padding core-loading-full-height">
<!-- Activity info. -->
<core-course-module-info [module]="module" [courseId]="courseId" [description]="displayDescription && description"
@ -76,8 +76,12 @@
</ion-label>
</ion-item>
</ng-container>
</ion-list>
</ng-container>
<ion-button expand="block" class="ion-margin" (click)="open(openFileAction.OPEN)">
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="mode == 'external'">
<ion-button expand="block" (click)="open(openFileAction.OPEN)" class="ion-margin ion-text-wrap">
<ng-container *ngIf="isStreamedFile">
<ion-icon name="fas-play" slot="start" aria-hidden="true"></ion-icon>
{{ 'core.play' | translate }}
@ -88,15 +92,13 @@
</ng-container>
</ion-button>
<ion-button *ngIf="isIOS && (!shouldOpenInBrowser || !isOnline)" expand="block" class="ion-margin"
(click)="open(openFileAction.OPEN_WITH)">
<ion-button *ngIf="isIOS && (!shouldOpenInBrowser || !isOnline)" expand="block" (click)="open(openFileAction.OPEN_WITH)"
class="ion-margin ion-text-wrap">
<ion-icon name="far-share-square" slot="start" aria-hidden="true"></ion-icon>
{{ 'core.openwith' | translate }}
</ion-button>
</ion-list>
</ng-container>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -21,7 +21,7 @@
</ion-item>
</ion-card>
<ng-container *ngIf="scorm && !showLoading && !scorm.warningMessage">
<div *ngIf="scorm && !showLoading && !scorm.warningMessage" class="list-item-limited-width">
<!-- Attempts status. -->
<ion-card *ngIf="(scorm.displayattemptstatus || offlineAttempts.length) && !skip">
<ion-card-header class="ion-text-wrap">
@ -155,9 +155,12 @@
</ion-item>
</ion-list>
</ion-card>
</div>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="scorm && !scorm.warningMessage">
<!-- Open in browser button. -->
<ion-card *ngIf="errorMessage">
<ng-container *ngIf="errorMessage">
<ion-item class="ion-text-wrap">
<ion-label>
<p class="text-danger">{{ errorMessage | translate }}</p>
@ -167,20 +170,19 @@
{{ 'core.openinbrowser' | translate }}
<ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</ion-card>
</ng-container>
<!-- Warning that user doesn't have any more attempts. -->
<ion-card *ngIf="!errorMessage && attemptsLeft == 0">
<ion-card *ngIf="!errorMessage && attemptsLeft == 0" class="core-danger-card">
<ion-item class="ion-text-wrap">
<ion-label>
<p class="text-danger">{{ 'addon.mod_scorm.exceededmaxattempts' | translate }}</p>
<p>{{ 'addon.mod_scorm.exceededmaxattempts' | translate }}</p>
</ion-label>
</ion-item>
</ion-card>
<ng-container *ngIf="!errorMessage && (!scorm.lastattemptlock || attemptsLeft > 0)">
<!-- Open SCORM in app form -->
<ion-card *ngIf="!errorMessage && scorm && (!scorm.lastattemptlock || attemptsLeft > 0)">
<ion-list>
<ng-container *ngIf="!downloading && !skip">
<!-- Create new attempt -->
<ion-item class="ion-text-wrap" *ngIf="!scorm.forcenewattempt && numAttempts > 0 && !incomplete && attemptsLeft > 0">
@ -189,29 +191,21 @@
</ion-checkbox>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="statusMessage">
<ion-label>
<ion-item *ngIf="statusMessage">
<ion-label class="ion-text-wrap ion-no-margin ion-margin-top">
<p>{{ statusMessage | translate }}</p>
</ion-label>
</ion-item>
<!-- Open mode (Preview or Normal) -->
<ion-grid>
<ion-row class="ion-align-items-center">
<ion-col *ngIf="!scorm.hidebrowse">
<ion-button expand="block" fill="outline" (click)="open($event, true)" class="ion-text-wrap">
<ion-button *ngIf="!scorm.hidebrowse" expand="block" fill="outline" (click)="open($event, true)"
class="ion-text-wrap ion-margin">
<ion-icon name="fas-search" slot="start" aria-hidden="true"></ion-icon>
{{ 'addon.mod_scorm.browse' | translate }}
<ion-icon name="fas-search" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</ion-col>
<ion-col>
<ion-button expand="block" (click)="open($event)" class="ion-text-wrap">
<ion-button expand="block" (click)="open($event)" class="ion-text-wrap ion-margin">
{{ 'addon.mod_scorm.enter' | translate }}
<ion-icon name="fas-arrow-right" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ng-container>
<!-- Download progress. -->
@ -223,11 +217,9 @@
</core-progress-bar>
</ion-label>
</ion-item>
</ion-list>
</ion-card>
</ng-container>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -21,10 +21,6 @@
{{ 'addon.mod_survey.surveycompletednograph' | translate }}
</ion-label>
</ion-item>
<ion-button class="ion-margin" expand="block" [href]="module.url" core-link>
<ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon>
{{ 'addon.mod_survey.results' | translate }}
</ion-button>
</ion-card>
<!-- Survey questions -->
@ -119,18 +115,22 @@
</ng-container>
</ion-grid>
<ion-item>
<ion-label>
<ion-button expand="block" (click)="submit()" [disabled]="!isValidResponse()">
{{ 'core.submit' | translate }}
</ion-button>
</ion-label>
</ion-item>
</form>
</core-loading>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="survey && (survey.surveydone || (!hasOffline && questions && questions.length))">
<ion-button class="ion-text-wrap ion-margin" expand="block" [href]="module.url" core-link *ngIf="survey.surveydone">
{{ 'addon.mod_survey.results' | translate }}
<ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon>
</ion-button>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<ion-button expand="block" class="ion-text-wrap ion-margin" (click)="submit()" [disabled]="!isValidResponse()"
*ngIf="!survey.surveydone && !hasOffline && questions && questions.length">
{{ 'core.submit' | translate }}
</ion-button>
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -35,17 +35,16 @@
<p>{{ url }}</p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap">
<ion-label>
<ion-button expand="block" (click)="go()">
</ion-list>
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="url && !shouldIframe && (!shouldEmbed || !isOther)">
<ion-button expand="block" (click)="go()" class="ion-margin ion-text-wrap">
<ion-icon name="fas-link" slot="start" aria-hidden="true"></ion-icon>
{{ 'addon.mod_url.accessurl' | translate }}
</ion-button>
</ion-label>
</ion-item>
</ion-list>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -117,20 +117,6 @@
<addon-mod-workshop-submission *ngIf="submission" [submission]="submission" [courseId]="workshop!.course" [module]="module"
[workshop]="workshop" [access]="access">
</addon-mod-workshop-submission>
<!-- Show only on current phase -->
<ion-item class="ion-text-wrap" *ngIf="showSubmit">
<ion-label>
<ion-button expand="block" *ngIf="access.creatingsubmissionallowed && !submission" (click)="gotoSubmit()">
<ion-icon slot="start" name="fas-plus" aria-hidden="true"></ion-icon>
{{ 'addon.mod_workshop.createsubmission' | translate }}
</ion-button>
<ion-button expand="block" *ngIf="access.modifyingsubmissionallowed && submission" (click)="gotoSubmit()">
<ion-icon slot="start" name="fas-edit" aria-hidden="true"></ion-icon>
{{ 'addon.mod_workshop.editsubmission' | translate }}
</ion-button>
</ion-label>
</ion-item>
</ion-card>
@ -231,8 +217,25 @@
</ion-grid>
</ion-card>
</div>
</core-loading>
<core-course-module-navigation collapsible-footer [hidden]="showLoading" [courseId]="courseId" [currentModule]="module"
(completionChanged)="onCompletionChange()">
<div collapsible-footer *ngIf="!showLoading" slot="fixed">
<div class="list-item-limited-width" *ngIf="access && workshop?.phase >= PHASE_SUBMISSION && canSubmit && showSubmit &&
((access.creatingsubmissionallowed && !submission) || (access.modifyingsubmissionallowed && submission))">
<!-- Show only on current phase -->
<ion-button expand="block" *ngIf="access.creatingsubmissionallowed && !submission" (click)="gotoSubmit()"
class="ion-text-wrap ion-margin">
<ion-icon slot="start" name="fas-plus" aria-hidden="true"></ion-icon>
{{ 'addon.mod_workshop.createsubmission' | translate }}
</ion-button>
<ion-button expand="block" *ngIf="access.modifyingsubmissionallowed && submission" (click)="gotoSubmit()"
class="ion-text-wrap ion-margin">
<ion-icon slot="start" name="fas-edit" aria-hidden="true"></ion-icon>
{{ 'addon.mod_workshop.editsubmission' | translate }}
</ion-button>
</div>
<core-course-module-navigation [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
</core-course-module-navigation>
</div>
</core-loading>

View File

@ -140,7 +140,7 @@ body {
@each $color-name, $unused in $colors {
.text-#{$color-name},
p.text-#{$color-name} {
color: var(--ion-color-#{$color-name});
color: var(--ion-color-#{$color-name}) !important;
}
}
@ -831,8 +831,8 @@ ion-list.core-course-module-list-wrapper,
.list-item-limited-width,
.core-course-module-list-wrapper {
max-width: var(--list-item--max-width);
margin-left: auto;
margin-right: auto;
margin-left: auto !important;
margin-right: auto !important;
}
ion-toolbar h1 img.core-bar-button-image,
@ -1451,13 +1451,19 @@ ion-grid.core-no-grid > ion-row {
--core-collapsible-footer-height: auto;
}
.ion-margin {
margin-top: 8px;
margin-bottom: 8px;
}
filter: var(--scroll-shadow-top, none);
-webkit-filter: var(--scroll-shadow-top, none);
width: 100%;
bottom: 0;
z-index: 3;
height: var(--core-collapsible-footer-height, auto);
background-color: var(--core-collapsible-footer-background);
display: block;
border-top: 1px solid var(--stroke);
@include core-transition(all, 200ms);
}

View File

@ -334,7 +334,9 @@
--addon-forum-border-color: var(--stroke);
--addon-forum-highlight-color: var(--light);
--drop-shadow: 0, 0, 0, 0.18;
--drop-shadow: 0, 0, 0, 0.5;
--scroll-shadow-bottom: drop-shadow(0px 3px 3px rgba(var(--drop-shadow)));
--scroll-shadow-top: drop-shadow(0px 3px 3px rgba(var(--drop-shadow)));
--core-question-correct-color: var(--success-shade);
--core-question-correct-color-bg: var(--success-tint);