Skip to content

Commit 5dc6ae4

Browse files
committed
MOBILE-4653 html: Adapt new control flow on core components
Some changes left untouched because in implies type checking
1 parent 66a281f commit 5dc6ae4

File tree

37 files changed

+765
-497
lines changed

37 files changed

+765
-497
lines changed

src/core/components/attachments/core-attachments.html

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
<ion-item class="ion-text-wrap">
44
<ion-label>
55
<p class="item-heading">{{ title }} <span [core-mark-required]="required" class="core-mark-required"></span></p>
6-
<span *ngIf="maxSubmissionsReadable">
7-
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
6+
<span>
7+
@if (maxSubmissionsReadable) {
8+
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
9+
} @else {
10+
{{ 'core.maxfilesize' | translate:{$a: maxSizeReadable} }}
11+
}
812
</span>
9-
<span *ngIf="!maxSubmissionsReadable">{{ 'core.maxfilesize' | translate:{$a: maxSizeReadable} }}</span>
1013
</ion-label>
11-
<ion-button slot="end" (click)="add()" [ariaLabel]="'core.fileuploader.addfiletext' | translate"
12-
*ngIf="unlimitedFiles || (maxSubmissions !== undefined && maxSubmissions >= 0 && files && files.length < maxSubmissions)">
13-
<ion-icon name="fas-plus" slot="icon-only" aria-hidden="true" />
14-
</ion-button>
14+
@if (unlimitedFiles || (maxSubmissions !== undefined && maxSubmissions >= 0 && files && files.length < maxSubmissions)) {
15+
<ion-button slot="end" (click)="add()" [ariaLabel]="'core.fileuploader.addfiletext' | translate">
16+
<ion-icon name="fas-plus" slot="icon-only" aria-hidden="true" />
17+
</ion-button>
18+
}
1519
</ion-item>
1620

1721
@if (fileTypes && fileTypes.mimetypes && fileTypes.mimetypes.length) {
@@ -25,30 +29,36 @@
2529
</ion-item>
2630

2731
<ul class="core-attachments" slot="content">
28-
<li *ngFor="let typeInfo of fileTypes.info">
29-
<strong *ngIf="typeInfo.name">{{typeInfo.name}} </strong>{{typeInfo.extlist}}
30-
</li>
32+
@for (typeInfo of fileTypes.info; track typeInfo.name) {
33+
<li>
34+
@if (typeInfo.name) {
35+
<strong>{{typeInfo.name}} </strong>
36+
}
37+
{{typeInfo.extlist}}
38+
</li>
39+
}
3140
</ul>
3241
</ion-accordion>
3342
</ion-accordion-group>
3443
}
3544

36-
37-
3845
<ng-container *ngFor="let file of files; let index=index">
39-
<!-- Files already attached to the submission, either in online or in offline. -->
40-
<core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="componentId" [canDelete]="true"
41-
(onDelete)="delete(index, true)" [canDownload]="!file.offline" />
42-
43-
<!-- Files added to draft but not attached to submission yet. -->
44-
<core-local-file *ngIf="file.name" [file]="file" [manage]="true" (onDelete)="delete(index, false)"
45-
(onRename)="renamed(index, $event)" />
46+
@if (file.name) {
47+
<!-- Files added to draft but not attached to submission yet. -->
48+
<core-local-file [file]="file" [manage]="true" (onDelete)="delete(index, false)" (onRename)="renamed(index, $event)" />
49+
} @else {
50+
<!-- Files already attached to the submission, either in online or in offline. -->
51+
<core-file [file]="file" [component]="component" [componentId]="componentId" [canDelete]="true"
52+
(onDelete)="delete(index, true)" [canDownload]="!file.offline" />
53+
}
4654
</ng-container>
4755

48-
<ion-item class="ion-text-wrap" *ngIf="!files || !files.length">
49-
<ion-label>
50-
<p>{{ 'core.fileuploader.nofilesattached' | translate }}</p>
51-
</ion-label>
52-
</ion-item>
56+
@if (!files || !files.length) {
57+
<ion-item class="ion-text-wrap">
58+
<ion-label>
59+
<p>{{ 'core.fileuploader.nofilesattached' | translate }}</p>
60+
</ion-label>
61+
</ion-item>
62+
}
5363
</ion-card>
5464
</core-loading>
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<ion-item class="ion-text-wrap">
22
<ion-label>
3-
<p *ngIf="html" [innerHTML]="content"></p>
4-
<p *ngIf="!html">{{content}}</p>
3+
@if (html) {
4+
<p [innerHTML]="content"></p>
5+
} @else {
6+
<p>{{content}}</p>
7+
}
58
</ion-label>
69
</ion-item>
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
<div *ngIf="!loading" @coreShowHideAnimation>
2-
<ng-content />
3-
</div>
4-
5-
<!-- Spinner. -->
6-
<ion-spinner *ngIf="loading" @coreShowHideAnimation [attr.aria-label]="loadingLabel | translate" />
1+
@if (loading) {
2+
<ion-spinner @coreShowHideAnimation [attr.aria-label]="loadingLabel | translate" />
3+
} @else {
4+
<div @coreShowHideAnimation>
5+
<ng-content />
6+
</div>
7+
}
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
<canvas #canvas [attr.height]="height"></canvas>
22

3-
<ion-list *ngIf="chart">
4-
<ion-item *ngFor="let data of legendItems">
5-
<ion-icon name="fas-square" slot="start" [style.color]="data.fillStyle" aria-hidden="true" />
6-
<ion-label>{{data.text}}</ion-label>
7-
</ion-item>
8-
</ion-list>
3+
@if (chart) {
4+
<ion-list>
5+
@for (data of legendItems; track data.text) {
6+
<ion-item>
7+
<ion-icon name="fas-square" slot="start" [style.color]="data.fillStyle" aria-hidden="true" />
8+
<ion-label>{{data.text}}</ion-label>
9+
</ion-item>
10+
}
11+
</ion-list>
12+
}
Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
1-
<ion-select *ngIf="interface !== 'modal'" class="ion-text-start" [(ngModel)]="selection" (ngModelChange)="onValueChanged(selection)"
2-
interface="popover" [disabled]="disabled" [class.combobox-icon-only]="icon"
3-
[interfaceOptions]="{alignment: 'start', arrow: false, cssClass: 'core-combobox-select'}">
4-
<div slot="label">
5-
<span class="sr-only" *ngIf="label">{{ label }}</span>
6-
<ion-icon *ngIf="icon" [name]="icon" aria-hidden="true" />
7-
</div>
1+
@if (interface !== 'modal') {
2+
<ion-select class="ion-text-start" [(ngModel)]="selection" (ngModelChange)="onValueChanged(selection)" interface="popover"
3+
[disabled]="disabled" [class.combobox-icon-only]="icon"
4+
[interfaceOptions]="{alignment: 'start', arrow: false, cssClass: 'core-combobox-select'}">
5+
<div slot="label">
6+
@if (label) {
7+
<span class="sr-only">{{ label }}</span>
8+
}
9+
@if (icon) {
10+
<ion-icon [name]="icon" aria-hidden="true" />
11+
}
12+
</div>
813

9-
<ng-content />
10-
</ion-select>
14+
<ng-content />
15+
</ion-select>
16+
} @else {
17+
<ion-button aria-haspopup="listbox" [attr.aria-controls]="listboxId" [attr.aria-owns]="listboxId" [attr.aria-expanded]="expanded"
18+
(click)="openModal()" [disabled]="disabled" expand="block" role="combobox">
19+
@if (icon) {
20+
<ion-icon [name]="icon" slot="start" aria-hidden="true" />
21+
}
1122

12-
<ion-button *ngIf="interface === 'modal'" aria-haspopup="listbox" [attr.aria-controls]="listboxId" [attr.aria-owns]="listboxId"
13-
[attr.aria-expanded]="expanded" (click)="openModal()" [disabled]="disabled" expand="block" role="combobox">
14-
<ion-icon *ngIf="icon" [name]="icon" slot="start" aria-hidden="true" />
23+
@if (label) {
24+
<span class="sr-only">{{ label }},</span>
25+
}
26+
<div class="select-text">
27+
<slot name="text"><core-format-text [text]="selection" /></slot>
28+
</div>
1529

16-
<span class="sr-only" *ngIf="label">{{ label }},</span>
17-
<div class="select-text">
18-
<slot name="text"><core-format-text [text]="selection" /></slot>
19-
</div>
20-
21-
<div class="select-icon" role="presentation" aria-hidden="true" slot="end">
22-
<div class="select-icon-inner"></div>
23-
</div>
24-
</ion-button>
30+
<div class="select-icon" role="presentation" aria-hidden="true" slot="end">
31+
<div class="select-icon-inner"></div>
32+
</div>
33+
</ion-button>
34+
}

src/core/components/context-menu/context-menu-item.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import { Component, Input, Output, OnInit, OnDestroy, EventEmitter, OnChanges, SimpleChange } from '@angular/core';
1616
import { CoreContextMenuComponent } from '../context-menu/context-menu';
1717
import { toBoolean } from '@/core/transforms/boolean';
18+
import { CoreUtils } from '@singletons/utils';
1819

1920
/**
2021
* This directive adds a item to the Context Menu popover.
@@ -58,6 +59,8 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange
5859
@Output() onClosed?: EventEmitter<() => void>; // Will emit an event when the popover is closed because the item was clicked.
5960
@Output() toggleChange = new EventEmitter<boolean>();// Will emit an event when toggle changes to enable 2-way data binding.
6061

62+
uniqueId = CoreUtils.getUniqueId('CoreContextMenuItem');
63+
6164
protected hasAction = false;
6265
protected destroyed = false;
6366

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,38 @@
11
<ion-content>
22
<ion-list [id]="uniqueId" role="menu">
3-
<ion-item class="ion-text-wrap" lines="none" *ngFor="let item of items" core-link [capture]="item.captureLink"
4-
[autoLogin]="item.autoLogin" [href]="item.href" (click)="itemClicked($event, item)" [attr.aria-label]="item.ariaAction"
5-
[hidden]="item.hidden" [detail]="!!(item.href && !item.iconAction)" role="menuitem" [button]="!!(item.href && !item.iconAction)"
6-
[showBrowserWarning]="item.showBrowserWarning">
7-
<ion-toggle *ngIf="item.iconAction === 'toggle'" [(ngModel)]="item.toggle" (ionChange)="item.toggleChanged($event)">
8-
<p class="item-heading">{{ item.content }}</p>
9-
</ion-toggle>
10-
<ng-container *ngIf="item.iconAction !== 'toggle'">
11-
<ion-label>
12-
<p class="item-heading">{{ item.content }}</p>
13-
</ion-label>
14-
<ng-container *ngIf="(item.href || item.action) && item.iconAction">
15-
<ion-icon *ngIf="item.iconAction !== 'spinner'" [name]="item.iconAction" [class.icon-slash]="item.iconSlash" slot="end"
16-
aria-hidden="true" />
17-
<ion-spinner *ngIf="item.iconAction === 'spinner'" slot="end" [attr.aria-label]="'core.loading' | translate" />
18-
</ng-container>
19-
</ng-container>
20-
<ion-badge class="{{item.badgeClass}}" slot="end" *ngIf="item.badge">
21-
<span [attr.ara-hidden]="!!item.badgeA11yText">{{item.badge}}</span>
22-
<span class="sr-only" *ngIf="item.badgeA11yText">
23-
{{ item.badgeA11yText | translate: {$a : item.badge } }}
24-
</span>
25-
</ion-badge>
26-
</ion-item>
3+
@for (item of items; track item.uniqueId) {
4+
<ion-item class="ion-text-wrap" lines="none" core-link [capture]="item.captureLink" [autoLogin]="item.autoLogin"
5+
[href]="item.href" (click)="itemClicked($event, item)" [attr.aria-label]="item.ariaAction" [hidden]="item.hidden"
6+
[detail]="!!(item.href && !item.iconAction)" role="menuitem" [button]="!!(item.href && !item.iconAction)"
7+
[showBrowserWarning]="item.showBrowserWarning">
8+
@if (item.iconAction === 'toggle') {
9+
<ion-toggle [(ngModel)]="item.toggle" (ionChange)="item.toggleChanged($event)">
10+
<p class="item-heading">{{ item.content }}</p>
11+
</ion-toggle>
12+
} @else {
13+
<ion-label>
14+
<p class="item-heading">{{ item.content }}</p>
15+
</ion-label>
16+
@if ((item.href || item.action) && item.iconAction) {
17+
@if (item.iconAction === 'spinner') {
18+
<ion-spinner slot="end" [attr.aria-label]="'core.loading' | translate" />
19+
} @else {
20+
<ion-icon [name]="item.iconAction" [class.icon-slash]="item.iconSlash" slot="end" aria-hidden="true" />
21+
}
22+
}
23+
}
24+
25+
@if (item.badge) {
26+
<ion-badge class="{{item.badgeClass}}" slot="end">
27+
<span [attr.ara-hidden]="!!item.badgeA11yText">{{item.badge}}</span>
28+
@if (item.badgeA11yText) {
29+
<span class="sr-only">
30+
{{ item.badgeA11yText | translate: {$a : item.badge } }}
31+
</span>
32+
}
33+
</ion-badge>
34+
}
35+
</ion-item>
36+
}
2737
</ion-list>
2838
</ion-content>
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
<ion-icon *ngIf="!course().courseimage" name="fas-graduation-cap" slot="start" aria-hidden="true" />
2-
<ion-avatar *ngIf="course().courseimage" slot="start">
3-
<img [url]="course().courseimage" core-external-content alt="" (error)="loadFallbackCourseIcon()" />
4-
</ion-avatar>
1+
@if (course().courseimage) {
2+
<ion-avatar slot="start">
3+
<img [url]="course().courseimage" core-external-content alt="" (error)="loadFallbackCourseIcon()" />
4+
</ion-avatar>
5+
} @else {
6+
<ion-icon name="fas-graduation-cap" slot="start" aria-hidden="true" />
7+
}
Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
1-
<ng-container *ngIf="enabled && !loading">
1+
@if (enabled && !loading) {
2+
23
<!-- Download button. -->
3-
<ion-button *ngIf="status === statusNotDownloaded" fill="clear" (click)="download($event, false)" @coreShowHideAnimation
4-
[ariaLabel]="(statusTranslatable || translates.notdownloaded) | translate: { name : statusSubject }">
5-
<ion-icon slot="icon-only" name="fas-cloud-arrow-down" aria-hidden="true" />
6-
</ion-button>
4+
@if (status === statusNotDownloaded) {
5+
<ion-button fill="clear" (click)="download($event, false)" @coreShowHideAnimation
6+
[ariaLabel]="(statusTranslatable || translates.notdownloaded) | translate: { name : statusSubject }">
7+
<ion-icon slot="icon-only" name="fas-cloud-arrow-down" aria-hidden="true" />
8+
</ion-button>
9+
}
710

811
<!-- Refresh button. -->
9-
<ion-button *ngIf="status === statusOutdated || (status === statusDownloaded && !canTrustDownload)" fill="clear"
10-
(click)="download($event, true)" @coreShowHideAnimation
11-
[ariaLabel]="(statusTranslatable || translates.outdated) | translate: { name : statusSubject }">
12-
<ion-icon slot="icon-only" name="fam-cloud-refresh" aria-hidden="true" />
13-
</ion-button>
12+
@if (status === statusOutdated || (status === statusDownloaded && !canTrustDownload)) {
13+
<ion-button fill="clear" (click)="download($event, true)" @coreShowHideAnimation
14+
[ariaLabel]="(statusTranslatable || translates.outdated) | translate: { name : statusSubject }">
15+
<ion-icon slot="icon-only" name="fam-cloud-refresh" aria-hidden="true" />
16+
</ion-button>
17+
}
1418

1519
<!-- Downloaded status icon. -->
16-
<ion-icon *ngIf="status === statusDownloaded && canTrustDownload" class="core-icon-downloaded ion-padding-horizontal" color="success"
17-
name="fam-cloud-done" [attr.aria-label]="(statusTranslatable || translates.downloaded) | translate: { name : statusSubject }"
18-
role="status" />
20+
@if (status === statusDownloaded && canTrustDownload) {
21+
<ion-icon class="core-icon-downloaded ion-padding-horizontal" color="success" name="fam-cloud-done"
22+
[attr.aria-label]="(statusTranslatable || translates.downloaded) | translate: { name : statusSubject }" role="status" />
23+
} @else if (status === statusDownloading) {
24+
<ion-spinner @coreShowHideAnimation
25+
[attr.aria-label]="(statusTranslatable || translates.downloading) | translate: { name : statusSubject }" />
26+
}
1927

20-
<ion-spinner *ngIf="status === statusDownloading" @coreShowHideAnimation
21-
[attr.aria-label]="(statusTranslatable || translates.downloading) | translate: { name : statusSubject }" />
22-
</ng-container>
28+
}
2329

2430
<!-- Spinner. -->
25-
<ion-spinner *ngIf="loading" @coreShowHideAnimation [attr.aria-label]="translates.loading | translate: { name : statusSubject }" />
31+
@if (loading) {
32+
<ion-spinner @coreShowHideAnimation [attr.aria-label]="translates.loading | translate: { name : statusSubject }" />
33+
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<!-- Content to display if no dynamic component. -->
2-
<ng-content *ngIf="!instance" />
2+
@if (!instance) {
3+
<ng-content />
4+
}
35

46
<!-- Container of the dynamic component -->
57
<ng-container #dynamicComponent />

0 commit comments

Comments
 (0)