Fix: When you would select all after selecting mat-select, it would give an error

This commit is contained in:
2026-08-29 20:27:50 +00:00
parent 15288b270a
commit 09b11e7e79
4 changed files with 30 additions and 35 deletions
@@ -16,16 +16,16 @@
<div class="row-container"> <div class="row-container">
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-select [formField]="form.period"> <mat-select [formField]="form.period">
@for (p of periods(); track p.id) { @for (p of periods(); track p) {
<mat-option [value]="p"> {{ p.validFrom }} to {{ p.validTill }} </mat-option> <mat-option [value]="p.id"> {{ p.validFrom }} to {{ p.validTill }} </mat-option>
} }
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field class="flex-auto"> <mat-form-field class="flex-auto">
<mat-label>Product Type</mat-label> <mat-label>Product Type</mat-label>
<mat-select [formField]="form.productGroup" (selectionChange)="filterProductGroup($event.value)"> <mat-select [formField]="form.productGroup" (selectionChange)="filterProductGroup($event.value)">
<mat-option>-- All Products --</mat-option> <mat-option [value]="null">-- All Products --</mat-option>
@for (mc of productGroups(); track mc.id) { @for (mc of productGroups(); track mc) {
<mat-option [value]="mc.id"> <mat-option [value]="mc.id">
{{ mc.name }} {{ mc.name }}
</mat-option> </mat-option>
@@ -1,4 +1,4 @@
import { Component, inject, input, computed, effect, signal } from '@angular/core'; import { Component, inject, input, computed, effect, signal, linkedSignal } from '@angular/core';
import { form as createForm, FormField, FormRoot } from '@angular/forms/signals'; import { form as createForm, FormField, FormRoot } from '@angular/forms/signals';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatOptionModule } from '@angular/material/core'; import { MatOptionModule } from '@angular/material/core';
@@ -11,7 +11,6 @@ import { MatSortModule, Sort } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table'; import { MatTableModule } from '@angular/material/table';
import { Router, RouterModule } from '@angular/router'; import { Router, RouterModule } from '@angular/router';
import { ProductGroup } from '../../core/product-group';
import { Period } from '../../period/period'; import { Period } from '../../period/period';
import { PeriodService } from '../../period/period.service'; import { PeriodService } from '../../period/period.service';
import { ProductGroupService } from '../../product-group/product-group.service'; import { ProductGroupService } from '../../product-group/product-group.service';
@@ -19,6 +18,10 @@ import { ErrorStateComponent } from '../../shared/error-state/error-state.compon
import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component'; import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component';
import { RecipeService } from '../recipe.service'; import { RecipeService } from '../recipe.service';
export interface RecipeListFormData {
period: string | null;
productGroup: string | null;
}
@Component({ @Component({
selector: 'app-recipe-list', selector: 'app-recipe-list',
templateUrl: './recipe-list.component.html', templateUrl: './recipe-list.component.html',
@@ -52,31 +55,34 @@ export class RecipeListComponent {
sortActive = signal(''); sortActive = signal('');
sortDirection = signal(''); sortDirection = signal('');
p = input<string>(); p = input('', { transform: (v: string | null | undefined) => v ?? null });
model = signal({
period: null as Period | null,
productGroup: null as ProductGroup | string | null,
});
form = createForm(this.model);
periodsResource = this.periodSer.list(); periodsResource = this.periodSer.list();
periods = computed(() => this.periodsResource.value() ?? []); periods = computed(() => this.periodsResource.value() ?? []);
model = linkedSignal<string | null, RecipeListFormData>({
source: () => this.p(),
computation: (period) => ({
period: period,
productGroup: null,
}),
});
form = createForm(this.model);
productGroupsResource = this.productGroupSer.list(); productGroupsResource = this.productGroupSer.list();
productGroups = computed(() => this.productGroupsResource.value() ?? []); productGroups = computed(() => this.productGroupsResource.value() ?? []);
periodFilter = computed(() => this.p() || ''); resource = this.ser.list(this.p);
resource = this.ser.list(this.periodFilter); productGroupFilter = computed(() => this.model().productGroup ?? null);
info = computed(() => this.resource.value() ?? []); info = computed(() => this.resource.value() ?? []);
sortedList = computed(() => { sortedList = computed(() => {
let data = this.info() ?? []; let data = this.info() ?? [];
const pg = this.model().productGroup; const pg = this.productGroupFilter();
if (pg) { if (pg) {
const pgId = typeof pg === 'string' ? pg : pg.id; data = data.filter((r) => r.productGroupId === pg);
data = data.filter((r) => r.productGroupId === pgId);
} }
const active = this.sortActive(); const active = this.sortActive();
@@ -118,18 +124,13 @@ export class RecipeListComponent {
const x = this.model().period; const x = this.model().period;
if (!x) return; if (!x) return;
this.router.navigate([], { this.router.navigate([], {
queryParams: { p: x.id }, queryParams: { p: x },
replaceUrl: true, replaceUrl: true,
queryParamsHandling: 'merge', queryParamsHandling: 'merge',
}); });
this.period = x;
}); });
} }
filterProductGroup(val: string) {
this.model.update((m) => ({ ...m, productGroup: val }));
}
handlePageEvent(e: PageEvent) { handlePageEvent(e: PageEvent) {
this.pageSize.set(e.pageSize); this.pageSize.set(e.pageSize);
this.pageIndex.set(e.pageIndex); this.pageIndex.set(e.pageIndex);
@@ -8,7 +8,7 @@
<mat-form-field class="flex-auto basis-30"> <mat-form-field class="flex-auto basis-30">
<mat-label>Product Group</mat-label> <mat-label>Product Group</mat-label>
<mat-select [formField]="form.productGroup"> <mat-select [formField]="form.productGroup">
<mat-option>-- All Products --</mat-option> <mat-option [value]="null">-- All Products --</mat-option>
@for (pg of productGroups(); track pg) { @for (pg of productGroups(); track pg) {
<mat-option [value]="pg.id"> <mat-option [value]="pg.id">
{{ pg.name }} {{ pg.name }}
@@ -9,7 +9,6 @@ import { MatSelectModule } from '@angular/material/select';
import { MatTableModule } from '@angular/material/table'; import { MatTableModule } from '@angular/material/table';
import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { Product, StockKeepingUnit } from '../../core/product';
import { ProductGroupService } from '../../product-group/product-group.service'; import { ProductGroupService } from '../../product-group/product-group.service';
import { ErrorStateComponent } from '../../shared/error-state/error-state.component'; import { ErrorStateComponent } from '../../shared/error-state/error-state.component';
import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component'; import { SkeletonLoaderComponent } from '../../shared/skeleton-loader/skeleton-loader.component';
@@ -18,7 +17,7 @@ import { TemporalProductService } from '../temporal-product.service';
export interface TemporalProductListFormData { export interface TemporalProductListFormData {
filter: string; filter: string;
productGroup: Product | StockKeepingUnit | string | null; productGroup: string | null;
} }
@Component({ @Component({
@@ -66,16 +65,11 @@ export class TemporalProductListComponent {
form = createForm(this.formModel); form = createForm(this.formModel);
filterSignal = computed(() => this.formModel().filter); filterSignal = computed(() => this.formModel().filter);
debouncedFilter = debounced(this.filterSignal, 150); debouncedFilter = debounced(this.filterSignal, 150);
productGroupFilter = computed(() => this.formModel().productGroup ?? null);
filteredList = computed(() => { filteredList = computed(() => {
const data = this.list(); const data = this.list();
const search = this.debouncedFilter.value() ?? ''; const search = this.debouncedFilter.value() ?? '';
const productGroup = this.formModel().productGroup; const productGroup = this.productGroupFilter();
const groupId =
typeof productGroup === 'string'
? productGroup
: productGroup && 'id' in productGroup
? (productGroup.id ?? '')
: '';
const tokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean); const tokens = search.trim().toLowerCase().split(/\s+/).filter(Boolean);
@@ -97,7 +91,7 @@ export class TemporalProductListComponent {
}), }),
); );
const matchesProductGroup = !groupId || products.some((k) => (k.productGroup?.id ?? '') === groupId); const matchesProductGroup = !productGroup || products.some((k) => k.productGroup?.id === productGroup);
return matchesSearch && matchesProductGroup; return matchesSearch && matchesProductGroup;
}); });
}); });