Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Search flow in NGRX to fix routing #267

Merged
merged 14 commits into from
Sep 16, 2024
Merged
37 changes: 0 additions & 37 deletions apps/client-asset-sg/src/app/app-matchers.ts

This file was deleted.

8 changes: 3 additions & 5 deletions apps/client-asset-sg/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { HttpClient } from '@angular/common/http';
import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService, AuthState, ErrorService } from '@asset-sg/auth';
import { AppPortalService, appSharedStateActions, setCssCustomProperties } from '@asset-sg/client-shared';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { Store } from '@ngrx/store';
import { WINDOW } from 'ngx-window-token';
import { debounceTime, fromEvent, startWith, tap } from 'rxjs';
import { debounceTime, fromEvent, startWith, switchMap } from 'rxjs';
import { assert } from 'tsafe';
import { AppState } from './state/app-state';

Expand All @@ -23,16 +22,15 @@ export class AppComponent {
private _httpClient = inject(HttpClient);
public appPortalService = inject(AppPortalService);

private readonly router: Router = inject(Router);
readonly errorService = inject(ErrorService);
readonly authService = inject(AuthService);
private readonly store = inject(Store<AppState>);

constructor() {
this._httpClient
.get<Record<string, unknown>>('api/oauth-config/config')
.pipe(tap(async (config) => await this.authService.initialize(config)))
.subscribe(async (oAuthConfig) => {
.pipe(switchMap(async (config) => await this.authService.initialize(config)))
.subscribe(async () => {
this.store.dispatch(appSharedStateActions.loadWorkgroups());
this.store.dispatch(appSharedStateActions.loadReferenceData());
});
Expand Down
6 changes: 1 addition & 5 deletions apps/client-asset-sg/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
icons,
TranslateTsLoader,
} from '@asset-sg/client-shared';
import { assetsPageMatcher } from '@asset-sg/client-shared';
import { storeLogger } from '@asset-sg/core';
import { provideSvgIcons, SvgIconComponent } from '@ngneat/svg-icon';
import { EffectsModule } from '@ngrx/effects';
Expand All @@ -34,7 +35,6 @@ import { PushModule } from '@rx-angular/template/push';
import { environment } from '../environments/environment';

import { adminGuard, notAnonymousGuard } from './app-guards';
import { assetsPageMatcher } from './app-matchers';
import { AppComponent } from './app.component';
import { AppBarComponent, MenuBarComponent, NotFoundComponent, RedirectToLangComponent } from './components';
import { SplashScreenComponent } from './components/splash-screen/splash-screen.component';
Expand All @@ -59,10 +59,6 @@ registerLocaleData(locale_deCH, 'de-CH');
BrowserAnimationsModule,
HttpClientModule,
RouterModule.forRoot([
{
path: ':lang/auth',
loadChildren: () => AuthModule,
},
{
path: ':lang/profile',
loadChildren: () => import('@asset-sg/profile').then((m) => m.ProfileModule),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

:host {
box-shadow: 0px 4px 4px #00000029;
z-index: 1;
z-index: 10;
display: flex;
align-items: center;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ENTER } from '@angular/cdk/keycodes';
import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, Component, ElementRef, Input, OnInit, Output, ViewChild } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { supportedLangs } from '@asset-sg/client-shared';
import { isTruthy } from '@asset-sg/core';
import { Lang } from '@asset-sg/shared';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
Expand Down Expand Up @@ -52,7 +53,7 @@ export class AppBarComponent implements OnInit {
public links$ = this._currentLang$.pipe(
debounceTime(0),
map((currentLang) => ({
links: ['de', 'fr', 'it', 'rm', 'en'].map(
links: supportedLangs.map(
(lang) =>
pipe(
currentLang,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,43 @@
<div>
<button
<a
*ngIf="{ active: (isAssetsActive$ | async) ?? false } as isAsset"
[routerLink]="[_translateService.currentLang]"
asset-sg-reset
class="menu-bar-item active"
*ngIf="isAssetsActive$ | async; else notAssetsActive"
(click)="openAssetDrawer()"
class="menu-bar-item"
[ngClass]="{ active: isAsset.active }"
(click)="isAsset.active ? openAssetDrawer() : null"
>
<svg-icon key="assets" />
<span translate>menuBar.assets</span>
</button>
<ng-template #notAssetsActive>
<a [routerLink]="[_translateService.currentLang]" asset-sg-reset class="menu-bar-item" (click)="openAssetDrawer()">
<svg-icon key="assets" />
<span translate>menuBar.assets</span>
</a>
</ng-template>
</a>
<a
*ngIf="userExists$ | async"
asset-sg-reset
[disabled]="true"
[routerLink]="[_translateService.currentLang, 'favourites']"
aria-disabled="true"
class="menu-bar-item"
[ngClass]="{ active: (isFavouritesActive$ | async) }"
routerLinkActive="active"
>
<svg-icon key="favourite" />
<span translate>menuBar.favourites</span>
</a>
<ng-container *canCreate="AssetEditPolicy">
<button
asset-sg-reset
class="menu-bar-item active"
*ngIf="isEditActive$ | async; else notAssetEditActive"
[disabled]="true"
>
<svg-icon key="edit" />
<span translate>menuBar.admin</span>
</button>
<ng-template #notAssetEditActive>
<a
[routerLink]="[_translateService.currentLang, 'asset-admin']"
asset-sg-reset
class="menu-bar-item"
[ngClass]="{ active: (isEditActive$ | async) }"
>
<svg-icon key="edit" />
<span translate>menuBar.admin</span>
</a>
</ng-template>
</ng-container>

<a
*canCreate="AssetEditPolicy"
[routerLink]="[_translateService.currentLang, 'asset-admin']"
asset-sg-reset
class="menu-bar-item"
routerLinkActive="active"
>
<svg-icon key="edit" />
<span translate>menuBar.admin</span>
</a>
<a
*adminOnly
[routerLink]="[_translateService.currentLang, 'admin']"
asset-sg-reset
class="menu-bar-item"
[class]="{ active: (isAdminActive$ | async) }"
routerLinkActive="active"
>
<svg-icon key="user-management" />
<span translate>menuBar.userManagement</span>
Expand All @@ -64,7 +49,7 @@
[routerLink]="[_translateService.currentLang, 'profile']"
asset-sg-reset
class="menu-bar-item"
[ngClass]="{ active: (isProfileActive$ | async) }"
routerLinkActive="active"
>
<svg-icon key="profile" />
<span translate>menuBar.profile</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { ChangeDetectionStrategy, Component, HostBinding, inject } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { appSharedStateActions, fromAppShared } from '@asset-sg/client-shared';
import { appSharedStateActions, assetsPageMatcher, fromAppShared } from '@asset-sg/client-shared';
import { AssetEditPolicy } from '@asset-sg/shared/v2';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { UntilDestroy } from '@ngneat/until-destroy';
import { Store } from '@ngrx/store';
import { TranslateService } from '@ngx-translate/core';
import queryString from 'query-string';
import { filter, map, shareReplay } from 'rxjs';
import { filter, map } from 'rxjs';

import { AppState } from '../../state/app-state';

Expand All @@ -24,30 +23,13 @@ export class MenuBarComponent {
private _store = inject(Store<AppState>);

public userExists$ = this._store.select(fromAppShared.selectIsAnonymousMode).pipe(map((anonymous) => !anonymous));
public isAssetsActive$ = this.createIsRouteActive$((url) => Boolean(url.match(/^\/\w\w$/)));
public isEditActive$ = this.isSegmentActive('asset-admin');
public isFavouritesActive$ = this.isSegmentActive('favourites');
public isAdminActive$ = this.isSegmentActive('admin');
public isProfileActive$ = this.isSegmentActive('profile');

private createIsRouteActive$(fn: (url: string) => boolean) {
const o$ = this._router.events.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => {
const { url } = queryString.parseUrl(this._router.url);
return fn(url);
}),
shareReplay({ bufferSize: 1, refCount: true })
);
o$.pipe(untilDestroyed(this)).subscribe();
return o$;
}

private isSegmentActive(segment: string) {
return this.createIsRouteActive$((url) => {
return Boolean(url.match(`^/\\w\\w/${segment}`));
});
}
public isAssetsActive$ = this._router.events.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => {
const segments = this._router.parseUrl(this._router.url).root.children['primary'].segments;
return assetsPageMatcher(segments) !== null;
})
);

public openAssetDrawer() {
this._store.dispatch(appSharedStateActions.toggleSearchFilter());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Component, inject } from '@angular/core';
import { AuthService, AuthState } from '@asset-sg/auth';
import { CURRENT_LANG } from '@asset-sg/client-shared';
import { TranslateService } from '@ngx-translate/core';
import { Observable, map, startWith } from 'rxjs';

@Component({
selector: 'app-splash-screen',
Expand All @@ -18,18 +17,6 @@ export class SplashScreenComponent {
return window.location.host;
}

get languages$(): Observable<Array<{ name: string; isActive: boolean }>> {
return this.currentLang$.pipe(
startWith('de'),
map((lang) =>
['de', 'fr', 'it', 'rm', 'en'].map((it) => ({
name: it,
isActive: lang === it,
}))
)
);
}

selectLanguage(language: string): void {
this.translateService.use(language);
}
Expand Down
1 change: 0 additions & 1 deletion apps/server-asset-sg/src/features/ocr/ocr.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export class OcrController {
private config: Config;

constructor(private prismaService: PrismaService, private httpService: HttpService) {
console.log('hello ocr controller');
this.config = pipe(
Config.decode({
ocrUrl: process.env.OCR_URL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ export class AssetEditorTabPageComponent {
this._form.controls.administration.controls.newStatusWorkItemCode.disable();
}
});
this._form.valueChanges.subscribe(() => {
// console.log('value', this._form.value);
});

this._lc.afterViewInit$
.pipe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export class AssetSearchFilterListComponent<T> {
activeValues.add(filter.value);
}
this.store.dispatch(
actions.searchByFilterConfiguration({
filterConfiguration: { [filter.queryKey]: activeValues.size > 0 ? [...activeValues] : undefined },
actions.search({
query: { [filter.queryKey]: activeValues.size > 0 ? [...activeValues] : undefined },
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
padding: 0 1rem 1rem 0;
display: flex;
flex-direction: column;
z-index: 1;
}

@include drawerPanel.draw-panel-header;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class AssetSearchRefineComponent implements OnInit, OnDestroy, AfterViewI

public updateSearch(filterConfiguration: Partial<AssetSearchQuery>) {
if (this.isFiltersOpen) {
this.store.dispatch(actions.searchByFilterConfiguration({ filterConfiguration }));
this.store.dispatch(actions.search({ query: filterConfiguration }));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="header">
<div>
{{ "search.searchResults" | translate }}:
<asset-sg-animate-number [nextValue]="(pageStats$ | async)?.total ?? 0" />
<asset-sg-animate-number [nextValue]="(total$ | async) ?? 0" />
</div>
<button asset-sg-icon-button style="width: unset" (click)="toggleResultsOpen(isResultsOpen)">
<span> {{ (isResultsOpen ? "search.hideTable" : "search.showTable") | translate }} </span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { AppStateWithAssetSearch } from '../../state/asset-search/asset-search.r
import {
AssetEditDetailVM,
selectAssetEditDetailVM,
selectAssetSearchPageData,
selectAssetSearchTotalResults,
selectCurrentAssetDetail,
selectIsResultsOpen,
} from '../../state/asset-search/asset-search.selector';
Expand Down Expand Up @@ -46,12 +46,12 @@ export class AssetSearchResultsComponent implements OnInit, OnDestroy {
public allResults: AssetEditDetailVM[] = [];
public resultsToDisplay: AssetEditDetailVM[] = [];
private size = 0;
private limit = 100;
private limit = 50;

private readonly _store = inject(Store<AppStateWithAssetSearch>);
public readonly isResultsOpen$ = this._store.select(selectIsResultsOpen);
public readonly assets$ = this._store.select(selectAssetEditDetailVM);
public readonly pageStats$ = this._store.select(selectAssetSearchPageData);
public readonly total$ = this._store.select(selectAssetSearchTotalResults);
public readonly currentAssetDetail$ = this._store.select(selectCurrentAssetDetail);
private readonly subscriptions: Subscription = new Subscription();
private changeDetector = inject(ChangeDetectorRef);
Expand All @@ -69,11 +69,7 @@ export class AssetSearchResultsComponent implements OnInit, OnDestroy {
}

public toggleResultsOpen(isCurrentlyOpen: boolean) {
if (isCurrentlyOpen) {
this._store.dispatch(actions.closeResults());
} else {
this._store.dispatch(actions.openResults());
}
this._store.dispatch(actions.manualToggleResult());
}

public onScroll(event: Event) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<mat-progress-bar *ngIf="isLoading$ | async" mode="indeterminate" class="loading-bar" />
<asset-sg-map
[highlightedAssetId]="highlightedAssetId"
(assetsClick)="assetClicked$.next($event)"
(initializeEnd)="handleMapInitialised()"
/>
<asset-sg-map [highlightedAssetId]="highlightedAssetId" (assetsClick)="assetClicked$.next($event)" />

<asset-sg-asset-picker
class="asset-picker"
Expand Down
Loading