Merge remote-tracking branch 'origin/release/12.4' into dev

pull/11980/head
ulferts 2 years ago
commit dfc1adf2b7
No known key found for this signature in database
GPG Key ID: A205708DE1284017
  1. 10
      frontend/src/app/core/state/in-app-notifications/in-app-notifications.service.ts
  2. 23
      frontend/src/app/core/state/resource-collection.service.ts
  3. 7
      frontend/src/app/features/hal/resources/error-resource.ts
  4. 14
      frontend/src/app/features/in-app-notifications/bell/state/ian-bell.service.ts

@ -6,17 +6,11 @@ import {
markNotificationsAsRead,
notificationsMarkedRead,
} from 'core-app/core/state/in-app-notifications/in-app-notifications.actions';
import {
EffectCallback,
EffectHandler,
} from 'core-app/core/state/effects/effect-handler.decorator';
import { EffectCallback, EffectHandler } from 'core-app/core/state/effects/effect-handler.decorator';
import { ActionsService } from 'core-app/core/state/actions/actions.service';
import { InAppNotificationsStore } from './in-app-notifications.store';
import { INotification } from './in-app-notification.model';
import {
CollectionStore,
ResourceCollectionService,
} from 'core-app/core/state/resource-collection.service';
import { CollectionStore, ResourceCollectionService } from 'core-app/core/state/resource-collection.service';
import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator';
@EffectHandler

@ -65,6 +65,10 @@ import { ToastService } from 'core-app/shared/components/toaster/toast.service';
export type CollectionStore<T> = EntityStore<CollectionState<T>>;
export interface ResourceCollectionLoadOptions {
handleErrors:boolean;
}
@Injectable()
export abstract class ResourceCollectionService<T extends { id:ID }> {
protected store:CollectionStore<T> = this.createStore();
@ -225,8 +229,14 @@ export abstract class ResourceCollectionService<T extends { id:ID }> {
/**
* Fetch a given collection, ensuring it is being flagged as loaded
*
* @param params {ApiV3ListParameters|string} collection key or list params to build collection key from
* @param options {ResourceCollectionLoadOptions} Handle collection loading errors within the resource service
*/
fetchCollection(params:ApiV3ListParameters|string):Observable<IHALCollection<T>> {
fetchCollection(
params:ApiV3ListParameters|string,
options:ResourceCollectionLoadOptions = { handleErrors: true },
):Observable<IHALCollection<T>> {
const key = typeof params === 'string' ? params : collectionKey(params);
setCollectionLoading(this.store, key);
@ -238,7 +248,10 @@ export abstract class ResourceCollectionService<T extends { id:ID }> {
tap((collection) => insertCollectionIntoState(this.store, collection, key)),
finalize(() => removeCollectionLoading(this.store, key)),
catchError((error:unknown) => {
this.handleCollectionLoadingError(error as HttpErrorResponse, key);
if (options.handleErrors) {
this.handleCollectionLoadingError(error as HttpErrorResponse, key);
}
throw error;
}),
);
@ -256,6 +269,12 @@ export abstract class ResourceCollectionService<T extends { id:ID }> {
*/
protected abstract basePath():string;
/**
* By default, add a toast error in case of loading errors
* @param error
* @param _collectionKey
* @protected
*/
protected handleCollectionLoadingError(error:HttpErrorResponse, _collectionKey:string):void {
this.toastService.addError(error);
}

@ -38,9 +38,10 @@ export interface IHalErrorBase {
errorIdentifier:string;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,@typescript-eslint/no-explicit-any
export function isHalError(err:any):err is IHalErrorBase {
return '_type' in err && 'message' in err && 'errorIdentifier' in err;
export function isHalError(err:unknown):err is IHalErrorBase {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
const hasOwn = (key:string):boolean => Object.prototype.hasOwnProperty.call(err, key);
return !!err && hasOwn('_type') && hasOwn('message') && hasOwn('errorIdentifier');
}
export interface IHalSingleError extends IHalErrorBase {

@ -1,6 +1,8 @@
import { Injectable } from '@angular/core';
import { IanBellStore } from './ian-bell.store';
import { InAppNotificationsResourceService } from 'core-app/core/state/in-app-notifications/in-app-notifications.service';
import {
InAppNotificationsResourceService,
} from 'core-app/core/state/in-app-notifications/in-app-notifications.service';
import { IAN_FACET_FILTERS } from 'core-app/features/in-app-notifications/center/state/ian-center.store';
import {
map,
@ -17,7 +19,10 @@ import {
EffectCallback,
EffectHandler,
} from 'core-app/core/state/effects/effect-handler.decorator';
import { notificationsMarkedRead, notificationCountIncreased } from 'core-app/core/state/in-app-notifications/in-app-notifications.actions';
import {
notificationsMarkedRead,
notificationCountIncreased,
} from 'core-app/core/state/in-app-notifications/in-app-notifications.actions';
import { ActionsService } from 'core-app/core/state/actions/actions.service';
/**
@ -48,7 +53,10 @@ export class IanBellService {
fetchUnread():Observable<number> {
return this
.resourceService
.fetchCollection({ filters: IAN_FACET_FILTERS.unread, pageSize: 0 })
.fetchCollection(
{ filters: IAN_FACET_FILTERS.unread, pageSize: 0 },
{ handleErrors: false },
)
.pipe(
map((result) => result.total),
tap(

Loading…
Cancel
Save