MOBILE-3814 course: Improve course storage page

main
Pau Ferrer Ocaña 2022-03-03 17:33:22 +01:00
parent 0097b78963
commit d0b59ce92b
10 changed files with 69 additions and 33 deletions

View File

@ -1106,6 +1106,7 @@
"addon.storagemanager.confirmdeletedatafrom": "local_moodlemobileapp",
"addon.storagemanager.coursedownloads": "local_moodlemobileapp",
"addon.storagemanager.courseinfo": "local_moodlemobileapp",
"addon.storagemanager.deleteall": "moodle",
"addon.storagemanager.deleteallsitedata": "local_moodlemobileapp",
"addon.storagemanager.deleteallsitedatainfo": "local_moodlemobileapp",
"addon.storagemanager.deletecourses": "local_moodlemobileapp",

View File

@ -4,7 +4,7 @@
</ion-label>
<div slot="end" class="flex-row">
<!-- Download all courses. -->
<div *ngIf="downloadCoursesEnabled && filteredCourses.length > 1" class="core-button-spinner">
<div *ngIf="downloadCoursesEnabled && filteredCourses.length > 0" class="core-button-spinner">
<ion-button *ngIf="!prefetchCoursesData.loading" fill="clear" (click)="prefetchCourses()"
[attr.aria-label]="prefetchCoursesData.statusTranslatable | translate">
<ion-icon [name]="prefetchCoursesData.icon" slot="icon-only" aria-hidden="true">

View File

@ -5,6 +5,7 @@
"confirmdeletedatafrom": "Delete all downloaded data from '{{name}}'?",
"coursedownloads": "Course downloads",
"courseinfo": "Download course content to work offline. Your activity will sync automatically when your device is back online.",
"deleteall": "Delete all",
"deleteallsitedata": "Delete all site downloaded data",
"deleteallsitedatainfo": "This will delete all downloaded data from '{{name}}', including all downloaded courses and data that allows you to work offline.",
"deletecourses": "Delete downloaded data from all courses",

View File

@ -10,36 +10,51 @@
</ion-header>
<ion-content>
<core-loading [hideUntil]="loaded" class="list-item-limited-width">
<ion-item class="ion-text-wrap">
<ion-label>
<p>{{ 'addon.storagemanager.courseinfo' | translate }}</p>
</ion-label>
</ion-item>
<ion-card class="wholecourse">
<ion-card-header>
<p class="ion-text-wrap ion-no-margin">{{ 'addon.storagemanager.courseinfo' | translate }}</p>
<ion-card-title>{{ title }}</ion-card-title>
<ion-item class="size ion-text-wrap ion-no-padding">
<ion-label>
<p class="item-heading ion-text-wrap">{{ 'addon.storagemanager.totaldownloads' | translate }}</p>
<ion-badge color="light">{{ totalSize | coreBytesToSize }}</ion-badge>
</ion-label>
<ion-button slot="end" (click)="deleteForCourse()" [disabled]="totalSize == 0" color="danger" fill="clear">
<ion-icon name="fas-trash" slot="icon-only" [attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate:
{ name: title }">
</ion-icon>
</ion-button>
<ion-badge color="light" slot="end">{{ totalSize | coreBytesToSize }}
</ion-badge>
</ion-item>
<ion-button *ngIf="downloadCourseEnabled" (click)="prefetchCourse()" expand="block" fill="outline">
<ion-button *ngIf="downloadCourseEnabled" (click)="prefetchCourse()" expand="block" fill="outline" class="ion-no-margin">
<ion-icon *ngIf="!prefetchCourseData.loading" [name]="prefetchCourseData.icon" slot="start"></ion-icon>
<ion-spinner *ngIf="prefetchCourseData.loading" slot="start"></ion-spinner>
{{ prefetchCourseData.statusTranslatable | translate }}
</ion-button>
<ion-button *ngIf="totalSize > 0" (click)="deleteForCourse()" expand="block" color="danger"
class="ion-no-margin ion-margin-top">
<ion-icon name="fas-trash" slot="start" [attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate:
{ name: title }">
</ion-icon>
{{ 'addon.storagemanager.deleteall' | translate }}
</ion-button>
</ion-card-header>
</ion-card>
<ng-container *ngFor="let section of sections">
<ion-card class="section" *ngIf="section.modules.length > 0">
<ion-card-header>
<ion-item class="ion-no-padding">
<ion-item class="ion-no-padding" lines="full">
<ion-label>
<p class="item-heading ion-text-wrap">{{ section.name }}</p>
<ion-badge color="light" *ngIf="section.totalSize > 0">
{{ section.totalSize | coreBytesToSize }}
<p class="item-heading ion-text-wrap">
<core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="section.course"
[adaptImg]="false">
</core-format-text>
</p>
<ion-badge [color]="section.downloadStatus == statusDownloaded ? 'success' : 'light'"
*ngIf="section.totalSize > 0">
<ion-icon aria-hidden="true" name="fam-cloud-done" *ngIf="section.downloadStatus == statusDownloaded">
</ion-icon>{{ section.totalSize | coreBytesToSize }}
</ion-badge>
<!-- Download progress. -->
<p *ngIf="downloadEnabled && section.isDownloading">
@ -48,15 +63,10 @@
</p>
</ion-label>
<div class="storage-buttons" slot="end" *ngIf="section.totalSize > 0 || downloadEnabled">
<ion-button (click)="deleteForSection(section)" *ngIf="section.totalSize > 0" color="danger" fill="clear">
<ion-icon name="fas-trash" slot="icon-only"
[attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: section.name }">
</ion-icon>
</ion-button>
<div *ngIf="downloadEnabled" slot="end" class="core-button-spinner">
<core-download-refresh *ngIf="!section.isDownloading" [status]="section.downloadStatus" [enabled]="true"
(action)="prefecthSection(section)" [loading]="section.isDownloading || section.isCalculating"
[canTrustDownload]="true">
<core-download-refresh *ngIf="!section.isDownloading && section.downloadStatus != statusDownloaded"
[status]="section.downloadStatus" [enabled]="true" (action)="prefecthSection(section)"
[loading]="section.isDownloading || section.isCalculating" [canTrustDownload]="true">
</core-download-refresh>
<ion-badge class="core-course-download-section-progress"
@ -66,6 +76,11 @@
{{section.count}} / {{section.total}}
</ion-badge>
</div>
<ion-button (click)="deleteForSection(section)" *ngIf="section.totalSize > 0" color="danger" fill="clear">
<ion-icon name="fas-trash" slot="icon-only"
[attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: section.name }">
</ion-icon>
</ion-button>
</div>
</ion-item>
</ion-card-header>
@ -81,22 +96,25 @@
[contextInstanceId]="module.id" [adaptImg]="false">
</core-format-text>
</h3>
<ion-badge color="light" *ngIf="module.totalSize > 0">
{{ module.totalSize | coreBytesToSize }}
<ion-badge [color]="module.downloadStatus == statusDownloaded ? 'success' : 'light'"
*ngIf="module.totalSize > 0">
<ion-icon aria-hidden="true" name="fam-cloud-done" *ngIf="module.downloadStatus == statusDownloaded">
</ion-icon>{{ module.totalSize | coreBytesToSize }}
</ion-badge>
</ion-label>
<div class="storage-buttons" slot="end">
<core-download-refresh *ngIf="downloadEnabled && module.handlerData?.showDownloadButton &&
module.downloadStatus != statusDownloaded" [status]="module.downloadStatus" [enabled]="true"
[canTrustDownload]="true" [loading]="module.spinner || module.handlerData.spinner"
(action)="prefetchModule(module, section)">
</core-download-refresh>
<ion-button fill="clear" (click)="deleteForModule(module, section)" *ngIf="module.totalSize > 0"
color="danger">
<ion-icon name="fas-trash" slot="icon-only"
[attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: module.name }">
</ion-icon>
</ion-button>
<core-download-refresh *ngIf="downloadEnabled && module.handlerData?.showDownloadButton"
[status]="module.downloadStatus" [enabled]="true" [canTrustDownload]="true"
[loading]="module.spinner || module.handlerData.spinner" (action)="prefetchModule(module, section)">
</core-download-refresh>
</div>
</ion-item>
</ng-container>

View File

@ -30,6 +30,20 @@
}
}
ion-badge {
margin-top: 8px;
ion-icon {
@include margin-horizontal(null, 8px);
}
}
ion-item core-mod-icon {
--size: 18px;
padding: 9px;
--margin-vertical: 8px;
--margin-end: 8px;
}
.storage-buttons {
display: flex;
align-items: center;

View File

@ -59,6 +59,8 @@ export class AddonStorageManagerCourseStoragePage implements OnInit, OnDestroy {
loading: true,
};
statusDownloaded = CoreConstants.DOWNLOADED;
protected siteUpdatedObserver?: CoreEventObserver;
protected courseStatusObserver?: CoreEventObserver;
protected sectionStatusObserver?: CoreEventObserver;

View File

@ -12,7 +12,7 @@
"completeenrolmentbrowser": "Complete enrolment in browser",
"confirmselfenrol": "Are you sure you want to enrol yourself in this course?",
"courses": "Courses",
"downloadcourses": "Download courses",
"downloadcourses": "Download all courses",
"enrolme": "Enrol me",
"errorloadcategories": "An error occurred while loading categories.",
"errorloadcourses": "An error occurred while loading courses.",

View File

@ -29,7 +29,7 @@
</ion-label>
<div slot="end" class="flex-row">
<!-- Download all courses. -->
<div *ngIf="downloadCoursesEnabled && myOverviewBlock && myOverviewBlock.filteredCourses.length > 1"
<div *ngIf="downloadCoursesEnabled && myOverviewBlock && myOverviewBlock.filteredCourses.length > 0"
class="core-button-spinner">
<ion-button *ngIf="!myOverviewBlock.prefetchCoursesData.loading" fill="clear"
(click)="myOverviewBlock.prefetchCourses()"

View File

@ -7,10 +7,10 @@
"cannotsyncoffline": "Cannot synchronise offline.",
"cannotsyncwithoutwifi": "Cannot synchronise because the current settings only allow to synchronise when connected to Wi-Fi. Please connect to a Wi-Fi network.",
"colorscheme": "Color Scheme",
"colorscheme-system": "System default",
"colorscheme-system-notice": "System default mode will depend on your device support.",
"colorscheme-dark": "Dark",
"colorscheme-light": "Light",
"colorscheme-system": "System default",
"colorscheme-system-notice": "System default mode will depend on your device support.",
"compilationinfo": "Compilation info",
"copyinfo": "Copy device info on the clipboard",
"cordovadevicemodel": "Cordova device model",
@ -27,7 +27,7 @@
"disableall": "Disable notifications",
"disabled": "Disabled",
"disabledfeatures": "Disabled features",
"disallowed": "Disallowed",
"disallowed": "Locked off",
"displayformat": "Display format",
"enabledownloadsection": "Enable download sections",
"enablefirebaseanalytics": "Enable Firebase analytics",

View File

@ -936,7 +936,7 @@ ion-select-popover ion-item.core-select-option-title {
ion-badge {
line-height: 1.1;
padding: 4px 8px;
padding: 2px 8px;
border-radius: var(--big-radius);
}