(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">
No results found!
</mat-option>
<mat-option
class="group relative h-14 px-6 py-0 sm:px-8 text-md"
*ngFor="let result of results"
[routerLink]="result.link">
<ng-container
[ngTemplateOutlet]="searchResult"
[ngTemplateOutletContext]="{$implicit: result}"></ng-container>
</mat-option>
<ng-container *ngFor="let result of results">
<mat-option
class="group relative h-14 px-6 py-0 sm:px-8 text-md"
[routerLink]="result.link">
<ng-container
[ngTemplateOutlet]="searchResult"
[ngTemplateOutletContext]="{$implicit: result}"></ng-container>
</mat-option>
</ng-container>
</mat-autocomplete>
<button
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">
No results found!
</mat-option>
<mat-option
class="group relative h-14 px-5 py-0 text-md"
*ngFor="let result of results"
[routerLink]="result.link">
<ng-container
[ngTemplateOutlet]="searchResult"
[ngTemplateOutletContext]="{$implicit: result}"></ng-container>
</mat-option>
<ng-container *ngFor="let result of results">
<mat-option
class="group relative h-14 px-5 py-0 text-md"
[routerLink]="result.link">
<ng-container
[ngTemplateOutlet]="searchResult"
[ngTemplateOutletContext]="{$implicit: result}"></ng-container>
</mat-option>
</ng-container>
</mat-autocomplete>
</div>
</ng-container>

View File

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

View File

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

View File

@ -9,25 +9,25 @@
[svgIcon]="'heroicons_solid:plus-circle'"
(click)="addCalendar()"></mat-icon>
</div>
<div
class="group flex items-center justify-between mt-2"
*ngFor="let calendar of calendars">
<div
class="flex items-center"
(click)="toggleCalendarVisibility(calendar)">
<ng-container *ngFor="let calendar of calendars">
<div class="group flex items-center justify-between mt-2">
<div
class="flex items-center"
(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
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>
class="hidden group-hover:inline-flex icon-size-5 cursor-pointer"
[svgIcon]="'heroicons_solid:pencil-alt'"
(click)="openEditPanel(calendar)"></mat-icon>
</div>
<mat-icon
class="hidden group-hover:inline-flex icon-size-5 cursor-pointer"
[svgIcon]="'heroicons_solid:pencil-alt'"
(click)="openEditPanel(calendar)"></mat-icon>
</div>
</ng-container>
<!-- Settings -->
<div class="-mx-4 mt-auto">
@ -62,19 +62,20 @@
</mat-select-trigger>
<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">
<mat-option
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
*ngFor="let color of calendarColors"
[value]="color"
#matOption="matOption">
<mat-icon
class="absolute m-3 text-white"
*ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon>
<span
class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="color"></span>
</mat-option>
<ng-container *ngFor="let color of calendarColors">
<mat-option
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
[value]="color"
#matOption="matOption">
<mat-icon
class="absolute m-3 text-white"
*ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon>
<span
class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="color"></span>
</mat-option>
</ng-container>
</div>
</mat-select>
</mat-form-field>

View File

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

View File

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

View File

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

View File

@ -42,19 +42,20 @@
</mat-select-trigger>
<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">
<mat-option
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
*ngFor="let color of labelColors"
[value]="color"
#matOption="matOption">
<mat-icon
class="absolute m-3 text-white"
*ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon>
<span
class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="labelColorDefs[color].bg"></span>
</mat-option>
<ng-container *ngFor="let color of labelColors">
<mat-option
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
[value]="color"
#matOption="matOption">
<mat-icon
class="absolute m-3 text-white"
*ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon>
<span
class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="labelColorDefs[color].bg"></span>
</mat-option>
</ng-container>
</div>
</mat-select>
<button
@ -90,19 +91,20 @@
</mat-select-trigger>
<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">
<mat-option
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
*ngFor="let color of labelColors"
[value]="color"
#matOption="matOption">
<mat-icon
class="absolute m-3 text-white"
*ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon>
<span
class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="labelColorDefs[color].bg"></span>
</mat-option>
<ng-container *ngFor="let color of labelColors">
<mat-option
class="relative flex w-12 h-12 p-0 cursor-pointer rounded-full bg-transparent"
[value]="color"
#matOption="matOption">
<mat-icon
class="absolute m-3 text-white"
*ngIf="matOption.selected"
[svgIcon]="'heroicons_outline:check'"></mat-icon>
<span
class="flex w-10 h-10 m-1 rounded-full"
[ngClass]="labelColorDefs[color].bg"></span>
</mat-option>
</ng-container>
</div>
</mat-select>
<button

View File

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

View File

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