Skip to content

Commit

Permalink
Migrate to new Angular control flow tools
Browse files Browse the repository at this point in the history
This used the built-in `ng generate @angular/core:control-flow` to migrate to using the new control flow tools.

I also fixed a couple of oddities that I noticed when I ran this on the iteration template.
  • Loading branch information
NicMcPhee committed Feb 5, 2024
1 parent 9ddefc3 commit cbac7bb
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 68 deletions.
36 changes: 22 additions & 14 deletions client/src/app/users/user-card.component.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
<mat-card appearance="outlined" class="user-card" *ngIf="this.user">
<mat-card-header>
<img mat-card-avatar [src]="this.user.avatar" alt="Avatar for {{this.user.name}}" class="user-avatar" *ngIf="this.user.avatar">
<mat-card-title class="user-card-name">{{ this.user.name }}</mat-card-title>
<mat-card-subtitle class="user-card-company">{{ this.user.company }}</mat-card-subtitle>
</mat-card-header>
<mat-card-content *ngIf="!this.simple">
<p>Role: <span class="user-card-role">{{ this.user.role }}</span></p>
<p>Age: <span class="user-card-age">{{ this.user.age }}</span></p>
<p>Email: <a href="mailto:{{this.user.email}}" class="user-card-email">{{this.user.email}}</a></p>
</mat-card-content>
<mat-card-actions>
<button mat-button data-test="viewProfileButton" *ngIf="this.simple" [routerLink]="['/users', this.user._id]">View Profile</button>
</mat-card-actions>
@if (this.user) {
<mat-card appearance="outlined" class="user-card">
<mat-card-header>
@if (this.user.avatar) {
<img mat-card-avatar [src]="this.user.avatar" alt="Avatar for {{this.user.name}}" class="user-avatar">
}
<mat-card-title class="user-card-name">{{ this.user.name }}</mat-card-title>
<mat-card-subtitle class="user-card-company">{{ this.user.company }}</mat-card-subtitle>
</mat-card-header>
@if (!this.simple) {
<mat-card-content>
<p>Role: <span class="user-card-role">{{ this.user.role }}</span></p>
<p>Age: <span class="user-card-age">{{ this.user.age }}</span></p>
<p>Email: <a href="mailto:{{this.user.email}}" class="user-card-email">{{this.user.email}}</a></p>
</mat-card-content>
}
@if (this.simple) {
<mat-card-actions>
<button mat-button data-test="viewProfileButton" [routerLink]="['/users', this.user._id]">View Profile</button>
</mat-card-actions>
}
</mat-card>
}
4 changes: 2 additions & 2 deletions client/src/app/users/user-card.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { User } from './user';
import { RouterLink } from '@angular/router';
import { MatButton } from '@angular/material/button';
import { MatCard, MatCardHeader, MatCardAvatar, MatCardTitle, MatCardSubtitle, MatCardContent, MatCardActions } from '@angular/material/card';
import { NgIf } from '@angular/common';


@Component({
selector: 'app-user-card',
templateUrl: './user-card.component.html',
styleUrls: ['./user-card.component.scss'],
standalone: true,
imports: [NgIf, MatCard, MatCardHeader, MatCardAvatar, MatCardTitle, MatCardSubtitle, MatCardContent, MatCardActions, MatButton, RouterLink]
imports: [MatCard, MatCardHeader, MatCardAvatar, MatCardTitle, MatCardSubtitle, MatCardContent, MatCardActions, MatButton, RouterLink]
})
export class UserCardComponent {

Expand Down
110 changes: 60 additions & 50 deletions client/src/app/users/user-list.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
<mat-form-field class="input-field">
<mat-label>Name</mat-label>
<input matInput data-test="userNameInput" placeholder="Filter by name"
[(ngModel)]="userName" (input)="updateFilter()">
[(ngModel)]="userName" (input)="updateFilter()">
<mat-hint>Filtered on client</mat-hint>
</mat-form-field>

<mat-form-field class="input-field">
<mat-label>Company</mat-label>
<input matInput data-test="userCompanyInput" placeholder="Filter by company"
[(ngModel)]="userCompany" (input)="updateFilter()">
[(ngModel)]="userCompany" (input)="updateFilter()">
<mat-hint>Filtered on client</mat-hint>
</mat-form-field>
</div>
Expand All @@ -29,7 +29,7 @@
<mat-form-field class="input-field">
<mat-label>Age</mat-label>
<input matInput data-test="userAgeInput" type="number" placeholder="Filter by age"
min="0" max="200" [(ngModel)]="userAge" (input)="getUsersFromServer()">
min="0" max="200" [(ngModel)]="userAge" (input)="getUsersFromServer()">
<mat-hint>Filtered on server</mat-hint>
</mat-form-field>

Expand All @@ -46,57 +46,67 @@
</div>

<br>
<div class="flex-row gap-10 flex-wrap">
<label for="viewType">View type: </label>
<mat-radio-group aria-label="View type" [(ngModel)]="viewType" data-test="viewTypeRadio">
<mat-radio-button value="card">Card</mat-radio-button>
<mat-radio-button value="list">List</mat-radio-button>
</mat-radio-group>
</div>

</mat-card-content>
</mat-card>
</div>
</div>

<div class="flex-row">
<div class="flex-1" fxFlex.gt-sm="80" fxFlexOffset.gt-sm="10" *ngIf="serverFilteredUsers; else usersError" >
<!-- Switch between card and list view based on the viewType variable, set above in the mar-radio-group -->
<div [ngSwitch]="viewType">

<!-- Card grid view -->
<div *ngSwitchCase="'card'" class="user-cards-container flex-row gap-10 flex-wrap">
<app-user-card [simple]="true" *ngFor="let user of filteredUsers" class="user-card" [user]="user" fxFlex="1 1 280px"></app-user-card>
</div>
<div class="flex-row gap-10 flex-wrap">
<label for="viewType">View type: </label>
<mat-radio-group aria-label="View type" [(ngModel)]="viewType" data-test="viewTypeRadio">
<mat-radio-button value="card">Card</mat-radio-button>
<mat-radio-button value="list">List</mat-radio-button>
</mat-radio-group>
</div>

<!-- List view -->
<mat-card appearance="outlined" *ngSwitchCase="'list'">
<mat-card-content>
<mat-nav-list class="user-nav-list">
<h3 mat-subheader>Users</h3>
<a mat-list-item *ngFor="let user of this.filteredUsers" [routerLink]="['/users', user._id]" class="user-list-item">
<img matListItemAvatar [src]="user.avatar" alt="Avatar for {{ user.name }}" *ngIf="this.user.avatar">
<span matListItemTitle mat-line class="user-list-name"> {{user.name}} </span>
<span matListItemLine class="user-list-role"> {{user.role}} </span>
</a>
</mat-nav-list>
</mat-card-content>
</mat-card>

</div>
</div>

<!-- Maybe this should be a pop-up instead of just a text message? Not sure. -->
<ng-template #usersError>
<div class="flex-1" fxFlex.gt-sm="80" fxFlexOffset.gt-sm="10" class="user-error">
<mat-error>
There was a problem loading the users. Possibly the server is down or perhaps there are network
issues.
</mat-error>
<mat-error>
Please wait a bit and try again or start the server.
</mat-error>
</div>
</ng-template>
<div class="flex-row">
@if (serverFilteredUsers) {
<div class="flex-1" fxFlex.gt-sm="80" fxFlexOffset.gt-sm="10" >
<!-- Switch between card and list view based on the viewType variable, set above in the mar-radio-group -->
<div>
@switch (viewType) {
<!-- Card grid view -->
@case ('card') {
<div class="user-cards-container flex-row gap-10 flex-wrap">
@for (user of filteredUsers; track user._id) {
<app-user-card [simple]="true" class="user-card" [user]="user" fxFlex="1 1 280px"></app-user-card>
}
</div>
}
<!-- List view -->
@case ('list') {
<mat-card appearance="outlined">
<mat-card-content>
<mat-nav-list class="user-nav-list">
<h3 mat-subheader>Users</h3>
@for (user of this.filteredUsers; track user._id) {
<a mat-list-item [routerLink]="['/users', user._id]" class="user-list-item">
@if (this.user.avatar) {
<img matListItemAvatar [src]="user.avatar" alt="Avatar for {{ user.name }}">
}
<span matListItemTitle mat-line class="user-list-name"> {{user.name}} </span>
<span matListItemLine class="user-list-role"> {{user.role}} </span>
</a>
}
</mat-nav-list>
</mat-card-content>
</mat-card>
}
}
</div>
</div>
} @else {
<div class="flex-1" fxFlex.gt-sm="80" fxFlexOffset.gt-sm="10" class="user-error">
<mat-error>
There was a problem loading the users. Possibly the server is down or perhaps there are network
issues.
</mat-error>
<mat-error>
Please wait a bit and try again or start the server.
</mat-error>
</div>
}

<!-- Maybe this should be a pop-up instead of just a text message? Not sure. -->

</div>
</div>
4 changes: 2 additions & 2 deletions client/src/app/users/user-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Subject, takeUntil } from 'rxjs';
import { RouterLink } from '@angular/router';
import { MatNavList, MatListSubheaderCssMatStyler, MatListItem, MatListItemAvatar, MatListItemTitle, MatListItemLine } from '@angular/material/list';
import { UserCardComponent } from './user-card.component';
import { NgIf, NgSwitch, NgSwitchCase, NgFor } from '@angular/common';

import { MatRadioGroup, MatRadioButton } from '@angular/material/radio';
import { MatOption } from '@angular/material/core';
import { MatSelect } from '@angular/material/select';
Expand All @@ -31,7 +31,7 @@ import { MatCard, MatCardTitle, MatCardContent } from '@angular/material/card';
styleUrls: ['./user-list.component.scss'],
providers: [],
standalone: true,
imports: [MatCard, MatCardTitle, MatCardContent, MatFormField, MatLabel, MatInput, FormsModule, MatHint, MatSelect, MatOption, MatRadioGroup, MatRadioButton, NgIf, NgSwitch, NgSwitchCase, NgFor, UserCardComponent, MatNavList, MatListSubheaderCssMatStyler, MatListItem, RouterLink, MatListItemAvatar, MatListItemTitle, MatListItemLine, MatError]
imports: [MatCard, MatCardTitle, MatCardContent, MatFormField, MatLabel, MatInput, FormsModule, MatHint, MatSelect, MatOption, MatRadioGroup, MatRadioButton, UserCardComponent, MatNavList, MatListSubheaderCssMatStyler, MatListItem, RouterLink, MatListItemAvatar, MatListItemTitle, MatListItemLine, MatError]
})
export class UserListComponent implements OnInit {
// These are public so that tests can reference them (.spec.ts)
Expand Down

0 comments on commit cbac7bb

Please sign in to comment.