Merge branch 'fix/catalog-filter' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into fix/catalog-filter

This commit is contained in:
Andreas Schickinger
2021-05-26 17:52:45 +02:00
2 changed files with 82 additions and 55 deletions

View File

@@ -211,22 +211,44 @@ export class ArticleSearchStore extends ComponentStore<ArticleSearchState> {
)
);
connect(route: ActivatedRoute, options?: { connected?: (params: StringDictionary<string>) => void; disconnected?: () => void }) {
connect(
route: ActivatedRoute,
options?: {
beforeParamsChange?: (
current: StringDictionary<string>,
previous: StringDictionary<string>
) => StringDictionary<string> | Promise<StringDictionary<string>>;
afterParamsChange?: (params: StringDictionary<string>, original?: StringDictionary<string>) => void | Promise<void>;
connected?: (params: StringDictionary<string>) => void | Promise<void>;
disconnected?: () => void;
}
) {
this.disconnect();
let connected = false;
this.connectedRouteSubscription = route.queryParams.pipe(finalize(() => options?.disconnected?.call(undefined))).subscribe((params) => {
const current = this.get(this.queryParamsSelector);
this.connectedRouteSubscription = route.queryParams
.pipe(finalize(() => options?.disconnected?.call(undefined)))
.subscribe(async (params) => {
let next = { ...params };
let previous = this.get(this.queryParamsSelector);
if (!isEqual(current, params)) {
this.setQueryParams({ params });
}
if (typeof options?.beforeParamsChange === 'function') {
next = await options.beforeParamsChange(params, previous);
}
if (!connected) {
connected = true;
setTimeout(() => options?.connected?.call(undefined, params), 0);
}
});
if (!isEqual(previous, next)) {
this.setQueryParams({ params: next });
}
if (typeof options?.afterParamsChange === 'function') {
await options.afterParamsChange(next, params);
}
if (!connected) {
connected = true;
setTimeout(() => options?.connected?.call(undefined, next), 0);
}
});
return {
disconnect: () => {
@@ -246,9 +268,9 @@ export class ArticleSearchStore extends ComponentStore<ArticleSearchState> {
for (const crumb of crumbs) {
if (crumb.tags.includes('results')) {
this.breadcrumb.patchBreadcrumb(crumb.id, { params, name: `${query} (${hits} Ergebnisse)` });
this.breadcrumb.patchBreadcrumb(crumb.id, { params: { ...params }, name: `${query} (${hits} Ergebnisse)` });
} else {
this.breadcrumb.patchBreadcrumb(crumb.id, { params });
this.breadcrumb.patchBreadcrumb(crumb.id, { params: { ...params } });
}
}
}

View File

@@ -1,11 +1,12 @@
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ViewChild, AfterContentInit, AfterViewInit } from '@angular/core';
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { StringDictionary } from '@cmf/core';
import { ApplicationService } from '@core/application';
import { BreadcrumbService } from '@core/breadcrumb';
import { ItemDTO } from '@swagger/cat';
import { CacheService } from 'apps/core/cache/src/public-api';
import { BehaviorSubject, Subscription } from 'rxjs';
import { BehaviorSubject } from 'rxjs';
import { first, map } from 'rxjs/operators';
import { ArticleSearchStore } from '../article-search-new.store';
@@ -15,15 +16,15 @@ import { ArticleSearchStore } from '../article-search-new.store';
styleUrls: ['search-results.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterContentInit, AfterViewInit {
@ViewChild('scrollContainer', { static: false }) scrollContainer: CdkVirtualScrollViewport;
export class ArticleSearchResultsComponent implements OnInit, OnDestroy {
@ViewChild('scrollContainer', { static: true })
scrollContainer: CdkVirtualScrollViewport;
loading$ = new BehaviorSubject<boolean>(false);
results$ = this.store.items$;
fetching$ = this.store.searchState$.pipe(map((state) => state === 'fetching'));
scrollPosSubscription: Subscription;
trackByItemId = (item: ItemDTO) => item.id;
constructor(
@@ -35,23 +36,41 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterCo
) {}
ngOnInit() {
let previousProcessId: number;
this.store.connect(this.route, {
connected: () => {
this.route.queryParams.subscribe((params) => {
const cachedItems = this.cache.get(params);
if (cachedItems) {
this.store.setItems({ items: cachedItems });
}
this.store.search({ reload: true });
beforeParamsChange: async (current, previous) => {
if (previousProcessId) {
this.cache.set(previous, this.store.items);
await this.updateBreadcrumbs(previousProcessId, {
...previous,
scrollPos: String(this.scrollContainer.measureScrollOffset('top')),
});
}
previousProcessId = this.application.activatedProcessId;
// if (params.scrollPos) {
// this.scrollTo(Number(params.scrollPos));
// }
});
const params = { ...current };
delete params['scrollPos'];
return params;
},
afterParamsChange: async (params, original) => {
const items = this.cache.get<ItemDTO[]>(params);
if (items) {
this.store.setItems({ items });
} else {
this.store.search({ reload: true });
}
const scrollPos = Number(original?.scrollPos);
if (scrollPos !== null) {
this.scrollTop(scrollPos);
}
},
disconnected: () => {
// this.store.setQueryParam({ key: 'scrollPos', value: this.scrollContainer.measureScrollOffset('top').toString() });
this.cache.set(this.store.queryParams, this.store.items);
this.updateBreadcrumbs(previousProcessId, {
...this.store.queryParams,
scrollPos: String(this.scrollContainer.measureScrollOffset('top')),
});
},
});
@@ -64,43 +83,29 @@ export class ArticleSearchResultsComponent implements OnInit, OnDestroy, AfterCo
params: queryParams,
tags: ['catalog', 'filter', 'results'],
});
// this.scrollPosSubscription = this.store.onSearch.subscribe((options) => {
// if (options?.clear) {
// this.store.setQueryParam({ key: 'scrollPos', value: '0' });
// this.scrollTo(0);
// }
// });
}
ngOnDestroy() {
this.store.disconnect();
this.loading$.complete();
// this.scrollPosSubscription.unsubscribe();
}
ngAfterContentInit() {
// const scrollPos = this.route?.snapshot?.queryParams?.scrollPos;
// if (scrollPos) {
// this.scrollTo(Number(scrollPos));
// }
scrollTop(scrollPos: number) {
setTimeout(() => this.scrollContainer.scrollTo({ top: scrollPos }), 0);
}
ngAfterViewInit() {
// const scrollPos = this.route?.snapshot?.queryParams?.scrollPos;
// if (scrollPos) {
// this.scrollTo(Number(scrollPos));
// }
}
// scrollTo(scrollPos: number) {
// this.scrollContainer.scrollTo({ top: scrollPos });
// }
async scrolledIndexChange(index: number) {
const results = await this.results$.pipe(first()).toPromise();
if (index >= results.length - 20 && results.length - 20 > 0) {
this.store.search({ clear: false });
}
}
async updateBreadcrumbs(processId: number, params: StringDictionary<string>) {
const crumbs = await this.breadcrumb.getBreadcrumbsByKeyAndTags$(processId, ['catalog', 'filter', 'results']).pipe(first()).toPromise();
for (const crumb of crumbs) {
this.breadcrumb.patchBreadcrumb(crumb.id, { params: { ...params } });
}
}
}