diff --git a/.prettierrc b/.prettierrc index 8d3dfb0..789f4dd 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,5 +4,7 @@ "useTabs": false, "tabWidth": 2, "semi": true, - "bracketSpacing": true + "bracketSpacing": true, + "arrowParens": "avoid", + "trailingComma": "none" } diff --git a/package.json b/package.json index 58210ab..eb81a97 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "lint-staged": "^8.1.0", "markdown-it": "^12.2.0", "nodemon": "^1.18.7", - "prettier": "^1.15.2", + "prettier": "^3.3.1", "shorthash": "^0.0.2", "ts-loader": "^5.3.1", "ts-node": "~8.3.0", diff --git a/src/app/app.component.html b/src/app/app.component.html index e3c4080..36397f5 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,2 +1,4 @@ - +@if (loading$ | async) { + +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 4829d2a..75a0290 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -3,7 +3,7 @@ import { NavigationEnd, NavigationStart, Router, RouterOutlet } from '@angular/r import { merge, Observable } from 'rxjs'; import { filter, mapTo } from 'rxjs/operators'; import { MatProgressBar } from '@angular/material/progress-bar'; -import { AsyncPipe, NgIf } from '@angular/common'; +import { AsyncPipe } from '@angular/common'; @Component({ standalone: true, @@ -11,7 +11,7 @@ import { AsyncPipe, NgIf } from '@angular/common'; templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - imports: [RouterOutlet, AsyncPipe, NgIf, MatProgressBar] + imports: [RouterOutlet, AsyncPipe, MatProgressBar] }) export class AppComponent implements OnInit { loading$: Observable; 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..b3f8acd 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 @@ -1,5 +1,6 @@
-
+ @if (filter) { +
-
- - + } @if (showActionButtons) { +
+ +
+ }
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..c0df2d6 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 @@ -2,14 +2,14 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; 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: [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..d80fb98 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,14 +1,13 @@ - -
- Done - - -
- - This practice includes outdated content currently under review. Contributions are welcome. - -
-
+@if (item(); as item) { +
+ Done + + +
+@if (item.rework) { + + This practice includes outdated content currently under review. Contributions are welcome. + +} +
+} diff --git a/src/app/checklist/checklist-detail-view/checklist-detail-view.component.ts b/src/app/checklist/checklist-detail-view/checklist-detail-view.component.ts index 9f276ff..2c9717d 100644 --- a/src/app/checklist/checklist-detail-view/checklist-detail-view.component.ts +++ b/src/app/checklist/checklist-detail-view/checklist-detail-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 { ChecklistItem } from '../models/checklist.model'; @@ -9,23 +8,17 @@ import { BannerComponent } from '../../shared/banner/banner.component'; import { ChecklistMetadataComponent } from '../checklist-item-metadata/checklist-metadata.component'; import { ChecklistFavoriteButtonComponent } from '../checklist-favorite-button/checklist-favorite-button.component'; import { MatCheckbox } from '@angular/material/checkbox'; -import { NgIf, AsyncPipe } from '@angular/common'; @Component({ standalone: true, selector: 'ac-checklist-detail-view', templateUrl: './checklist-detail-view.component.html', styleUrls: ['./checklist-detail-view.component.scss'], - imports: [NgIf, MatCheckbox, ChecklistFavoriteButtonComponent, ChecklistMetadataComponent, BannerComponent, AsyncPipe] + imports: [MatCheckbox, ChecklistFavoriteButtonComponent, ChecklistMetadataComponent, BannerComponent] }) -export class ChecklistDetailViewComponent implements OnInit { - item$: Observable; - - 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..cf48938 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,27 +1,21 @@
Favorites
- + - - -
    -

    {{ favorite.category.title }}

    - - - - -
-
- -
- No Data - You have no favorites yet... but they are only a few clicks away! -
-
-
+@for (favorite of favorites(); track favorite.category.title) { +
    +

    {{ favorite.category.title }}

    + + @for (item of favorite.items; track item.id) { + + + } + +
+} @empty { +
+ No Data + You have no favorites yet... but they are only a few clicks away! +
+} 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..655efa8 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,6 @@ 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 { ChecklistCtaBarComponent } from '../checklist-cta-bar/checklist-cta-bar.component'; @Component({ @@ -16,18 +14,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, 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)); @@ -40,12 +32,4 @@ export class ChecklistFavoritesViewComponent implements OnInit { toggleFavorite(item: ChecklistItem) { this.store.dispatch(new ToggleFavorite(item)); } - - trackByCategoryTitle(_, favorite: Favorite) { - return favorite.category.title; - } - - trackById(_, item: ChecklistItem) { - return item.id; - } } diff --git a/src/app/checklist/checklist-item-metadata/checklist-metadata.component.html b/src/app/checklist/checklist-item-metadata/checklist-metadata.component.html index d20af15..3432509 100644 --- a/src/app/checklist/checklist-item-metadata/checklist-metadata.component.html +++ b/src/app/checklist/checklist-item-metadata/checklist-metadata.component.html @@ -1,2 +1,5 @@ -{{ author.name }} -Source +@if (author) { +{{ author.name }} +} @if (source) { +Source +} diff --git a/src/app/checklist/checklist-item-metadata/checklist-metadata.component.ts b/src/app/checklist/checklist-item-metadata/checklist-metadata.component.ts index 75cad18..3e199d7 100644 --- a/src/app/checklist/checklist-item-metadata/checklist-metadata.component.ts +++ b/src/app/checklist/checklist-item-metadata/checklist-metadata.component.ts @@ -1,13 +1,11 @@ import { Component, Input } from '@angular/core'; import { Author } from '../models/checklist.model'; -import { NgIf } from '@angular/common'; @Component({ standalone: true, selector: 'ac-checklist-metadata', templateUrl: './checklist-metadata.component.html', - styleUrls: ['./checklist-metadata.component.scss'], - imports: [NgIf] + styleUrls: ['./checklist-metadata.component.scss'] }) export class ChecklistMetadataComponent { @Input() author: Author; 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..b17d00c 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 @@ - + @for (item of items(); track item.id) { + + } diff --git a/src/app/checklist/checklist-list-view/checklist-list-view.component.ts b/src/app/checklist/checklist-list-view/checklist-list-view.component.ts index a227e70..dcb361b 100644 --- a/src/app/checklist/checklist-list-view/checklist-list-view.component.ts +++ b/src/app/checklist/checklist-list-view/checklist-list-view.component.ts @@ -1,15 +1,12 @@ -import { Component, OnInit } from '@angular/core'; -import { select, Store } from '@ngrx/store'; -import { combineLatest, Observable } from 'rxjs'; +import { Component, Signal, computed, inject } from '@angular/core'; +import { Store } from '@ngrx/store'; import { CheckAll, ToggleFavorite, ToggleItem, UncheckAll } from '../../projects/state/projects.actions'; import { BreakpointService } from '../../shared/breakpoint.service'; -import { selectOnce } from '../../shared/operators'; import { ApplicationState } from '../../state/app.state'; import { CategoryEntity, ChecklistFilter, ChecklistItem } from '../models/checklist.model'; import { SetCategoriesFilter } from '../state/checklist.actions'; import { ChecklistSelectors } from '../state/checklist.selectors'; import { ChecklistListItemComponent } from '../checklist-list/checklist-list-item.component'; -import { NgFor, AsyncPipe } from '@angular/common'; import { ChecklistListComponent } from '../checklist-list/checklist-list.component'; import { ChecklistCtaBarComponent } from '../checklist-cta-bar/checklist-cta-bar.component'; @@ -18,22 +15,14 @@ import { ChecklistCtaBarComponent } from '../checklist-cta-bar/checklist-cta-bar selector: 'ac-list-view', templateUrl: './checklist-list-view.component.html', styleUrls: ['./checklist-list-view.component.scss'], - imports: [ChecklistCtaBarComponent, ChecklistListComponent, NgFor, ChecklistListItemComponent, AsyncPipe] + imports: [ChecklistCtaBarComponent, ChecklistListComponent, ChecklistListItemComponent] }) -export class ListViewComponent implements OnInit { - items$: Observable; - 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,22 +33,20 @@ 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) { this.store.dispatch(new ToggleFavorite(item)); } - trackById(_, item: ChecklistItem) { - 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-list/checklist-list-item.component.html b/src/app/checklist/checklist-list/checklist-list-item.component.html index 41c4449..0cc1ef4 100644 --- a/src/app/checklist/checklist-list/checklist-list-item.component.html +++ b/src/app/checklist/checklist-list/checklist-list-item.component.html @@ -1,6 +1,8 @@ {{ item.title }} -needs rework +@if (item.rework) { +needs rework +} - - - - +@if (breadcrumbs(); as breadcrumb) { + +} diff --git a/src/app/checklist/checklist-overview/checklist-overview.component.ts b/src/app/checklist/checklist-overview/checklist-overview.component.ts index bb48c80..63f2a70 100644 --- a/src/app/checklist/checklist-overview/checklist-overview.component.ts +++ b/src/app/checklist/checklist-overview/checklist-overview.component.ts @@ -1,23 +1,20 @@ 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 { 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: [MatIcon, RouterOutlet], animations: [ trigger('breadcrumb', [ transition('* <=> *', [ @@ -50,36 +47,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 +83,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..e5d8a18 100644 --- a/src/app/checklist/checklist-search/checklist-search.component.html +++ b/src/app/checklist/checklist-search/checklist-search.component.html @@ -1,17 +1,15 @@ - + - - {{ result.document.category }} + @for (result of results(); track result) { + + @if (result.document.category) { + {{ 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..de8fe92 100644 --- a/src/app/checklist/checklist-search/checklist-search.component.ts +++ b/src/app/checklist/checklist-search/checklist-search.component.ts @@ -1,47 +1,36 @@ -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 { 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, MatOption] }) -export class ChecklistSearchComponent implements OnInit { - results$: Observable; +export class ChecklistSearchComponent { + private searchService = inject(SearchService); + private router = inject(Router); searchField = new FormControl(''); + search = toSignal(this.searchField.valueChanges.pipe(debounceTime(150))); - 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)) - ); - } + results = computed(() => { + const search = this.search(); + const results = this.searchService.search(search); + return results.map(this.mapToSearchResult); + }); 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..11bf7d0 100644 --- a/src/app/checklist/checklist.component.html +++ b/src/app/checklist/checklist.component.html @@ -1,10 +1,10 @@ - + - + @@ -12,18 +12,20 @@ edit Manage Projects - + @if (mediumUp()) { + + } - +
-
🧐 Ups, seems like you're in edit mode!
+ @if (editMode()) { +
🧐 Ups, seems like you're in edit mode!
+ }
diff --git a/src/app/checklist/checklist.component.ts b/src/app/checklist/checklist.component.ts index a4c5948..2bae513 100644 --- a/src/app/checklist/checklist.component.ts +++ b/src/app/checklist/checklist.component.ts @@ -1,15 +1,13 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, Signal, computed, inject, signal } from '@angular/core'; import { MatSidenav, MatDrawerMode, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav'; import { MatDialog } from '@angular/material/dialog'; import { Router, RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router'; -import { select, Store } from '@ngrx/store'; -import { BehaviorSubject, combineLatest, Observable, of, zip } from 'rxjs'; -import { filter, map, switchMap } from 'rxjs/operators'; -import { Project } from '../projects/models/projects.model'; +import { Store } from '@ngrx/store'; +import { of } from 'rxjs'; +import { tap } from 'rxjs/operators'; import { ToggleAllFavorites, ToggleCategory } from '../projects/state/projects.actions'; import { ProjectsSelectors } from '../projects/state/projects.selectors'; import { BreakpointService } from '../shared/breakpoint.service'; -import { selectOnce } from '../shared/operators'; import { hasEntities } from '../shared/utils'; import { ApplicationState } from '../state/app.state'; import { ConfirmationDialogComponent } from './confirmation-dialog/confirmation-dialog.component'; @@ -22,7 +20,6 @@ import { MatSlideToggle } from '@angular/material/slide-toggle'; import { MatBadge } from '@angular/material/badge'; import { ScoreChartComponent } from '../shared/score-chart/score-chart.component'; import { ChecklistSearchComponent } from './checklist-search/checklist-search.component'; -import { NgIf, NgFor, AsyncPipe } from '@angular/common'; import { DropdownStaticOptionsComponent, DropdownStaticOptionComponent @@ -53,7 +50,6 @@ enum CategoryListMode { DropdownStaticOptionsComponent, DropdownStaticOptionComponent, RouterLink, - NgIf, ChecklistSearchComponent, MatSidenavContainer, MatSidenav, @@ -61,118 +57,69 @@ enum CategoryListMode { RouterLinkActive, MatBadge, MatSlideToggle, - NgFor, MatCheckbox, MatSidenavContent, RouterOutlet, - FooterComponent, - AsyncPipe + FooterComponent ], providers: [SearchService] }) -export class ChecklistComponent implements OnInit { - private editMode$ = new BehaviorSubject(CategoryListMode.List); - - small$: Observable; - mediumUp$: Observable; - desktop$: Observable; - - categories$: Observable>; - projects$: Observable>; - selectedProjectId$: Observable; - favoritesCount$: Observable; - favoritesScore$: Observable; - overallScore$: Observable; - - editMode = false; - - sideNavMode: MatDrawerMode = 'side'; - - @ViewChild(MatSidenav, { static: true }) - sideNav: MatSidenav; - - constructor( - private store: Store, - private breakpointService: BreakpointService, - private dialog: MatDialog, - private router: Router - ) {} - - ngOnInit() { - this.categories$ = this.editMode$.pipe(switchMap(mode => this.getCategories(mode))); - this.projects$ = this.store.pipe(select(ProjectsSelectors.getProjects)); - this.selectedProjectId$ = this.store.pipe(select(ProjectsSelectors.getSelectedProjectId)); - this.favoritesCount$ = this.store.pipe(select(ChecklistSelectors.getFavoritesCount)); - this.favoritesScore$ = this.store.pipe(select(ChecklistSelectors.getFavoritesScore)); - - const { small$, medium$, desktop$ } = this.breakpointService.getAllBreakpoints(); - - this.small$ = small$; - this.desktop$ = desktop$; - this.mediumUp$ = combineLatest([medium$, desktop$]).pipe(map(([medium, desktop]) => medium || desktop)); - - desktop$.subscribe(matches => { - if (!matches) { - this.sideNav.close(); - this.setSidenavMode('over'); - } else { - this.sideNav.open(); - this.setSidenavMode('side'); - } - }); - } - - toggleCategory(category: Category) { - this.store - .pipe( - selectOnce(ChecklistSelectors.getFavoriteEntitiesByCategory(category.slug)), - switchMap((favorites: Array) => { - if (hasEntities(favorites) && category.enabled) { - return this.openUserPrompt(favorites); - } - - return of(true); - }), - filter(remove => remove) - ) - .subscribe(() => this.store.dispatch(new ToggleCategory(category.slug))); +export class ChecklistComponent { + private store = inject>(Store); + private breakpointService = inject(BreakpointService); + private dialog = inject(MatDialog); + private router = inject(Router); + + small = this.breakpointService.small; + medium = this.breakpointService.medium; + desktop = this.breakpointService.desktop; + mediumUp = computed(() => this.medium() || this.desktop()); + + projects = this.store.selectSignal(ProjectsSelectors.getProjects); + selectedProjectId = this.store.selectSignal(ProjectsSelectors.getSelectedProjectId); + favoritesCount = this.store.selectSignal(ChecklistSelectors.getFavoritesCount); + favoritesScore = this.store.selectSignal(ChecklistSelectors.getFavoritesScore); + private activeCategories = this.store.selectSignal(ChecklistSelectors.getActiveCategories); + private allCategories = this.store.selectSignal(ChecklistSelectors.getAllCategories); + + categories = computed(() => { + const mode = this.editMode() ? CategoryListMode.Edit : CategoryListMode.List; + const categories = mode ? this.allCategories : this.activeCategories; + return categories(); + }); + + editMode = signal(false); + + sideNavMode = computed(() => (this.mediumUp() ? 'side' : 'over')); + + toggleCategory(category: Category): any { + const selector = ChecklistSelectors.getFavoriteEntitiesByCategory(category.slug); + const favorites = this.store.selectSignal(selector)() as ChecklistItem[]; + let observe = of(true); + if (hasEntities(favorites) && category.enabled) { + observe = this.openUserPrompt(favorites); + } + observe.subscribe(valid => valid && this.store.dispatch(new ToggleCategory(category.slug))); } toggleEditMode() { - this.editMode = !this.editMode; + const editMode = !this.editMode(); + this.editMode.set(editMode); this.store.dispatch(new ToggleEditMode()); - this.editMode$.next(this.editMode ? CategoryListMode.Edit : CategoryListMode.List); - - of(this.editMode) - .pipe( - filter(editMode => !editMode), - switchMap(_ => this.store.pipe(selectOnce(ChecklistSelectors.getSelectedCategory))), - filter(category => !!category), - filter(category => !category.enabled), - switchMap(_ => - zip( - this.store.pipe(selectOnce(ChecklistSelectors.getActiveCategories)), - this.store.pipe(selectOnce(ProjectsSelectors.getSelectedProjectId)) - ) - ) - ) - .subscribe(([categories, projectId]) => { + if (!editMode) { + const category = this.store.selectSignal(ChecklistSelectors.getSelectedCategory)(); + if (category && !category.enabled) { + const categories = this.activeCategories(); + const projectId = this.selectedProjectId(); this.router.navigate(['/', projectId, 'checklist', categories[0].slug]); - }); + } + } } navigateToProject(project: string) { this.router.navigate([`/${project}/checklist`]); } - trackBySlug(_, category: Category) { - return category.slug; - } - - trackById(_, item: ChecklistItem) { - return item.id; - } - private openUserPrompt(favorites: Array) { const dialogRef = this.dialog.open(ConfirmationDialogComponent, { data: { @@ -182,28 +129,14 @@ export class ChecklistComponent implements OnInit { } }); - return dialogRef.afterClosed().pipe(switchMap(result => this.processDialogResult(result, favorites))); + return dialogRef.afterClosed().pipe( + tap(result => this.processDialogResult(result, favorites)) + ); } private processDialogResult(result: boolean, favorites: Array) { if (result) { this.store.dispatch(new ToggleAllFavorites(favorites)); } - - return of(result); - } - - private getCategories(mode: CategoryListMode) { - let categories$ = this.store.pipe(select(ChecklistSelectors.getActiveCategories)); - - if (mode === CategoryListMode.Edit) { - categories$ = this.store.pipe(select(ChecklistSelectors.getAllCategories)); - } - - return categories$; - } - - private setSidenavMode(mode: 'side' | 'over') { - this.sideNavMode = mode; } } diff --git a/src/app/checklist/confirmation-dialog/confirmation-dialog.component.ts b/src/app/checklist/confirmation-dialog/confirmation-dialog.component.ts index 5d2b9e6..93a6a79 100644 --- a/src/app/checklist/confirmation-dialog/confirmation-dialog.component.ts +++ b/src/app/checklist/confirmation-dialog/confirmation-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, Inject, OnInit } from '@angular/core'; +import { Component, HostBinding, inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogTitle, @@ -15,15 +15,14 @@ import { MatButton } from '@angular/material/button'; styleUrls: ['./confirmation-dialog.component.scss'], imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatButton, MatDialogClose] }) -export class ConfirmationDialogComponent implements OnInit { - @HostBinding('style.maxWidth') - width = '350px'; +export class ConfirmationDialogComponent { + public data = inject(MAT_DIALOG_DATA); - confirmationButtonColor = 'warn'; + @HostBinding('style.maxWidth') width = '350px'; - constructor(@Inject(MAT_DIALOG_DATA) public data: any) {} + confirmationButtonColor = 'warn'; - ngOnInit() { + constructor() { const { width, confirmationButtonColor } = this.data; if (width) { diff --git a/src/app/checklist/project-exists.guard.ts b/src/app/checklist/project-exists.guard.ts index 945b3df..dfd782d 100644 --- a/src/app/checklist/project-exists.guard.ts +++ b/src/app/checklist/project-exists.guard.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { ActivatedRouteSnapshot, Router } from '@angular/router'; import { select, Store } from '@ngrx/store'; import { of } from 'rxjs'; @@ -11,7 +11,8 @@ import { ApplicationState } from '../state/app.state'; providedIn: 'root' }) export class ProjectExistsGuard { - constructor(private store: Store, private router: Router) {} + private store = inject>(Store); + private router = inject(Router); canActivate(snapshot: ActivatedRouteSnapshot) { const projectId = snapshot.params.project; diff --git a/src/app/checklist/search/search.service.ts b/src/app/checklist/search/search.service.ts index 125de99..6de83be 100644 --- a/src/app/checklist/search/search.service.ts +++ b/src/app/checklist/search/search.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { ActionsSubject, select, Store } from '@ngrx/store'; import * as fuzzysort from 'fuzzysort'; import { merge, of, zip } from 'rxjs'; @@ -13,6 +13,8 @@ import { IndexEntry } from './search.models'; @Injectable() export class SearchService { + private store = inject>(Store); + private actions = inject(ActionsSubject); private index: Array>; private options: Fuzzysort.KeyOptions = { @@ -22,7 +24,7 @@ export class SearchService { threshold: -10000 }; - constructor(private store: Store, private actions: ActionsSubject) { + constructor() { const actions$ = this.actions.pipe(filter(action => action.type === ProjectsActionTypes.TOGGLE_CATEGORY)); merge(actions$, of('INIT INDEX')) @@ -33,7 +35,7 @@ export class SearchService { } search(term: string) { - return of(fuzzysort.go(term, this.index, this.options)); + return fuzzysort.go(term, this.index, this.options); } createIndex(categoryEntities: CategoryEntities, itemEntities: ItemEntities, projectId: string) { diff --git a/src/app/checklist/state/checklist.selectors.ts b/src/app/checklist/state/checklist.selectors.ts index cb1bd70..df76e3f 100644 --- a/src/app/checklist/state/checklist.selectors.ts +++ b/src/app/checklist/state/checklist.selectors.ts @@ -163,7 +163,7 @@ export namespace ChecklistSelectors { }); return acc; - }, []); + }, [] as { category: CategoryEntity; items: ChecklistItem[] }[]); } ); diff --git a/src/app/projects/project-dialog/project-dialog.component.html b/src/app/projects/project-dialog/project-dialog.component.html index fa63d29..777275a 100644 --- a/src/app/projects/project-dialog/project-dialog.component.html +++ b/src/app/projects/project-dialog/project-dialog.component.html @@ -14,11 +14,15 @@

type="text" /> {{ projectName.value?.length || 0 }}/{{ maxLength }} - Project already exists - + @if (projectName.hasError('projectExists')) { + Project already exists + } @if (projectName.pending) { + + }

-
+ @if (isEditMode()) { +

DANGER ZONE

  • @@ -36,6 +40,7 @@

    DANGER ZONE

+ } diff --git a/src/app/projects/project-dialog/project-dialog.component.ts b/src/app/projects/project-dialog/project-dialog.component.ts index 9fe535c..ac2764a 100644 --- a/src/app/projects/project-dialog/project-dialog.component.ts +++ b/src/app/projects/project-dialog/project-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { FormControl, Validators, ReactiveFormsModule } from '@angular/forms'; import { ErrorStateMatcher } from '@angular/material/core'; import { @@ -19,7 +19,6 @@ import { Project } from '../models/projects.model'; import { ProjectsSelectors } from '../state/projects.selectors'; import { MatButton } from '@angular/material/button'; import { MatProgressSpinner } from '@angular/material/progress-spinner'; -import { NgIf } from '@angular/common'; import { MatInput } from '@angular/material/input'; import { MatFormField, MatHint, MatError, MatSuffix } from '@angular/material/form-field'; @@ -82,7 +81,6 @@ const verifyProjectName = (projectName: string) => { MatInput, ReactiveFormsModule, MatHint, - NgIf, MatError, MatProgressSpinner, MatSuffix, @@ -91,7 +89,10 @@ const verifyProjectName = (projectName: string) => { MatDialogClose ] }) -export class ProjectDialogComponent implements OnInit { +export class ProjectDialogComponent { + public data = inject(MAT_DIALOG_DATA); + private store = inject>(Store); + public dialogRef = inject>(MatDialogRef); mode: ProjectDialogMode; title: string; project: Partial; @@ -104,13 +105,7 @@ export class ProjectDialogComponent implements OnInit { verifyProjectName = new FormControl(''); errorStateMatcher = new CustomErrorStateMatcher(); - constructor( - @Inject(MAT_DIALOG_DATA) public data: ProjectDialogData, - private store: Store, - public dialogRef: MatDialogRef - ) {} - - ngOnInit() { + constructor() { const { title, project, mode = ProjectDialogMode.Create, submitButtonText } = this.data; this.project = project ? project : { name: '' }; diff --git a/src/app/projects/projects-view/projects-view.component.html b/src/app/projects/projects-view/projects-view.component.html index 660e65f..6b54d17 100644 --- a/src/app/projects/projects-view/projects-view.component.html +++ b/src/app/projects/projects-view/projects-view.component.html @@ -18,7 +18,8 @@
Your Projects
add Add Project - + @for (project of projects(); track project.id) { +

{{ project.name }}

@@ -33,6 +34,7 @@

{{ project.name }}

+ }
diff --git a/src/app/projects/projects-view/projects-view.component.ts b/src/app/projects/projects-view/projects-view.component.ts index 5a07954..d6561c2 100644 --- a/src/app/projects/projects-view/projects-view.component.ts +++ b/src/app/projects/projects-view/projects-view.component.ts @@ -1,8 +1,8 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; -import { select, Store } from '@ngrx/store'; -import { asyncScheduler, Observable } from 'rxjs'; +import { Store } from '@ngrx/store'; +import { asyncScheduler } from 'rxjs'; import { filter, map, observeOn } from 'rxjs/operators'; import { ApplicationState } from '../../state/app.state'; import { Project } from '../models/projects.model'; @@ -18,7 +18,7 @@ import { import { AddProject, DeleteProject, EditProject } from '../state/projects.actions'; import { ProjectsSelectors } from '../state/projects.selectors'; import { MatIconButton } from '@angular/material/button'; -import { NgFor, AsyncPipe, PercentPipe } from '@angular/common'; +import { PercentPipe } from '@angular/common'; import { MatIcon } from '@angular/material/icon'; import { MatRipple } from '@angular/material/core'; import { MatCard, MatCardContent, MatCardActions } from '@angular/material/card'; @@ -36,11 +36,9 @@ import { FooterComponent } from 'src/app/shared/footer/footer.component'; MatCard, MatRipple, MatIcon, - NgFor, MatCardContent, MatCardActions, MatIconButton, - AsyncPipe, PercentPipe, ToolbarComponent, ToolbarLogoComponent, @@ -48,14 +46,11 @@ import { FooterComponent } from 'src/app/shared/footer/footer.component'; FooterComponent ] }) -export class ProjectsViewComponent implements OnInit { - projects$: Observable>; - - constructor(private store: Store, private router: Router, private dialog: MatDialog) {} - - ngOnInit() { - this.projects$ = this.store.pipe(select(ProjectsSelectors.getProjects)); - } +export class ProjectsViewComponent { + private store = inject>(Store); + private router = inject(Router); + private dialog = inject(MatDialog); + projects = this.store.selectSignal(ProjectsSelectors.getProjects); navigateToProject(projectId: string) { this.router.navigate([`/${projectId}/checklist`]); diff --git a/src/app/shared/breakpoint.service.ts b/src/app/shared/breakpoint.service.ts index 663a21c..28e84f9 100644 --- a/src/app/shared/breakpoint.service.ts +++ b/src/app/shared/breakpoint.service.ts @@ -1,31 +1,32 @@ -import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout'; -import { Injectable } from '@angular/core'; -import { map, shareReplay } from 'rxjs/operators'; -import { Observable } from 'rxjs'; +import { BreakpointObserver } from '@angular/cdk/layout'; +import { Injectable, inject } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { map } from 'rxjs/operators'; export enum Breakpoint { - Small = 'small$', - Medium = 'medium$', - Desktop = 'desktop$' + Small = 'small', + Medium = 'medium', + Desktop = 'desktop' } @Injectable({ providedIn: 'root' }) export class BreakpointService { - private _small$: Observable; - private _medium$: Observable; - private _desktop$: Observable; + private breakPointObserver = inject(BreakpointObserver); + readonly small = toSignal(this.breakpoint('(max-width: 600px)')); + readonly medium = toSignal(this.breakpoint('(min-width: 600px) and (max-width: 992px)')); + readonly desktop = toSignal(this.breakpoint('(min-width: 992px)')); - constructor(private breakPointObserver: BreakpointObserver) { - this.setupBreakpoints(); + private breakpoint(query: string) { + return this.breakPointObserver.observe([query]).pipe(map(breakPoint => breakPoint.matches)); } getAllBreakpoints() { return { - [Breakpoint.Small]: this._small$, - [Breakpoint.Medium]: this._medium$, - [Breakpoint.Desktop]: this._desktop$ + [Breakpoint.Small]: this.small, + [Breakpoint.Medium]: this.medium, + [Breakpoint.Desktop]: this.desktop }; } @@ -33,25 +34,4 @@ export class BreakpointService { const breakpoints = this.getAllBreakpoints(); return breakpoints[breakpoint]; } - - private setupBreakpoints() { - const small$ = this.breakPointObserver.observe(['(max-width: 600px)']).pipe( - map(breakPoint => breakPoint.matches), - shareReplay(1) - ); - - const medium$ = this.breakPointObserver.observe(['(min-width: 600px) and (max-width: 992px)']).pipe( - map(breakPoint => breakPoint.matches), - shareReplay(1) - ); - - const desktop$ = this.breakPointObserver.observe(['(min-width: 992px)']).pipe( - map(breakPoint => breakPoint.matches), - shareReplay(1) - ); - - this._small$ = small$; - this._medium$ = medium$; - this._desktop$ = desktop$; - } } diff --git a/src/app/shared/dropdown/dropdown-static-options.component.ts b/src/app/shared/dropdown/dropdown-static-options.component.ts index ffe9334..c2c16e9 100644 --- a/src/app/shared/dropdown/dropdown-static-options.component.ts +++ b/src/app/shared/dropdown/dropdown-static-options.component.ts @@ -3,9 +3,7 @@ import { Component } from '@angular/core'; @Component({ standalone: true, selector: 'ac-dropdown-static-options', - template: ` - - `, + template: ` `, styleUrls: ['./dropdown-static-options.component.scss'] }) export class DropdownStaticOptionsComponent {} @@ -13,9 +11,7 @@ export class DropdownStaticOptionsComponent {} @Component({ standalone: true, selector: 'ac-dropdown-static-option', - template: ` - - `, + template: ` `, styleUrls: ['./dropdown-static-option.component.scss'] }) export class DropdownStaticOptionComponent {} diff --git a/src/app/shared/dropdown/dropdown.component.html b/src/app/shared/dropdown/dropdown.component.html index 94f2e97..613268e 100644 --- a/src/app/shared/dropdown/dropdown.component.html +++ b/src/app/shared/dropdown/dropdown.component.html @@ -1,4 +1,5 @@ - +@if (items) { + - {{ item[bindLabel] }} + @for (item of items; track item[bindValue]) { + {{ item[bindLabel] }} + } +} diff --git a/src/app/shared/dropdown/dropdown.component.scss b/src/app/shared/dropdown/dropdown.component.scss index 23a2313..1eb8642 100644 --- a/src/app/shared/dropdown/dropdown.component.scss +++ b/src/app/shared/dropdown/dropdown.component.scss @@ -15,7 +15,9 @@ border-radius: 8px; margin: 5px 0 0 0; max-height: 268px !important; - box-shadow: 0 1px 2px 0 rgba(60, 64, 67, 0.3), 0 2px 6px 2px rgba(60, 64, 67, 0.15) !important; + box-shadow: + 0 1px 2px 0 rgba(60, 64, 67, 0.3), + 0 2px 6px 2px rgba(60, 64, 67, 0.15) !important; .mat-mdc-selected:not(.mat-mdc-option-multiple) { background: mat.get-color-from-palette(theme.$app-primary, lighter, 0.3) !important; diff --git a/src/app/shared/dropdown/dropdown.component.ts b/src/app/shared/dropdown/dropdown.component.ts index fb9c7eb..ae0cfbd 100644 --- a/src/app/shared/dropdown/dropdown.component.ts +++ b/src/app/shared/dropdown/dropdown.component.ts @@ -3,14 +3,13 @@ import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { MatOption } from '@angular/material/core'; import { MatSelect } from '@angular/material/select'; import { MatFormField } from '@angular/material/form-field'; -import { NgIf, NgFor } from '@angular/common'; @Component({ standalone: true, selector: 'ac-dropdown', templateUrl: './dropdown.component.html', styleUrls: ['./dropdown.component.scss'], - imports: [NgIf, MatFormField, MatSelect, ReactiveFormsModule, NgFor, MatOption] + imports: [MatFormField, MatSelect, ReactiveFormsModule, MatOption] }) export class DropdownComponent implements OnChanges { @Input() items: Array; diff --git a/src/app/shared/score-chart/score-chart.component.ts b/src/app/shared/score-chart/score-chart.component.ts index ce699bd..88b1d94 100644 --- a/src/app/shared/score-chart/score-chart.component.ts +++ b/src/app/shared/score-chart/score-chart.component.ts @@ -7,8 +7,8 @@ import { OnChanges, SimpleChanges, HostBinding, - Inject, - PLATFORM_ID + PLATFORM_ID, + inject } from '@angular/core'; @Component({ @@ -19,14 +19,15 @@ import { changeDetection: ChangeDetectionStrategy.OnPush }) export class ScoreChartComponent implements OnChanges { + private elementRef = inject(ElementRef); @Input() score: number; @HostBinding('class.done') done = false; isBrowser = true; - constructor(private elementRef: ElementRef, @Inject(PLATFORM_ID) platformId: string) { - this.isBrowser = isPlatformBrowser(platformId); + constructor() { + this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); } ngOnChanges(changes: SimpleChanges) { diff --git a/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.html b/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.html index 98526a8..b833067 100644 --- a/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.html +++ b/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.html @@ -1,4 +1,6 @@ diff --git a/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.ts b/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.ts index cfe66f6..5d6ae28 100644 --- a/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.ts +++ b/src/app/shared/toolbar/toolbar-logo/toolbar-logo.component.ts @@ -1,5 +1,4 @@ import { Component, Input } from '@angular/core'; -import { NgIf } from '@angular/common'; import { RouterLink } from '@angular/router'; @Component({ @@ -7,7 +6,7 @@ import { RouterLink } from '@angular/router'; selector: 'ac-toolbar-logo', templateUrl: './toolbar-logo.component.html', styleUrls: ['./toolbar-logo.component.scss'], - imports: [RouterLink, NgIf] + imports: [RouterLink] }) export class ToolbarLogoComponent { @Input() showText = true; diff --git a/src/app/shared/utils.ts b/src/app/shared/utils.ts index a47944c..f105eef 100644 --- a/src/app/shared/utils.ts +++ b/src/app/shared/utils.ts @@ -9,8 +9,5 @@ export const hasEntities = (entityState: EntityState) => { }; export const convertToProjectId = (projectName: string) => { - return projectName - .toLowerCase() - .replace(/\s+/g, '-') - .trim(); + return projectName.toLowerCase().replace(/\s+/g, '-').trim(); }; diff --git a/src/index.html b/src/index.html index 00e0651..7ebd414 100644 --- a/src/index.html +++ b/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/src/scss/custom-theme.scss b/src/scss/custom-theme.scss index 75a5504..5b1d0b8 100644 --- a/src/scss/custom-theme.scss +++ b/src/scss/custom-theme.scss @@ -31,7 +31,7 @@ $custom-green: ( A100: black, A200: black, A400: black, - A700: black, + A700: black ) ); @@ -39,13 +39,15 @@ $app-primary: mat.define-palette(mat.$deep-purple-palette); $app-accent: mat.define-palette($custom-green, 600); $app-warn: mat.define-palette(mat.$red-palette); -$app-theme: mat.define-light-theme(( - color: ( - primary: $app-primary, - accent: $app-accent, - warn: $app-warn, +$app-theme: mat.define-light-theme( + ( + color: ( + primary: $app-primary, + accent: $app-accent, + warn: $app-warn + ) ) -)); +); $primary: mat.get-theme-color($app-theme, primary); $accent: mat.get-theme-color($app-theme, accent); diff --git a/src/styles.scss b/src/styles.scss index 89c5ea0..53ed838 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -12,7 +12,7 @@ body { :root { --warn-color: hsl(48 95% 85% / 1); - --warn-color-darker: hsl(48 95% 48% / 1) + --warn-color-darker: hsl(48 95% 48% / 1); } a { diff --git a/tools/markdown.ts b/tools/markdown.ts index 703131b..bae81d0 100644 --- a/tools/markdown.ts +++ b/tools/markdown.ts @@ -23,7 +23,7 @@ export const markdown = new MarkdownIt({ }); const convertHeadings = state => { - state.tokens.forEach(function(token, i) { + state.tokens.forEach(function (token, i) { if (token.type === 'heading_open' || token.type === 'heading_close') { const rawToken = token.tag.split(''); rawToken[1] = parseInt(rawToken[1], 10) + 2; diff --git a/tools/utils.ts b/tools/utils.ts index 11d613a..40e2ee2 100644 --- a/tools/utils.ts +++ b/tools/utils.ts @@ -60,7 +60,7 @@ export const buildChecklist = async contentFolder => { }; export const extractFrontMatter = (filePath: string): FrontMatter => { - return (matter(readFileSync(filePath)) as unknown) as FrontMatter; + return matter(readFileSync(filePath)) as unknown as FrontMatter; }; export const compileFilesForCategory = (files: Array, category: string, categoryPath: string) => { diff --git a/yarn.lock b/yarn.lock index c992173..e52914a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1650,236 +1650,6 @@ resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@esbuild/aix-ppc64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz#2acd20be6d4f0458bc8c784103495ff24f13b1d3" - integrity sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g== - -"@esbuild/aix-ppc64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" - integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== - -"@esbuild/android-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz#b45d000017385c9051a4f03e17078abb935be220" - integrity sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q== - -"@esbuild/android-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" - integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== - -"@esbuild/android-arm@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.11.tgz#f46f55414e1c3614ac682b29977792131238164c" - integrity sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw== - -"@esbuild/android-arm@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" - integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== - -"@esbuild/android-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.11.tgz#bfc01e91740b82011ef503c48f548950824922b2" - integrity sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg== - -"@esbuild/android-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" - integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== - -"@esbuild/darwin-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz" - integrity sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ== - -"@esbuild/darwin-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz" - integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== - -"@esbuild/darwin-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz#62f3819eff7e4ddc656b7c6815a31cf9a1e7d98e" - integrity sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g== - -"@esbuild/darwin-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" - integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== - -"@esbuild/freebsd-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz#d478b4195aa3ca44160272dab85ef8baf4175b4a" - integrity sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA== - -"@esbuild/freebsd-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" - integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== - -"@esbuild/freebsd-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz#7bdcc1917409178257ca6a1a27fe06e797ec18a2" - integrity sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw== - -"@esbuild/freebsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" - integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== - -"@esbuild/linux-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz#58ad4ff11685fcc735d7ff4ca759ab18fcfe4545" - integrity sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg== - -"@esbuild/linux-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" - integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== - -"@esbuild/linux-arm@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz#ce82246d873b5534d34de1e5c1b33026f35e60e3" - integrity sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q== - -"@esbuild/linux-arm@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" - integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== - -"@esbuild/linux-ia32@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz#cbae1f313209affc74b80f4390c4c35c6ab83fa4" - integrity sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA== - -"@esbuild/linux-ia32@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" - integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== - -"@esbuild/linux-loong64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz#5f32aead1c3ec8f4cccdb7ed08b166224d4e9121" - integrity sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg== - -"@esbuild/linux-loong64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" - integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== - -"@esbuild/linux-mips64el@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz#38eecf1cbb8c36a616261de858b3c10d03419af9" - integrity sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg== - -"@esbuild/linux-mips64el@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" - integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== - -"@esbuild/linux-ppc64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz#9c5725a94e6ec15b93195e5a6afb821628afd912" - integrity sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA== - -"@esbuild/linux-ppc64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" - integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== - -"@esbuild/linux-riscv64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz#2dc4486d474a2a62bbe5870522a9a600e2acb916" - integrity sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ== - -"@esbuild/linux-riscv64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" - integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== - -"@esbuild/linux-s390x@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz#4ad8567df48f7dd4c71ec5b1753b6f37561a65a8" - integrity sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q== - -"@esbuild/linux-s390x@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" - integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== - -"@esbuild/linux-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz#b7390c4d5184f203ebe7ddaedf073df82a658766" - integrity sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA== - -"@esbuild/linux-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" - integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== - -"@esbuild/netbsd-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz#d633c09492a1721377f3bccedb2d821b911e813d" - integrity sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ== - -"@esbuild/netbsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" - integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== - -"@esbuild/openbsd-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz#17388c76e2f01125bf831a68c03a7ffccb65d1a2" - integrity sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw== - -"@esbuild/openbsd-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" - integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== - -"@esbuild/sunos-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz#e320636f00bb9f4fdf3a80e548cb743370d41767" - integrity sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ== - -"@esbuild/sunos-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" - integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== - -"@esbuild/win32-arm64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz#c778b45a496e90b6fc373e2a2bb072f1441fe0ee" - integrity sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ== - -"@esbuild/win32-arm64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" - integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== - -"@esbuild/win32-ia32@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz#481a65fee2e5cce74ec44823e6b09ecedcc5194c" - integrity sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg== - -"@esbuild/win32-ia32@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" - integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== - -"@esbuild/win32-x64@0.19.11": - version "0.19.11" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04" - integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw== - -"@esbuild/win32-x64@0.19.12": - version "0.19.12" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" - integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== - "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -2973,71 +2743,6 @@ resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@rollup/rollup-android-arm-eabi@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz#66b8d9cb2b3a474d115500f9ebaf43e2126fe496" - integrity sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg== - -"@rollup/rollup-android-arm64@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz#46327d5b86420d2307946bec1535fdf00356e47d" - integrity sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw== - -"@rollup/rollup-darwin-arm64@4.9.6": - version "4.9.6" - resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz" - integrity sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw== - -"@rollup/rollup-darwin-x64@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz#a2e6e096f74ccea6e2f174454c26aef6bcdd1274" - integrity sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog== - -"@rollup/rollup-linux-arm-gnueabihf@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz#09fcd4c55a2d6160c5865fec708a8e5287f30515" - integrity sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ== - -"@rollup/rollup-linux-arm64-gnu@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz#19a3c0b6315c747ca9acf86e9b710cc2440f83c9" - integrity sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ== - -"@rollup/rollup-linux-arm64-musl@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz#94aaf95fdaf2ad9335983a4552759f98e6b2e850" - integrity sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ== - -"@rollup/rollup-linux-riscv64-gnu@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz#160510e63f4b12618af4013bddf1761cf9fc9880" - integrity sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA== - -"@rollup/rollup-linux-x64-gnu@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz#5ac5d068ce0726bd0a96ca260d5bd93721c0cb98" - integrity sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw== - -"@rollup/rollup-linux-x64-musl@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz#bafa759ab43e8eab9edf242a8259ffb4f2a57a5d" - integrity sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ== - -"@rollup/rollup-win32-arm64-msvc@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz#1cc3416682e5a20d8f088f26657e6e47f8db468e" - integrity sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA== - -"@rollup/rollup-win32-ia32-msvc@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz#7d2251e1aa5e8a1e47c86891fe4547a939503461" - integrity sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ== - -"@rollup/rollup-win32-x64-msvc@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz#2c1fb69e02a3f1506f52698cfdc3a8b6386df9a6" - integrity sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ== - "@samverschueren/stream-to-observable@^0.3.0": version "0.3.1" resolved "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz" @@ -5700,11 +5405,59 @@ esbuild@0.19.11: version "0.19.11" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz" integrity sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.11" + "@esbuild/android-arm" "0.19.11" + "@esbuild/android-arm64" "0.19.11" + "@esbuild/android-x64" "0.19.11" + "@esbuild/darwin-arm64" "0.19.11" + "@esbuild/darwin-x64" "0.19.11" + "@esbuild/freebsd-arm64" "0.19.11" + "@esbuild/freebsd-x64" "0.19.11" + "@esbuild/linux-arm" "0.19.11" + "@esbuild/linux-arm64" "0.19.11" + "@esbuild/linux-ia32" "0.19.11" + "@esbuild/linux-loong64" "0.19.11" + "@esbuild/linux-mips64el" "0.19.11" + "@esbuild/linux-ppc64" "0.19.11" + "@esbuild/linux-riscv64" "0.19.11" + "@esbuild/linux-s390x" "0.19.11" + "@esbuild/linux-x64" "0.19.11" + "@esbuild/netbsd-x64" "0.19.11" + "@esbuild/openbsd-x64" "0.19.11" + "@esbuild/sunos-x64" "0.19.11" + "@esbuild/win32-arm64" "0.19.11" + "@esbuild/win32-ia32" "0.19.11" + "@esbuild/win32-x64" "0.19.11" esbuild@^0.19.3: version "0.19.12" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz" integrity sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.19.12" + "@esbuild/android-arm" "0.19.12" + "@esbuild/android-arm64" "0.19.12" + "@esbuild/android-x64" "0.19.12" + "@esbuild/darwin-arm64" "0.19.12" + "@esbuild/darwin-x64" "0.19.12" + "@esbuild/freebsd-arm64" "0.19.12" + "@esbuild/freebsd-x64" "0.19.12" + "@esbuild/linux-arm" "0.19.12" + "@esbuild/linux-arm64" "0.19.12" + "@esbuild/linux-ia32" "0.19.12" + "@esbuild/linux-loong64" "0.19.12" + "@esbuild/linux-mips64el" "0.19.12" + "@esbuild/linux-ppc64" "0.19.12" + "@esbuild/linux-riscv64" "0.19.12" + "@esbuild/linux-s390x" "0.19.12" + "@esbuild/linux-x64" "0.19.12" + "@esbuild/netbsd-x64" "0.19.12" + "@esbuild/openbsd-x64" "0.19.12" + "@esbuild/sunos-x64" "0.19.12" + "@esbuild/win32-arm64" "0.19.12" + "@esbuild/win32-ia32" "0.19.12" + "@esbuild/win32-x64" "0.19.12" escalade@^3.1.1: version "3.1.1" @@ -9729,10 +9482,10 @@ prepend-http@^1.0.1: resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz" integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg== -prettier@^1.15.2: - version "1.19.1" - resolved "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== +prettier@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.1.tgz#e68935518dd90bb7ec4821ba970e68f8de16e1ac" + integrity sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg== pretty-bytes@^5.3.0: version "5.6.0" @@ -10304,6 +10057,19 @@ rollup@^4.2.0: dependencies: "@types/estree" "1.0.5" optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.9.6" + "@rollup/rollup-android-arm64" "4.9.6" + "@rollup/rollup-darwin-arm64" "4.9.6" + "@rollup/rollup-darwin-x64" "4.9.6" + "@rollup/rollup-linux-arm-gnueabihf" "4.9.6" + "@rollup/rollup-linux-arm64-gnu" "4.9.6" + "@rollup/rollup-linux-arm64-musl" "4.9.6" + "@rollup/rollup-linux-riscv64-gnu" "4.9.6" + "@rollup/rollup-linux-x64-gnu" "4.9.6" + "@rollup/rollup-linux-x64-musl" "4.9.6" + "@rollup/rollup-win32-arm64-msvc" "4.9.6" + "@rollup/rollup-win32-ia32-msvc" "4.9.6" + "@rollup/rollup-win32-x64-msvc" "4.9.6" fsevents "~2.3.2" run-async@^3.0.0: @@ -11018,7 +10784,7 @@ string-argv@^0.0.2: resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz" integrity sha512-p6/Mqq0utTQWUeGMi/m0uBtlLZEwXSY3+mXzeRRqw7fz5ezUb28Wr0R99NlfbWaMmL/jCyT9be4jpn7Yz8IO8w== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -11044,6 +10810,15 @@ string-width@^2.0.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" @@ -11076,7 +10851,7 @@ stringify-object@^3.2.2: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11097,6 +10872,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" @@ -11974,7 +11756,7 @@ wordwrap@~0.0.2: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" integrity sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -12008,6 +11790,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"