(refactoring) Move *ngFor directives to their own <ng-container> elements. This is mostly a personal preference but it's a good habit to have as you cannot put more than one structural directive on a single element. This way our main repeated element is free of any common structural directives so we can use ours on them if needed.

This commit is contained in:
sercan 2021-05-07 12:10:45 +03:00
parent 7e430a269c
commit 2bea991ba3
11 changed files with 213 additions and 199 deletions

View File

@ -31,14 +31,15 @@
*ngIf="results && !results.length"> *ngIf="results && !results.length">
No results found! No results found!
</mat-option> </mat-option>
<mat-option <ng-container *ngFor="let result of results">
class="group relative h-14 px-6 py-0 sm:px-8 text-md" <mat-option
*ngFor="let result of results" class="group relative h-14 px-6 py-0 sm:px-8 text-md"
[routerLink]="result.link"> [routerLink]="result.link">
<ng-container <ng-container
[ngTemplateOutlet]="searchResult" [ngTemplateOutlet]="searchResult"
[ngTemplateOutletContext]="{$implicit: result}"></ng-container> [ngTemplateOutletContext]="{$implicit: result}"></ng-container>
</mat-option> </mat-option>
</ng-container>
</mat-autocomplete> </mat-autocomplete>
<button <button
class="absolute top-1/2 right-5 sm:right-7 flex-shrink-0 w-10 h-10 -mt-5" class="absolute top-1/2 right-5 sm:right-7 flex-shrink-0 w-10 h-10 -mt-5"
@ -72,14 +73,15 @@
*ngIf="results && !results.length"> *ngIf="results && !results.length">
No results found! No results found!
</mat-option> </mat-option>
<mat-option <ng-container *ngFor="let result of results">
class="group relative h-14 px-5 py-0 text-md" <mat-option
*ngFor="let result of results" class="group relative h-14 px-5 py-0 text-md"
[routerLink]="result.link"> [routerLink]="result.link">
<ng-container <ng-container
[ngTemplateOutlet]="searchResult" [ngTemplateOutlet]="searchResult"
[ngTemplateOutletContext]="{$implicit: result}"></ng-container> [ngTemplateOutletContext]="{$implicit: result}"></ng-container>
</mat-option> </mat-option>
</ng-container>
</mat-autocomplete> </mat-autocomplete>
</div> </div>
</ng-container> </ng-container>

View File

@ -319,16 +319,16 @@
[ngClass]="getCalendar(eventForm.get('calendarId').value)?.color"></span> [ngClass]="getCalendar(eventForm.get('calendarId').value)?.color"></span>
<span class="ml-3">{{getCalendar(eventForm.get('calendarId').value)?.title}}</span> <span class="ml-3">{{getCalendar(eventForm.get('calendarId').value)?.title}}</span>
</mat-select-trigger> </mat-select-trigger>
<mat-option <ng-container *ngFor="let calendar of calendars">
*ngFor="let calendar of calendars" <mat-option [value]="calendar.id">
[value]="calendar.id"> <div class="inline-flex items-center">
<div class="inline-flex items-center"> <span
<span class="w-3 h-3 rounded-full"
class="w-3 h-3 rounded-full" [ngClass]="calendar.color"></span>
[ngClass]="calendar.color"></span> <span class="ml-3">{{calendar.title}}</span>
<span class="ml-3">{{calendar.title}}</span> </div>
</div> </mat-option>
</mat-option> </ng-container>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -35,14 +35,15 @@
class="mt-1.5 border-0 space-x-1" class="mt-1.5 border-0 space-x-1"
[formControlName]="'byDay'" [formControlName]="'byDay'"
[multiple]="true"> [multiple]="true">
<mat-button-toggle <ng-container *ngFor="let weekday of weekdays">
class="w-10 h-10 border-0 rounded-full" <mat-button-toggle
*ngFor="let weekday of weekdays" class="w-10 h-10 border-0 rounded-full"
[disableRipple]="true" [disableRipple]="true"
[value]="weekday.value" [value]="weekday.value"
[matTooltip]="weekday.label"> [matTooltip]="weekday.label">
{{weekday.abbr}} {{weekday.abbr}}
</mat-button-toggle> </mat-button-toggle>
</ng-container>
</mat-button-toggle-group> </mat-button-toggle-group>
</div> </div>

View File

@ -9,25 +9,25 @@
[svgIcon]="'heroicons_solid:plus-circle'" [svgIcon]="'heroicons_solid:plus-circle'"
(click)="addCalendar()"></mat-icon> (click)="addCalendar()"></mat-icon>
</div> </div>
<div <ng-container *ngFor="let calendar of calendars">
class="group flex items-center justify-between mt-2" <div class="group flex items-center justify-between mt-2">
*ngFor="let calendar of calendars"> <div
<div class="flex items-center"
class="flex items-center" (click)="toggleCalendarVisibility(calendar)">
(click)="toggleCalendarVisibility(calendar)"> <mat-icon
class="cursor-pointer"
[svgIcon]="calendar.visible ? 'check_box' : 'check_box_outline_blank'"></mat-icon>
<span
class="w-3 h-3 ml-2 rounded-full"
[ngClass]="calendar.color"></span>
<span class="ml-2 leading-none">{{calendar.title}}</span>
</div>
<mat-icon <mat-icon
class="cursor-pointer" class="hidden group-hover:inline-flex icon-size-5 cursor-pointer"
[svgIcon]="calendar.visible ? 'check_box' : 'check_box_outline_blank'"></mat-icon> [svgIcon]="'heroicons_solid:pencil-alt'"
<span (click)="openEditPanel(calendar)"></mat-icon>
class="w-3 h-3 ml-2 rounded-full"
[ngClass]="calendar.color"></span>
<span class="ml-2 leading-none">{{calendar.title}}</span>
</div> </div>
<mat-icon </ng-container>
class="hidden group-hover:inline-flex icon-size-5 cursor-pointer"
[svgIcon]="'heroicons_solid:pencil-alt'"
(click)="openEditPanel(calendar)"></mat-icon>
</div>
<!-- Settings --> <!-- Settings -->
<div class="-mx-4 mt-auto"> <div class="-mx-4 mt-auto">
@ -62,19 +62,20 @@
</mat-select-trigger> </mat-select-trigger>
<div class="px-4 pt-5 text-xl font-semibold">Calendar color</div> <div class="px-4 pt-5 text-xl font-semibold">Calendar color</div>
<div class="flex flex-wrap w-48 my-4 mx-3 -mr-5"> <div class="flex flex-wrap w-48 my-4 mx-3 -mr-5">
<mat-option <ng-container *ngFor="let color of calendarColors">
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent" <mat-option
*ngFor="let color of calendarColors" class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
[value]="color" [value]="color"
#matOption="matOption"> #matOption="matOption">
<mat-icon <mat-icon
class="absolute m-3 text-white" class="absolute m-3 text-white"
*ngIf="matOption.selected" *ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon> [svgIcon]="'heroicons_outline:check'"></mat-icon>
<span <span
class="flex w-10 h-10 m-1 rounded-full" class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="color"></span> [ngClass]="color"></span>
</mat-option> </mat-option>
</ng-container>
</div> </div>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>

View File

@ -330,41 +330,42 @@
class="flex flex-col max-h-64 py-2 border-t overflow-y-auto"> class="flex flex-col max-h-64 py-2 border-t overflow-y-auto">
<!-- Tags --> <!-- Tags -->
<ng-container *ngIf="!tagsEditMode"> <ng-container *ngIf="!tagsEditMode">
<div <ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
*ngFor="let tag of filteredTags; trackBy: trackByFn" <div
class="flex items-center h-10 min-h-10 px-4 cursor-pointer hover:bg-hover" class="flex items-center h-10 min-h-10 px-4 cursor-pointer hover:bg-hover"
(click)="toggleContactTag(tag)" (click)="toggleContactTag(tag)"
matRipple> matRipple>
<mat-checkbox <mat-checkbox
class="flex items-center h-10 min-h-10 pointer-events-none" class="flex items-center h-10 min-h-10 pointer-events-none"
[checked]="contact.tags.includes(tag.id)" [checked]="contact.tags.includes(tag.id)"
[color]="'primary'" [color]="'primary'"
[disableRipple]="true"> [disableRipple]="true">
</mat-checkbox> </mat-checkbox>
<div class="ml-1">{{tag.title}}</div> <div class="ml-1">{{tag.title}}</div>
</div> </div>
</ng-container>
</ng-container> </ng-container>
<!-- Tags editing --> <!-- Tags editing -->
<ng-container *ngIf="tagsEditMode"> <ng-container *ngIf="tagsEditMode">
<div class="py-2 space-y-2"> <div class="py-2 space-y-2">
<div <ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
class="flex items-center" <div class="flex items-center">
*ngFor="let tag of filteredTags; trackBy: trackByFn"> <mat-form-field class="fuse-mat-dense fuse-mat-no-subscript w-full mx-4">
<mat-form-field class="fuse-mat-dense fuse-mat-no-subscript w-full mx-4"> <input
<input matInput
matInput [value]="tag.title"
[value]="tag.title" (input)="updateTagTitle(tag, $event)">
(input)="updateTagTitle(tag, $event)"> <button
<button mat-icon-button
mat-icon-button (click)="deleteTag(tag)"
(click)="deleteTag(tag)" matSuffix>
matSuffix> <mat-icon
<mat-icon class="icon-size-5 ml-2"
class="icon-size-5 ml-2" [svgIcon]="'heroicons_solid:trash'"></mat-icon>
[svgIcon]="'heroicons_solid:trash'"></mat-icon> </button>
</button> </mat-form-field>
</mat-form-field> </div>
</div> </ng-container>
</div> </div>
</ng-container> </ng-container>
<!-- Create tag --> <!-- Create tag -->
@ -496,19 +497,19 @@
<span class="sm:mx-0.5 font-medium text-default">{{getCountryByIso(phoneNumber.get('country').value).code}}</span> <span class="sm:mx-0.5 font-medium text-default">{{getCountryByIso(phoneNumber.get('country').value).code}}</span>
</span> </span>
</mat-select-trigger> </mat-select-trigger>
<mat-option <ng-container *ngFor="let country of countries; trackBy: trackByFn">
*ngFor="let country of countries; trackBy: trackByFn" <mat-option [value]="country.iso">
[value]="country.iso"> <span class="flex items-center">
<span class="flex items-center"> <span
<span class="w-6 h-4 overflow-hidden"
class="w-6 h-4 overflow-hidden" [style.background]="'url(\'/assets/images/apps/contacts/flags.png\') no-repeat 0 0'"
[style.background]="'url(\'/assets/images/apps/contacts/flags.png\') no-repeat 0 0'" [style.backgroundSize]="'24px 3876px'"
[style.backgroundSize]="'24px 3876px'" [style.backgroundPosition]="country.flagImagePos"></span>
[style.backgroundPosition]="country.flagImagePos"></span> <span class="ml-2">{{country.name}}</span>
<span class="ml-2">{{country.name}}</span> <span class="ml-2 font-medium">{{country.code}}</span>
<span class="ml-2 font-medium">{{country.code}}</span> </span>
</span> </mat-option>
</mat-option> </ng-container>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field class="fuse-mat-no-subscript flex-auto w-full max-w-24 sm:max-w-40 ml-2 sm:ml-4"> <mat-form-field class="fuse-mat-no-subscript flex-auto w-full max-w-24 sm:max-w-40 ml-2 sm:ml-4">

View File

@ -309,31 +309,31 @@
<mat-form-field class="w-1/3 pr-2"> <mat-form-field class="w-1/3 pr-2">
<mat-label>Category</mat-label> <mat-label>Category</mat-label>
<mat-select [formControlName]="'category'"> <mat-select [formControlName]="'category'">
<mat-option <ng-container *ngFor="let category of categories">
*ngFor="let category of categories" <mat-option [value]="category.id">
[value]="category.id"> {{category.name}}
{{category.name}} </mat-option>
</mat-option> </ng-container>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field class="w-1/3 px-2"> <mat-form-field class="w-1/3 px-2">
<mat-label>Brand</mat-label> <mat-label>Brand</mat-label>
<mat-select [formControlName]="'brand'"> <mat-select [formControlName]="'brand'">
<mat-option <ng-container *ngFor="let brand of brands">
*ngFor="let brand of brands" <mat-option [value]="brand.id">
[value]="brand.id"> {{brand.name}}
{{brand.name}} </mat-option>
</mat-option> </ng-container>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field class="w-1/3 pl-2"> <mat-form-field class="w-1/3 pl-2">
<mat-label>Vendor</mat-label> <mat-label>Vendor</mat-label>
<mat-select [formControlName]="'vendor'"> <mat-select [formControlName]="'vendor'">
<mat-option <ng-container *ngFor="let vendor of vendors">
*ngFor="let vendor of vendors" <mat-option [value]="vendor.id">
[value]="vendor.id"> {{vendor.name}}
{{vendor.name}} </mat-option>
</mat-option> </ng-container>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -18,12 +18,14 @@
<ng-container *ngFor="let faqCategory of faqCategories; trackBy: trackByFn"> <ng-container *ngFor="let faqCategory of faqCategories; trackBy: trackByFn">
<div class="mt-12 sm:mt-16 text-3xl font-bold leading-tight tracking-tight">{{faqCategory.title}}</div> <div class="mt-12 sm:mt-16 text-3xl font-bold leading-tight tracking-tight">{{faqCategory.title}}</div>
<mat-accordion class="max-w-4xl mt-8"> <mat-accordion class="max-w-4xl mt-8">
<mat-expansion-panel *ngFor="let faq of faqCategory.faqs; trackBy: trackByFn"> <ng-container *ngFor="let faq of faqCategory.faqs; trackBy: trackByFn">
<mat-expansion-panel-header [collapsedHeight]="'56px'"> <mat-expansion-panel>
<mat-panel-title class="font-medium leading-tight">{{faq.question}}</mat-panel-title> <mat-expansion-panel-header [collapsedHeight]="'56px'">
</mat-expansion-panel-header> <mat-panel-title class="font-medium leading-tight">{{faq.question}}</mat-panel-title>
{{faq.answer}} </mat-expansion-panel-header>
</mat-expansion-panel> {{faq.answer}}
</mat-expansion-panel>
</ng-container>
</mat-accordion> </mat-accordion>
</ng-container> </ng-container>
</div> </div>

View File

@ -93,12 +93,14 @@
<div class="mt-24 text-3xl sm:text-5xl font-extrabold leading-tight tracking-tight text-center">Most frequently asked questions</div> <div class="mt-24 text-3xl sm:text-5xl font-extrabold leading-tight tracking-tight text-center">Most frequently asked questions</div>
<div class="mt-2 text-xl text-center text-secondary">Here are the most frequently asked questions you may check before getting started</div> <div class="mt-2 text-xl text-center text-secondary">Here are the most frequently asked questions you may check before getting started</div>
<mat-accordion class="max-w-4xl mt-12"> <mat-accordion class="max-w-4xl mt-12">
<mat-expansion-panel *ngFor="let faq of faqCategory.faqs; trackBy: trackByFn"> <ng-container *ngFor="let faq of faqCategory.faqs; trackBy: trackByFn">
<mat-expansion-panel-header [collapsedHeight]="'56px'"> <mat-expansion-panel>
<mat-panel-title>{{faq.question}}</mat-panel-title> <mat-expansion-panel-header [collapsedHeight]="'56px'">
</mat-expansion-panel-header> <mat-panel-title>{{faq.question}}</mat-panel-title>
{{faq.answer}} </mat-expansion-panel-header>
</mat-expansion-panel> {{faq.answer}}
</mat-expansion-panel>
</ng-container>
</mat-accordion> </mat-accordion>
</div> </div>
</div> </div>

View File

@ -42,19 +42,20 @@
</mat-select-trigger> </mat-select-trigger>
<div class="px-4 pt-5 text-xl font-semibold">Label color</div> <div class="px-4 pt-5 text-xl font-semibold">Label color</div>
<div class="flex flex-wrap w-48 my-4 mx-3 -mr-5"> <div class="flex flex-wrap w-48 my-4 mx-3 -mr-5">
<mat-option <ng-container *ngFor="let color of labelColors">
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent" <mat-option
*ngFor="let color of labelColors" class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
[value]="color" [value]="color"
#matOption="matOption"> #matOption="matOption">
<mat-icon <mat-icon
class="absolute m-3 text-white" class="absolute m-3 text-white"
*ngIf="matOption.selected" *ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon> [svgIcon]="'heroicons_outline:check'"></mat-icon>
<span <span
class="flex w-10 h-10 m-1 rounded-full" class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="labelColorDefs[color].bg"></span> [ngClass]="labelColorDefs[color].bg"></span>
</mat-option> </mat-option>
</ng-container>
</div> </div>
</mat-select> </mat-select>
<button <button
@ -90,19 +91,20 @@
</mat-select-trigger> </mat-select-trigger>
<div class="px-4 pt-5 text-xl font-semibold">Label color</div> <div class="px-4 pt-5 text-xl font-semibold">Label color</div>
<div class="flex flex-wrap w-48 my-4 mx-3 -mr-5"> <div class="flex flex-wrap w-48 my-4 mx-3 -mr-5">
<mat-option <ng-container *ngFor="let color of labelColors">
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent" <mat-option
*ngFor="let color of labelColors" class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
[value]="color" [value]="color"
#matOption="matOption"> #matOption="matOption">
<mat-icon <mat-icon
class="absolute m-3 text-white" class="absolute m-3 text-white"
*ngIf="matOption.selected" *ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon> [svgIcon]="'heroicons_outline:check'"></mat-icon>
<span <span
class="flex w-10 h-10 m-1 rounded-full" class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="labelColorDefs[color].bg"></span> [ngClass]="labelColorDefs[color].bg"></span>
</mat-option> </mat-option>
</ng-container>
</div> </div>
</mat-select> </mat-select>
<button <button

View File

@ -142,40 +142,41 @@
class="flex flex-col max-h-64 py-2 border-t overflow-y-auto"> class="flex flex-col max-h-64 py-2 border-t overflow-y-auto">
<!-- Tags --> <!-- Tags -->
<ng-container *ngIf="!tagsEditMode"> <ng-container *ngIf="!tagsEditMode">
<div <ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
*ngFor="let tag of filteredTags; trackBy: trackByFn" <div
class="flex items-center h-10 min-h-10 px-4 cursor-pointer hover:bg-hover" class="flex items-center h-10 min-h-10 px-4 cursor-pointer hover:bg-hover"
(click)="toggleTaskTag(tag)" (click)="toggleTaskTag(tag)"
matRipple> matRipple>
<mat-checkbox <mat-checkbox
class="flex items-center h-10 min-h-10" class="flex items-center h-10 min-h-10"
[color]="'primary'" [color]="'primary'"
[checked]="task.tags.includes(tag.id)"> [checked]="task.tags.includes(tag.id)">
</mat-checkbox> </mat-checkbox>
<div class="ml-1">{{tag.title}}</div> <div class="ml-1">{{tag.title}}</div>
</div> </div>
</ng-container>
</ng-container> </ng-container>
<!-- Tags editing --> <!-- Tags editing -->
<ng-container *ngIf="tagsEditMode"> <ng-container *ngIf="tagsEditMode">
<div class="py-2 space-y-2"> <div class="py-2 space-y-2">
<div <ng-container *ngFor="let tag of filteredTags; trackBy: trackByFn">
class="flex items-center" <div class="flex items-center">
*ngFor="let tag of filteredTags; trackBy: trackByFn"> <mat-form-field class="fuse-mat-dense fuse-mat-no-subscript w-full mx-4">
<mat-form-field class="fuse-mat-dense fuse-mat-no-subscript w-full mx-4"> <input
<input matInput
matInput [value]="tag.title"
[value]="tag.title" (input)="updateTagTitle(tag, $event)">
(input)="updateTagTitle(tag, $event)"> <button
<button mat-icon-button
mat-icon-button (click)="deleteTag(tag)"
(click)="deleteTag(tag)" matSuffix>
matSuffix> <mat-icon
<mat-icon class="icon-size-5 ml-2"
class="icon-size-5 ml-2" [svgIcon]="'heroicons_solid:trash'"></mat-icon>
[svgIcon]="'heroicons_solid:trash'"></mat-icon> </button>
</button> </mat-form-field>
</mat-form-field> </div>
</div> </ng-container>
</div> </div>
</ng-container> </ng-container>
<!-- Create tag --> <!-- Create tag -->

View File

@ -25,14 +25,16 @@
<div class="font-semibold text-md text-secondary ml-4">{{item.releaseDate}}</div> <div class="font-semibold text-md text-secondary ml-4">{{item.releaseDate}}</div>
</div> </div>
<hr class="mt-6"> <hr class="mt-6">
<div <ng-container *ngFor="let change of item.changes">
class="mt-8" <div class="mt-8">
*ngFor="let change of item.changes"> <span class="inline-flex bg-default rounded px-3 py-1 text-secondary font-bold">{{change.type}}</span>
<span class="inline-flex bg-default rounded px-3 py-1 text-secondary font-bold">{{change.type}}</span> <ul>
<ul> <ng-container *ngFor="let listItem of change.list">
<li *ngFor="let listItem of change.list">{{listItem}}</li> <li>{{listItem}}</li>
</ul> </ng-container>
</div> </ul>
</div>
</ng-container>
</div> </div>
</ng-container> </ng-container>
</div> </div>