diff --git a/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.html b/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.html
index 97c9cca..4927f01 100644
--- a/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.html
+++ b/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.html
@@ -14,7 +14,7 @@
-
-
+
+
diff --git a/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.ts b/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.ts
index b9545be..62fa1d1 100644
--- a/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.ts
+++ b/src/app/checklist/checklist-cta-bar/checklist-cta-bar.component.ts
@@ -3,13 +3,14 @@ import { ChecklistFilter } from '../models/checklist.model';
import { MatIcon } from '@angular/material/icon';
import { MatButton } from '@angular/material/button';
import { NgIf } from '@angular/common';
+import { MatTooltip } from '@angular/material/tooltip';
@Component({
standalone: true,
selector: 'ac-checklist-cta-bar',
templateUrl: './checklist-cta-bar.component.html',
styleUrls: ['./checklist-cta-bar.component.scss'],
- imports: [NgIf, MatButton, MatIcon]
+ imports: [NgIf, MatButton, MatIcon, MatTooltip]
})
export class ChecklistCtaBarComponent {
@Input() filter: ChecklistFilter;
diff --git a/src/app/checklist/checklist-detail-view/checklist-detail-view.component.html b/src/app/checklist/checklist-detail-view/checklist-detail-view.component.html
index 9558052..1efcda3 100644
--- a/src/app/checklist/checklist-detail-view/checklist-detail-view.component.html
+++ b/src/app/checklist/checklist-detail-view/checklist-detail-view.component.html
@@ -1,4 +1,4 @@
-
+
Done
;
-
- constructor(private store: Store) {}
-
- ngOnInit() {
- this.item$ = this.store.pipe(select(ChecklistSelectors.getSelectedItem));
- }
+export class ChecklistDetailViewComponent {
+ private store = inject>(Store);
+ item = this.store.selectSignal(ChecklistSelectors.getSelectedItem);
toggleItem(item: ChecklistItem) {
this.store.dispatch(new ToggleItem(item));
diff --git a/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.html b/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.html
index f2017af..4c052de 100644
--- a/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.html
+++ b/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.html
@@ -1,9 +1,9 @@
-
+
-
+
{{ favorite.category.title }}
diff --git a/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.ts b/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.ts
index 7cf6ffe..55ec841 100644
--- a/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.ts
+++ b/src/app/checklist/checklist-favorites-view/checklist-favorites-view.component.ts
@@ -1,6 +1,5 @@
-import { Component, OnInit } from '@angular/core';
-import { select, Store } from '@ngrx/store';
-import { Observable } from 'rxjs';
+import { Component, inject } from '@angular/core';
+import { Store } from '@ngrx/store';
import { ToggleFavorite, ToggleItem } from '../../projects/state/projects.actions';
import { ApplicationState } from '../../state/app.state';
import { ChecklistFilter, ChecklistItem, Favorite } from '../models/checklist.model';
@@ -8,7 +7,7 @@ import { SetFavoritesFilter } from '../state/checklist.actions';
import { ChecklistSelectors } from '../state/checklist.selectors';
import { ChecklistListItemComponent } from '../checklist-list/checklist-list-item.component';
import { ChecklistListComponent } from '../checklist-list/checklist-list.component';
-import { NgIf, NgFor, AsyncPipe } from '@angular/common';
+import { NgIf, NgFor } from '@angular/common';
import { ChecklistCtaBarComponent } from '../checklist-cta-bar/checklist-cta-bar.component';
@Component({
@@ -16,18 +15,12 @@ import { ChecklistCtaBarComponent } from '../checklist-cta-bar/checklist-cta-bar
selector: 'ac-checklist-favorites-view',
templateUrl: './checklist-favorites-view.component.html',
styleUrls: ['./checklist-favorites-view.component.scss'],
- imports: [ChecklistCtaBarComponent, NgIf, NgFor, ChecklistListComponent, ChecklistListItemComponent, AsyncPipe]
+ imports: [ChecklistCtaBarComponent, NgIf, NgFor, ChecklistListComponent, ChecklistListItemComponent]
})
-export class ChecklistFavoritesViewComponent implements OnInit {
- favorites$: Observable>;
- filter$: Observable;
-
- constructor(private store: Store) {}
-
- ngOnInit() {
- this.favorites$ = this.store.pipe(select(ChecklistSelectors.getFilteredFavorites));
- this.filter$ = this.store.pipe(select(ChecklistSelectors.getFavoritesFilter));
- }
+export class ChecklistFavoritesViewComponent {
+ private store = inject>(Store);
+ favorites = this.store.selectSignal(ChecklistSelectors.getFilteredFavorites);
+ filter = this.store.selectSignal(ChecklistSelectors.getFavoritesFilter);
setFilter(filter: ChecklistFilter) {
this.store.dispatch(new SetFavoritesFilter(filter));
diff --git a/src/app/checklist/checklist-list-view/checklist-list-view.component.html b/src/app/checklist/checklist-list-view/checklist-list-view.component.html
index c18c5fd..3354863 100644
--- a/src/app/checklist/checklist-list-view/checklist-list-view.component.html
+++ b/src/app/checklist/checklist-list-view/checklist-list-view.component.html
@@ -1,6 +1,6 @@
;
- filter$: Observable;
- showActionButtons$: Observable;
-
- constructor(private store: Store, private breakpointService: BreakpointService) {}
-
- ngOnInit() {
- this.items$ = this.store.pipe(select(ChecklistSelectors.getItemsFromSelectedCategory));
- this.filter$ = this.store.pipe(select(ChecklistSelectors.getCategoriesFilter));
-
- const { medium$, desktop$ } = this.breakpointService.getAllBreakpoints();
- this.showActionButtons$ = combineLatest(medium$, desktop$, (medium, desktop) => medium || desktop);
- }
+export class ListViewComponent {
+ private store = inject>(Store);
+ private breakpointService = inject(BreakpointService);
+ items = this.store.selectSignal(ChecklistSelectors.getItemsFromSelectedCategory);
+ filter = this.store.selectSignal(ChecklistSelectors.getCategoriesFilter);
+ showActionButtons = computed(() => this.breakpointService.medium() || this.breakpointService.desktop());
toggleItem(item: ChecklistItem) {
this.store.dispatch(new ToggleItem(item));
@@ -44,11 +34,13 @@ export class ListViewComponent implements OnInit {
}
checkAllItems() {
- this.getSelectedCategory().subscribe(category => this.store.dispatch(new CheckAll(category)));
+ const categories = this.getSelectedCategory();
+ this.store.dispatch(new CheckAll(categories));
}
uncheckAllItems() {
- this.getSelectedCategory().subscribe(category => this.store.dispatch(new UncheckAll(category)));
+ const categories = this.getSelectedCategory();
+ this.store.dispatch(new UncheckAll(categories));
}
toggleFavorite(item: ChecklistItem) {
@@ -59,7 +51,7 @@ export class ListViewComponent implements OnInit {
return item.id;
}
- private getSelectedCategory(): Observable {
- return this.store.pipe(selectOnce(ChecklistSelectors.getSelectedCategory));
+ private get getSelectedCategory(): Signal {
+ return this.store.selectSignal(ChecklistSelectors.getSelectedCategory);
}
}
diff --git a/src/app/checklist/checklist-overview/checklist-overview.component.html b/src/app/checklist/checklist-overview/checklist-overview.component.html
index b7b9f1a..abb1122 100644
--- a/src/app/checklist/checklist-overview/checklist-overview.component.html
+++ b/src/app/checklist/checklist-overview/checklist-overview.component.html
@@ -1,4 +1,4 @@
-
+
- {{ item.title }}
- chevron_right
diff --git a/src/app/checklist/checklist-overview/checklist-overview.component.ts b/src/app/checklist/checklist-overview/checklist-overview.component.ts
index bb48c80..1e93e3c 100644
--- a/src/app/checklist/checklist-overview/checklist-overview.component.ts
+++ b/src/app/checklist/checklist-overview/checklist-overview.component.ts
@@ -1,23 +1,21 @@
import { animate, query, stagger, style, transition, trigger } from '@angular/animations';
-import { Component, OnInit } from '@angular/core';
+import { Component, effect, inject, untracked } from '@angular/core';
import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';
-import { select, Store } from '@ngrx/store';
-import { Observable, zip } from 'rxjs';
-import { filter, switchMap, tap } from 'rxjs/operators';
-import { selectOnce } from '../../shared/operators';
+import { Store } from '@ngrx/store';
import { extractRouteParams, getActivatedChild } from '../../shared/router.utils';
import { ApplicationState } from '../../state/app.state';
-import { Category, ChecklistItem } from '../models/checklist.model';
+import { BreadcrumbItem } from '../models/checklist.model';
import { ChecklistSelectors } from '../state/checklist.selectors';
import { MatIcon } from '@angular/material/icon';
-import { NgIf, NgFor, AsyncPipe } from '@angular/common';
+import { NgIf, NgFor } from '@angular/common';
+import { toSignal } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
selector: 'ac-checklist-overview',
templateUrl: './checklist-overview.component.html',
styleUrls: ['./checklist-overview.component.scss'],
- imports: [NgIf, NgFor, MatIcon, RouterOutlet, AsyncPipe],
+ imports: [NgIf, NgFor, MatIcon, RouterOutlet],
animations: [
trigger('breadcrumb', [
transition('* <=> *', [
@@ -50,36 +48,33 @@ import { NgIf, NgFor, AsyncPipe } from '@angular/common';
])
]
})
-export class ChecklistOverviewComponent implements OnInit {
- breadcrumb$: Observable;
+export class ChecklistOverviewComponent {
+ private store = inject>(Store);
+ private router = inject(Router);
+ private route = inject(ActivatedRoute);
+ breadcrumbs = this.store.selectSignal(ChecklistSelectors.getBreadcrumb);
- constructor(private store: Store, private router: Router, private route: ActivatedRoute) {}
+ constructor() {
+ const params = toSignal(this.route.params);
+ const categories = this.store.selectSignal(ChecklistSelectors.getActiveCategories);
+ const entities = this.store.selectSignal(ChecklistSelectors.getActiveCategoryEntities);
+ const editMode = this.store.selectSignal(ChecklistSelectors.getEditMode);
- ngOnInit() {
- this.breadcrumb$ = this.store.pipe(select(ChecklistSelectors.getBreadcrumb));
-
- this.route.params
- .pipe(
- switchMap(_ =>
- zip(
- this.store.pipe(selectOnce(ChecklistSelectors.getActiveCategoryEntities)),
- this.store.pipe(selectOnce(ChecklistSelectors.getActiveCategories)),
- this.store.pipe(selectOnce(ChecklistSelectors.getEditMode))
- )
- ),
- filter(([, categories]) => !!categories.length),
- tap(([entities, categories, editMode]) => {
+ effect(() => {
+ const _ = params();
+ untracked(() => {
+ if (categories().length) {
const { category } = extractRouteParams(this.route.snapshot, 1);
- const categoryDisabled = !category || !entities[category];
+ const categoryDisabled = !category || !entities()[category];
- if (categoryDisabled && !editMode) {
- this.router.navigate([categories[0].slug], {
+ if (categoryDisabled && !editMode()) {
+ this.router.navigate([categories()[0].slug], {
relativeTo: this.route
});
}
- })
- )
- .subscribe();
+ }
+ });
+ });
}
goBack(last: boolean) {
@@ -89,7 +84,7 @@ export class ChecklistOverviewComponent implements OnInit {
}
}
- trackByTitle(_, item: Category | ChecklistItem) {
+ trackByTitle(_, item: BreadcrumbItem) {
return item.title;
}
}
diff --git a/src/app/checklist/checklist-search/checklist-search.component.html b/src/app/checklist/checklist-search/checklist-search.component.html
index 393a310..5ae52bc 100644
--- a/src/app/checklist/checklist-search/checklist-search.component.html
+++ b/src/app/checklist/checklist-search/checklist-search.component.html
@@ -1,7 +1,7 @@
@@ -10,7 +10,7 @@
[displayWith]="getOptionText.bind(this)"
(optionSelected)="optionSelected($event)"
>
-
+
{{ result.document.category }}
diff --git a/src/app/checklist/checklist-search/checklist-search.component.ts b/src/app/checklist/checklist-search/checklist-search.component.ts
index b4c53fb..e68ce3d 100644
--- a/src/app/checklist/checklist-search/checklist-search.component.ts
+++ b/src/app/checklist/checklist-search/checklist-search.component.ts
@@ -1,47 +1,43 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, computed, inject, signal } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteSelectedEvent, MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete';
import { Router } from '@angular/router';
import * as fuzzysort from 'fuzzysort';
-import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
-import { debounceTime, map, switchMap } from 'rxjs/operators';
+import { debounceTime } from 'rxjs/operators';
import { CategoryEntity, ChecklistItem } from '../models/checklist.model';
import { IndexEntry, SearchResult } from '../search/search.models';
import { SearchService } from '../search/search.service';
import { MatOption } from '@angular/material/core';
-import { NgFor, NgIf, AsyncPipe } from '@angular/common';
+import { NgFor, NgIf } from '@angular/common';
+import { toSignal } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
selector: 'ac-checklist-search',
templateUrl: './checklist-search.component.html',
styleUrls: ['./checklist-search.component.scss'],
- imports: [ReactiveFormsModule, MatAutocompleteTrigger, MatAutocomplete, NgFor, MatOption, NgIf, AsyncPipe]
+ imports: [ReactiveFormsModule, MatAutocompleteTrigger, MatAutocomplete, NgFor, MatOption, NgIf]
})
-export class ChecklistSearchComponent implements OnInit {
- results$: Observable;
+export class ChecklistSearchComponent {
+ private searchService = inject(SearchService);
+ private router = inject(Router);
searchField = new FormControl('');
-
- focus$ = new BehaviorSubject('INIT');
-
- constructor(private searchService: SearchService, private router: Router) {}
-
- ngOnInit() {
- const search$ = this.searchField.valueChanges.pipe(debounceTime(150));
-
- this.results$ = combineLatest([this.focus$, search$]).pipe(
- map(([, term]) => term),
- switchMap(term => this.searchService.search(term)),
- map(results => results.map(this.mapToSearchResult))
- );
+ search = toSignal(this.searchField.valueChanges.pipe(debounceTime(150)));
+ focus = signal(0);
+
+ results = computed(() => {
+ const _ = this.focus();
+ const search = this.search();
+ const results = this.searchService.search(search);
+ return results.map(this.mapToSearchResult);
+ });
+
+ focused() {
+ this.focus.update(prev => prev + 1);
}
getOptionText(value: SearchResult) {
- if (!value) {
- return '';
- }
-
- return value.document.title;
+ return value?.document?.title || '';
}
optionSelected({ option }: MatAutocompleteSelectedEvent) {
diff --git a/src/app/checklist/checklist.component.html b/src/app/checklist/checklist.component.html
index 5938364..f9703b1 100644
--- a/src/app/checklist/checklist.component.html
+++ b/src/app/checklist/checklist.component.html
@@ -1,10 +1,10 @@
-
+
-
+
@@ -12,18 +12,18 @@
edit Manage Projects
-
+
-
+
-