MOBILE-4636 course: Enclose sections in cards instead of modules

main
Pau Ferrer Ocaña 2024-08-20 14:54:30 +02:00
parent 7271ee3c24
commit 074246f715
10 changed files with 80 additions and 37 deletions

View File

@ -4,7 +4,7 @@
</ion-label>
</ion-item-divider>
<core-loading [hideUntil]="loaded">
<ion-list *ngIf="mainMenuBlock" class="core-course-module-list-wrapper">
<ion-list *ngIf="mainMenuBlock" class="core-course-module-list-wrapper list-item-limited-width">
<ion-item class="ion-text-wrap" *ngIf="mainMenuBlock.summary">
<ion-label>
<core-format-text [text]="mainMenuBlock.summary" [component]="component" [componentId]="siteHomeId" contextLevel="course"

View File

@ -8,7 +8,7 @@
<core-loading [hideUntil]="loaded">
<!-- Single section. -->
<div *ngIf="selectedSection && selectedSection.id !== allSectionsId">
<div *ngIf="selectedSection && selectedSection.id !== allSectionsId" class="single-section list-item-limited-width">
<core-dynamic-component [component]="singleSectionComponent" [data]="data">
<ng-container *ngTemplateOutlet="sectionTemplate; context: {section: selectedSection}" />
<core-empty-box *ngIf="!selectedSection.hasContent" icon="fas-table-cells-large"
@ -17,7 +17,7 @@
</div>
<!-- Multiple sections. -->
<div *ngIf="selectedSection && selectedSection.id === allSectionsId">
<div *ngIf="selectedSection && selectedSection.id === allSectionsId" class="multiple-sections list-item-limited-width">
<core-dynamic-component [component]="allSectionsComponent" [data]="data">
<ng-container *ngFor="let section of sections; index as i">
<ng-container *ngIf="i <= lastShownSectionIndex">

View File

@ -14,3 +14,18 @@
.course-section {
--inner-padding-end: 12px;
}
.multiple-sections .core-course-module-list-wrapper {
border: var(--ion-card-border-width) solid var(--ion-card-border-color);
border-radius: var(--ion-card-radius);
margin: 8px 4px;
width: calc(100% - 8px);
ion-card {
--ion-card-background: transparent;
}
ion-item-divider {
--background: transparent;
}
}

View File

@ -1,7 +1,7 @@
<ion-card *ngIf="module.handlerData && module.visibleoncoursepage !== 0"
class="activity-card core-course-module-handler {{module.handlerData.class}}" [class.core-course-module-with-view]="moduleHasView"
[class.item-dimmed]="module.visible === 0 || module.uservisible === false" [class.activityinline]="activityInline"
(click)="moduleClicked($event)" [button]="module.handlerData.action && module.uservisible"
[class.item-dimmed]="module.visible === 0 || module.uservisible === false" (click)="moduleClicked($event)"
[button]="module.handlerData.action && module.uservisible"
[attr.aria-label]="module.handlerData.a11yTitle ? module.handlerData.a11yTitle : null" id="core-course-module-{{module.id}}">
<ng-container *ngIf="!module.handlerData.loading">
<ion-item class="ion-text-wrap">

View File

@ -4,13 +4,15 @@
--horizontal-margin: 12px;
--vertical-margin: 12px;
--card-padding: 16px;
--card-border-width: 0px;
--card-radius: 0px;
--card-background: transparent;
ion-card {
margin: var(--vertical-margin) var(--horizontal-margin);
&.activityinline {
border: 0px;
}
--ion-card-border-width: var(--card-border-width);
--ion-card-radius: var(--card-radius);
--ion-card-background: var(--card-background);
}
ion-item {
@ -125,6 +127,7 @@
}
.activity-extrabadges {
font: var(--mdl-typography-body-font-md);
color: var(--medium);
}
@ -182,13 +185,11 @@
}
&.indented ion-card {
border: none;
--ion-card-radius: 0;
@include margin-horizontal(calc(var(--horizontal-margin) + 1rem), null);
}
&.indented + ::ng-deep core-course-module.indented ion-card {
border-top: 1px solid var(--border-color);
& + ::ng-deep core-course-module ion-card {
border-top: 1px solid var(--ion-card-border-color);
}
// Hide download folder icon meanwhile MOBILE-4147 is not solved

View File

@ -66,7 +66,6 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
prefetchStatusIcon$ = new BehaviorSubject<string>(''); // Module prefetch status icon.
prefetchStatusText$ = new BehaviorSubject<string>(''); // Module prefetch status text.
moduleHasView = true;
activityInline = false;
protected prefetchHandler?: CoreCourseModulePrefetchHandler;
@ -103,18 +102,6 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
this.module.handlerData.a11yTitle = this.module.handlerData.a11yTitle ?? this.module.handlerData.title;
this.moduleHasView = CoreCourse.moduleHasView(this.module);
if (
this.module.handlerData.hasCustomCmListItem &&
(!this.showAvailability || !this.module.availabilityinfo) &&
(!this.showCompletion || !this.hasCompletion) &&
(!this.showActivityDates || !this.module.dates?.length) &&
!this.module.groupmode &&
!(this.module.visible === 0) &&
!(this.module.visible !== 0 && this.module.isStealth)
) {
this.activityInline = true;
}
if (this.showDownloadStatus && this.module.handlerData.showDownloadButton) {
const status = await CoreCourseModulePrefetchDelegate.getDownloadedModuleStatus(this.module, this.module.course);
this.updateModuleStatus(status);

View File

@ -8,7 +8,7 @@
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-content class="limited-width">
<ion-refresher slot="fixed" [disabled]="!loaded" (ionRefresh)="refreshData($event.target)">
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}" />
</ion-refresher>
@ -18,7 +18,7 @@
<ion-list class="core-course-module-list-wrapper">
<ng-container *ngFor="let section of sections; index as i">
<ng-container *ngIf="i <= lastShownSectionIndex">
<ion-card *ngIf="i <= lastShownSectionIndex">
<ion-item-divider class="course-section ion-text-wrap" *ngIf="section.name">
<ion-label>
<h2>
@ -30,7 +30,7 @@
<core-course-module [module]="module" [section]="section" [showActivityDates]="false" [showAvailability]="false"
[showExtra]="false" [showDownloadStatus]="false" [showCompletion]="false" [showIndentation]="false" />
</ng-container>
</ng-container>
</ion-card>
</ng-container>
</ion-list>
<core-infinite-loading [enabled]="canLoadMore" (action)="showMoreActivities($event)" />

View File

@ -8,9 +8,37 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}" />
</ion-refresher>
<core-loading [hideUntil]="dataLoaded">
<ion-list class="core-course-module-list-wrapper">
<ion-list class="list-item-limited-width">
<!-- Site home main contents. -->
<ng-container *ngIf="section && section.hasContent">
<section *ngIf="section && section.hasContent" class="core-course-module-list-wrapper">
<ion-item-divider class="course-section ion-text-wrap"
[class.item-dimmed]="section.visible === 0 || section.uservisible === false">
<ion-label>
<h2 *ngIf="section.name" class="big" [id]="'core-section-name-' + section.id">
<core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="siteHomeId" />
</h2>
<div *ngIf="section.visible === 0 && section.uservisible !== false">
<ion-badge color="warning">
{{ 'core.course.hiddenfromstudents' | translate }}
</ion-badge>
</div>
<div *ngIf="section.visible === 0 && section.uservisible === false">
<ion-badge color="warning">
{{ 'core.notavailable' | translate }}
</ion-badge>
</div>
<div *ngIf="section.availabilityinfo">
<ion-chip class="clickable">
<ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate" />
<ion-label>
<core-format-text [text]=" section.availabilityinfo" contextLevel="course"
[contextInstanceId]="siteHomeId" />
</ion-label>
</ion-chip>
</div>
</ion-label>
</ion-item-divider>
<ion-item class="ion-text-wrap section-summary" *ngIf="section.summary">
<ion-label>
<core-format-text [text]="section.summary" contextLevel="course" [contextInstanceId]="siteHomeId" />
@ -18,11 +46,10 @@
</ion-item>
<core-course-module *ngFor="let module of section.modules" [module]="module" [section]="section" />
</ng-container>
</section>
<!-- Site home items: news, categories, courses, etc. -->
<ng-container *ngIf="items.length > 0">
<core-spacer *ngIf="section && section!.hasContent" />
<ng-container *ngFor="let item of items">
<ng-container [ngSwitch]="item">
<ng-container *ngSwitchCase="'LIST_OF_COURSE'">

View File

@ -10,6 +10,21 @@ ion-item ion-icon {
@include margin-horizontal(null, var(--margin-end));
}
core-spacer {
--spacer-horizontal: 10px;
section.core-course-module-list-wrapper {
border: var(--ion-card-border-width) solid var(--ion-card-border-color);
border-radius: var(--ion-card-radius);
margin: 12px;
ion-card {
--ion-card-background: transparent;
}
ion-item-divider {
--background: transparent;
}
}
core-course-module.core-sitehome-news {
--card-border-width: var(--ion-card-border-width);
--card-radius: var(--ion-card-radius);
}

View File

@ -207,9 +207,7 @@ img[core-external-content]:not([src]) {
border-radius: var(--mdl-shape-borderRadius-lg);
}
ion-list.core-course-module-list-wrapper,
.list-item-limited-width,
.core-course-module-list-wrapper,
ion-content.limited-width > :not([slot]) {
max-width: var(--list-item-max-width);
margin-left: auto !important;