MOBILE-3814 course: Adapt course styles

main
Pau Ferrer Ocaña 2022-02-10 10:50:51 +01:00
parent 492278be00
commit f61a465c0a
16 changed files with 135 additions and 88 deletions

View File

@ -13,7 +13,7 @@
<ion-content> <ion-content>
<ion-list id="core-course-section-selector" role="listbox" aria-labelledby="core-course-section-selector-label"> <ion-list id="core-course-section-selector" role="listbox" aria-labelledby="core-course-section-selector-label">
<ng-container *ngFor="let section of sectionsToRender"> <ng-container *ngFor="let section of sectionsToRender">
<ion-item *ngIf="allSectionId == section.id" class="ion-text-wrap divider core-course-index-all" <ion-item *ngIf="allSectionId == section.id" class="divider core-course-index-all"
(click)="selectSectionOrModule($event, section.id)" button [class.item-current]="selectedId === section.id" detail="false"> (click)="selectSectionOrModule($event, section.id)" button [class.item-current]="selectedId === section.id" detail="false">
<ion-label> <ion-label>
<h2> <h2>
@ -23,7 +23,7 @@
</ion-label> </ion-label>
</ion-item> </ion-item>
<ng-container *ngIf="allSectionId != section.id"> <ng-container *ngIf="allSectionId != section.id">
<ion-item class="ion-text-wrap divider section" (click)="selectSectionOrModule($event, section.id)" button <ion-item class="divider section" (click)="selectSectionOrModule($event, section.id)" button
[class.item-current]="selectedId === section.id" [class.item-dimmed]="section.visible === 0" detail="false" [class.item-current]="selectedId === section.id" [class.item-dimmed]="section.visible === 0" detail="false"
sticky="true"> sticky="true">
<ion-icon *ngIf="section.hasVisibleModules" [name]="section.expanded ? 'fas-chevron-down' : 'fas-chevron-right'" <ion-icon *ngIf="section.hasVisibleModules" [name]="section.expanded ? 'fas-chevron-down' : 'fas-chevron-right'"

View File

@ -22,15 +22,25 @@ ion-item::part(native) {
ion-icon { ion-icon {
margin: 0; margin: 0;
@include padding(12px, 32px, 12px, 16px); @include padding(12px, 16px, 12px, 16px);
} }
ion-item.core-course-index-all::part(native) { ion-item.core-course-index-all::part(native) {
--padding-start: 16px; --padding-start: 16px;
} }
ion-item.item-current ion-icon.expandable-status-icon { ion-item.item.item-current {
@include padding(null, null, null, 11px); --background: var(--primary);
--color: var(--primary-contrast);
border: 0;
ion-badge {
border: 1px solid var(--primary-contrast);
}
::ng-deep ion-icon {
color: var(--primary-contrast);
}
} }
ion-icon.restricted { ion-icon.restricted {

View File

@ -23,7 +23,6 @@ import { CoreCourseFormatDelegate } from '@features/course/services/format-deleg
import { CoreCourseAnyCourseData } from '@features/courses/services/courses'; import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { IonContent } from '@ionic/angular'; import { IonContent } from '@ionic/angular';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
import { ModalController } from '@singletons'; import { ModalController } from '@singletons';
/** /**
@ -62,12 +61,11 @@ export class CoreCourseCourseIndexComponent implements OnInit {
} }
let completionEnabled = !!this.course.enablecompletion; let completionEnabled = !!this.course.enablecompletion;
if (completionEnabled && 'courseformatoptions' in this.course && this.course.courseformatoptions) { if (completionEnabled && 'completionusertracked' in this.course && this.course.completionusertracked !== undefined) {
const formatOptions = CoreUtils.objectToKeyValueMap(this.course.courseformatoptions, 'name', 'value'); completionEnabled = this.course.completionusertracked;
}
if (formatOptions) { if (completionEnabled && 'showcompletionconditions' in this.course && this.course.showcompletionconditions !== undefined) {
completionEnabled = !!formatOptions.completionusertracked; completionEnabled = this.course.showcompletionconditions;
}
} }
const currentSection = await CoreCourseFormatDelegate.getCurrentSection(this.course, this.sections); const currentSection = await CoreCourseFormatDelegate.getCurrentSection(this.course, this.sections);

View File

@ -20,7 +20,7 @@
</ion-item> </ion-item>
<ng-content select="[description]"></ng-content> <ng-content select="[description]"></ng-content>
<ion-item class="ion-text-wrap core-module-dates" *ngIf="showCompletion && (module.dates?.length || <ion-item class="ion-text-wrap" *ngIf="showCompletion && (module.dates?.length ||
(module.completiondata && module.completiondata.isautomatic && module.uservisible))"> (module.completiondata && module.completiondata.isautomatic && module.uservisible))">
<ion-label> <ion-label>
<!-- Activity dates. --> <!-- Activity dates. -->

View File

@ -16,8 +16,14 @@
align-self: flex-start; align-self: flex-start;
} }
.core-module-dates ion-icon { .core-module-dates {
@include margin-horizontal(null, 8px); background: var(--light);
border-radius: var(--small-radius);
padding: 8px;
ion-icon {
@include margin-horizontal(null, 8px);
}
} }
} }

View File

@ -3,7 +3,6 @@
<ion-item id="core-course-module-{{module.id}}" detail="false" <ion-item id="core-course-module-{{module.id}}" detail="false"
class="ion-text-wrap core-course-module-handler core-module-main-item {{module.handlerData.class}}" class="ion-text-wrap core-course-module-handler core-module-main-item {{module.handlerData.class}}"
(click)="moduleClicked($event)" [attr.aria-label]="module.handlerData.a11yTitle" [ngClass]="{ (click)="moduleClicked($event)" [attr.aria-label]="module.handlerData.a11yTitle" [ngClass]="{
'has-module-info': hasInfo,
'item-media': module.handlerData.icon, 'item-media': module.handlerData.icon,
'item-dimmed': module.visible === 0 || module.uservisible === false 'item-dimmed': module.visible === 0 || module.uservisible === false
}" [button]="module.handlerData.action && module.uservisible"> }" [button]="module.handlerData.action && module.uservisible">
@ -19,24 +18,26 @@
</core-format-text> </core-format-text>
</p> </p>
<!-- Basic module completion. --> <div class="core-module-additional-info">
<core-course-module-completion *ngIf="module.completiondata && module.uservisible" [completion]="module.completiondata" <!-- Basic module completion. -->
[moduleName]="module.name" [moduleId]="module.id" [showCompletionConditions]="showCompletionConditions" <core-course-module-completion *ngIf="module.completiondata && module.uservisible" [completion]="module.completiondata"
[showManualCompletion]="showManualCompletion" (completionChanged)="completionChanged.emit($event)" mode="basic"> [moduleName]="module.name" [moduleId]="module.id" [showCompletionConditions]="showCompletionConditions"
</core-course-module-completion> [showManualCompletion]="showManualCompletion" (completionChanged)="completionChanged.emit($event)" mode="basic">
</core-course-module-completion>
<ion-chip *ngIf="module.handlerData.extraBadge" [color]="module.handlerData.extraBadgeColor" <ion-chip *ngIf="module.handlerData.extraBadge" [color]="module.handlerData.extraBadgeColor"
class="ion-text-wrap ion-text-start" [outline]="true"> class="ion-text-wrap ion-text-start" [outline]="true">
<ion-label><span [innerHTML]="module.handlerData.extraBadge"></span></ion-label> <ion-label><span [innerHTML]="module.handlerData.extraBadge"></span></ion-label>
</ion-chip> </ion-chip>
<!-- Hidden badges --> <!-- Hidden badges -->
<ion-badge color="warning" *ngIf="module.visible === 0 && (!section || section.visible)"> <ion-badge color="warning" *ngIf="module.visible === 0 && (!section || section.visible)">
{{ 'core.course.hiddenfromstudents' | translate }} {{ 'core.course.hiddenfromstudents' | translate }}
</ion-badge> </ion-badge>
<ion-badge color="warning" *ngIf="module.visible !== 0 && module.isStealth"> <ion-badge color="warning" *ngIf="module.visible !== 0 && module.isStealth">
{{ 'core.course.hiddenoncoursepage' | translate }} {{ 'core.course.hiddenoncoursepage' | translate }}
</ion-badge> </ion-badge>
</div>
</ion-label> </ion-label>
<!-- Buttons. --> <!-- Buttons. -->
<div slot="end" *ngIf="module.uservisible !== false" class="buttons core-module-buttons" <div slot="end" *ngIf="module.uservisible !== false" class="buttons core-module-buttons"
@ -72,24 +73,24 @@
[moduleName]="module.name" [moduleId]="module.id" [showCompletionConditions]="showCompletionConditions"> [moduleName]="module.name" [moduleId]="module.id" [showCompletionConditions]="showCompletionConditions">
</core-course-module-completion> </core-course-module-completion>
<!-- Activity dates. --> <div class="core-module-dates-availabilityinfo"
<div *ngIf="showActivityDates && module.dates && module.dates.length" class="core-module-dates"> *ngIf="(showActivityDates && module.dates && module.dates.length) || module.availabilityinfo">
<p *ngFor="let date of module.dates"> <!-- Activity dates. -->
<ion-icon name="fas-calendar" aria-hidden="true"></ion-icon><strong>{{ date.label }}</strong> {{ date.timestamp * <div *ngIf="showActivityDates && module.dates && module.dates.length" class="core-module-dates">
1000 | coreFormatDate:'strftimedatetime' }} <p *ngFor="let date of module.dates">
</p> <ion-icon name="fas-calendar" aria-hidden="true"></ion-icon><strong>{{ date.label }}</strong> {{ date.timestamp
</div> *
1000 | coreFormatDate:'strftimedatetime' }}
</p>
</div>
<!-- Availability info --> <!-- Availability info -->
<div *ngIf="module.availabilityinfo"> <div *ngIf="module.availabilityinfo" class="core-module-availabilityinfo">
<ion-chip class="core-module-availabilityinfo">
<ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate"></ion-icon> <ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate"></ion-icon>
<ion-label> <core-format-text [text]="module.availabilityinfo" contextLevel="module" [contextInstanceId]="module.id"
<core-format-text [text]="module.availabilityinfo" contextLevel="module" [contextInstanceId]="module.id" [courseId]="module.course">
[courseId]="module.course"> </core-format-text>
</core-format-text> </div>
</ion-label>
</ion-chip>
</div> </div>
</ion-label> </ion-label>

View File

@ -35,13 +35,29 @@
.core-module-buttons core-course-module-completion { .core-module-buttons core-course-module-completion {
text-align: center; text-align: center;
} }
.core-module-additional-info {
display: flex;
align-items: center;
}
} }
.core-course-module-info { .core-course-module-info {
.core-module-dates-availabilityinfo {
background: var(--light);
border-radius: var(--small-radius);
padding: 8px;
}
.core-module-dates + .core-module-availabilityinfo {
border-top: 1px solid var(--stroke);
padding-top: 8px;
}
.core-module-availabilityinfo { .core-module-availabilityinfo {
font-size: 90%; font-size: 90%;
ul { ::ng-deep ul {
margin-block-start: 0.5em; margin-top: 0.5em;
} }
} }
} }
@ -57,10 +73,6 @@
margin-top: 0px; margin-top: 0px;
} }
.core-module-main-item.has-module-info {
--inner-border-width: 0px;
}
.core-module-availabilityinfo ion-icon, .core-module-availabilityinfo ion-icon,
.core-module-dates ion-icon { .core-module-dates ion-icon {
@include margin-horizontal(null, 8px); @include margin-horizontal(null, 8px);

View File

@ -27,38 +27,39 @@
<core-course-module-info [module]="module" [courseId]="courseId" [description]="module.description" [component]="module.modname" <core-course-module-info [module]="module" [courseId]="courseId" [description]="module.description" [component]="module.modname"
[componentId]="module.id" [expandDescription]="true"> [componentId]="module.id" [expandDescription]="true">
<div class="ion-padding" *ngIf="module.handlerData?.extraBadge"> <ion-item class="ion-text-wrap" *ngIf="module.handlerData?.extraBadge ||
<ion-chip *ngIf="module.handlerData?.extraBadge" [color]="module.handlerData?.extraBadgeColor" (module.visible === 0 && (!section || section.visible)) ||
class="ion-text-wrap ion-text-start" [outline]="true"> (module.visible !== 0 && module.isStealth) ||
<ion-label><span [innerHTML]="module.handlerData?.extraBadge"></span></ion-label> module.availabilityinfo">
</ion-chip> <ion-label>
</div> <div class="ion-padding" *ngIf="module.handlerData?.extraBadge">
<ion-chip *ngIf="module.handlerData?.extraBadge" [color]="module.handlerData?.extraBadgeColor"
class="ion-text-wrap ion-text-start" [outline]="true">
<ion-label><span [innerHTML]="module.handlerData?.extraBadge"></span></ion-label>
</ion-chip>
</div>
<!-- Hidden badges --> <!-- Hidden badges -->
<div *ngIf="module.visible === 0 && (!section || section.visible)"> <div *ngIf="module.visible === 0 && (!section || section.visible)">
<ion-chip color="warning"> <ion-badge color="warning">
<ion-icon name="fas-eye-slash" aria-hidden="true"></ion-icon> {{ 'core.course.hiddenfromstudents' | translate }}
<ion-label>{{ 'core.course.hiddenfromstudents' | translate }}</ion-label> </ion-badge>
</ion-chip> </div>
</div> <div *ngIf="module.visible !== 0 && module.isStealth">
<div *ngIf="module.visible !== 0 && module.isStealth"> <ion-badge color="warning">
<ion-chip color="warning"> {{ 'core.course.hiddenoncoursepage' | translate }}
<ion-icon name="fas-eye-slash" aria-hidden="true"></ion-icon> </ion-badge>
<ion-label>{{ 'core.course.hiddenoncoursepage' | translate }}</ion-label> </div>
</ion-chip>
</div>
<!-- Availability info --> <!-- Availability info -->
<div *ngIf="module.availabilityinfo"> <div *ngIf="module.availabilityinfo" class="core-module-availabilityinfo">
<ion-chip class="core-module-availabilityinfo"> <ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate"></ion-icon>
<ion-icon name="fas-lock" [attr.aria-label]="'core.restricted' | translate"></ion-icon>
<ion-label>
<core-format-text [text]="module.availabilityinfo" contextLevel="module" [contextInstanceId]="module.id" <core-format-text [text]="module.availabilityinfo" contextLevel="module" [contextInstanceId]="module.id"
[courseId]="module.course"> [courseId]="module.course">
</core-format-text> </core-format-text>
</ion-label> </div>
</ion-chip> </ion-label>
</div> </ion-item>
<core-course-unsupported-module *ngIf="unsupported" [module]="module" [courseId]="courseId"></core-course-unsupported-module> <core-course-unsupported-module *ngIf="unsupported" [module]="module" [courseId]="courseId"></core-course-unsupported-module>
</core-course-module-info> </core-course-module-info>

View File

@ -27,6 +27,7 @@ import { CoreUtils } from '@services/utils/utils';
@Component({ @Component({
selector: 'page-core-course-module-preview', selector: 'page-core-course-module-preview',
templateUrl: 'module-preview.html', templateUrl: 'module-preview.html',
styleUrls: ['module-preview.scss'],
}) })
export class CoreCourseModulePreviewPage implements OnInit { export class CoreCourseModulePreviewPage implements OnInit {

View File

@ -0,0 +1,15 @@
@import "~theme/globals";
.core-module-availabilityinfo {
background: var(--light);
border-radius: var(--small-radius);
padding: 8px;
font-size: 90%;
::ng-deep ul {
margin-top: 0.5em;
}
ion-icon {
@include margin-horizontal(null, 8px);
}
}

View File

@ -160,7 +160,7 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
const tint = CoreColors.lighter(this.course.color, 50); const tint = CoreColors.lighter(this.course.color, 50);
this.element.style.setProperty('--course-color-tint', tint); this.element.style.setProperty('--course-color-tint', tint);
} else { } else if(this.course.colorNumber !== undefined) {
this.element.classList.add('course-color-' + this.course.colorNumber); this.element.classList.add('course-color-' + this.course.colorNumber);
} }
} }

View File

@ -13,6 +13,7 @@
core-block ::ng-deep ion-card.addon-block-myoverview { core-block ::ng-deep ion-card.addon-block-myoverview {
--border-width: 0; --border-width: 0;
--background: transparent;
} }
@if ($core-dashboard-logo) { @if ($core-dashboard-logo) {

View File

@ -5,6 +5,7 @@ ion-item ion-icon {
border-radius: var(--module-icon-radius); border-radius: var(--module-icon-radius);
padding: 0.7rem; padding: 0.7rem;
background-color: var(--gray-100); background-color: var(--gray-100);
color: var(--gray-900);
line-height: var(--size); line-height: var(--size);
--margin-end: 1rem; --margin-end: 1rem;
@include margin-horizontal(null, var(--margin-end)); @include margin-horizontal(null, var(--margin-end));

View File

@ -36,7 +36,7 @@ $background-color-dark-rgb: color-to-rgb-list($background-color-dark) !default;
$ion-item-background: $white !default; $ion-item-background: $white !default;
$ion-item-background-rgb: color-to-rgb-list($ion-item-background) !default; $ion-item-background-rgb: color-to-rgb-list($ion-item-background) !default;
$ion-item-background-dark: mix(#ffffff, #000000, 20%) !default; // #333333 $ion-item-background-dark: $gray-900 !default;
$ion-item-background-dark-rgb: color-to-rgb-list($ion-item-background-dark) !default; $ion-item-background-dark-rgb: color-to-rgb-list($ion-item-background-dark) !default;
$primary: $blue !default; $primary: $blue !default;

View File

@ -415,8 +415,9 @@ ion-alert {
} }
// Ionic list. // Ionic list.
ion-list.list-md { ion-list {
padding: 0; padding: 0;
--ion-item-background: transparent;
} }
// Safe areas // Safe areas
@ -1249,7 +1250,6 @@ ion-item.item-input ion-input.has-focus {
ion-item-divider.item, ion-item-divider.item,
ion-item.item.divider { ion-item.item.divider {
--inner-padding-end: 8px; --inner-padding-end: 8px;
background: var(--background);
min-height: var(--min-height); min-height: var(--min-height);
border-bottom-width: var(--item-divider-border-width); border-bottom-width: var(--item-divider-border-width);
--border-width: var(--item-divider-border-width); --border-width: var(--item-divider-border-width);

View File

@ -76,12 +76,13 @@
--core-progressbar-text-color: var(--gray-100); --core-progressbar-text-color: var(--gray-100);
--ion-item-background: #{$ion-item-background-dark}; --ion-item-background: #{$ion-item-background-dark};
--ion-item-detail-icon-color: var(--white); --item-divider-background: var(--ion-item-background);
--item-divider-color: var(--text-color); --item-divider-color: var(--text-color);
--spacer-background: var(--gray-100); --spacer-background: var(--gray-700);
--core-combobox-background: var(--ion-item-background); --core-combobox-background: var(--ion-item-background);
--core-combobox-color: var(--white); --core-combobox-color: var(--gray-100);
--core-combobox-border-color: var(--stroke);
--core-login-background: var(--gray-900); --core-login-background: var(--gray-900);
--core-login-text-color: var(--white); --core-login-text-color: var(--white);