87968: Automatic upgrade to NgRx 13

This commit is contained in:
Yura Bondarenko
2022-03-14 18:36:57 +01:00
parent 8f7389c83a
commit 8e4f1993bf
17 changed files with 182 additions and 182 deletions

View File

@@ -69,9 +69,9 @@
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
"@ng-dynamic-forms/core": "^14.0.1",
"@ng-dynamic-forms/ui-ng-bootstrap": "^14.0.1",
"@ngrx/effects": "^12.5.1",
"@ngrx/router-store": "^12.5.1",
"@ngrx/store": "^12.5.1",
"@ngrx/effects": "^13.0.2",
"@ngrx/router-store": "^13.0.2",
"@ngrx/store": "^13.0.2",
"@nguniversal/express-engine": "^13.0.2",
"@ngx-translate/core": "^13.0.0",
"@nicky-lenaers/ngx-scroll-to": "^9.0.0",
@@ -134,7 +134,7 @@
"@angular/language-service": "~13.2.6",
"@cypress/schematic": "^1.5.0",
"@fortawesome/fontawesome-free": "^5.5.0",
"@ngrx/store-devtools": "^12.5.1",
"@ngrx/store-devtools": "^13.0.2",
"@ngtools/webpack": "^13.2.6",
"@nguniversal/builders": "^13.0.2",
"@types/deep-freeze": "0.1.2",

View File

@@ -10,7 +10,7 @@ import {
} from 'rxjs';
import { catchError, filter, map, observeOn, switchMap, take, tap } from 'rxjs/operators';
// import @ngrx
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Action, select, Store } from '@ngrx/store';
// import services
@@ -67,8 +67,8 @@ export class AuthEffects {
* Authenticate user.
* @method authenticate
*/
@Effect()
public authenticate$: Observable<Action> = this.actions$.pipe(
public authenticate$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.AUTHENTICATE),
switchMap((action: AuthenticateAction) => {
return this.authService.authenticate(action.payload.email, action.payload.password).pipe(
@@ -77,26 +77,26 @@ export class AuthEffects {
catchError((error) => observableOf(new AuthenticationErrorAction(error)))
);
})
);
));
@Effect()
public authenticateSuccess$: Observable<Action> = this.actions$.pipe(
public authenticateSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.AUTHENTICATE_SUCCESS),
map((action: AuthenticationSuccessAction) => new AuthenticatedAction(action.payload))
);
));
@Effect()
public authenticated$: Observable<Action> = this.actions$.pipe(
public authenticated$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.AUTHENTICATED),
switchMap((action: AuthenticatedAction) => {
return this.authService.authenticatedUser(action.payload).pipe(
map((userHref: string) => new AuthenticatedSuccessAction((userHref !== null), action.payload, userHref)),
catchError((error) => observableOf(new AuthenticatedErrorAction(error))),);
})
);
));
@Effect()
public authenticatedSuccess$: Observable<Action> = this.actions$.pipe(
public authenticatedSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.AUTHENTICATED_SUCCESS),
tap((action: AuthenticatedSuccessAction) => this.authService.storeToken(action.payload.authToken)),
switchMap((action: AuthenticatedSuccessAction) => this.authService.getRedirectUrl().pipe(
@@ -110,26 +110,26 @@ export class AuthEffects {
return new RetrieveAuthenticatedEpersonAction(action.payload.userHref);
}
})
);
));
@Effect({ dispatch: false })
public redirectAfterLoginSuccess$: Observable<Action> = this.actions$.pipe(
public redirectAfterLoginSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS),
tap((action: RedirectAfterLoginSuccessAction) => {
this.authService.clearRedirectUrl();
this.authService.navigateToRedirectUrl(action.payload);
})
);
), { dispatch: false });
// It means "reacts to this action but don't send another"
@Effect({ dispatch: false })
public authenticatedError$: Observable<Action> = this.actions$.pipe(
public authenticatedError$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.AUTHENTICATED_ERROR),
tap((action: LogOutSuccessAction) => this.authService.removeToken())
);
), { dispatch: false });
@Effect()
public retrieveAuthenticatedEperson$: Observable<Action> = this.actions$.pipe(
public retrieveAuthenticatedEperson$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.RETRIEVE_AUTHENTICATED_EPERSON),
switchMap((action: RetrieveAuthenticatedEpersonAction) => {
const impersonatedUserID = this.authService.getImpersonateID();
@@ -143,20 +143,20 @@ export class AuthEffects {
map((user: EPerson) => new RetrieveAuthenticatedEpersonSuccessAction(user.id)),
catchError((error) => observableOf(new RetrieveAuthenticatedEpersonErrorAction(error))));
})
);
));
@Effect()
public checkToken$: Observable<Action> = this.actions$.pipe(ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN),
public checkToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN),
switchMap(() => {
return this.authService.hasValidAuthenticationToken().pipe(
map((token: AuthTokenInfo) => new AuthenticatedAction(token)),
catchError((error) => observableOf(new CheckAuthenticationTokenCookieAction()))
);
})
);
));
@Effect()
public checkTokenCookie$: Observable<Action> = this.actions$.pipe(
public checkTokenCookie$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE),
switchMap(() => {
return this.authService.checkAuthenticationCookie().pipe(
@@ -171,10 +171,10 @@ export class AuthEffects {
catchError((error) => observableOf(new AuthenticatedErrorAction(error)))
);
})
);
));
@Effect()
public retrieveToken$: Observable<Action> = this.actions$.pipe(
public retrieveToken$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.RETRIEVE_TOKEN),
switchMap((action: AuthenticateAction) => {
return this.authService.refreshAuthenticationToken(null).pipe(
@@ -183,31 +183,31 @@ export class AuthEffects {
catchError((error) => observableOf(new AuthenticationErrorAction(error)))
);
})
);
));
@Effect()
public refreshToken$: Observable<Action> = this.actions$.pipe(ofType(AuthActionTypes.REFRESH_TOKEN),
public refreshToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.REFRESH_TOKEN),
switchMap((action: RefreshTokenAction) => {
return this.authService.refreshAuthenticationToken(action.payload).pipe(
map((token: AuthTokenInfo) => new RefreshTokenSuccessAction(token)),
catchError((error) => observableOf(new RefreshTokenErrorAction()))
);
})
);
));
// It means "reacts to this action but don't send another"
@Effect({ dispatch: false })
public refreshTokenSuccess$: Observable<Action> = this.actions$.pipe(
public refreshTokenSuccess$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.REFRESH_TOKEN_SUCCESS),
tap((action: RefreshTokenSuccessAction) => this.authService.replaceToken(action.payload))
);
), { dispatch: false });
/**
* When the store is rehydrated in the browser,
* clear a possible invalid token or authentication errors
*/
@Effect({ dispatch: false })
public clearInvalidTokenOnRehydrate$: Observable<any> = this.actions$.pipe(
public clearInvalidTokenOnRehydrate$: Observable<any> = createEffect(() => this.actions$.pipe(
ofType(StoreActionTypes.REHYDRATE),
switchMap(() => {
const isLoaded$ = this.store.pipe(select(isAuthenticatedLoaded));
@@ -218,20 +218,20 @@ export class AuthEffects {
tap(() => this.authService.removeToken()),
tap(() => this.authService.resetAuthenticationError())
);
}));
})), { dispatch: false });
/**
* When the store is rehydrated in the browser, invalidate all cache hits regarding the
* authorizations endpoint, to be sure to have consistent responses after a login with external idp
*
*/
@Effect({ dispatch: false }) invalidateAuthorizationsRequestCache$ = this.actions$
invalidateAuthorizationsRequestCache$ = createEffect(() => this.actions$
.pipe(ofType(StoreActionTypes.REHYDRATE),
tap(() => this.authorizationsService.invalidateAuthorizationsRequestCache())
);
), { dispatch: false });
@Effect()
public logOut$: Observable<Action> = this.actions$
public logOut$: Observable<Action> = createEffect(() => this.actions$
.pipe(
ofType(AuthActionTypes.LOG_OUT),
switchMap(() => {
@@ -241,26 +241,26 @@ export class AuthEffects {
catchError((error) => observableOf(new LogOutErrorAction(error)))
);
})
);
));
@Effect({ dispatch: false })
public logOutSuccess$: Observable<Action> = this.actions$
public logOutSuccess$: Observable<Action> = createEffect(() => this.actions$
.pipe(ofType(AuthActionTypes.LOG_OUT_SUCCESS),
tap(() => this.authService.removeToken()),
tap(() => this.authService.clearRedirectUrl()),
tap(() => this.authService.refreshAfterLogout())
);
), { dispatch: false });
@Effect({ dispatch: false })
public redirectToLoginTokenExpired$: Observable<Action> = this.actions$
public redirectToLoginTokenExpired$: Observable<Action> = createEffect(() => this.actions$
.pipe(
ofType(AuthActionTypes.REDIRECT_TOKEN_EXPIRED),
tap(() => this.authService.removeToken()),
tap(() => this.authService.redirectToLoginWhenTokenExpired())
);
), { dispatch: false });
@Effect()
public retrieveMethods$: Observable<Action> = this.actions$
public retrieveMethods$: Observable<Action> = createEffect(() => this.actions$
.pipe(
ofType(AuthActionTypes.RETRIEVE_AUTH_METHODS),
switchMap((action: RetrieveAuthMethodsAction) => {
@@ -270,7 +270,7 @@ export class AuthEffects {
catchError((error) => observableOf(new RetrieveAuthMethodsErrorAction()))
);
})
);
));
/**
* For any action that is not in {@link IDLE_TIMER_IGNORE_TYPES} that comes in => Start the idleness timer
@@ -278,8 +278,8 @@ export class AuthEffects {
* => Return the action to set the user as idle ({@link SetUserAsIdleAction})
* @method trackIdleness
*/
@Effect()
public trackIdleness$: Observable<Action> = this.actions$.pipe(
public trackIdleness$: Observable<Action> = createEffect(() => this.actions$.pipe(
filter((action: Action) => !IDLE_TIMER_IGNORE_TYPES.includes(action.type)),
// Using switchMap the effect will stop subscribing to the previous timer if a new action comes
// in, and start a new timer
@@ -290,7 +290,7 @@ export class AuthEffects {
// Re-enter the zone to dispatch the action
observeOn(new EnterZoneScheduler(this.zone, queueScheduler)),
map(() => new SetUserAsIdleAction()),
);
));
/**
* @constructor

View File

@@ -1,6 +1,6 @@
import { map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { StoreActionTypes } from '../../store.actions';
import { ResetObjectCacheTimestampsAction } from './object-cache.actions';
@@ -16,10 +16,10 @@ export class ObjectCacheEffects {
* This assumes that the server cached everything a negligible
* time ago, and will likely need to be revisited later
*/
@Effect() fixTimestampsOnRehydrate = this.actions$
fixTimestampsOnRehydrate = createEffect(() => this.actions$
.pipe(ofType(StoreActionTypes.REHYDRATE),
map(() => new ResetObjectCacheTimestampsAction(new Date().getTime()))
);
));
constructor(private actions$: Actions) {
}

View File

@@ -1,6 +1,6 @@
import { delay, exhaustMap, map, switchMap, take } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { coreSelector } from '../core.selectors';
import {
AddToSSBAction,
@@ -32,7 +32,7 @@ export class ServerSyncBufferEffects {
* Then dispatch a CommitSSBAction
* When the delay is running, no new AddToSSBActions are processed in this effect
*/
@Effect() setTimeoutForServerSync = this.actions$
setTimeoutForServerSync = createEffect(() => this.actions$
.pipe(
ofType(ServerSyncBufferActionTypes.ADD),
exhaustMap((action: AddToSSBAction) => {
@@ -42,7 +42,7 @@ export class ServerSyncBufferEffects {
delay(timeoutInSeconds * 1000),
);
})
);
));
/**
* When a CommitSSBAction is dispatched
@@ -50,7 +50,7 @@ export class ServerSyncBufferEffects {
* When the list of actions is not empty, also dispatch an EmptySSBAction
* When the list is empty dispatch a NO_ACTION placeholder action
*/
@Effect() commitServerSyncBuffer = this.actions$
commitServerSyncBuffer = createEffect(() => this.actions$
.pipe(
ofType(ServerSyncBufferActionTypes.COMMIT),
switchMap((action: CommitSSBAction) => {
@@ -86,7 +86,7 @@ export class ServerSyncBufferEffects {
})
);
})
);
));
/**
* private method to create an ApplyPatchObjectCacheAction based on a cache entry

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import {
DiscardObjectUpdatesAction,
ObjectUpdatesAction,
@@ -52,7 +52,7 @@ export class ObjectUpdatesEffects {
/**
* Effect that makes sure all last fired ObjectUpdatesActions are stored in the map of this service, with the url as their key
*/
@Effect({ dispatch: false }) mapLastActions$ = this.actions$
mapLastActions$ = createEffect(() => this.actions$
.pipe(
ofType(...Object.values(ObjectUpdatesActionTypes)),
map((action: ObjectUpdatesAction) => {
@@ -64,12 +64,12 @@ export class ObjectUpdatesEffects {
this.actionMap$[url].next(action);
}
})
);
), { dispatch: false });
/**
* Effect that makes sure all last fired NotificationActions are stored in the notification map of this service, with the id as their key
*/
@Effect({ dispatch: false }) mapLastNotificationActions$ = this.actions$
mapLastNotificationActions$ = createEffect(() => this.actions$
.pipe(
ofType(...Object.values(NotificationsActionTypes)),
map((action: RemoveNotificationAction) => {
@@ -80,7 +80,7 @@ export class ObjectUpdatesEffects {
this.notificationActionMap$[id].next(action);
}
)
);
), { dispatch: false });
/**
* Effect that checks whether the removeAction's notification timeout ends before a user triggers another ObjectUpdatesAction
@@ -88,7 +88,7 @@ export class ObjectUpdatesEffects {
* When a REINSTATE action is fired during the timeout, a NO_ACTION action will be returned
* When any other ObjectUpdatesAction is fired during the timeout, a RemoteObjectUpdatesAction will be returned
*/
@Effect() removeAfterDiscardOrReinstateOnUndo$ = this.actions$
removeAfterDiscardOrReinstateOnUndo$ = createEffect(() => this.actions$
.pipe(
ofType(ObjectUpdatesActionTypes.DISCARD),
switchMap((action: DiscardObjectUpdatesAction) => {
@@ -134,7 +134,7 @@ export class ObjectUpdatesEffects {
);
}
)
);
));
constructor(private actions$: Actions,
private notificationsService: NotificationsService) {

View File

@@ -1,6 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { catchError, filter, map, mergeMap, take } from 'rxjs/operators';
import { hasValue, isNotEmpty } from '../../shared/empty.util';
@@ -24,7 +24,7 @@ import { ParsedResponse } from '../cache/response.models';
@Injectable()
export class RequestEffects {
@Effect() execute = this.actions$.pipe(
execute = createEffect(() => this.actions$.pipe(
ofType(RequestActionTypes.EXECUTE),
mergeMap((action: RequestExecuteAction) => {
return this.requestService.getByUUID(action.payload).pipe(
@@ -53,7 +53,7 @@ export class RequestEffects {
})
);
})
);
));
/**
* When the store is rehydrated in the browser, set all cache
@@ -63,10 +63,10 @@ export class RequestEffects {
* This assumes that the server cached everything a negligible
* time ago, and will likely need to be revisited later
*/
@Effect() fixTimestampsOnRehydrate = this.actions$
fixTimestampsOnRehydrate = createEffect(() => this.actions$
.pipe(ofType(StoreActionTypes.REHYDRATE),
map(() => new ResetResponseTimestampsAction(new Date().getTime()))
);
));
constructor(
private actions$: Actions,

View File

@@ -1,6 +1,6 @@
import { filter, map, switchMap, take } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import {
AddToObjectCacheAction,
@@ -24,7 +24,7 @@ import { NoOpAction } from '../../shared/ngrx/no-op.action';
@Injectable()
export class UUIDIndexEffects {
@Effect() addObject$ = this.actions$
addObject$ = createEffect(() => this.actions$
.pipe(
ofType(ObjectCacheActionTypes.ADD),
filter((action: AddToObjectCacheAction) => hasValue(action.payload.objectToCache.uuid)),
@@ -35,13 +35,13 @@ export class UUIDIndexEffects {
action.payload.objectToCache._links.self.href
);
})
);
));
/**
* Adds an alternative link to an object to the ALTERNATIVE_OBJECT_LINK index
* When the self link of the objectToCache is not the same as the alternativeLink
*/
@Effect() addAlternativeObjectLink$ = this.actions$
addAlternativeObjectLink$ = createEffect(() => this.actions$
.pipe(
ofType(ObjectCacheActionTypes.ADD),
map((action: AddToObjectCacheAction) => {
@@ -57,9 +57,9 @@ export class UUIDIndexEffects {
return new NoOpAction();
}
})
);
));
@Effect() removeObject$ = this.actions$
removeObject$ = createEffect(() => this.actions$
.pipe(
ofType(ObjectCacheActionTypes.REMOVE),
map((action: RemoveFromObjectCacheAction) => {
@@ -68,9 +68,9 @@ export class UUIDIndexEffects {
action.payload
);
})
);
));
@Effect() addRequest$ = this.actions$
addRequest$ = createEffect(() => this.actions$
.pipe(
ofType(RequestActionTypes.CONFIGURE),
filter((action: RequestConfigureAction) => action.payload.method === RestRequestMethod.GET),
@@ -95,7 +95,7 @@ export class UUIDIndexEffects {
)];
return actions;
})
);
));
constructor(private actions$: Actions, private store: Store<CoreState>) {

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import {
CommitPatchOperationsAction, FlushPatchOperationsAction,
@@ -17,11 +17,11 @@ export class JsonPatchOperationsEffects {
/**
* Dispatches a FlushPatchOperationsAction for every dispatched CommitPatchOperationsAction
*/
@Effect() commit$ = this.actions$.pipe(
commit$ = createEffect(() => this.actions$.pipe(
ofType(JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS),
map((action: CommitPatchOperationsAction) => {
return new FlushPatchOperationsAction(action.payload.resourceType, action.payload.resourceId);
}));
})));
constructor(private actions$: Actions) {}

View File

@@ -1,6 +1,6 @@
import { filter, map, pairwise } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import * as fromRouter from '@ngrx/router-store';
import { RouterNavigationAction } from '@ngrx/router-store';
import { Router } from '@angular/router';
@@ -12,7 +12,7 @@ export class RouterEffects {
* Effect that fires a new RouteUpdateAction when then path of route is changed
* @type {Observable<RouteUpdateAction>}
*/
@Effect() routeChange$ = this.actions$
routeChange$ = createEffect(() => this.actions$
.pipe(
ofType(fromRouter.ROUTER_NAVIGATION),
pairwise(),
@@ -23,7 +23,7 @@ export class RouterEffects {
})),
filter((actions: string[]) => actions[0] !== actions[1]),
map(() => new RouteUpdateAction())
);
));
constructor(private actions$: Actions, private router: Router) {
}

View File

@@ -1,6 +1,6 @@
import { map, tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { ResetRouteStateAction, RouteActionTypes } from './route.actions';
import { RouterActionTypes } from '../router/router.actions';
import { RouteService } from './route.service';
@@ -11,17 +11,17 @@ export class RouteEffects {
* Effect that resets the route state on reroute
* @type {Observable<ResetRouteStateAction>}
*/
@Effect() routeChange$ = this.actions$
routeChange$ = createEffect(() => this.actions$
.pipe(
ofType(RouterActionTypes.ROUTE_UPDATE),
map(() => new ResetRouteStateAction()),
);
));
@Effect({dispatch: false }) afterResetChange$ = this.actions$
afterResetChange$ = createEffect(() => this.actions$
.pipe(
ofType(RouteActionTypes.RESET),
tap(() => this.service.setCurrentRouteInfo()),
);
), {dispatch: false });
constructor(private actions$: Actions, private service: RouteService) {
}

View File

@@ -1,6 +1,6 @@
import { first, map, switchMap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import * as fromRouter from '@ngrx/router-store';
import { HostWindowActionTypes } from '../shared/host-window.actions';
@@ -21,26 +21,26 @@ export class NavbarEffects {
* Effect that collapses the public menu on window resize
* @type {Observable<CollapseMenuAction>}
*/
@Effect() resize$ = this.actions$
resize$ = createEffect(() => this.actions$
.pipe(
ofType(HostWindowActionTypes.RESIZE),
map(() => new CollapseMenuAction(this.menuID))
);
));
/**
* Effect that collapses the public menu on reroute
* @type {Observable<CollapseMenuAction>}
*/
@Effect() routeChange$ = this.actions$
routeChange$ = createEffect(() => this.actions$
.pipe(
ofType(fromRouter.ROUTER_NAVIGATION),
map(() => new CollapseMenuAction(this.menuID))
);
));
/**
* Effect that collapses the public menu when the admin sidebar opens
* @type {Observable<CollapseMenuAction>}
*/
@Effect() openAdminSidebar$ = this.actions$
openAdminSidebar$ = createEffect(() => this.actions$
.pipe(
ofType(MenuActionTypes.EXPAND_MENU_PREVIEW),
switchMap((action: ExpandMenuPreviewAction) => {
@@ -55,7 +55,7 @@ export class NavbarEffects {
return new NoOpAction();
}));
})
);
));
constructor(private actions$: Actions, private menuService: MenuService) {
}

View File

@@ -1,5 +1,5 @@
import { Inject, Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { filter, map, mergeMap, switchMap, take } from 'rxjs/operators';
import { BehaviorSubject, Observable } from 'rxjs';
import { RelationshipService } from '../../../../../core/data/relationship.service';
@@ -61,7 +61,7 @@ export class RelationshipEffects {
/**
* Effect that makes sure all last fired RelationshipActions' types are stored in the map of this service, with the object uuid as their key
*/
@Effect({ dispatch: false }) mapLastActions$ = this.actions$
mapLastActions$ = createEffect(() => this.actions$
.pipe(
ofType(RelationshipActionTypes.ADD_RELATIONSHIP, RelationshipActionTypes.REMOVE_RELATIONSHIP),
map((action: RelationshipAction) => {
@@ -97,14 +97,14 @@ export class RelationshipEffects {
}
}
)
);
), { dispatch: false });
/**
* Updates the namevariant in a relationship
* If the relationship is currently being added or removed, it will add the name variant to an update map so it will be sent with the next add request instead
* Otherwise the update is done immediately
*/
@Effect({ dispatch: false }) updateNameVariantsActions$ = this.actions$
updateNameVariantsActions$ = createEffect(() => this.actions$
.pipe(
ofType(RelationshipActionTypes.UPDATE_NAME_VARIANT),
map((action: UpdateRelationshipNameVariantAction) => {
@@ -125,29 +125,29 @@ export class RelationshipEffects {
}
}
)
);
), { dispatch: false });
/**
* Save the latest submission ID, to make sure it's updated when the patch is finished
*/
@Effect({ dispatch: false }) updateRelationshipActions$ = this.actions$
updateRelationshipActions$ = createEffect(() => this.actions$
.pipe(
ofType(RelationshipActionTypes.UPDATE_RELATIONSHIP),
map((action: UpdateRelationshipAction) => {
this.updateAfterPatchSubmissionId = action.payload.submissionId;
})
);
), { dispatch: false });
/**
* Save the submission object with ID updateAfterPatchSubmissionId
*/
@Effect() saveSubmissionSection = this.actions$
saveSubmissionSection = createEffect(() => this.actions$
.pipe(
ofType(ServerSyncBufferActionTypes.EMPTY, JsonPatchOperationsActionTypes.COMMIT_JSON_PATCH_OPERATIONS),
filter(() => hasValue(this.updateAfterPatchSubmissionId)),
switchMap(() => this.refreshWorkspaceItemInCache(this.updateAfterPatchSubmissionId)),
map((submissionObject) => new SaveSubmissionSectionFormSuccessAction(this.updateAfterPatchSubmissionId, [submissionObject], false))
);
));
constructor(private actions$: Actions,
private relationshipService: RelationshipService,

View File

@@ -1,7 +1,7 @@
import { ActivatedRoute } from '@angular/router';
import { MenuSection } from './menu.reducer';
import { hasNoValue, hasValue } from '../empty.util';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { MenuService } from './menu.service';
import { Observable } from 'rxjs';
import { Action } from '@ngrx/store';
@@ -19,8 +19,8 @@ export class MenuEffects {
/**
* On route change, build menu sections for every menu type depending on the current route data
*/
@Effect({ dispatch: false })
public buildRouteMenuSections$: Observable<Action> = this.actions$
public buildRouteMenuSections$: Observable<Action> = createEffect(() => this.actions$
.pipe(
ofType(ROUTER_NAVIGATED),
tap(() => {
@@ -28,7 +28,7 @@ export class MenuEffects {
this.buildRouteMenuSections(menuID);
});
})
);
), { dispatch: false });
constructor(private actions$: Actions,
private menuService: MenuService,

View File

@@ -1,6 +1,6 @@
import { map, tap, filter } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import * as fromRouter from '@ngrx/router-store';
import { SidebarCollapseAction } from './sidebar.actions';
@@ -12,7 +12,7 @@ import { URLBaser } from '../../core/url-baser/url-baser';
@Injectable()
export class SidebarEffects {
private previousPath: string;
@Effect() routeChange$ = this.actions$
routeChange$ = createEffect(() => this.actions$
.pipe(
ofType(fromRouter.ROUTER_NAVIGATION),
filter((action) => this.previousPath !== this.getBaseUrl(action)),
@@ -20,7 +20,7 @@ export class SidebarEffects {
this.previousPath = this.getBaseUrl(action);
}),
map(() => new SidebarCollapseAction())
);
));
constructor(private actions$: Actions) {

View File

@@ -2,7 +2,7 @@ import { of as observableOf } from 'rxjs';
import { map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Action, Store } from '@ngrx/store';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { AppState } from './app.reducer';
import { StoreActionTypes } from './store.actions';
@@ -11,7 +11,7 @@ import { HostWindowResizeAction } from './shared/host-window.actions';
@Injectable()
export class StoreEffects {
@Effect({ dispatch: false }) replay = this.actions.pipe(
replay = createEffect(() => this.actions.pipe(
ofType(StoreActionTypes.REPLAY),
map((replayAction: Action) => {
// TODO: should be able to replay all actions before the browser attempts to
@@ -19,12 +19,12 @@ export class StoreEffects {
// this.store.dispatch(action);
// });
return observableOf({});
}));
})), { dispatch: false });
@Effect() resize = this.actions.pipe(
resize = createEffect(() => this.actions.pipe(
ofType(StoreActionTypes.REPLAY, StoreActionTypes.REHYDRATE),
map(() => new HostWindowResizeAction(window.innerWidth, window.innerHeight))
);
));
constructor(private actions: Actions, private store: Store<AppState>) {

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { TranslateService } from '@ngx-translate/core';
import { isEqual, union } from 'lodash';
@@ -58,7 +58,7 @@ export class SubmissionObjectEffects {
/**
* Dispatch a [InitSectionAction] for every submission sections and dispatch a [CompleteInitSubmissionFormAction]
*/
@Effect() loadForm$ = this.actions$.pipe(
loadForm$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.INIT_SUBMISSION_FORM),
map((action: InitSubmissionFormAction) => {
const definition = action.payload.submissionDefinition;
@@ -97,12 +97,12 @@ export class SubmissionObjectEffects {
result.mappedActions.concat(
new CompleteInitSubmissionFormAction(result.action.payload.submissionId)
));
}));
})));
/**
* Dispatch a [InitSubmissionFormAction]
*/
@Effect() resetForm$ = this.actions$.pipe(
resetForm$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.RESET_SUBMISSION_FORM),
map((action: ResetSubmissionFormAction) =>
new InitSubmissionFormAction(
@@ -113,12 +113,12 @@ export class SubmissionObjectEffects {
action.payload.sections,
action.payload.item,
null
)));
))));
/**
* Dispatch a [SaveSubmissionFormSuccessAction] or a [SaveSubmissionFormErrorAction] on error
*/
@Effect() saveSubmission$ = this.actions$.pipe(
saveSubmission$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM),
switchMap((action: SaveSubmissionFormAction) => {
return this.operationsService.jsonPatchByResourceType(
@@ -127,12 +127,12 @@ export class SubmissionObjectEffects {
'sections').pipe(
map((response: SubmissionObject[]) => new SaveSubmissionFormSuccessAction(action.payload.submissionId, response, action.payload.isManual)),
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
}));
})));
/**
* Dispatch a [SaveForLaterSubmissionFormSuccessAction] or a [SaveSubmissionFormErrorAction] on error
*/
@Effect() saveForLaterSubmission$ = this.actions$.pipe(
saveForLaterSubmission$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM),
switchMap((action: SaveForLaterSubmissionFormAction) => {
return this.operationsService.jsonPatchByResourceType(
@@ -141,37 +141,37 @@ export class SubmissionObjectEffects {
'sections').pipe(
map((response: SubmissionObject[]) => new SaveForLaterSubmissionFormSuccessAction(action.payload.submissionId, response)),
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
}));
})));
/**
* Call parseSaveResponse and dispatch actions
*/
@Effect() saveSubmissionSuccess$ = this.actions$.pipe(
saveSubmissionSuccess$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_SUCCESS),
withLatestFrom(this.store$),
map(([action, currentState]: [SaveSubmissionFormSuccessAction, any]) => {
return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId],
action.payload.submissionObject, action.payload.submissionId, currentState.forms, action.payload.notify);
}),
mergeMap((actions) => observableFrom(actions)));
mergeMap((actions) => observableFrom(actions))));
/**
* Call parseSaveResponse and dispatch actions.
* Notification system is forced to be disabled.
*/
@Effect() saveSubmissionSectionSuccess$ = this.actions$.pipe(
saveSubmissionSectionSuccess$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_SUCCESS),
withLatestFrom(this.store$),
map(([action, currentState]: [SaveSubmissionSectionFormSuccessAction, any]) => {
return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId],
action.payload.submissionObject, action.payload.submissionId, currentState.forms, false);
}),
mergeMap((actions) => observableFrom(actions)));
mergeMap((actions) => observableFrom(actions))));
/**
* Dispatch a [SaveSubmissionSectionFormSuccessAction] or a [SaveSubmissionSectionFormErrorAction] on error
*/
@Effect() saveSection$ = this.actions$.pipe(
saveSection$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM),
switchMap((action: SaveSubmissionSectionFormAction) => {
return this.operationsService.jsonPatchByResourceID(
@@ -181,20 +181,20 @@ export class SubmissionObjectEffects {
action.payload.sectionId).pipe(
map((response: SubmissionObject[]) => new SaveSubmissionSectionFormSuccessAction(action.payload.submissionId, response)),
catchError(() => observableOf(new SaveSubmissionSectionFormErrorAction(action.payload.submissionId))));
}));
})));
/**
* Show a notification on error
*/
@Effect({ dispatch: false }) saveError$ = this.actions$.pipe(
saveError$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_SUBMISSION_FORM_ERROR, SubmissionObjectActionTypes.SAVE_SUBMISSION_SECTION_FORM_ERROR),
withLatestFrom(this.store$),
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.save_error_notice'))));
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.save_error_notice')))), { dispatch: false });
/**
* Call parseSaveResponse and dispatch actions or dispatch [SaveSubmissionFormErrorAction] on error
*/
@Effect() saveAndDeposit$ = this.actions$.pipe(
saveAndDeposit$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION),
withLatestFrom(this.submissionService.hasUnsavedModification()),
switchMap(([action, hasUnsavedModification]: [SaveAndDepositSubmissionAction, boolean]) => {
@@ -219,58 +219,58 @@ export class SubmissionObjectEffects {
}
}),
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
}));
})));
/**
* Dispatch a [DepositSubmissionSuccessAction] or a [DepositSubmissionErrorAction] on error
*/
@Effect() depositSubmission$ = this.actions$.pipe(
depositSubmission$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION),
withLatestFrom(this.store$),
switchMap(([action, state]: [DepositSubmissionAction, any]) => {
return this.submissionService.depositSubmission(state.submission.objects[action.payload.submissionId].selfUrl).pipe(
map(() => new DepositSubmissionSuccessAction(action.payload.submissionId)),
catchError((error) => observableOf(new DepositSubmissionErrorAction(action.payload.submissionId))));
}));
})));
/**
* Show a notification on success and redirect to MyDSpace page
*/
@Effect({ dispatch: false }) saveForLaterSubmissionSuccess$ = this.actions$.pipe(
saveForLaterSubmissionSuccess$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.SAVE_FOR_LATER_SUBMISSION_FORM_SUCCESS),
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.save_success_notice'))),
tap(() => this.submissionService.redirectToMyDSpace()));
tap(() => this.submissionService.redirectToMyDSpace())), { dispatch: false });
/**
* Show a notification on success and redirect to MyDSpace page
*/
@Effect({ dispatch: false }) depositSubmissionSuccess$ = this.actions$.pipe(
depositSubmissionSuccess$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS),
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))),
tap(() => this.submissionService.redirectToMyDSpace()));
tap(() => this.submissionService.redirectToMyDSpace())), { dispatch: false });
/**
* Show a notification on error
*/
@Effect({ dispatch: false }) depositSubmissionError$ = this.actions$.pipe(
depositSubmissionError$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_ERROR),
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice'))));
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.deposit_error_notice')))), { dispatch: false });
/**
* Dispatch a [DiscardSubmissionSuccessAction] or a [DiscardSubmissionErrorAction] on error
*/
@Effect() discardSubmission$ = this.actions$.pipe(
discardSubmission$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION),
switchMap((action: DepositSubmissionAction) => {
return this.submissionService.discardSubmission(action.payload.submissionId).pipe(
map(() => new DiscardSubmissionSuccessAction(action.payload.submissionId)),
catchError(() => observableOf(new DiscardSubmissionErrorAction(action.payload.submissionId))));
}));
})));
/**
* Adds all metadata an item to the SubmissionForm sections of the submission
*/
@Effect() addAllMetadataToSectionData = this.actions$.pipe(
addAllMetadataToSectionData = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.UPDATE_SECTION_DATA),
switchMap((action: UpdateSectionDataAction) => {
return this.sectionService.getSectionState(action.payload.submissionId, action.payload.sectionId, SectionsType.Upload)
@@ -298,23 +298,23 @@ export class SubmissionObjectEffects {
return observableOf(new UpdateSectionDataSuccessAction());
}
}),
);
));
/**
* Show a notification on success and redirect to MyDSpace page
*/
@Effect({ dispatch: false })
discardSubmissionSuccess$ = this.actions$.pipe(
discardSubmissionSuccess$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_SUCCESS),
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.discard_success_notice'))),
tap(() => this.submissionService.redirectToMyDSpace()));
tap(() => this.submissionService.redirectToMyDSpace())), { dispatch: false });
/**
* Show a notification on error
*/
@Effect({ dispatch: false }) discardSubmissionError$ = this.actions$.pipe(
discardSubmissionError$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR),
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice'))));
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice')))), { dispatch: false });
constructor(private actions$: Actions,
private notificationsService: NotificationsService,

View File

@@ -1582,31 +1582,31 @@
dependencies:
tslib "^2.0.0"
"@ngrx/effects@^12.5.1":
version "12.5.1"
resolved "https://registry.yarnpkg.com/@ngrx/effects/-/effects-12.5.1.tgz#acd0ff86d8db514e47337508dde83cc98f7a3416"
integrity sha512-fVNGIIntYLRWW1XWe0os2XOv03L22S4WTkX0OPZ9O6ztwuaNq0yzxWN7UeAC6H385F+g0k76KwRV78zHyP0bfQ==
"@ngrx/effects@^13.0.2":
version "13.0.2"
resolved "https://registry.yarnpkg.com/@ngrx/effects/-/effects-13.0.2.tgz#785e54459efaef70ed3754a33d9f4ddd0ff9f033"
integrity sha512-7yW/KCxlRatDkdEriSnORlOYX8+1QAWEjPulNmHSPwehkzTQ3fIPfRBQy8xP8bnjwvGxnEZNwQlU4q1KVYOfhg==
dependencies:
tslib "^2.0.0"
"@ngrx/router-store@^12.5.1":
version "12.5.1"
resolved "https://registry.yarnpkg.com/@ngrx/router-store/-/router-store-12.5.1.tgz#006e9a05a81a6238b408dfb2de3aeb9a5b8f61e4"
integrity sha512-F3D4lo0HCvzcNUZlMcpkBQOU4dQyqLwFvJBgNetIFT376aPp+LOy7m3gAT4BMRRx6dM0zj9Gosubyc+/DoOymA==
"@ngrx/router-store@^13.0.2":
version "13.0.2"
resolved "https://registry.yarnpkg.com/@ngrx/router-store/-/router-store-13.0.2.tgz#e57084cd74071760378645417bba94805c8b4514"
integrity sha512-XrzHjrD2hhnXdGeIpQm/msN77hoAL/QD3ZYGFJs3yT5d3x/T3L1JFlra7wC0OlKJkOs6zAh5Kz9cJ94YO/TEtQ==
dependencies:
tslib "^2.0.0"
"@ngrx/store-devtools@^12.5.1":
version "12.5.1"
resolved "https://registry.yarnpkg.com/@ngrx/store-devtools/-/store-devtools-12.5.1.tgz#75f8ef9a4bf4a40d5343ff437651f0f3092914b5"
integrity sha512-SXMxVO3KzQUfB9G20gdNT5t/RcbtbaUySXLuH+b69z/eb34wH9AOYifdSdcEi8oqPjDrWYBq6a8Uh+yDHf9IfA==
"@ngrx/store-devtools@^13.0.2":
version "13.0.2"
resolved "https://registry.yarnpkg.com/@ngrx/store-devtools/-/store-devtools-13.0.2.tgz#2b412fe47894fbb0c2aec8c1402f150bc139d5e9"
integrity sha512-fcQ5A7cv9PONFvqlpFPXHswWjEflJvqrNt6wmywlxMtJDjkgzCHpvRiJqup/FiTosblRERoeZXN0oHW3Er3+rw==
dependencies:
tslib "^2.0.0"
"@ngrx/store@^12.5.1":
version "12.5.1"
resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-12.5.1.tgz#a7c21d7df1d017d2cb7e77804b210cc14bcf8786"
integrity sha512-NLVkHLVeZc7IboXSDZlFoq1QrupmwYTYKRHS6se7ZasAv/lrIjHWsVVdICKSVRBsHZYu3+dmCXmu+YgulP7iHw==
"@ngrx/store@^13.0.2":
version "13.0.2"
resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-13.0.2.tgz#43f187956e07f33baed3e6215cd2fc59a06e9789"
integrity sha512-F7tsc3oCvKh+62MKiXTrvSeaxR41u4p8bch3BLjz12F37376rMuBnXf+V1thsPTZ6RB6aycAi821EQYVXFCXZg==
dependencies:
tslib "^2.0.0"