diff --git a/.husky/pre-commit b/.husky/pre-commit index d24fdfc60..5a182ef10 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npx lint-staged +yarn lint-staged diff --git a/apps/picsa-tools/resources-tool/src/app/pages/search/search.component.ts b/apps/picsa-tools/resources-tool/src/app/pages/search/search.component.ts index 24527ae98..c71278aaf 100644 --- a/apps/picsa-tools/resources-tool/src/app/pages/search/search.component.ts +++ b/apps/picsa-tools/resources-tool/src/app/pages/search/search.component.ts @@ -1,8 +1,10 @@ import { CommonModule } from '@angular/common'; -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { PicsaTranslateModule } from '@picsa/shared/modules'; import Fuse, { FuseResult, IFuseOptions } from 'fuse.js'; +import { Subject, takeUntil } from 'rxjs'; import { ResourcesComponentsModule } from '../../components/components.module'; import { IResourceBase, IResourceCollection, IResourceFile, IResourceLink } from '../../schemas'; @@ -22,7 +24,7 @@ interface ISearchResultsByType { styleUrls: ['./search.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class ResourceSearchComponent implements OnInit { +export class ResourceSearchComponent implements OnInit, OnDestroy { query: string = ''; // https://www.fusejs.io/api/options.html @@ -43,12 +45,27 @@ export class ResourceSearchComponent implements OnInit { searchResults: ISearchResultsByType = { collection: [], file: [], link: [] }; + private componentDestroyed$ = new Subject(); + /** Store total number of results across types */ public totalResults?: number; - constructor(private service: ResourcesToolService, private cdr: ChangeDetectorRef) {} + constructor( + private service: ResourcesToolService, + private cdr: ChangeDetectorRef, + private router: Router, + private route: ActivatedRoute + ) {} async ngOnInit() { + await this.initializeServiceData(); + this.subscribeToQueryParams(); + } + async ngOnDestroy() { + this.componentDestroyed$.next(true); + } + + private async initializeServiceData() { await this.service.ready(); const fileDocs = await this.service.dbFiles.find().exec(); const linkDocs = await this.service.dbLinks.find().exec(); @@ -58,15 +75,26 @@ export class ResourceSearchComponent implements OnInit { this.fuse = new Fuse(allResources, this.fuseOptions); } + private subscribeToQueryParams() { + this.route.queryParams.pipe(takeUntil(this.componentDestroyed$)).subscribe((params: Params) => { + if (params.searchText) { + this.query = params.searchText; + this.onSearchInputChange(); + } + }); + } + onSearchInputChange() { // Only display search results if user has typed more than 2 characters if (this.query.length > 2) { const searchResults = this.fuse.search(this.query); this.setSearchResultsByType(searchResults); this.totalResults = searchResults.length; + this.setRouteSearchParam(this.query); } else { this.searchResults = { collection: [], file: [], link: [] }; this.totalResults = undefined; + this.setRouteSearchParam(undefined); } this.cdr.markForCheck(); } @@ -86,4 +114,10 @@ export class ResourceSearchComponent implements OnInit { } this.searchResults = searchResults; } + + /** Update route param to match search text. Passing undefined will remove the param */ + private setRouteSearchParam(searchText?: string) { + const queryParams = { searchText }; + this.router.navigate([], { relativeTo: this.route, queryParams }); + } } diff --git a/package.json b/package.json index 0bcc3777f..a1786e534 100644 --- a/package.json +++ b/package.json @@ -191,7 +191,7 @@ }, "packageManager": "yarn@3.6.3", "lint-staged": { - "*.js": "eslint --cache --fix", - "*.{js,css,md}": "prettier --write" + "*.ts": "eslint --cache --fix", + "*.{ts,scss}": "prettier --write" } }