MOBILE-3931 module: Improve module summary style

main
Pau Ferrer Ocaña 2022-02-17 13:58:10 +01:00
parent c2ec52584c
commit 97a8dc3f7a
36 changed files with 137 additions and 111 deletions

View File

@ -1114,6 +1114,7 @@
"addon.storagemanager.deletedata": "local_moodlemobileapp",
"addon.storagemanager.deletedatafrom": "local_moodlemobileapp",
"addon.storagemanager.downloadedcourses": "local_moodlemobileapp",
"addon.storagemanager.downloads": "local_moodlemobileapp",
"addon.storagemanager.errordeletedownloadeddata": "local_moodlemobileapp",
"addon.storagemanager.managedownloads": "local_moodlemobileapp",
"addon.storagemanager.totaldownloads": "local_moodlemobileapp",

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -12,7 +12,7 @@
</core-context-menu-item>
</core-context-menu>
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -296,7 +296,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
this.hasNextPage = numEntries >= AddonModDataProvider.PER_PAGE && ((this.search.page + 1) *
AddonModDataProvider.PER_PAGE) < entries.totalcount;
this.hasOffline = entries.hasOfflineActions;
this.hasOffline = !!entries.hasOfflineActions;
this.hasOfflineRatings = !!entries.hasOfflineRatings;

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -9,7 +9,7 @@
<ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -10,7 +10,7 @@
</core-context-menu-item>
</core-context-menu>
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -4,7 +4,7 @@
<ion-icon name="fas-bookmark" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -73,7 +73,6 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
canManage?: boolean; // Whether the user can manage the lesson.
canViewReports?: boolean; // Whether the user can view the lesson reports.
showSpinner?: boolean; // Whether to display a spinner.
hasOffline?: boolean; // Whether there's offline data.
retakeToReview?: AddonModLessonRetakeFinishedInSyncDBRecord; // A retake to review.
preventReasons: AddonModLessonPreventAccessReason[] = []; // List of reasons that prevent the lesson from being seen.
leftDuringTimed?: boolean; // Whether the user has started and left a retake.

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -21,7 +21,7 @@
</core-context-menu-item>
</core-context-menu>
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -1,6 +1,6 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons slot="end">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.course.modulesummary' | translate">
<ion-button fill="clear" (click)="openModuleSummary()" aria-haspopup="true" [attr.aria-label]="'core.info' | translate">
<ion-icon name="fas-info-circle" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</core-navbar-buttons>

View File

@ -11,6 +11,7 @@
"deletedata": "Delete downloaded data",
"deletedatafrom": "Delete all downloaded data from '{{name}}'",
"downloadedcourses": "Downloaded courses",
"downloads": "Downloads",
"errordeletedownloadeddata": "Error deleting downloaded data.",
"managedownloads": "Manage downloads",
"totaldownloads": "Total downloads",

View File

@ -115,7 +115,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
* @return Promise resolved when done.
*/
async doRefresh(refresher?: IonRefresher | null, showErrors = false): Promise<void> {
if (!this.loaded || !this.module) {
if (!this.module) {
// Module can be undefined if course format changes from single activity to weekly/topics.
return;
}
@ -224,7 +224,7 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
const lastDownloaded =
await CoreCourseHelper.getModulePackageLastDownloaded(this.module, this.component);
this.downloadTimeReadable = lastDownloaded.downloadTimeReadable;
this.downloadTimeReadable = CoreTextUtils.ucFirst(lastDownloaded.downloadTimeReadable);
}
/**
@ -416,24 +416,14 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
});
if (data) {
if (data.action == 'refresh') {
const modal = await CoreDomUtils.showModalLoading();
if (this.loaded && (data.action == 'refresh' || data.action == 'sync')) {
this.loaded = false;
try {
await this.doRefresh();
await this.doRefresh(undefined, data.action == 'sync');
} finally {
modal.dismiss();
}
} else if (data.action == 'sync') {
const modal = await CoreDomUtils.showModalLoading();
try {
await this.doRefresh( undefined, true);
} finally {
modal.dismiss();
this.loaded = true;
}
}
}
}

View File

@ -11,8 +11,13 @@
<!-- Content. -->
<core-loading [hideUntil]="loaded">
<!-- Activity info. -->
<ion-item class="ion-text-wrap" *ngIf="module">
<ion-item class="ion-text-wrap" *ngIf="module" lines="full">
<ion-label>
<p *ngIf="moduleNameTranslated" class="core-modulename">
<core-mod-icon slot="start" [modicon]="modicon" [modname]="module.modname" [componentId]="module.instance">
</core-mod-icon>
{{moduleNameTranslated}}
</p>
<h1>
<core-format-text [text]="module.name" contextLevel="module" [component]="component" [componentId]="componentId"
[contextInstanceId]="module.id" [courseId]="courseId">
@ -25,9 +30,12 @@
</ion-button>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="course" (click)="openCourse()" button [detail]="true">
<ion-item class="ion-text-wrap" *ngIf="course" (click)="openCourse()" button [detail]="true" lines="full">
<ion-label>
<p class="item-heading">{{ 'core.course' | translate}}</p>
<p class="item-heading">
<ion-icon name="fas-graduation-cap" aria-hidden="true"></ion-icon>
{{ 'core.course' | translate}}
</p>
<p>
<core-format-text [text]="course.displayname || course.fullname" contextLevel="course" [contextInstanceId]="courseId">
</core-format-text>
@ -35,44 +43,60 @@
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="module && description && displayOptions.displayDescription">
<ion-item class="ion-text-wrap" *ngIf="module && description && displayOptions.displayDescription" lines="full">
<ion-label>
<p class="item-heading">
{{ 'core.description' | translate}}
</p>
<core-format-text [text]="description" [component]="component" [componentId]="componentId" contextLevel="module"
[contextInstanceId]="module.id" [courseId]="courseId" [maxHeight]="120">
</core-format-text>
</ion-label>
</ion-item>
<ion-item button *ngIf="prefetchText && displayOptions.displayPrefetch" class="ion-text-wrap">
<ion-label>
<p class="item-heading ion-text-wrap">{{ prefetchText }}</p>
<p *ngIf="downloadTimeReadable">{{ downloadTimeReadable }}</p>
</ion-label>
<ion-button *ngIf="prefetchStatusIcon && prefetchStatusIcon != 'spinner'" (click)="prefetch()" color="primary" fill="outline"
[attr.aria-label]="'core.download' | translate" slot="end">
<ion-icon [name]="prefetchStatusIcon" slot="icon-only" aria-hidden="true">
</ion-icon>
<ion-card *ngIf="(canPrefetch && displayOptions.displayPrefetch) || (sizeReadable && displayOptions.displaySize)">
<ion-item lines="full" class="ion-text-wrap">
<ion-label>
<h2>
<ion-icon name="cloud-done" aria-hidden="true"></ion-icon>
{{ 'addon.storagemanager.downloads' | translate }}
</h2>
</ion-label>
</ion-item>
<ion-item *ngIf="sizeReadable && displayOptions.displaySize" class="ion-text-wrap">
<ion-label>
<p class="item-heading ion-text-wrap">{{ 'addon.storagemanager.totalspaceusage' | translate }}</p>
<ion-badge color="light">{{ sizeReadable | coreBytesToSize }}</ion-badge>
</ion-label>
<ion-button *ngIf="!removeFilesLoading" [disabled]="prefetchLoading" (click)="removeFiles()" color="danger" fill="clear"
[attr.aria-label]="'core.clearstoreddata' | translate:{$a: sizeReadable}" slot="end">
<ion-icon name="fas-trash" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
<ion-spinner *ngIf="removeFilesLoading" slot="end" aria-hidden="true"></ion-spinner>
</ion-item>
<ion-item *ngIf="downloadTimeReadable" class="ion-text-wrap">
<ion-label>
<p class="ion-text-wrap">{{ 'core.lastdownloaded' | translate }} {{ downloadTimeReadable }}</p>
</ion-label>
</ion-item>
<ion-button fill="outline" expand="block" *ngIf="canPrefetch && displayOptions.displayPrefetch" class="ion-text-wrap"
(click)="prefetch()" color="primary" [disabled]="prefetchDisabled">
<ion-icon *ngIf="!prefetchLoading" name="cloud-done" slot="start" aria-hidden="true"></ion-icon>
<ion-spinner *ngIf="prefetchLoading" slot="start" aria-hidden="true"></ion-spinner>
<ion-label>
{{ 'core.download' | translate }}
</ion-label>
</ion-button>
<ion-spinner *ngIf="prefetchStatusIcon == 'spinner'" slot="end" aria-hidden="true"></ion-spinner>
</ion-item>
<ion-item button *ngIf="sizeReadable && displayOptions.displaySize" class="ion-text-wrap">
<ion-label>
<p class="item-heading ion-text-wrap">{{ 'addon.storagemanager.totalspaceusage' | translate }}</p>
<ion-badge color="light">{{ sizeReadable | coreBytesToSize }}</ion-badge>
</ion-label>
<ion-button *ngIf="!removeFilesLoading && size > 0" (click)="removeFiles()" color="danger" fill="outline"
[attr.aria-label]="'core.clearstoreddata' | translate:{$a: sizeReadable}" slot="end">
<ion-icon name="fas-trash" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
<ion-spinner *ngIf="removeFilesLoading" slot="end" aria-hidden="true"></ion-spinner>
</ion-item>
</ion-card>
<ion-card *ngIf="displayOptions.displayGrades && grades?.length > 0">
<ion-list>
<ion-item lines="full" class="ion-text-wrap">
<ion-label>
<h2>{{ 'core.grades.gradebook' | translate }}</h2>
<h2>
<ion-icon name="fas-chart-bar" slot="end" aria-hidden="true"></ion-icon>{{ 'core.grades.gradebook' | translate
}}
</h2>
</ion-label>
</ion-item>
<ng-container *ngFor="let grade of grades">
@ -90,7 +114,8 @@
<p class="item-heading" *ngIf="grade.itemmodule">
{{ 'core.grades.grade' | translate}}
</p>
<p *ngIf="grade.grade" [innerHTML]="grade.grade"></p>
<p *ngIf="grade.grade && grade.grade != '-'" [innerHTML]="grade.grade"></p>
<ion-badge *ngIf="!grade.grade || grade.grade == '-'" color="light">Not graded</ion-badge>
</ion-label>
<ion-icon *ngIf="grade.icon" name="{{grade.icon}}" slot="end" [attr.aria-label]="grade.iconAlt">
</ion-icon>
@ -163,12 +188,12 @@
</ion-list>
</ion-card>
<ion-button *ngIf="blog && displayOptions.displayBlog" (click)="gotoBlog()" expand="block" fill="outline">
<ion-item button *ngIf="blog && displayOptions.displayBlog" (click)="gotoBlog()" [detail]="true">
<ion-icon name="far-newspaper" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
{{ 'addon.blog.blog' | translate }}
</ion-label>
</ion-button>
</ion-item>
</core-loading>
</ion-content>
<ion-footer *ngIf="loaded && isOnline && displayOptions.displayRefresh">

View File

@ -1,3 +1,4 @@
@import "~theme/globals";
:host ::ng-deep .collapsible-title ion-label {
margin-top: 12px;
@ -6,3 +7,18 @@
h1 {
font-size: 20px;
}
.core-modulename {
text-transform: uppercase;
core-mod-icon {
padding: 3px;
--size: 10px;
margin: 0;
}
}
ion-item ion-label ion-icon {
@include margin-horizontal(0, 4px);
vertical-align: text-top;
}

View File

@ -30,7 +30,7 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
import { CoreUtils } from '@services/utils/utils';
import { ModalController, Network, Translate, NgZone } from '@singletons';
import { ModalController, Network, NgZone } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { Subscription } from 'rxjs';
@ -59,16 +59,17 @@ export class CoreCourseModuleSummaryComponent implements OnInit, OnDestroy {
externalUrl?: string; // External URL to open in browser.
removeFilesLoading = false;
prefetchStatusIcon?: string;
prefetchStatus?: string;
prefetchText?: string;
sizeReadable?: string;
downloadTimeReadable?: string; // Last download time in a readable format.
size = 0;
prefetchLoading = false;
canPrefetch = false;;
prefetchDisabled = false;
sizeReadable = '';
downloadTimeReadable = ''; // Last download time in a readable format.
grades?: CoreGradesFormattedRow[];
blog = false; // If blog is available.
isOnline = false; // If the app is online or not.
course?: CoreEnrolledCourseData;
modicon = '';
moduleNameTranslated = '';
protected onlineSubscription: Subscription; // It will observe the status of the network connection.
protected packageStatusObserver?: CoreEventObserver; // Observer of package status.
@ -172,6 +173,9 @@ export class CoreCourseModuleSummaryComponent implements OnInit, OnDestroy {
this.externalUrl = this.module.url;
this.courseId = this.courseId || this.module.course;
this.modicon = await CoreCourseModuleDelegate.getModuleIconSrc(this.module.modname, this.module.modicon, this.module);
this.moduleNameTranslated = CoreCourse.translateModuleName(this.module.modname || '');
this.blog = await AddonBlog.isPluginEnabled();
await Promise.all([
@ -196,27 +200,20 @@ export class CoreCourseModuleSummaryComponent implements OnInit, OnDestroy {
const moduleInfo =
await CoreCourseHelper.getModulePrefetchInfo(this.module, this.courseId, refresh, this.component);
this.prefetchStatusIcon = moduleInfo.statusIcon;
this.prefetchStatus = moduleInfo.status;
this.canPrefetch = moduleInfo.status != CoreConstants.NOT_DOWNLOADABLE;
this.downloadTimeReadable = '';
if (moduleInfo.status != CoreConstants.NOT_DOWNLOADABLE) {
// Module is downloadable, get the text to display to prefetch.
if (this.canPrefetch) {
if (moduleInfo.downloadTime && moduleInfo.downloadTime > 0) {
this.prefetchText = Translate.instant('core.lastdownloaded');
this.downloadTimeReadable = CoreTextUtils.ucFirst(moduleInfo.downloadTimeReadable);
} else {
// Module not downloaded, show a default text.
this.prefetchText = Translate.instant('core.download');
}
this.prefetchLoading = moduleInfo.status == CoreConstants.DOWNLOADING;
this.prefetchDisabled = moduleInfo.status == CoreConstants.DOWNLOADED;
}
this.sizeReadable = moduleInfo.sizeReadable;
this.size = moduleInfo.size;
if (moduleInfo.status == CoreConstants.DOWNLOADING) {
// Set this to empty to prevent "remove file" option showing up while downloading.
this.sizeReadable = '';
}
this.sizeReadable = moduleInfo.size && moduleInfo.size > 0
? moduleInfo.sizeReadable
: '';
}
/**
@ -280,8 +277,7 @@ export class CoreCourseModuleSummaryComponent implements OnInit, OnDestroy {
return;
}
const initialIcon = this.prefetchStatusIcon;
this.prefetchStatusIcon = CoreConstants.ICON_DOWNLOADING; // Show spinner since this operation might take a while.
this.prefetchLoading = true; // Show spinner since this operation might take a while.
try {
// We need to call getDownloadSize, the package might have been updated.
@ -293,7 +289,7 @@ export class CoreCourseModuleSummaryComponent implements OnInit, OnDestroy {
await this.getPackageStatus(true);
} catch (error) {
this.prefetchStatusIcon = initialIcon;
this.prefetchLoading = false;
if (!this.isDestroyed) {
CoreDomUtils.showErrorModalDefault(error, 'core.errordownloading', true);
@ -309,7 +305,7 @@ export class CoreCourseModuleSummaryComponent implements OnInit, OnDestroy {
return;
}
if (this.prefetchStatus == CoreConstants.DOWNLOADING) {
if (this.prefetchLoading) {
CoreDomUtils.showAlertTranslated(undefined, 'core.course.cannotdeletewhiledownloading');
return;

View File

@ -1426,8 +1426,6 @@ export class CoreCourseHelperProvider {
downloadTimeReadable = moment(downloadTime * 1000).calendar();
}
downloadTimeReadable = CoreTextUtils.ucFirst(downloadTimeReadable);
return {
downloadTime,
downloadTimeReadable,

View File

@ -4,7 +4,7 @@
<div *ngIf="layout == 'card' || layout == 'summarycard'" (click)="openCourse()" class="core-course-thumb"
[class.core-course-color-img]="course.courseImage">
<img *ngIf="course.courseImage" [src]="course.courseImage" core-external-content alt="" />
<ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" class="course-icon">
<ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" class="course-icon" aria-hidden="true">
</ion-icon>
</div>
@ -31,7 +31,8 @@
[class.item-disabled]="course.visible == 0">
<ng-container *ngIf="layout == 'list' || layout == 'listwithenrol'">
<ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" slot="start" class="course-icon core-course-thumb">
<ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" slot="start" class="course-icon core-course-thumb"
aria-hidden="true">
</ion-icon>
<ion-avatar *ngIf="course.courseImage" slot="start" class="core-course-thumb">
<img [src]="course.courseImage" core-external-content alt="" />

View File

@ -80,8 +80,8 @@
}
core-mod-icon {
padding: 0.1rem;
--size: 16px;
padding: 3px;
--size: 10px;
}

View File

@ -601,7 +601,7 @@ export class CoreGradesHelperProvider {
row.iconAlt = Translate.instant('core.grades.aggregatesum');
} else if (text.indexOf('/outcomes') > -1 || text.indexOf('fa-tasks') > -1) {
row.itemtype = 'outcome';
row.icon = 'fas-chart-pie';
row.icon = 'fas-tasks';
row.iconAlt = Translate.instant('core.grades.outcome');
} else if (text.indexOf('i/folder') > -1 || text.indexOf('fa-folder') > -1) {
row.itemtype = 'category';

View File

@ -206,14 +206,8 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C
},
});
if (data && data.action == 'refresh') {
const modal = await CoreDomUtils.showModalLoading();
try {
await this.doRefresh();
} finally {
modal.dismiss();
}
if (data && data.action == 'refresh' && this.content?.dataLoaded) {
this.content?.refreshContent(true);
}
}

View File

@ -307,6 +307,11 @@ ion-button {
img[slot=end] {
@include margin-horizontal(-0.3em, 0.3em);
}
ion-spinner[slot] {
width: 20px;
color: inherit;
}
}
ion-button.button-outline {