From 172755451722a2dc7a90a3d13d72d0e9def24d27 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 24 Mar 2022 11:36:21 +0000 Subject: [PATCH] [AAE-7145] upgrade to Ngrx 10 (#2479) * upgrade to ngrx 10 * fix auth proxy * migrate effects to newer syntax --- app/proxy.conf.js | 13 +- app/src/app/store/effects/app.effects.ts | 53 +- .../app/store/effects/contextmenu.effects.ts | 33 +- app/src/app/store/effects/download.effects.ts | 57 +- app/src/app/store/effects/favorite.effects.ts | 76 +-- app/src/app/store/effects/library.effects.ts | 193 +++--- app/src/app/store/effects/node.effects.ts | 584 ++++++++++-------- app/src/app/store/effects/search.effects.ts | 31 +- app/src/app/store/effects/template.effects.ts | 100 +-- app/src/app/store/effects/upload.effects.ts | 59 +- app/src/app/store/effects/viewer.effects.ts | 195 +++--- docs/extending/dialog-actions.md | 26 +- docs/ja/extending/tutorials.md | 26 +- docs/ja/tutorials/dialog-actions.md | 26 +- docs/tutorials/dialog-actions.md | 26 +- package-lock.json | 62 +- package.json | 8 +- .../store/src/effects/dialog.effects.ts | 13 +- .../store/src/effects/router.effects.ts | 85 +-- .../store/src/effects/snackbar.effects.ts | 47 +- .../src/lib/effects/aos.effects.ts | 21 +- 21 files changed, 975 insertions(+), 759 deletions(-) diff --git a/app/proxy.conf.js b/app/proxy.conf.js index 3bc754ac6..be998bbba 100644 --- a/app/proxy.conf.js +++ b/app/proxy.conf.js @@ -10,6 +10,17 @@ module.exports = { "^/alfresco/alfresco": "" }, "changeOrigin": true, - 'logLevel': 'debug' + 'logLevel': 'debug', + onProxyReq: function(request) { + if(request["method"] !== "GET") + request.setHeader("origin", APP_CONFIG_ECM_HOST); + }, + // workaround for REPO-2260 + onProxyRes: function (proxyRes) { + const header = proxyRes.headers['www-authenticate']; + if (header && header.startsWith('Basic')) { + proxyRes.headers['www-authenticate'] = 'x' + header; + } + } } }; diff --git a/app/src/app/store/effects/app.effects.ts b/app/src/app/store/effects/app.effects.ts index d2ed1aa70..33582c88e 100644 --- a/app/src/app/store/effects/app.effects.ts +++ b/app/src/app/store/effects/app.effects.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; import { AppActionTypes, LogoutAction, ReloadDocumentListAction, ResetSelectionAction } from '@alfresco/aca-shared/store'; @@ -35,31 +35,40 @@ import { AppHookService } from '@alfresco/aca-shared'; export class AppEffects { constructor(private actions$: Actions, private auth: AuthenticationService, private router: Router, private appHookService: AppHookService) {} - @Effect({ dispatch: false }) - reload = this.actions$.pipe( - ofType(AppActionTypes.ReloadDocumentList), - map((action) => { - this.appHookService.reload.next(action); - }) + reload = createEffect( + () => + this.actions$.pipe( + ofType(AppActionTypes.ReloadDocumentList), + map((action) => { + this.appHookService.reload.next(action); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - resetSelection = this.actions$.pipe( - ofType(AppActionTypes.ResetSelection), - map((action) => { - this.appHookService.reset.next(action); - }) + resetSelection = createEffect( + () => + this.actions$.pipe( + ofType(AppActionTypes.ResetSelection), + map((action) => { + this.appHookService.reset.next(action); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - logout$ = this.actions$.pipe( - ofType(AppActionTypes.Logout), - map(() => { - this.auth.logout().subscribe( - () => this.redirectToLogin(), - () => this.redirectToLogin() - ); - }) + logout$ = createEffect( + () => + this.actions$.pipe( + ofType(AppActionTypes.Logout), + map(() => { + this.auth.logout().subscribe( + () => this.redirectToLogin(), + () => this.redirectToLogin() + ); + }) + ), + { dispatch: false } ); private redirectToLogin(): Promise { diff --git a/app/src/app/store/effects/contextmenu.effects.ts b/app/src/app/store/effects/contextmenu.effects.ts index 07e1d30b5..f4a1c63c7 100644 --- a/app/src/app/store/effects/contextmenu.effects.ts +++ b/app/src/app/store/effects/contextmenu.effects.ts @@ -25,7 +25,7 @@ import { ContextMenuActionTypes, ContextMenu } from '@alfresco/aca-shared/store'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { map } from 'rxjs/operators'; import { ContextMenuOverlayRef } from '../../components/context-menu/context-menu-overlay'; import { ContextMenuService } from '../../components/context-menu/context-menu.service'; @@ -36,20 +36,23 @@ export class ContextMenuEffects { constructor(private contextMenuService: ContextMenuService, private actions$: Actions) {} - @Effect({ dispatch: false }) - contextMenu$ = this.actions$.pipe( - ofType(ContextMenuActionTypes.ContextMenu), - map((action) => { - if (this.overlayRef) { - this.overlayRef.close(); - } + contextMenu$ = createEffect( + () => + this.actions$.pipe( + ofType(ContextMenuActionTypes.ContextMenu), + map((action) => { + if (this.overlayRef) { + this.overlayRef.close(); + } - this.overlayRef = this.contextMenuService.open({ - source: action.event, - hasBackdrop: false, - backdropClass: 'cdk-overlay-transparent-backdrop', - panelClass: 'cdk-overlay-pane' - }); - }) + this.overlayRef = this.contextMenuService.open({ + source: action.event, + hasBackdrop: false, + backdropClass: 'cdk-overlay-transparent-backdrop', + panelClass: 'cdk-overlay-pane' + }); + }) + ), + { dispatch: false } ); } diff --git a/app/src/app/store/effects/download.effects.ts b/app/src/app/store/effects/download.effects.ts index 3f2521eeb..ebbcba9e2 100644 --- a/app/src/app/store/effects/download.effects.ts +++ b/app/src/app/store/effects/download.effects.ts @@ -28,7 +28,7 @@ import { DownloadZipDialogComponent } from '@alfresco/adf-core'; import { MinimalNodeEntity, Version } from '@alfresco/js-api'; import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { map, take } from 'rxjs/operators'; import { ContentApiService } from '@alfresco/aca-shared'; @@ -44,32 +44,35 @@ export class DownloadEffects { private contentUrlService: ContentUrlService ) {} - @Effect({ dispatch: false }) - downloadNode$ = this.actions$.pipe( - ofType(NodeActionTypes.Download), - map((action) => { - if (action.payload && action.payload.length > 0) { - this.downloadNodes(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - this.store - .select(getCurrentVersion) - .pipe(take(1)) - .subscribe((version) => { - if (version) { - this.downloadFileVersion(selection.nodes[0].entry, version.entry); - } else { - this.downloadNodes(selection.nodes); - } - }); - } - }); - } - }) + downloadNode$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.Download), + map((action) => { + if (action.payload && action.payload.length > 0) { + this.downloadNodes(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + this.store + .select(getCurrentVersion) + .pipe(take(1)) + .subscribe((version) => { + if (version) { + this.downloadFileVersion(selection.nodes[0].entry, version.entry); + } else { + this.downloadNodes(selection.nodes); + } + }); + } + }); + } + }) + ), + { dispatch: false } ); private downloadNodes(toDownload: Array) { diff --git a/app/src/app/store/effects/favorite.effects.ts b/app/src/app/store/effects/favorite.effects.ts index 776dd5e9d..01e34e188 100644 --- a/app/src/app/store/effects/favorite.effects.ts +++ b/app/src/app/store/effects/favorite.effects.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map, take } from 'rxjs/operators'; import { AppStore, NodeActionTypes, AddFavoriteAction, RemoveFavoriteAction, getAppSelection } from '@alfresco/aca-shared/store'; @@ -34,41 +34,47 @@ import { ContentManagementService } from '../../services/content-management.serv export class FavoriteEffects { constructor(private store: Store, private actions$: Actions, private content: ContentManagementService) {} - @Effect({ dispatch: false }) - addFavorite$ = this.actions$.pipe( - ofType(NodeActionTypes.AddFavorite), - map((action) => { - if (action.payload && action.payload.length > 0) { - this.content.addFavorite(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - this.content.addFavorite(selection.nodes); - } - }); - } - }) + addFavorite$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.AddFavorite), + map((action) => { + if (action.payload && action.payload.length > 0) { + this.content.addFavorite(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + this.content.addFavorite(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - removeFavorite$ = this.actions$.pipe( - ofType(NodeActionTypes.RemoveFavorite), - map((action) => { - if (action.payload && action.payload.length > 0) { - this.content.removeFavorite(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - this.content.removeFavorite(selection.nodes); - } - }); - } - }) + removeFavorite$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.RemoveFavorite), + map((action) => { + if (action.payload && action.payload.length > 0) { + this.content.removeFavorite(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + this.content.removeFavorite(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); } diff --git a/app/src/app/store/effects/library.effects.ts b/app/src/app/store/effects/library.effects.ts index abb833f0b..509e3a60d 100644 --- a/app/src/app/store/effects/library.effects.ts +++ b/app/src/app/store/effects/library.effects.ts @@ -36,7 +36,7 @@ import { getAppSelection } from '@alfresco/aca-shared/store'; import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { map, mergeMap, take } from 'rxjs/operators'; import { ContentApiService } from '@alfresco/aca-shared'; @@ -51,94 +51,109 @@ export class LibraryEffects { private contentApi: ContentApiService ) {} - @Effect({ dispatch: false }) - deleteLibrary$ = this.actions$.pipe( - ofType(LibraryActionTypes.Delete), - map((action) => { - if (action.payload) { - this.content.deleteLibrary(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.library) { - this.content.deleteLibrary(selection.library.entry.id); - } - }); - } - }) - ); - - @Effect({ dispatch: false }) - leaveLibrary$ = this.actions$.pipe( - ofType(LibraryActionTypes.Leave), - map((action) => { - if (action.payload) { - this.content.leaveLibrary(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.library) { - this.content.leaveLibrary(selection.library.entry.id); - } - }); - } - }) - ); - - @Effect() - createLibrary$ = this.actions$.pipe( - ofType(LibraryActionTypes.Create), - mergeMap(() => this.content.createLibrary()), - map((libraryId) => new NavigateLibraryAction(libraryId)) - ); - - @Effect({ dispatch: false }) - navigateLibrary$ = this.actions$.pipe( - ofType(LibraryActionTypes.Navigate), - map((action) => { - const libraryId = action.payload; - if (libraryId) { - this.contentApi - .getNode(libraryId, { relativePath: '/documentLibrary' }) - .pipe(map((node) => node.entry.id)) - .subscribe( - (id) => { - const route = action.route ? action.route : 'libraries'; - this.store.dispatch(new NavigateRouteAction([route, id])); - }, - () => { - this.store.dispatch(new SnackbarErrorAction('APP.MESSAGES.ERRORS.MISSING_CONTENT')); - } - ); - } - }) - ); - - @Effect({ dispatch: false }) - updateLibrary$ = this.actions$.pipe( - ofType(LibraryActionTypes.Update), - map((action) => { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.library) { - const { id } = selection.library.entry; - const { title, description, visibility } = action.payload; - - const siteBody = { - title, - description, - visibility - }; - - this.content.updateLibrary(id, siteBody); + deleteLibrary$ = createEffect( + () => + this.actions$.pipe( + ofType(LibraryActionTypes.Delete), + map((action) => { + if (action.payload) { + this.content.deleteLibrary(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.library) { + this.content.deleteLibrary(selection.library.entry.id); + } + }); } - }); - }) + }) + ), + { dispatch: false } + ); + + leaveLibrary$ = createEffect( + () => + this.actions$.pipe( + ofType(LibraryActionTypes.Leave), + map((action) => { + if (action.payload) { + this.content.leaveLibrary(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.library) { + this.content.leaveLibrary(selection.library.entry.id); + } + }); + } + }) + ), + { dispatch: false } + ); + + createLibrary$ = createEffect( + () => + this.actions$.pipe( + ofType(LibraryActionTypes.Create), + mergeMap(() => this.content.createLibrary()), + map((libraryId) => new NavigateLibraryAction(libraryId)) + ), + { dispatch: true } + ); + + navigateLibrary$ = createEffect( + () => + this.actions$.pipe( + ofType(LibraryActionTypes.Navigate), + map((action) => { + const libraryId = action.payload; + if (libraryId) { + this.contentApi + .getNode(libraryId, { relativePath: '/documentLibrary' }) + .pipe(map((node) => node.entry.id)) + .subscribe( + (id) => { + const route = action.route ? action.route : 'libraries'; + this.store.dispatch(new NavigateRouteAction([route, id])); + }, + () => { + this.store.dispatch(new SnackbarErrorAction('APP.MESSAGES.ERRORS.MISSING_CONTENT')); + } + ); + } + }) + ), + { dispatch: false } + ); + + updateLibrary$ = createEffect( + () => + this.actions$.pipe( + ofType(LibraryActionTypes.Update), + map((action) => { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.library) { + const { id } = selection.library.entry; + const { title, description, visibility } = action.payload; + + const siteBody = { + title, + description, + visibility + }; + + this.content.updateLibrary(id, siteBody); + } + }); + }) + ), + { dispatch: false } ); } diff --git a/app/src/app/store/effects/node.effects.ts b/app/src/app/store/effects/node.effects.ts index 0a564e389..95d095169 100644 --- a/app/src/app/store/effects/node.effects.ts +++ b/app/src/app/store/effects/node.effects.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map, take } from 'rxjs/operators'; import { Store } from '@ngrx/store'; @@ -62,303 +62,351 @@ export class NodeEffects { private viewUtils: ViewUtilService ) {} - @Effect({ dispatch: false }) - shareNode$ = this.actions$.pipe( - ofType(NodeActionTypes.Share), - map((action) => { - if (action.payload) { - this.contentService.shareNode(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.file) { - this.contentService.shareNode(selection.file); - } - }); - } - }) + shareNode$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.Share), + map((action) => { + if (action.payload) { + this.contentService.shareNode(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.file) { + this.contentService.shareNode(selection.file); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - unshareNodes$ = this.actions$.pipe( - ofType(NodeActionTypes.Unshare), - map((action) => { - if (action && action.payload && action.payload.length > 0) { - this.contentService.unshareNodes(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - this.contentService.unshareNodes(selection.nodes); - } - }); - } - }) + unshareNodes$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.Unshare), + map((action) => { + if (action && action.payload && action.payload.length > 0) { + this.contentService.unshareNodes(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + this.contentService.unshareNodes(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - purgeDeletedNodes$ = this.actions$.pipe( - ofType(NodeActionTypes.PurgeDeleted), - map((action) => { - if (action && action.payload && action.payload.length > 0) { - this.contentService.purgeDeletedNodes(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.count > 0) { - this.contentService.purgeDeletedNodes(selection.nodes); - } - }); - } - }) + purgeDeletedNodes$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.PurgeDeleted), + map((action) => { + if (action && action.payload && action.payload.length > 0) { + this.contentService.purgeDeletedNodes(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.count > 0) { + this.contentService.purgeDeletedNodes(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - restoreDeletedNodes$ = this.actions$.pipe( - ofType(NodeActionTypes.RestoreDeleted), - map((action) => { - if (action && action.payload && action.payload.length > 0) { - this.contentService.restoreDeletedNodes(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.count > 0) { - this.contentService.restoreDeletedNodes(selection.nodes); - } - }); - } - }) + restoreDeletedNodes$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.RestoreDeleted), + map((action) => { + if (action && action.payload && action.payload.length > 0) { + this.contentService.restoreDeletedNodes(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.count > 0) { + this.contentService.restoreDeletedNodes(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - deleteNodes$ = this.actions$.pipe( - ofType(NodeActionTypes.Delete), - map((action) => { - if (action && action.payload && action.payload.length > 0) { - this.contentService.deleteNodes(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.count > 0) { - this.contentService.deleteNodes(selection.nodes); - } - }); - } - }) + deleteNodes$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.Delete), + map((action) => { + if (action && action.payload && action.payload.length > 0) { + this.contentService.deleteNodes(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.count > 0) { + this.contentService.deleteNodes(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - undoDeleteNodes$ = this.actions$.pipe( - ofType(NodeActionTypes.UndoDelete), - map((action) => { - if (action.payload.length > 0) { - this.contentService.undoDeleteNodes(action.payload); - } - }) + undoDeleteNodes$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.UndoDelete), + map((action) => { + if (action.payload.length > 0) { + this.contentService.undoDeleteNodes(action.payload); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - createFolder$ = this.actions$.pipe( - ofType(NodeActionTypes.CreateFolder), - map((action) => { - if (action.payload) { - this.contentService.createFolder(action.payload); - } else { - this.store - .select(getCurrentFolder) - .pipe(take(1)) - .subscribe((node) => { - if (node && node.id) { - this.contentService.createFolder(node.id); - } - }); - } - }) + createFolder$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.CreateFolder), + map((action) => { + if (action.payload) { + this.contentService.createFolder(action.payload); + } else { + this.store + .select(getCurrentFolder) + .pipe(take(1)) + .subscribe((node) => { + if (node && node.id) { + this.contentService.createFolder(node.id); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - editFolder$ = this.actions$.pipe( - ofType(NodeActionTypes.EditFolder), - map((action) => { - if (action.payload) { - this.contentService.editFolder(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.folder) { - this.contentService.editFolder(selection.folder); - } - }); - } - }) + editFolder$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.EditFolder), + map((action) => { + if (action.payload) { + this.contentService.editFolder(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.folder) { + this.contentService.editFolder(selection.folder); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - copyNodes$ = this.actions$.pipe( - ofType(NodeActionTypes.Copy), - map((action) => { - if (action.payload && action.payload.length > 0) { - this.contentService.copyNodes(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - this.contentService.copyNodes(selection.nodes); - } - }); - } - }) + copyNodes$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.Copy), + map((action) => { + if (action.payload && action.payload.length > 0) { + this.contentService.copyNodes(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + this.contentService.copyNodes(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - moveNodes$ = this.actions$.pipe( - ofType(NodeActionTypes.Move), - map((action) => { - if (action.payload && action.payload.length > 0) { - this.contentService.moveNodes(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - this.contentService.moveNodes(selection.nodes); - } - }); - } - }) + moveNodes$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.Move), + map((action) => { + if (action.payload && action.payload.length > 0) { + this.contentService.moveNodes(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + this.contentService.moveNodes(selection.nodes); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - managePermissions$ = this.actions$.pipe( - ofType(NodeActionTypes.ManagePermissions), - map((action) => { - if (action && action.payload) { - const route = 'personal-files/details'; - this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id, 'permissions'])); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - const route = 'personal-files/details'; - this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id, 'permissions'])); - } - }); - } - }) + managePermissions$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.ManagePermissions), + map((action) => { + if (action && action.payload) { + const route = 'personal-files/details'; + this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id, 'permissions'])); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + const route = 'personal-files/details'; + this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id, 'permissions'])); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - expandInfoDrawer$ = this.actions$.pipe( - ofType(NodeActionTypes.ExpandInfoDrawer), - map((action) => { - if (action && action.payload) { - const route = 'personal-files/details'; - this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id])); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - const route = 'personal-files/details'; - this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id])); - } - }); - } - }) + expandInfoDrawer$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.ExpandInfoDrawer), + map((action) => { + if (action && action.payload) { + const route = 'personal-files/details'; + this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id])); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + const route = 'personal-files/details'; + this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id])); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - manageVersions$ = this.actions$.pipe( - ofType(NodeActionTypes.ManageVersions), - map((action) => { - if (action && action.payload) { - this.contentService.manageVersions(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.file) { - this.contentService.manageVersions(selection.file); - } - }); - } - }) + manageVersions$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.ManageVersions), + map((action) => { + if (action && action.payload) { + this.contentService.manageVersions(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.file) { + this.contentService.manageVersions(selection.file); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - printFile$ = this.actions$.pipe( - ofType(NodeActionTypes.PrintFile), - map((action) => { - if (action && action.payload) { - this.printFile(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.file) { - this.printFile(selection.file); - } - }); - } - }) + printFile$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.PrintFile), + map((action) => { + if (action && action.payload) { + this.printFile(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.file) { + this.printFile(selection.file); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - unlockWrite$ = this.actions$.pipe( - ofType(NodeActionTypes.UnlockForWriting), - map((action) => { - if (action && action.payload) { - this.contentService.unlockNode(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && selection.file) { - this.contentService.unlockNode(selection.file); - } - }); - } - }) + unlockWrite$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.UnlockForWriting), + map((action) => { + if (action && action.payload) { + this.contentService.unlockNode(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && selection.file) { + this.contentService.unlockNode(selection.file); + } + }); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - aspectList$ = this.actions$.pipe( - ofType(NodeActionTypes.ChangeAspects), - map((action) => { - if (action && action.payload) { - this.contentService.manageAspects(action.payload); - } else { - this.store - .select(getAppSelection) - .pipe(take(1)) - .subscribe((selection) => { - if (selection && !selection.isEmpty) { - this.contentService.manageAspects(selection.nodes[0]); - } - }); - } - }) + aspectList$ = createEffect( + () => + this.actions$.pipe( + ofType(NodeActionTypes.ChangeAspects), + map((action) => { + if (action && action.payload) { + this.contentService.manageAspects(action.payload); + } else { + this.store + .select(getAppSelection) + .pipe(take(1)) + .subscribe((selection) => { + if (selection && !selection.isEmpty) { + this.contentService.manageAspects(selection.nodes[0]); + } + }); + } + }) + ), + { dispatch: false } ); printFile(node: any) { diff --git a/app/src/app/store/effects/search.effects.ts b/app/src/app/store/effects/search.effects.ts index 39bb9ba79..e6f5e215b 100644 --- a/app/src/app/store/effects/search.effects.ts +++ b/app/src/app/store/effects/search.effects.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; import { SearchActionTypes, SearchByTermAction, SearchOptionIds } from '@alfresco/aca-shared/store'; @@ -33,19 +33,22 @@ import { Router } from '@angular/router'; export class SearchEffects { constructor(private actions$: Actions, private router: Router) {} - @Effect({ dispatch: false }) - searchByTerm$ = this.actions$.pipe( - ofType(SearchActionTypes.SearchByTerm), - map((action) => { - const query = action.payload.replace(/[(]/g, '%28').replace(/[)]/g, '%29'); + searchByTerm$ = createEffect( + () => + this.actions$.pipe( + ofType(SearchActionTypes.SearchByTerm), + map((action) => { + const query = action.payload.replace(/[(]/g, '%28').replace(/[)]/g, '%29'); - const libItem = action.searchOptions.find((item) => item.id === SearchOptionIds.Libraries); - const librarySelected = !!libItem && libItem.value; - if (librarySelected) { - this.router.navigateByUrl('/search-libraries;q=' + encodeURIComponent(query)); - } else { - this.router.navigateByUrl('/search;q=' + encodeURIComponent(query)); - } - }) + const libItem = action.searchOptions.find((item) => item.id === SearchOptionIds.Libraries); + const librarySelected = !!libItem && libItem.value; + if (librarySelected) { + this.router.navigateByUrl('/search-libraries;q=' + encodeURIComponent(query)); + } else { + this.router.navigateByUrl('/search;q=' + encodeURIComponent(query)); + } + }) + ), + { dispatch: false } ); } diff --git a/app/src/app/store/effects/template.effects.ts b/app/src/app/store/effects/template.effects.ts index c5b35d117..369c330b1 100644 --- a/app/src/app/store/effects/template.effects.ts +++ b/app/src/app/store/effects/template.effects.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map, switchMap, debounceTime, take, catchError } from 'rxjs/operators'; import { Store } from '@ngrx/store'; @@ -46,7 +46,7 @@ import { MatDialog } from '@angular/material/dialog'; @Injectable() export class TemplateEffects { - _nodesApi: NodesApi; + private _nodesApi: NodesApi; get nodesApi(): NodesApi { this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance()); return this._nodesApi; @@ -61,53 +61,65 @@ export class TemplateEffects { private nodeTemplateService: NodeTemplateService ) {} - @Effect({ dispatch: false }) - fileFromTemplate$ = this.actions$.pipe( - ofType(TemplateActionTypes.FileFromTemplate), - map(() => { - this.openDialog({ - primaryPathName: 'app:node_templates', - selectionType: 'file' - }); - }) + fileFromTemplate$ = createEffect( + () => + this.actions$.pipe( + ofType(TemplateActionTypes.FileFromTemplate), + map(() => { + this.openDialog({ + primaryPathName: 'app:node_templates', + selectionType: 'file' + }); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - folderFromTemplate$ = this.actions$.pipe( - ofType(TemplateActionTypes.FolderFromTemplate), - map(() => - this.openDialog({ - primaryPathName: 'app:space_templates', - selectionType: 'folder' - }) - ) - ); - - @Effect({ dispatch: false }) - createFromTemplate$ = this.actions$.pipe( - ofType(TemplateActionTypes.CreateFromTemplate), - map((action) => { - this.store - .select(getCurrentFolder) - .pipe( - switchMap((folder) => this.copyNode(action.payload, folder.id)), - take(1) + folderFromTemplate$ = createEffect( + () => + this.actions$.pipe( + ofType(TemplateActionTypes.FolderFromTemplate), + map(() => + this.openDialog({ + primaryPathName: 'app:space_templates', + selectionType: 'folder' + }) ) - .subscribe((node: NodeEntry | null) => { - if (node) { - this.store.dispatch(new CreateFromTemplateSuccess(node.entry)); - } - }); - }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - createFromTemplateSuccess$ = this.actions$.pipe( - ofType(TemplateActionTypes.CreateFromTemplateSuccess), - map((payload) => { - this.matDialog.closeAll(); - this.appHookService.reload.next(payload.node); - }) + createFromTemplate$ = createEffect( + () => + this.actions$.pipe( + ofType(TemplateActionTypes.CreateFromTemplate), + map((action) => { + this.store + .select(getCurrentFolder) + .pipe( + switchMap((folder) => this.copyNode(action.payload, folder.id)), + take(1) + ) + .subscribe((node: NodeEntry | null) => { + if (node) { + this.store.dispatch(new CreateFromTemplateSuccess(node.entry)); + } + }); + }) + ), + { dispatch: false } + ); + + createFromTemplateSuccess$ = createEffect( + () => + this.actions$.pipe( + ofType(TemplateActionTypes.CreateFromTemplateSuccess), + map((payload) => { + this.matDialog.closeAll(); + this.appHookService.reload.next(payload.node); + }) + ), + { dispatch: false } ); private openDialog(config: TemplateDialogConfig) { diff --git a/app/src/app/store/effects/upload.effects.ts b/app/src/app/store/effects/upload.effects.ts index 05905df2c..08536292b 100644 --- a/app/src/app/store/effects/upload.effects.ts +++ b/app/src/app/store/effects/upload.effects.ts @@ -35,7 +35,7 @@ import { } from '@alfresco/aca-shared/store'; import { FileModel, FileUtils, UploadService } from '@alfresco/adf-core'; import { Injectable, NgZone, RendererFactory2 } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { of } from 'rxjs'; import { catchError, map, take } from 'rxjs/operators'; @@ -85,34 +85,43 @@ export class UploadEffects { renderer.appendChild(document.body, this.folderInput); } - @Effect({ dispatch: false }) - uploadFiles$ = this.actions$.pipe( - ofType(UploadActionTypes.UploadFiles), - map(() => { - this.fileInput.click(); - }) + uploadFiles$ = createEffect( + () => + this.actions$.pipe( + ofType(UploadActionTypes.UploadFiles), + map(() => { + this.fileInput.click(); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - uploadFolder$ = this.actions$.pipe( - ofType(UploadActionTypes.UploadFolder), - map(() => { - this.folderInput.click(); - }) + uploadFolder$ = createEffect( + () => + this.actions$.pipe( + ofType(UploadActionTypes.UploadFolder), + map(() => { + this.folderInput.click(); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - uploadVersion$ = this.actions$.pipe( - ofType(UploadActionTypes.UploadFileVersion), - map((action) => { - if (action?.payload) { - const node = action?.payload?.detail?.data?.node?.entry; - const file: any = action?.payload?.detail?.files[0]?.file; - this.contentService.versionUpdateDialog(node, file); - } else if (!action?.payload) { - this.fileVersionInput.click(); - } - }) + uploadVersion$ = createEffect( + () => + this.actions$.pipe( + ofType(UploadActionTypes.UploadFileVersion), + map((action) => { + if (action?.payload) { + const node = action?.payload?.detail?.data?.node?.entry; + const file: any = action?.payload?.detail?.files[0]?.file; + this.contentService.versionUpdateDialog(node, file); + } else if (!action?.payload) { + this.fileVersionInput.click(); + } + }) + ), + { dispatch: false } ); uploadVersion() { diff --git a/app/src/app/store/effects/viewer.effects.ts b/app/src/app/store/effects/viewer.effects.ts index c36a0cca8..82f9b673c 100644 --- a/app/src/app/store/effects/viewer.effects.ts +++ b/app/src/app/store/effects/viewer.effects.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map, take, tap } from 'rxjs/operators'; import { @@ -57,106 +57,121 @@ export class ViewerEffects { private dialog: MatDialog ) {} - @Effect({ dispatch: false }) - fullscreenViewer$ = this.actions$.pipe( - ofType(ViewerActionTypes.FullScreen), - map(() => { - this.enterFullScreen(); - }) + fullscreenViewer$ = createEffect( + () => + this.actions$.pipe( + ofType(ViewerActionTypes.FullScreen), + map(() => { + this.enterFullScreen(); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - viewNode$ = this.actions$.pipe( - ofType(ViewerActionTypes.ViewNode), - map((action) => { - if (action.viewNodeExtras) { - const { location, path } = action.viewNodeExtras; + viewNode$ = createEffect( + () => + this.actions$.pipe( + ofType(ViewerActionTypes.ViewNode), + map((action) => { + if (action.viewNodeExtras) { + const { location, path } = action.viewNodeExtras; - if (location) { - const navigation = this.getNavigationCommands(location); + if (location) { + const navigation = this.getNavigationCommands(location); - this.router.navigate([...navigation, { outlets: { viewer: ['view', action.nodeId] } }], { - queryParams: { location } - }); - } + this.router.navigate([...navigation, { outlets: { viewer: ['view', action.nodeId] } }], { + queryParams: { location } + }); + } - if (path) { - this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }], { - queryParams: { path } - }); - } - } else { - this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }]); - } - }) + if (path) { + this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }], { + queryParams: { path } + }); + } + } else { + this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }]); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - viewFile$ = this.actions$.pipe( - ofType(ViewerActionTypes.ViewFile), - map((action) => { - if (action.payload && action.payload.entry) { - const { id, nodeId, isFile } = action.payload.entry as any; + viewFile$ = createEffect( + () => + this.actions$.pipe( + ofType(ViewerActionTypes.ViewFile), + map((action) => { + if (action.payload && action.payload.entry) { + const { id, nodeId, isFile } = action.payload.entry as any; - if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { - this.displayPreview(nodeId || id, action.parentId); - } - } else { - this.store - .select(fileToPreview) - .pipe(take(1)) - .subscribe((result) => { - if (result.selection && result.selection.file) { - const { id, nodeId, isFile } = result.selection.file.entry as any; + if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { + this.displayPreview(nodeId || id, action.parentId); + } + } else { + this.store + .select(fileToPreview) + .pipe(take(1)) + .subscribe((result) => { + if (result.selection && result.selection.file) { + const { id, nodeId, isFile } = result.selection.file.entry as any; - if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { - const parentId = result.folder ? result.folder.id : null; - this.displayPreview(nodeId || id, parentId); + if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { + const parentId = result.folder ? result.folder.id : null; + this.displayPreview(nodeId || id, parentId); + } + } + }); + } + }) + ), + { dispatch: false } + ); + + viewNodeVersion$ = createEffect( + () => + this.actions$.pipe( + ofType(ViewerActionTypes.ViewNodeVersion), + map((action) => { + this.dialog.closeAll(); + if (action.viewNodeExtras) { + const { location, path } = action.viewNodeExtras; + if (location) { + const navigation = this.getNavigationCommands(location); + this.router.navigate([...navigation, { outlets: { viewer: ['view', action.nodeId, action.versionId] } }], { + queryParams: { location } + }); + } + + if (path) { + this.router.navigate(['view', { outlets: { viewer: [action.nodeId, action.versionId] } }], { + queryParams: { path } + }); + } + } else { + this.router.navigate(['view', { outlets: { viewer: [action.nodeId, action.versionId] } }]); + } + }) + ), + { dispatch: false } + ); + + pluginPreview$ = createEffect( + () => + this.actions$.pipe( + ofType(ViewerActionTypes.PluginPreview), + tap((action) => { + this.router.navigate([ + action.pluginRoute, + { + outlets: { + viewer: ['preview', action.nodeId] } } - }); - } - }) - ); - - @Effect({ dispatch: false }) - viewNodeVersion$ = this.actions$.pipe( - ofType(ViewerActionTypes.ViewNodeVersion), - map((action) => { - this.dialog.closeAll(); - if (action.viewNodeExtras) { - const { location, path } = action.viewNodeExtras; - if (location) { - const navigation = this.getNavigationCommands(location); - this.router.navigate([...navigation, { outlets: { viewer: ['view', action.nodeId, action.versionId] } }], { - queryParams: { location } - }); - } - - if (path) { - this.router.navigate(['view', { outlets: { viewer: [action.nodeId, action.versionId] } }], { - queryParams: { path } - }); - } - } else { - this.router.navigate(['view', { outlets: { viewer: [action.nodeId, action.versionId] } }]); - } - }) - ); - - @Effect({ dispatch: false }) - pluginPreview$ = this.actions$.pipe( - ofType(ViewerActionTypes.PluginPreview), - tap((action) => { - this.router.navigate([ - action.pluginRoute, - { - outlets: { - viewer: ['preview', action.nodeId] - } - } - ]); - }) + ]); + }) + ), + { dispatch: false } ); private displayPreview(nodeId: string, parentId: string) { diff --git a/docs/extending/dialog-actions.md b/docs/extending/dialog-actions.md index ee02a45bf..a470e8d95 100644 --- a/docs/extending/dialog-actions.md +++ b/docs/extending/dialog-actions.md @@ -63,14 +63,17 @@ See also: Update `src/app/store/effects/app.effects.ts`: ```ts +import { createEffect } from '@ngrx/effects'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; @Injectable() export class AppEffects { - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => {}) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => {}) + ), + { dispatch: false } ); } ``` @@ -82,6 +85,7 @@ See also: Update to raise a dialog ```ts +import { createEffect } from '@ngrx/effects'; import { MatDialog } from '@angular/material/dialog'; import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; @@ -89,12 +93,14 @@ import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my export class AppEffects { constructor(private dialog: MatDialog) {} - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => { - this.dialog.open(MyExtensionDialogComponent) - }) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => { + this.dialog.open(MyExtensionDialogComponent) + }) + ), + { dispatch: false } ); } ``` diff --git a/docs/ja/extending/tutorials.md b/docs/ja/extending/tutorials.md index 809dc3969..20869210a 100644 --- a/docs/ja/extending/tutorials.md +++ b/docs/ja/extending/tutorials.md @@ -189,14 +189,17 @@ export class ShowMydDialogAction implements Action { `src/app/store/effects/app.effects.ts` を更新します: ```ts +import { createEffect } from '@ngrx/effects'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; @Injectable() export class AppEffects { - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => {}) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => {}) + ), + { dispatch: false } ); } ``` @@ -208,6 +211,7 @@ export class AppEffects { ダイアログを表示するための更新 ```ts +import { createEffect } from '@ngrx/effects'; import { MatDialog } from '@angular/material/dialog'; import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; @@ -215,12 +219,14 @@ import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my export class AppEffects { constructor(private dialog: MatDialog) {} - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => { - this.dialog.open(MyExtensionDialogComponent) - }) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => { + this.dialog.open(MyExtensionDialogComponent) + }) + ), + { dispatch: false } ); } ``` diff --git a/docs/ja/tutorials/dialog-actions.md b/docs/ja/tutorials/dialog-actions.md index 6afea5b60..8834ea5a3 100644 --- a/docs/ja/tutorials/dialog-actions.md +++ b/docs/ja/tutorials/dialog-actions.md @@ -74,14 +74,17 @@ export class ShowMydDialogAction implements Action { `src/app/store/effects/app.effects.ts` を更新します: ```ts +import { createEffect } from '@ngrx/effects'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; @Injectable() export class AppEffects { - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => {}) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => {}) + ), + { dispatch: false } ); } ``` @@ -93,6 +96,7 @@ export class AppEffects { ダイアログを表示するための更新 ```ts +import { createEffect } from '@ngrx/effects'; import { MatDialog } from '@angular/material/dialog'; import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; @@ -100,12 +104,14 @@ import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my export class AppEffects { constructor(private dialog: MatDialog) {} - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => { - this.dialog.open(MyExtensionDialogComponent) - }) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => { + this.dialog.open(MyExtensionDialogComponent) + }) + ), + { dispatch: false } ); } ``` diff --git a/docs/tutorials/dialog-actions.md b/docs/tutorials/dialog-actions.md index c28854dc2..e4d9aeb1f 100644 --- a/docs/tutorials/dialog-actions.md +++ b/docs/tutorials/dialog-actions.md @@ -63,14 +63,17 @@ See also: Update `src/app/store/effects/app.effects.ts`: ```ts +import { createEffect } from '@ngrx/effects'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; @Injectable() export class AppEffects { - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => {}) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => {}) + ), + { dispatch: false } ); } ``` @@ -82,6 +85,7 @@ See also: Update to raise a dialog ```ts +import { createEffect } from '@ngrx/effects'; import { MatDialog } from '@angular/material/dialog'; import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; @@ -89,12 +93,14 @@ import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my export class AppEffects { constructor(private dialog: MatDialog) {} - @Effect({ dispatch: false }) - showMyDialog$ = this.actions$.pipe( - ofType(SHOW_MY_DIALOG), - map(() => { - this.dialog.open(MyExtensionDialogComponent) - }) + showMyDialog$ = createEffect( + () => this.actions$.pipe( + ofType(SHOW_MY_DIALOG), + map(() => { + this.dialog.open(MyExtensionDialogComponent) + }) + ), + { dispatch: false } ); } ``` diff --git a/package-lock.json b/package-lock.json index bf6e44cc8..fb39503ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2693,24 +2693,36 @@ } }, "@ngrx/effects": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-9.2.1.tgz", - "integrity": "sha512-qWOnRYHdKzjCvcH6WOKra+KPlrMyS9ahoVvOSboJK7S3xzj9Pp5mgtcDBXqN9LlPbXDEzjZjFDJQMAtlP4c3Ig==" + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-10.1.2.tgz", + "integrity": "sha512-6pX6FEzLlqdbtFVMbCvscsaL6QC/L95e72JKj76Xz+8V77UTlpVsxWyMo7YU9pM4EXNpBGmOpMs2xKjfBfK05Q==", + "requires": { + "tslib": "^2.0.0" + } }, "@ngrx/router-store": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-9.2.1.tgz", - "integrity": "sha512-r7IS7OqvM2/4HO2lDP96r0zMMgiF2iNXFJF38DMstGEp23BlRkcsNz+2PSgNT8B1YgTUjUAbtnhCSRxs/kl5kw==" + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-10.1.2.tgz", + "integrity": "sha512-IBsZee5ZUmLbXkY/O4OjhJP1Q6mdu4lcLcQ9jeXsdCMH/Vvc0EGK+MlhsZrxv5+v2ZXb1bhtKsLBUsTovanLWA==", + "requires": { + "tslib": "^2.0.0" + } }, "@ngrx/store": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-9.2.1.tgz", - "integrity": "sha512-18mLKH7CAi5+F1zYbbxoCDKE8piCxZkwOoPlXEsq/LBKrZvYIvOeSlEXMjiUp3cCL3QOT27QvWIqQkIuE9b7mg==" + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-10.1.2.tgz", + "integrity": "sha512-FUjN786ch4Qt9WgJ78ef7Yquq3mPCekgcWgZrs4ycZw1f+KdfTHLTk1bGDtO8A8CzOya5yTT7KhxbdVjbOS5ng==", + "requires": { + "tslib": "^2.0.0" + } }, "@ngrx/store-devtools": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-9.2.1.tgz", - "integrity": "sha512-f7/hg884uSKsXiQbcdBJS/3rpk1KKFmy6gR0OeCqxjkZRjSq/onCsEXPKURt7MqJcRYCiNA2rIHxF/fz2j+8Kg==" + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-10.1.2.tgz", + "integrity": "sha512-HE681GuZ+lRgSXpgt7y7LKzsfu/+Tgy9yPZpaitvkhg+eCIjnN5Uvs1rWqETHYWnsKliW25yoqFUAVw+xb7hug==", + "requires": { + "tslib": "^2.0.0" + } }, "@ngtools/webpack": { "version": "10.2.3", @@ -18439,18 +18451,18 @@ } }, "string.prototype.matchall": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", - "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", + "regexp.prototype.flags": "^1.4.1", "side-channel": "^1.0.4" }, "dependencies": { @@ -18482,6 +18494,12 @@ "unbox-primitive": "^1.0.1" } }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, "is-callable": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", @@ -18512,6 +18530,16 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "dev": true + }, + "regexp.prototype.flags": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz", + "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } } } }, diff --git a/package.json b/package.json index efe8317cc..3735a125c 100644 --- a/package.json +++ b/package.json @@ -43,10 +43,10 @@ "@angular/router": "10.0.4", "@mat-datetimepicker/core": "5.1.1", "@mat-datetimepicker/moment": "5.1.1", - "@ngrx/effects": "^9.2.0", - "@ngrx/router-store": "^9.2.0", - "@ngrx/store": "^9.2.0", - "@ngrx/store-devtools": "^9.2.0", + "@ngrx/effects": "^10.1.2", + "@ngrx/router-store": "^10.1.2", + "@ngrx/store": "^10.1.2", + "@ngrx/store-devtools": "^10.1.2", "@ngx-translate/core": "^13.0.0", "minimatch-browser": "^1.0.0", "moment": "^2.27.0", diff --git a/projects/aca-shared/store/src/effects/dialog.effects.ts b/projects/aca-shared/store/src/effects/dialog.effects.ts index 929d7884f..a12ebd788 100644 --- a/projects/aca-shared/store/src/effects/dialog.effects.ts +++ b/projects/aca-shared/store/src/effects/dialog.effects.ts @@ -23,7 +23,7 @@ * along with Alfresco. If not, see . */ -import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; import { MatDialog } from '@angular/material/dialog'; @@ -33,9 +33,12 @@ import { CloseModalDialogsAction, AppActionTypes } from '../actions/app.actions' export class DialogEffects { constructor(private actions$: Actions, private matDialog: MatDialog) {} - @Effect({ dispatch: false }) - closeAll$ = this.actions$.pipe( - ofType(AppActionTypes.CloseModalDialogs), - map(() => this.matDialog.closeAll()) + closeAll$ = createEffect( + () => + this.actions$.pipe( + ofType(AppActionTypes.CloseModalDialogs), + map(() => this.matDialog.closeAll()) + ), + { dispatch: false } ); } diff --git a/projects/aca-shared/store/src/effects/router.effects.ts b/projects/aca-shared/store/src/effects/router.effects.ts index 049664e8c..5c5a2bdfe 100644 --- a/projects/aca-shared/store/src/effects/router.effects.ts +++ b/projects/aca-shared/store/src/effects/router.effects.ts @@ -25,7 +25,7 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { MinimalNodeEntryEntity, PathInfoEntity } from '@alfresco/js-api'; import { map } from 'rxjs/operators'; import { Store } from '@ngrx/store'; @@ -45,48 +45,63 @@ import { SnackbarErrorAction } from '../actions/snackbar.actions'; export class RouterEffects { constructor(private store: Store, private actions$: Actions, private router: Router, private location: Location) {} - @Effect({ dispatch: false }) - navigateUrl$ = this.actions$.pipe( - ofType(RouterActionTypes.NavigateUrl), - map((action) => { - if (action.payload) { - this.router.navigateByUrl(action.payload); - } - }) + navigateUrl$ = createEffect( + () => + this.actions$.pipe( + ofType(RouterActionTypes.NavigateUrl), + map((action) => { + if (action.payload) { + this.router.navigateByUrl(action.payload); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - navigateRoute$ = this.actions$.pipe( - ofType(RouterActionTypes.NavigateRoute), - map((action) => { - this.router.navigate(action.payload); - }) + navigateRoute$ = createEffect( + () => + this.actions$.pipe( + ofType(RouterActionTypes.NavigateRoute), + map((action) => { + this.router.navigate(action.payload); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - navigateToFolder$ = this.actions$.pipe( - ofType(RouterActionTypes.NavigateFolder), - map((action) => { - if (action.payload && action.payload.entry) { - this.navigateToFolder(action.payload.entry); - } - }) + navigateToFolder$ = createEffect( + () => + this.actions$.pipe( + ofType(RouterActionTypes.NavigateFolder), + map((action) => { + if (action.payload && action.payload.entry) { + this.navigateToFolder(action.payload.entry); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - navigateToParentFolder$ = this.actions$.pipe( - ofType(RouterActionTypes.NavigateParentFolder), - map((action) => { - if (action.payload && action.payload.entry) { - this.navigateToParentFolder(action.payload.entry); - } - }) + navigateToParentFolder$ = createEffect( + () => + this.actions$.pipe( + ofType(RouterActionTypes.NavigateParentFolder), + map((action) => { + if (action.payload && action.payload.entry) { + this.navigateToParentFolder(action.payload.entry); + } + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - navigateToPreviousPage$ = this.actions$.pipe( - ofType(RouterActionTypes.NavigateToPreviousPage), - map(() => this.location.back()) + navigateToPreviousPage$ = createEffect( + () => + this.actions$.pipe( + ofType(RouterActionTypes.NavigateToPreviousPage), + map(() => this.location.back()) + ), + { dispatch: false } ); private navigateToFolder(node: MinimalNodeEntryEntity) { diff --git a/projects/aca-shared/store/src/effects/snackbar.effects.ts b/projects/aca-shared/store/src/effects/snackbar.effects.ts index 1f9c1f443..84b34e29f 100644 --- a/projects/aca-shared/store/src/effects/snackbar.effects.ts +++ b/projects/aca-shared/store/src/effects/snackbar.effects.ts @@ -26,7 +26,7 @@ import { TranslationService } from '@alfresco/adf-core'; import { Injectable } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { Store } from '@ngrx/store'; import { map } from 'rxjs/operators'; import { AppStore } from '../states/app.state'; @@ -41,28 +41,37 @@ export class SnackbarEffects { private translationService: TranslationService ) {} - @Effect({ dispatch: false }) - infoEffect = this.actions$.pipe( - ofType(SnackbarActionTypes.Info), - map((action: SnackbarInfoAction) => { - this.showSnackBar(action, 'adf-info-snackbar'); - }) + infoEffect = createEffect( + () => + this.actions$.pipe( + ofType(SnackbarActionTypes.Info), + map((action: SnackbarInfoAction) => { + this.showSnackBar(action, 'adf-info-snackbar'); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - warningEffect = this.actions$.pipe( - ofType(SnackbarActionTypes.Warning), - map((action: SnackbarWarningAction) => { - this.showSnackBar(action, 'adf-warning-snackbar'); - }) + warningEffect = createEffect( + () => + this.actions$.pipe( + ofType(SnackbarActionTypes.Warning), + map((action: SnackbarWarningAction) => { + this.showSnackBar(action, 'adf-warning-snackbar'); + }) + ), + { dispatch: false } ); - @Effect({ dispatch: false }) - errorEffect = this.actions$.pipe( - ofType(SnackbarActionTypes.Error), - map((action: SnackbarErrorAction) => { - this.showSnackBar(action, 'adf-error-snackbar'); - }) + errorEffect = createEffect( + () => + this.actions$.pipe( + ofType(SnackbarActionTypes.Error), + map((action: SnackbarErrorAction) => { + this.showSnackBar(action, 'adf-error-snackbar'); + }) + ), + { dispatch: false } ); private showSnackBar(action: SnackbarAction, panelClass: string) { diff --git a/projects/adf-office-services-ext/src/lib/effects/aos.effects.ts b/projects/adf-office-services-ext/src/lib/effects/aos.effects.ts index 3fbecd8cf..11294b8ce 100755 --- a/projects/adf-office-services-ext/src/lib/effects/aos.effects.ts +++ b/projects/adf-office-services-ext/src/lib/effects/aos.effects.ts @@ -24,7 +24,7 @@ */ import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; +import { Actions, ofType, createEffect } from '@ngrx/effects'; import { map } from 'rxjs/operators'; import { AOS_ACTION, AosAction } from '../actions/aos.actions'; @@ -34,13 +34,16 @@ import { AosEditOnlineService } from '../aos-extension.service'; export class AosEffects { constructor(private actions$: Actions, private aosEditOnlineService: AosEditOnlineService) {} - @Effect({ dispatch: false }) - openOffice$ = this.actions$.pipe( - ofType(AOS_ACTION), - map((action) => { - if (action.payload) { - this.aosEditOnlineService.onActionEditOnlineAos(action.payload); - } - }) + openOffice$ = createEffect( + () => + this.actions$.pipe( + ofType(AOS_ACTION), + map((action) => { + if (action.payload) { + this.aosEditOnlineService.onActionEditOnlineAos(action.payload); + } + }) + ), + { dispatch: false } ); }