[AAE-7145] upgrade to Ngrx 10 (#2479)

* upgrade to ngrx 10

* fix auth proxy

* migrate effects to newer syntax
This commit is contained in:
Denys Vuika 2022-03-24 11:36:21 +00:00 committed by GitHub
parent 305ec58e2b
commit 1727554517
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 975 additions and 759 deletions

View File

@ -10,6 +10,17 @@ module.exports = {
"^/alfresco/alfresco": "" "^/alfresco/alfresco": ""
}, },
"changeOrigin": true, "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;
}
}
} }
}; };

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Actions, ofType, createEffect } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { AppActionTypes, LogoutAction, ReloadDocumentListAction, ResetSelectionAction } from '@alfresco/aca-shared/store'; import { AppActionTypes, LogoutAction, ReloadDocumentListAction, ResetSelectionAction } from '@alfresco/aca-shared/store';
@ -35,31 +35,40 @@ import { AppHookService } from '@alfresco/aca-shared';
export class AppEffects { export class AppEffects {
constructor(private actions$: Actions, private auth: AuthenticationService, private router: Router, private appHookService: AppHookService) {} constructor(private actions$: Actions, private auth: AuthenticationService, private router: Router, private appHookService: AppHookService) {}
@Effect({ dispatch: false }) reload = createEffect(
reload = this.actions$.pipe( () =>
ofType<ReloadDocumentListAction>(AppActionTypes.ReloadDocumentList), this.actions$.pipe(
map((action) => { ofType<ReloadDocumentListAction>(AppActionTypes.ReloadDocumentList),
this.appHookService.reload.next(action); map((action) => {
}) this.appHookService.reload.next(action);
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) resetSelection = createEffect(
resetSelection = this.actions$.pipe( () =>
ofType<ResetSelectionAction>(AppActionTypes.ResetSelection), this.actions$.pipe(
map((action) => { ofType<ResetSelectionAction>(AppActionTypes.ResetSelection),
this.appHookService.reset.next(action); map((action) => {
}) this.appHookService.reset.next(action);
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) logout$ = createEffect(
logout$ = this.actions$.pipe( () =>
ofType<LogoutAction>(AppActionTypes.Logout), this.actions$.pipe(
map(() => { ofType<LogoutAction>(AppActionTypes.Logout),
this.auth.logout().subscribe( map(() => {
() => this.redirectToLogin(), this.auth.logout().subscribe(
() => this.redirectToLogin() () => this.redirectToLogin(),
); () => this.redirectToLogin()
}) );
})
),
{ dispatch: false }
); );
private redirectToLogin(): Promise<boolean> { private redirectToLogin(): Promise<boolean> {

View File

@ -25,7 +25,7 @@
import { ContextMenuActionTypes, ContextMenu } from '@alfresco/aca-shared/store'; import { ContextMenuActionTypes, ContextMenu } from '@alfresco/aca-shared/store';
import { Injectable } from '@angular/core'; 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 { map } from 'rxjs/operators';
import { ContextMenuOverlayRef } from '../../components/context-menu/context-menu-overlay'; import { ContextMenuOverlayRef } from '../../components/context-menu/context-menu-overlay';
import { ContextMenuService } from '../../components/context-menu/context-menu.service'; import { ContextMenuService } from '../../components/context-menu/context-menu.service';
@ -36,20 +36,23 @@ export class ContextMenuEffects {
constructor(private contextMenuService: ContextMenuService, private actions$: Actions) {} constructor(private contextMenuService: ContextMenuService, private actions$: Actions) {}
@Effect({ dispatch: false }) contextMenu$ = createEffect(
contextMenu$ = this.actions$.pipe( () =>
ofType<ContextMenu>(ContextMenuActionTypes.ContextMenu), this.actions$.pipe(
map((action) => { ofType<ContextMenu>(ContextMenuActionTypes.ContextMenu),
if (this.overlayRef) { map((action) => {
this.overlayRef.close(); if (this.overlayRef) {
} this.overlayRef.close();
}
this.overlayRef = this.contextMenuService.open({ this.overlayRef = this.contextMenuService.open({
source: action.event, source: action.event,
hasBackdrop: false, hasBackdrop: false,
backdropClass: 'cdk-overlay-transparent-backdrop', backdropClass: 'cdk-overlay-transparent-backdrop',
panelClass: 'cdk-overlay-pane' panelClass: 'cdk-overlay-pane'
}); });
}) })
),
{ dispatch: false }
); );
} }

View File

@ -28,7 +28,7 @@ import { DownloadZipDialogComponent } from '@alfresco/adf-core';
import { MinimalNodeEntity, Version } from '@alfresco/js-api'; import { MinimalNodeEntity, Version } from '@alfresco/js-api';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; 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 { Store } from '@ngrx/store';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { ContentApiService } from '@alfresco/aca-shared'; import { ContentApiService } from '@alfresco/aca-shared';
@ -44,32 +44,35 @@ export class DownloadEffects {
private contentUrlService: ContentUrlService private contentUrlService: ContentUrlService
) {} ) {}
@Effect({ dispatch: false }) downloadNode$ = createEffect(
downloadNode$ = this.actions$.pipe( () =>
ofType<DownloadNodesAction>(NodeActionTypes.Download), this.actions$.pipe(
map((action) => { ofType<DownloadNodesAction>(NodeActionTypes.Download),
if (action.payload && action.payload.length > 0) { map((action) => {
this.downloadNodes(action.payload); if (action.payload && action.payload.length > 0) {
} else { this.downloadNodes(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
this.store if (selection && !selection.isEmpty) {
.select(getCurrentVersion) this.store
.pipe(take(1)) .select(getCurrentVersion)
.subscribe((version) => { .pipe(take(1))
if (version) { .subscribe((version) => {
this.downloadFileVersion(selection.nodes[0].entry, version.entry); if (version) {
} else { this.downloadFileVersion(selection.nodes[0].entry, version.entry);
this.downloadNodes(selection.nodes); } else {
} this.downloadNodes(selection.nodes);
}); }
} });
}); }
} });
}) }
})
),
{ dispatch: false }
); );
private downloadNodes(toDownload: Array<MinimalNodeEntity>) { private downloadNodes(toDownload: Array<MinimalNodeEntity>) {

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Actions, ofType, createEffect } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { AppStore, NodeActionTypes, AddFavoriteAction, RemoveFavoriteAction, getAppSelection } from '@alfresco/aca-shared/store'; 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 { export class FavoriteEffects {
constructor(private store: Store<AppStore>, private actions$: Actions, private content: ContentManagementService) {} constructor(private store: Store<AppStore>, private actions$: Actions, private content: ContentManagementService) {}
@Effect({ dispatch: false }) addFavorite$ = createEffect(
addFavorite$ = this.actions$.pipe( () =>
ofType<AddFavoriteAction>(NodeActionTypes.AddFavorite), this.actions$.pipe(
map((action) => { ofType<AddFavoriteAction>(NodeActionTypes.AddFavorite),
if (action.payload && action.payload.length > 0) { map((action) => {
this.content.addFavorite(action.payload); if (action.payload && action.payload.length > 0) {
} else { this.content.addFavorite(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
this.content.addFavorite(selection.nodes); if (selection && !selection.isEmpty) {
} this.content.addFavorite(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) removeFavorite$ = createEffect(
removeFavorite$ = this.actions$.pipe( () =>
ofType<RemoveFavoriteAction>(NodeActionTypes.RemoveFavorite), this.actions$.pipe(
map((action) => { ofType<RemoveFavoriteAction>(NodeActionTypes.RemoveFavorite),
if (action.payload && action.payload.length > 0) { map((action) => {
this.content.removeFavorite(action.payload); if (action.payload && action.payload.length > 0) {
} else { this.content.removeFavorite(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
this.content.removeFavorite(selection.nodes); if (selection && !selection.isEmpty) {
} this.content.removeFavorite(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
} }

View File

@ -36,7 +36,7 @@ import {
getAppSelection getAppSelection
} from '@alfresco/aca-shared/store'; } from '@alfresco/aca-shared/store';
import { Injectable } from '@angular/core'; 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 { Store } from '@ngrx/store';
import { map, mergeMap, take } from 'rxjs/operators'; import { map, mergeMap, take } from 'rxjs/operators';
import { ContentApiService } from '@alfresco/aca-shared'; import { ContentApiService } from '@alfresco/aca-shared';
@ -51,94 +51,109 @@ export class LibraryEffects {
private contentApi: ContentApiService private contentApi: ContentApiService
) {} ) {}
@Effect({ dispatch: false }) deleteLibrary$ = createEffect(
deleteLibrary$ = this.actions$.pipe( () =>
ofType<DeleteLibraryAction>(LibraryActionTypes.Delete), this.actions$.pipe(
map((action) => { ofType<DeleteLibraryAction>(LibraryActionTypes.Delete),
if (action.payload) { map((action) => {
this.content.deleteLibrary(action.payload); if (action.payload) {
} else { this.content.deleteLibrary(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.library) { .subscribe((selection) => {
this.content.deleteLibrary(selection.library.entry.id); if (selection && selection.library) {
} this.content.deleteLibrary(selection.library.entry.id);
}); }
} });
})
);
@Effect({ dispatch: false })
leaveLibrary$ = this.actions$.pipe(
ofType<LeaveLibraryAction>(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<CreateLibraryAction>(LibraryActionTypes.Create),
mergeMap(() => this.content.createLibrary()),
map((libraryId) => new NavigateLibraryAction(libraryId))
);
@Effect({ dispatch: false })
navigateLibrary$ = this.actions$.pipe(
ofType<NavigateLibraryAction>(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<UpdateLibraryAction>(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 }
);
leaveLibrary$ = createEffect(
() =>
this.actions$.pipe(
ofType<LeaveLibraryAction>(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<CreateLibraryAction>(LibraryActionTypes.Create),
mergeMap(() => this.content.createLibrary()),
map((libraryId) => new NavigateLibraryAction(libraryId))
),
{ dispatch: true }
);
navigateLibrary$ = createEffect(
() =>
this.actions$.pipe(
ofType<NavigateLibraryAction>(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<UpdateLibraryAction>(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 }
); );
} }

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Actions, ofType, createEffect } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@ -62,303 +62,351 @@ export class NodeEffects {
private viewUtils: ViewUtilService private viewUtils: ViewUtilService
) {} ) {}
@Effect({ dispatch: false }) shareNode$ = createEffect(
shareNode$ = this.actions$.pipe( () =>
ofType<ShareNodeAction>(NodeActionTypes.Share), this.actions$.pipe(
map((action) => { ofType<ShareNodeAction>(NodeActionTypes.Share),
if (action.payload) { map((action) => {
this.contentService.shareNode(action.payload); if (action.payload) {
} else { this.contentService.shareNode(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.file) { .subscribe((selection) => {
this.contentService.shareNode(selection.file); if (selection && selection.file) {
} this.contentService.shareNode(selection.file);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) unshareNodes$ = createEffect(
unshareNodes$ = this.actions$.pipe( () =>
ofType<UnshareNodesAction>(NodeActionTypes.Unshare), this.actions$.pipe(
map((action) => { ofType<UnshareNodesAction>(NodeActionTypes.Unshare),
if (action && action.payload && action.payload.length > 0) { map((action) => {
this.contentService.unshareNodes(action.payload); if (action && action.payload && action.payload.length > 0) {
} else { this.contentService.unshareNodes(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
this.contentService.unshareNodes(selection.nodes); if (selection && !selection.isEmpty) {
} this.contentService.unshareNodes(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) purgeDeletedNodes$ = createEffect(
purgeDeletedNodes$ = this.actions$.pipe( () =>
ofType<PurgeDeletedNodesAction>(NodeActionTypes.PurgeDeleted), this.actions$.pipe(
map((action) => { ofType<PurgeDeletedNodesAction>(NodeActionTypes.PurgeDeleted),
if (action && action.payload && action.payload.length > 0) { map((action) => {
this.contentService.purgeDeletedNodes(action.payload); if (action && action.payload && action.payload.length > 0) {
} else { this.contentService.purgeDeletedNodes(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.count > 0) { .subscribe((selection) => {
this.contentService.purgeDeletedNodes(selection.nodes); if (selection && selection.count > 0) {
} this.contentService.purgeDeletedNodes(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) restoreDeletedNodes$ = createEffect(
restoreDeletedNodes$ = this.actions$.pipe( () =>
ofType<RestoreDeletedNodesAction>(NodeActionTypes.RestoreDeleted), this.actions$.pipe(
map((action) => { ofType<RestoreDeletedNodesAction>(NodeActionTypes.RestoreDeleted),
if (action && action.payload && action.payload.length > 0) { map((action) => {
this.contentService.restoreDeletedNodes(action.payload); if (action && action.payload && action.payload.length > 0) {
} else { this.contentService.restoreDeletedNodes(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.count > 0) { .subscribe((selection) => {
this.contentService.restoreDeletedNodes(selection.nodes); if (selection && selection.count > 0) {
} this.contentService.restoreDeletedNodes(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) deleteNodes$ = createEffect(
deleteNodes$ = this.actions$.pipe( () =>
ofType<DeleteNodesAction>(NodeActionTypes.Delete), this.actions$.pipe(
map((action) => { ofType<DeleteNodesAction>(NodeActionTypes.Delete),
if (action && action.payload && action.payload.length > 0) { map((action) => {
this.contentService.deleteNodes(action.payload); if (action && action.payload && action.payload.length > 0) {
} else { this.contentService.deleteNodes(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.count > 0) { .subscribe((selection) => {
this.contentService.deleteNodes(selection.nodes); if (selection && selection.count > 0) {
} this.contentService.deleteNodes(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) undoDeleteNodes$ = createEffect(
undoDeleteNodes$ = this.actions$.pipe( () =>
ofType<UndoDeleteNodesAction>(NodeActionTypes.UndoDelete), this.actions$.pipe(
map((action) => { ofType<UndoDeleteNodesAction>(NodeActionTypes.UndoDelete),
if (action.payload.length > 0) { map((action) => {
this.contentService.undoDeleteNodes(action.payload); if (action.payload.length > 0) {
} this.contentService.undoDeleteNodes(action.payload);
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) createFolder$ = createEffect(
createFolder$ = this.actions$.pipe( () =>
ofType<CreateFolderAction>(NodeActionTypes.CreateFolder), this.actions$.pipe(
map((action) => { ofType<CreateFolderAction>(NodeActionTypes.CreateFolder),
if (action.payload) { map((action) => {
this.contentService.createFolder(action.payload); if (action.payload) {
} else { this.contentService.createFolder(action.payload);
this.store } else {
.select(getCurrentFolder) this.store
.pipe(take(1)) .select(getCurrentFolder)
.subscribe((node) => { .pipe(take(1))
if (node && node.id) { .subscribe((node) => {
this.contentService.createFolder(node.id); if (node && node.id) {
} this.contentService.createFolder(node.id);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) editFolder$ = createEffect(
editFolder$ = this.actions$.pipe( () =>
ofType<EditFolderAction>(NodeActionTypes.EditFolder), this.actions$.pipe(
map((action) => { ofType<EditFolderAction>(NodeActionTypes.EditFolder),
if (action.payload) { map((action) => {
this.contentService.editFolder(action.payload); if (action.payload) {
} else { this.contentService.editFolder(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.folder) { .subscribe((selection) => {
this.contentService.editFolder(selection.folder); if (selection && selection.folder) {
} this.contentService.editFolder(selection.folder);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) copyNodes$ = createEffect(
copyNodes$ = this.actions$.pipe( () =>
ofType<CopyNodesAction>(NodeActionTypes.Copy), this.actions$.pipe(
map((action) => { ofType<CopyNodesAction>(NodeActionTypes.Copy),
if (action.payload && action.payload.length > 0) { map((action) => {
this.contentService.copyNodes(action.payload); if (action.payload && action.payload.length > 0) {
} else { this.contentService.copyNodes(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
this.contentService.copyNodes(selection.nodes); if (selection && !selection.isEmpty) {
} this.contentService.copyNodes(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) moveNodes$ = createEffect(
moveNodes$ = this.actions$.pipe( () =>
ofType<MoveNodesAction>(NodeActionTypes.Move), this.actions$.pipe(
map((action) => { ofType<MoveNodesAction>(NodeActionTypes.Move),
if (action.payload && action.payload.length > 0) { map((action) => {
this.contentService.moveNodes(action.payload); if (action.payload && action.payload.length > 0) {
} else { this.contentService.moveNodes(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
this.contentService.moveNodes(selection.nodes); if (selection && !selection.isEmpty) {
} this.contentService.moveNodes(selection.nodes);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) managePermissions$ = createEffect(
managePermissions$ = this.actions$.pipe( () =>
ofType<ManagePermissionsAction>(NodeActionTypes.ManagePermissions), this.actions$.pipe(
map((action) => { ofType<ManagePermissionsAction>(NodeActionTypes.ManagePermissions),
if (action && action.payload) { map((action) => {
const route = 'personal-files/details'; if (action && action.payload) {
this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id, 'permissions'])); const route = 'personal-files/details';
} else { this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id, 'permissions']));
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
const route = 'personal-files/details'; if (selection && !selection.isEmpty) {
this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id, 'permissions'])); const route = 'personal-files/details';
} this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id, 'permissions']));
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) expandInfoDrawer$ = createEffect(
expandInfoDrawer$ = this.actions$.pipe( () =>
ofType<ExpandInfoDrawerAction>(NodeActionTypes.ExpandInfoDrawer), this.actions$.pipe(
map((action) => { ofType<ExpandInfoDrawerAction>(NodeActionTypes.ExpandInfoDrawer),
if (action && action.payload) { map((action) => {
const route = 'personal-files/details'; if (action && action.payload) {
this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id])); const route = 'personal-files/details';
} else { this.store.dispatch(new NavigateRouteAction([route, action.payload.entry.id]));
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
const route = 'personal-files/details'; if (selection && !selection.isEmpty) {
this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id])); const route = 'personal-files/details';
} this.store.dispatch(new NavigateRouteAction([route, selection.first.entry.id]));
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) manageVersions$ = createEffect(
manageVersions$ = this.actions$.pipe( () =>
ofType<ManageVersionsAction>(NodeActionTypes.ManageVersions), this.actions$.pipe(
map((action) => { ofType<ManageVersionsAction>(NodeActionTypes.ManageVersions),
if (action && action.payload) { map((action) => {
this.contentService.manageVersions(action.payload); if (action && action.payload) {
} else { this.contentService.manageVersions(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.file) { .subscribe((selection) => {
this.contentService.manageVersions(selection.file); if (selection && selection.file) {
} this.contentService.manageVersions(selection.file);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) printFile$ = createEffect(
printFile$ = this.actions$.pipe( () =>
ofType<PrintFileAction>(NodeActionTypes.PrintFile), this.actions$.pipe(
map((action) => { ofType<PrintFileAction>(NodeActionTypes.PrintFile),
if (action && action.payload) { map((action) => {
this.printFile(action.payload); if (action && action.payload) {
} else { this.printFile(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.file) { .subscribe((selection) => {
this.printFile(selection.file); if (selection && selection.file) {
} this.printFile(selection.file);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) unlockWrite$ = createEffect(
unlockWrite$ = this.actions$.pipe( () =>
ofType<UnlockWriteAction>(NodeActionTypes.UnlockForWriting), this.actions$.pipe(
map((action) => { ofType<UnlockWriteAction>(NodeActionTypes.UnlockForWriting),
if (action && action.payload) { map((action) => {
this.contentService.unlockNode(action.payload); if (action && action.payload) {
} else { this.contentService.unlockNode(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && selection.file) { .subscribe((selection) => {
this.contentService.unlockNode(selection.file); if (selection && selection.file) {
} this.contentService.unlockNode(selection.file);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) aspectList$ = createEffect(
aspectList$ = this.actions$.pipe( () =>
ofType<ManageAspectsAction>(NodeActionTypes.ChangeAspects), this.actions$.pipe(
map((action) => { ofType<ManageAspectsAction>(NodeActionTypes.ChangeAspects),
if (action && action.payload) { map((action) => {
this.contentService.manageAspects(action.payload); if (action && action.payload) {
} else { this.contentService.manageAspects(action.payload);
this.store } else {
.select(getAppSelection) this.store
.pipe(take(1)) .select(getAppSelection)
.subscribe((selection) => { .pipe(take(1))
if (selection && !selection.isEmpty) { .subscribe((selection) => {
this.contentService.manageAspects(selection.nodes[0]); if (selection && !selection.isEmpty) {
} this.contentService.manageAspects(selection.nodes[0]);
}); }
} });
}) }
})
),
{ dispatch: false }
); );
printFile(node: any) { printFile(node: any) {

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Actions, ofType, createEffect } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { SearchActionTypes, SearchByTermAction, SearchOptionIds } from '@alfresco/aca-shared/store'; import { SearchActionTypes, SearchByTermAction, SearchOptionIds } from '@alfresco/aca-shared/store';
@ -33,19 +33,22 @@ import { Router } from '@angular/router';
export class SearchEffects { export class SearchEffects {
constructor(private actions$: Actions, private router: Router) {} constructor(private actions$: Actions, private router: Router) {}
@Effect({ dispatch: false }) searchByTerm$ = createEffect(
searchByTerm$ = this.actions$.pipe( () =>
ofType<SearchByTermAction>(SearchActionTypes.SearchByTerm), this.actions$.pipe(
map((action) => { ofType<SearchByTermAction>(SearchActionTypes.SearchByTerm),
const query = action.payload.replace(/[(]/g, '%28').replace(/[)]/g, '%29'); map((action) => {
const query = action.payload.replace(/[(]/g, '%28').replace(/[)]/g, '%29');
const libItem = action.searchOptions.find((item) => item.id === SearchOptionIds.Libraries); const libItem = action.searchOptions.find((item) => item.id === SearchOptionIds.Libraries);
const librarySelected = !!libItem && libItem.value; const librarySelected = !!libItem && libItem.value;
if (librarySelected) { if (librarySelected) {
this.router.navigateByUrl('/search-libraries;q=' + encodeURIComponent(query)); this.router.navigateByUrl('/search-libraries;q=' + encodeURIComponent(query));
} else { } else {
this.router.navigateByUrl('/search;q=' + encodeURIComponent(query)); this.router.navigateByUrl('/search;q=' + encodeURIComponent(query));
} }
}) })
),
{ dispatch: false }
); );
} }

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Actions, ofType, createEffect } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map, switchMap, debounceTime, take, catchError } from 'rxjs/operators'; import { map, switchMap, debounceTime, take, catchError } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@ -46,7 +46,7 @@ import { MatDialog } from '@angular/material/dialog';
@Injectable() @Injectable()
export class TemplateEffects { export class TemplateEffects {
_nodesApi: NodesApi; private _nodesApi: NodesApi;
get nodesApi(): NodesApi { get nodesApi(): NodesApi {
this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance()); this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance());
return this._nodesApi; return this._nodesApi;
@ -61,53 +61,65 @@ export class TemplateEffects {
private nodeTemplateService: NodeTemplateService private nodeTemplateService: NodeTemplateService
) {} ) {}
@Effect({ dispatch: false }) fileFromTemplate$ = createEffect(
fileFromTemplate$ = this.actions$.pipe( () =>
ofType<FileFromTemplate>(TemplateActionTypes.FileFromTemplate), this.actions$.pipe(
map(() => { ofType<FileFromTemplate>(TemplateActionTypes.FileFromTemplate),
this.openDialog({ map(() => {
primaryPathName: 'app:node_templates', this.openDialog({
selectionType: 'file' primaryPathName: 'app:node_templates',
}); selectionType: 'file'
}) });
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) folderFromTemplate$ = createEffect(
folderFromTemplate$ = this.actions$.pipe( () =>
ofType<FolderFromTemplate>(TemplateActionTypes.FolderFromTemplate), this.actions$.pipe(
map(() => ofType<FolderFromTemplate>(TemplateActionTypes.FolderFromTemplate),
this.openDialog({ map(() =>
primaryPathName: 'app:space_templates', this.openDialog({
selectionType: 'folder' primaryPathName: 'app:space_templates',
}) selectionType: 'folder'
) })
);
@Effect({ dispatch: false })
createFromTemplate$ = this.actions$.pipe(
ofType<CreateFromTemplate>(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) { { dispatch: false }
this.store.dispatch(new CreateFromTemplateSuccess(node.entry));
}
});
})
); );
@Effect({ dispatch: false }) createFromTemplate$ = createEffect(
createFromTemplateSuccess$ = this.actions$.pipe( () =>
ofType<CreateFromTemplateSuccess>(TemplateActionTypes.CreateFromTemplateSuccess), this.actions$.pipe(
map((payload) => { ofType<CreateFromTemplate>(TemplateActionTypes.CreateFromTemplate),
this.matDialog.closeAll(); map((action) => {
this.appHookService.reload.next(payload.node); 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<CreateFromTemplateSuccess>(TemplateActionTypes.CreateFromTemplateSuccess),
map((payload) => {
this.matDialog.closeAll();
this.appHookService.reload.next(payload.node);
})
),
{ dispatch: false }
); );
private openDialog(config: TemplateDialogConfig) { private openDialog(config: TemplateDialogConfig) {

View File

@ -35,7 +35,7 @@ import {
} from '@alfresco/aca-shared/store'; } from '@alfresco/aca-shared/store';
import { FileModel, FileUtils, UploadService } from '@alfresco/adf-core'; import { FileModel, FileUtils, UploadService } from '@alfresco/adf-core';
import { Injectable, NgZone, RendererFactory2 } from '@angular/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 { Store } from '@ngrx/store';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { catchError, map, take } from 'rxjs/operators'; import { catchError, map, take } from 'rxjs/operators';
@ -85,34 +85,43 @@ export class UploadEffects {
renderer.appendChild(document.body, this.folderInput); renderer.appendChild(document.body, this.folderInput);
} }
@Effect({ dispatch: false }) uploadFiles$ = createEffect(
uploadFiles$ = this.actions$.pipe( () =>
ofType<UploadFilesAction>(UploadActionTypes.UploadFiles), this.actions$.pipe(
map(() => { ofType<UploadFilesAction>(UploadActionTypes.UploadFiles),
this.fileInput.click(); map(() => {
}) this.fileInput.click();
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) uploadFolder$ = createEffect(
uploadFolder$ = this.actions$.pipe( () =>
ofType<UploadFolderAction>(UploadActionTypes.UploadFolder), this.actions$.pipe(
map(() => { ofType<UploadFolderAction>(UploadActionTypes.UploadFolder),
this.folderInput.click(); map(() => {
}) this.folderInput.click();
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) uploadVersion$ = createEffect(
uploadVersion$ = this.actions$.pipe( () =>
ofType<UploadFileVersionAction>(UploadActionTypes.UploadFileVersion), this.actions$.pipe(
map((action) => { ofType<UploadFileVersionAction>(UploadActionTypes.UploadFileVersion),
if (action?.payload) { map((action) => {
const node = action?.payload?.detail?.data?.node?.entry; if (action?.payload) {
const file: any = action?.payload?.detail?.files[0]?.file; const node = action?.payload?.detail?.data?.node?.entry;
this.contentService.versionUpdateDialog(node, file); const file: any = action?.payload?.detail?.files[0]?.file;
} else if (!action?.payload) { this.contentService.versionUpdateDialog(node, file);
this.fileVersionInput.click(); } else if (!action?.payload) {
} this.fileVersionInput.click();
}) }
})
),
{ dispatch: false }
); );
uploadVersion() { uploadVersion() {

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Actions, ofType, createEffect } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map, take, tap } from 'rxjs/operators'; import { map, take, tap } from 'rxjs/operators';
import { import {
@ -57,106 +57,121 @@ export class ViewerEffects {
private dialog: MatDialog private dialog: MatDialog
) {} ) {}
@Effect({ dispatch: false }) fullscreenViewer$ = createEffect(
fullscreenViewer$ = this.actions$.pipe( () =>
ofType<FullscreenViewerAction>(ViewerActionTypes.FullScreen), this.actions$.pipe(
map(() => { ofType<FullscreenViewerAction>(ViewerActionTypes.FullScreen),
this.enterFullScreen(); map(() => {
}) this.enterFullScreen();
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) viewNode$ = createEffect(
viewNode$ = this.actions$.pipe( () =>
ofType<ViewNodeAction>(ViewerActionTypes.ViewNode), this.actions$.pipe(
map((action) => { ofType<ViewNodeAction>(ViewerActionTypes.ViewNode),
if (action.viewNodeExtras) { map((action) => {
const { location, path } = action.viewNodeExtras; if (action.viewNodeExtras) {
const { location, path } = action.viewNodeExtras;
if (location) { if (location) {
const navigation = this.getNavigationCommands(location); const navigation = this.getNavigationCommands(location);
this.router.navigate([...navigation, { outlets: { viewer: ['view', action.nodeId] } }], { this.router.navigate([...navigation, { outlets: { viewer: ['view', action.nodeId] } }], {
queryParams: { location } queryParams: { location }
}); });
} }
if (path) { if (path) {
this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }], { this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }], {
queryParams: { path } queryParams: { path }
}); });
} }
} else { } else {
this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }]); this.router.navigate(['view', { outlets: { viewer: [action.nodeId] } }]);
} }
}) })
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) viewFile$ = createEffect(
viewFile$ = this.actions$.pipe( () =>
ofType<ViewFileAction>(ViewerActionTypes.ViewFile), this.actions$.pipe(
map((action) => { ofType<ViewFileAction>(ViewerActionTypes.ViewFile),
if (action.payload && action.payload.entry) { map((action) => {
const { id, nodeId, isFile } = action.payload.entry as any; if (action.payload && action.payload.entry) {
const { id, nodeId, isFile } = action.payload.entry as any;
if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) {
this.displayPreview(nodeId || id, action.parentId); this.displayPreview(nodeId || id, action.parentId);
} }
} else { } else {
this.store this.store
.select(fileToPreview) .select(fileToPreview)
.pipe(take(1)) .pipe(take(1))
.subscribe((result) => { .subscribe((result) => {
if (result.selection && result.selection.file) { if (result.selection && result.selection.file) {
const { id, nodeId, isFile } = result.selection.file.entry as any; const { id, nodeId, isFile } = result.selection.file.entry as any;
if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) {
const parentId = result.folder ? result.folder.id : null; const parentId = result.folder ? result.folder.id : null;
this.displayPreview(nodeId || id, parentId); this.displayPreview(nodeId || id, parentId);
}
}
});
}
})
),
{ dispatch: false }
);
viewNodeVersion$ = createEffect(
() =>
this.actions$.pipe(
ofType<ViewNodeVersionAction>(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<PluginPreviewAction>(ViewerActionTypes.PluginPreview),
tap((action) => {
this.router.navigate([
action.pluginRoute,
{
outlets: {
viewer: ['preview', action.nodeId]
} }
} }
}); ]);
} })
}) ),
); { dispatch: false }
@Effect({ dispatch: false })
viewNodeVersion$ = this.actions$.pipe(
ofType<ViewNodeVersionAction>(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<PluginPreviewAction>(ViewerActionTypes.PluginPreview),
tap((action) => {
this.router.navigate([
action.pluginRoute,
{
outlets: {
viewer: ['preview', action.nodeId]
}
}
]);
})
); );
private displayPreview(nodeId: string, parentId: string) { private displayPreview(nodeId: string, parentId: string) {

View File

@ -63,14 +63,17 @@ See also:
Update `src/app/store/effects/app.effects.ts`: Update `src/app/store/effects/app.effects.ts`:
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions';
@Injectable() @Injectable()
export class AppEffects { export class AppEffects {
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => {}) map(() => {})
),
{ dispatch: false }
); );
} }
``` ```
@ -82,6 +85,7 @@ See also:
Update to raise a dialog Update to raise a dialog
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; 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 { export class AppEffects {
constructor(private dialog: MatDialog) {} constructor(private dialog: MatDialog) {}
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => { map(() => {
this.dialog.open(MyExtensionDialogComponent) this.dialog.open(MyExtensionDialogComponent)
}) })
),
{ dispatch: false }
); );
} }
``` ```

View File

@ -189,14 +189,17 @@ export class ShowMydDialogAction implements Action {
`src/app/store/effects/app.effects.ts` を更新します: `src/app/store/effects/app.effects.ts` を更新します:
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions';
@Injectable() @Injectable()
export class AppEffects { export class AppEffects {
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => {}) map(() => {})
),
{ dispatch: false }
); );
} }
``` ```
@ -208,6 +211,7 @@ export class AppEffects {
ダイアログを表示するための更新 ダイアログを表示するための更新
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; 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 { export class AppEffects {
constructor(private dialog: MatDialog) {} constructor(private dialog: MatDialog) {}
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => { map(() => {
this.dialog.open(MyExtensionDialogComponent) this.dialog.open(MyExtensionDialogComponent)
}) })
),
{ dispatch: false }
); );
} }
``` ```

View File

@ -74,14 +74,17 @@ export class ShowMydDialogAction implements Action {
`src/app/store/effects/app.effects.ts` を更新します: `src/app/store/effects/app.effects.ts` を更新します:
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions';
@Injectable() @Injectable()
export class AppEffects { export class AppEffects {
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => {}) map(() => {})
),
{ dispatch: false }
); );
} }
``` ```
@ -93,6 +96,7 @@ export class AppEffects {
ダイアログを表示するための更新 ダイアログを表示するための更新
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; 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 { export class AppEffects {
constructor(private dialog: MatDialog) {} constructor(private dialog: MatDialog) {}
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => { map(() => {
this.dialog.open(MyExtensionDialogComponent) this.dialog.open(MyExtensionDialogComponent)
}) })
),
{ dispatch: false }
); );
} }
``` ```

View File

@ -63,14 +63,17 @@ See also:
Update `src/app/store/effects/app.effects.ts`: Update `src/app/store/effects/app.effects.ts`:
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions'; import { ShowMydDialogAction, SHOW_MY_DIALOG } from '../actions/app.actions';
@Injectable() @Injectable()
export class AppEffects { export class AppEffects {
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => {}) map(() => {})
),
{ dispatch: false }
); );
} }
``` ```
@ -82,6 +85,7 @@ See also:
Update to raise a dialog Update to raise a dialog
```ts ```ts
import { createEffect } from '@ngrx/effects';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { MyExtensionDialogComponent } from '../../dialogs/my-extension-dialog/my-extension-dialog.component'; 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 { export class AppEffects {
constructor(private dialog: MatDialog) {} constructor(private dialog: MatDialog) {}
@Effect({ dispatch: false }) showMyDialog$ = createEffect(
showMyDialog$ = this.actions$.pipe( () => this.actions$.pipe(
ofType<ShowMydDialogAction>(SHOW_MY_DIALOG), ofType<ShowMydDialogAction>(SHOW_MY_DIALOG),
map(() => { map(() => {
this.dialog.open(MyExtensionDialogComponent) this.dialog.open(MyExtensionDialogComponent)
}) })
),
{ dispatch: false }
); );
} }
``` ```

62
package-lock.json generated
View File

@ -2693,24 +2693,36 @@
} }
}, },
"@ngrx/effects": { "@ngrx/effects": {
"version": "9.2.1", "version": "10.1.2",
"resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-9.2.1.tgz", "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-10.1.2.tgz",
"integrity": "sha512-qWOnRYHdKzjCvcH6WOKra+KPlrMyS9ahoVvOSboJK7S3xzj9Pp5mgtcDBXqN9LlPbXDEzjZjFDJQMAtlP4c3Ig==" "integrity": "sha512-6pX6FEzLlqdbtFVMbCvscsaL6QC/L95e72JKj76Xz+8V77UTlpVsxWyMo7YU9pM4EXNpBGmOpMs2xKjfBfK05Q==",
"requires": {
"tslib": "^2.0.0"
}
}, },
"@ngrx/router-store": { "@ngrx/router-store": {
"version": "9.2.1", "version": "10.1.2",
"resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-9.2.1.tgz", "resolved": "https://registry.npmjs.org/@ngrx/router-store/-/router-store-10.1.2.tgz",
"integrity": "sha512-r7IS7OqvM2/4HO2lDP96r0zMMgiF2iNXFJF38DMstGEp23BlRkcsNz+2PSgNT8B1YgTUjUAbtnhCSRxs/kl5kw==" "integrity": "sha512-IBsZee5ZUmLbXkY/O4OjhJP1Q6mdu4lcLcQ9jeXsdCMH/Vvc0EGK+MlhsZrxv5+v2ZXb1bhtKsLBUsTovanLWA==",
"requires": {
"tslib": "^2.0.0"
}
}, },
"@ngrx/store": { "@ngrx/store": {
"version": "9.2.1", "version": "10.1.2",
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-9.2.1.tgz", "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-10.1.2.tgz",
"integrity": "sha512-18mLKH7CAi5+F1zYbbxoCDKE8piCxZkwOoPlXEsq/LBKrZvYIvOeSlEXMjiUp3cCL3QOT27QvWIqQkIuE9b7mg==" "integrity": "sha512-FUjN786ch4Qt9WgJ78ef7Yquq3mPCekgcWgZrs4ycZw1f+KdfTHLTk1bGDtO8A8CzOya5yTT7KhxbdVjbOS5ng==",
"requires": {
"tslib": "^2.0.0"
}
}, },
"@ngrx/store-devtools": { "@ngrx/store-devtools": {
"version": "9.2.1", "version": "10.1.2",
"resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-9.2.1.tgz", "resolved": "https://registry.npmjs.org/@ngrx/store-devtools/-/store-devtools-10.1.2.tgz",
"integrity": "sha512-f7/hg884uSKsXiQbcdBJS/3rpk1KKFmy6gR0OeCqxjkZRjSq/onCsEXPKURt7MqJcRYCiNA2rIHxF/fz2j+8Kg==" "integrity": "sha512-HE681GuZ+lRgSXpgt7y7LKzsfu/+Tgy9yPZpaitvkhg+eCIjnN5Uvs1rWqETHYWnsKliW25yoqFUAVw+xb7hug==",
"requires": {
"tslib": "^2.0.0"
}
}, },
"@ngtools/webpack": { "@ngtools/webpack": {
"version": "10.2.3", "version": "10.2.3",
@ -18439,18 +18451,18 @@
} }
}, },
"string.prototype.matchall": { "string.prototype.matchall": {
"version": "4.0.6", "version": "4.0.7",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz",
"integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==",
"dev": true, "dev": true,
"requires": { "requires": {
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"define-properties": "^1.1.3", "define-properties": "^1.1.3",
"es-abstract": "^1.19.1", "es-abstract": "^1.19.1",
"get-intrinsic": "^1.1.1", "get-intrinsic": "^1.1.1",
"has-symbols": "^1.0.2", "has-symbols": "^1.0.3",
"internal-slot": "^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" "side-channel": "^1.0.4"
}, },
"dependencies": { "dependencies": {
@ -18482,6 +18494,12 @@
"unbox-primitive": "^1.0.1" "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": { "is-callable": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", "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", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
"integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
"dev": true "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"
}
} }
} }
}, },

View File

@ -43,10 +43,10 @@
"@angular/router": "10.0.4", "@angular/router": "10.0.4",
"@mat-datetimepicker/core": "5.1.1", "@mat-datetimepicker/core": "5.1.1",
"@mat-datetimepicker/moment": "5.1.1", "@mat-datetimepicker/moment": "5.1.1",
"@ngrx/effects": "^9.2.0", "@ngrx/effects": "^10.1.2",
"@ngrx/router-store": "^9.2.0", "@ngrx/router-store": "^10.1.2",
"@ngrx/store": "^9.2.0", "@ngrx/store": "^10.1.2",
"@ngrx/store-devtools": "^9.2.0", "@ngrx/store-devtools": "^10.1.2",
"@ngx-translate/core": "^13.0.0", "@ngx-translate/core": "^13.0.0",
"minimatch-browser": "^1.0.0", "minimatch-browser": "^1.0.0",
"moment": "^2.27.0", "moment": "^2.27.0",

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Actions, ofType, createEffect } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
@ -33,9 +33,12 @@ import { CloseModalDialogsAction, AppActionTypes } from '../actions/app.actions'
export class DialogEffects { export class DialogEffects {
constructor(private actions$: Actions, private matDialog: MatDialog) {} constructor(private actions$: Actions, private matDialog: MatDialog) {}
@Effect({ dispatch: false }) closeAll$ = createEffect(
closeAll$ = this.actions$.pipe( () =>
ofType<CloseModalDialogsAction>(AppActionTypes.CloseModalDialogs), this.actions$.pipe(
map(() => this.matDialog.closeAll()) ofType<CloseModalDialogsAction>(AppActionTypes.CloseModalDialogs),
map(() => this.matDialog.closeAll())
),
{ dispatch: false }
); );
} }

View File

@ -25,7 +25,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Router } from '@angular/router'; 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 { MinimalNodeEntryEntity, PathInfoEntity } from '@alfresco/js-api';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@ -45,48 +45,63 @@ import { SnackbarErrorAction } from '../actions/snackbar.actions';
export class RouterEffects { export class RouterEffects {
constructor(private store: Store<AppStore>, private actions$: Actions, private router: Router, private location: Location) {} constructor(private store: Store<AppStore>, private actions$: Actions, private router: Router, private location: Location) {}
@Effect({ dispatch: false }) navigateUrl$ = createEffect(
navigateUrl$ = this.actions$.pipe( () =>
ofType<NavigateUrlAction>(RouterActionTypes.NavigateUrl), this.actions$.pipe(
map((action) => { ofType<NavigateUrlAction>(RouterActionTypes.NavigateUrl),
if (action.payload) { map((action) => {
this.router.navigateByUrl(action.payload); if (action.payload) {
} this.router.navigateByUrl(action.payload);
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) navigateRoute$ = createEffect(
navigateRoute$ = this.actions$.pipe( () =>
ofType<NavigateRouteAction>(RouterActionTypes.NavigateRoute), this.actions$.pipe(
map((action) => { ofType<NavigateRouteAction>(RouterActionTypes.NavigateRoute),
this.router.navigate(action.payload); map((action) => {
}) this.router.navigate(action.payload);
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) navigateToFolder$ = createEffect(
navigateToFolder$ = this.actions$.pipe( () =>
ofType<NavigateToFolder>(RouterActionTypes.NavigateFolder), this.actions$.pipe(
map((action) => { ofType<NavigateToFolder>(RouterActionTypes.NavigateFolder),
if (action.payload && action.payload.entry) { map((action) => {
this.navigateToFolder(action.payload.entry); if (action.payload && action.payload.entry) {
} this.navigateToFolder(action.payload.entry);
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) navigateToParentFolder$ = createEffect(
navigateToParentFolder$ = this.actions$.pipe( () =>
ofType<NavigateToParentFolder>(RouterActionTypes.NavigateParentFolder), this.actions$.pipe(
map((action) => { ofType<NavigateToParentFolder>(RouterActionTypes.NavigateParentFolder),
if (action.payload && action.payload.entry) { map((action) => {
this.navigateToParentFolder(action.payload.entry); if (action.payload && action.payload.entry) {
} this.navigateToParentFolder(action.payload.entry);
}) }
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) navigateToPreviousPage$ = createEffect(
navigateToPreviousPage$ = this.actions$.pipe( () =>
ofType<NavigateToPreviousPage>(RouterActionTypes.NavigateToPreviousPage), this.actions$.pipe(
map(() => this.location.back()) ofType<NavigateToPreviousPage>(RouterActionTypes.NavigateToPreviousPage),
map(() => this.location.back())
),
{ dispatch: false }
); );
private navigateToFolder(node: MinimalNodeEntryEntity) { private navigateToFolder(node: MinimalNodeEntryEntity) {

View File

@ -26,7 +26,7 @@
import { TranslationService } from '@alfresco/adf-core'; import { TranslationService } from '@alfresco/adf-core';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar'; 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 { Store } from '@ngrx/store';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { AppStore } from '../states/app.state'; import { AppStore } from '../states/app.state';
@ -41,28 +41,37 @@ export class SnackbarEffects {
private translationService: TranslationService private translationService: TranslationService
) {} ) {}
@Effect({ dispatch: false }) infoEffect = createEffect(
infoEffect = this.actions$.pipe( () =>
ofType<SnackbarInfoAction>(SnackbarActionTypes.Info), this.actions$.pipe(
map((action: SnackbarInfoAction) => { ofType<SnackbarInfoAction>(SnackbarActionTypes.Info),
this.showSnackBar(action, 'adf-info-snackbar'); map((action: SnackbarInfoAction) => {
}) this.showSnackBar(action, 'adf-info-snackbar');
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) warningEffect = createEffect(
warningEffect = this.actions$.pipe( () =>
ofType<SnackbarWarningAction>(SnackbarActionTypes.Warning), this.actions$.pipe(
map((action: SnackbarWarningAction) => { ofType<SnackbarWarningAction>(SnackbarActionTypes.Warning),
this.showSnackBar(action, 'adf-warning-snackbar'); map((action: SnackbarWarningAction) => {
}) this.showSnackBar(action, 'adf-warning-snackbar');
})
),
{ dispatch: false }
); );
@Effect({ dispatch: false }) errorEffect = createEffect(
errorEffect = this.actions$.pipe( () =>
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error), this.actions$.pipe(
map((action: SnackbarErrorAction) => { ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
this.showSnackBar(action, 'adf-error-snackbar'); map((action: SnackbarErrorAction) => {
}) this.showSnackBar(action, 'adf-error-snackbar');
})
),
{ dispatch: false }
); );
private showSnackBar(action: SnackbarAction, panelClass: string) { private showSnackBar(action: SnackbarAction, panelClass: string) {

View File

@ -24,7 +24,7 @@
*/ */
import { Injectable } from '@angular/core'; 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 { map } from 'rxjs/operators';
import { AOS_ACTION, AosAction } from '../actions/aos.actions'; import { AOS_ACTION, AosAction } from '../actions/aos.actions';
@ -34,13 +34,16 @@ import { AosEditOnlineService } from '../aos-extension.service';
export class AosEffects { export class AosEffects {
constructor(private actions$: Actions, private aosEditOnlineService: AosEditOnlineService) {} constructor(private actions$: Actions, private aosEditOnlineService: AosEditOnlineService) {}
@Effect({ dispatch: false }) openOffice$ = createEffect(
openOffice$ = this.actions$.pipe( () =>
ofType<AosAction>(AOS_ACTION), this.actions$.pipe(
map((action) => { ofType<AosAction>(AOS_ACTION),
if (action.payload) { map((action) => {
this.aosEditOnlineService.onActionEditOnlineAos(action.payload); if (action.payload) {
} this.aosEditOnlineService.onActionEditOnlineAos(action.payload);
}) }
})
),
{ dispatch: false }
); );
} }