reload active doclist via NgRx actions (#978)

* doclist reload action and effect

* deprecate folderEdited event

* deprecate "favoriteToggle" event

* deprecate "favoriteRemoved" event

* update docs

* unified reload function

* deprecate "nodesRestored" event

* deprecate "nodesPurged" event

* test fixes

* deprecate "nodesMoved" event

* reduce the use of "nodesDeleted"
This commit is contained in:
Denys Vuika 2019-02-27 13:45:55 +00:00 committed by GitHub
parent 0b5555d2fc
commit a25385049d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 89 additions and 289 deletions

View File

@ -117,3 +117,4 @@ Below is the list of public actions types you can use in the plugin definitions
| PRINT_FILE | MinimalNodeEntity | Print the file opened in the Viewer (or selected). | | PRINT_FILE | MinimalNodeEntity | Print the file opened in the Viewer (or selected). |
| FULLSCREEN_VIEWER | n/a | Enters fullscreen mode to view the file opened in the Viewer. | | FULLSCREEN_VIEWER | n/a | Enters fullscreen mode to view the file opened in the Viewer. |
| LOGOUT | n/a | Log out and redirect to Login screen. | | LOGOUT | n/a | Log out and redirect to Login screen. |
| RELOAD_DOCUMENT_LIST | n/a | Reload active document list |

View File

@ -35,7 +35,6 @@ import {
AppConfigPipe AppConfigPipe
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services'; import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../services/content-management.service';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { FavoritesComponent } from './favorites.component'; import { FavoritesComponent } from './favorites.component';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
@ -45,7 +44,6 @@ describe('FavoritesComponent', () => {
let fixture: ComponentFixture<FavoritesComponent>; let fixture: ComponentFixture<FavoritesComponent>;
let component: FavoritesComponent; let component: FavoritesComponent;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let contentService: ContentManagementService;
let contentApi: ContentApiService; let contentApi: ContentApiService;
let router: Router; let router: Router;
let page; let page;
@ -97,42 +95,9 @@ describe('FavoritesComponent', () => {
); );
contentApi = TestBed.get(ContentApiService); contentApi = TestBed.get(ContentApiService);
contentService = TestBed.get(ContentManagementService);
router = TestBed.get(Router); router = TestBed.get(Router);
}); });
describe('Events', () => {
beforeEach(() => {
spyOn(component, 'reload');
fixture.detectChanges();
});
it('should refresh on editing folder event', () => {
contentService.folderEdited.next(null);
expect(component.reload).toHaveBeenCalled();
});
it('should refresh on move node event', () => {
contentService.nodesMoved.next(null);
expect(component.reload).toHaveBeenCalled();
});
it('should refresh on node deleted event', () => {
contentService.nodesDeleted.next(null);
expect(component.reload).toHaveBeenCalled();
});
it('should refresh on node restore event', () => {
contentService.nodesRestored.next(null);
expect(component.reload).toHaveBeenCalled();
});
});
describe('Node navigation', () => { describe('Node navigation', () => {
beforeEach(() => { beforeEach(() => {
spyOn(contentApi, 'getNode').and.returnValue(of({ entry: node })); spyOn(contentApi, 'getNode').and.returnValue(of({ entry: node }));
@ -173,12 +138,12 @@ describe('FavoritesComponent', () => {
describe('refresh', () => { describe('refresh', () => {
it('should call document list reload', () => { it('should call document list reload', () => {
spyOn(component.documentList, 'reload'); spyOn(component, 'reload');
fixture.detectChanges(); fixture.detectChanges();
component.reload(); component.reload();
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
}); });
}); });

View File

@ -65,13 +65,6 @@ export class FavoritesComponent extends PageComponent implements OnInit {
super.ngOnInit(); super.ngOnInit();
this.subscriptions = this.subscriptions.concat([ this.subscriptions = this.subscriptions.concat([
this.content.nodesDeleted.subscribe(() => this.reload()),
this.content.nodesRestored.subscribe(() => this.reload()),
this.content.folderEdited.subscribe(() => this.reload()),
this.content.nodesMoved.subscribe(() => this.reload()),
this.content.favoriteRemoved.subscribe(() => this.reload()),
this.content.favoriteToggle.subscribe(() => this.reload()),
this.content.favoriteToggle.subscribe(() => this.reload()),
this.uploadService.fileUploadComplete this.uploadService.fileUploadComplete
.pipe(debounceTime(300)) .pipe(debounceTime(300))
.subscribe(file => this.onFileUploadedEvent(file)), .subscribe(file => this.onFileUploadedEvent(file)),
@ -125,6 +118,6 @@ export class FavoritesComponent extends PageComponent implements OnInit {
} }
private onFileUploadedEvent(event: FileUploadEvent) { private onFileUploadedEvent(event: FileUploadEvent) {
this.documentList.reload(); this.reload();
} }
} }

View File

@ -41,7 +41,6 @@ import {
AppConfigPipe AppConfigPipe
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services'; import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../services/content-management.service';
import { NodeActionsService } from '../../services/node-actions.service'; import { NodeActionsService } from '../../services/node-actions.service';
import { FilesComponent } from './files.component'; import { FilesComponent } from './files.component';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
@ -52,7 +51,6 @@ describe('FilesComponent', () => {
let node; let node;
let fixture: ComponentFixture<FilesComponent>; let fixture: ComponentFixture<FilesComponent>;
let component: FilesComponent; let component: FilesComponent;
let contentManagementService: ContentManagementService;
let uploadService: UploadService; let uploadService: UploadService;
let router: Router; let router: Router;
let nodeActionsService: NodeActionsService; let nodeActionsService: NodeActionsService;
@ -86,7 +84,6 @@ describe('FilesComponent', () => {
fixture = TestBed.createComponent(FilesComponent); fixture = TestBed.createComponent(FilesComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
contentManagementService = TestBed.get(ContentManagementService);
uploadService = TestBed.get(UploadService); uploadService = TestBed.get(UploadService);
router = TestBed.get(Router); router = TestBed.get(Router);
nodeActionsService = TestBed.get(NodeActionsService); nodeActionsService = TestBed.get(NodeActionsService);
@ -145,7 +142,7 @@ describe('FilesComponent', () => {
describe('refresh on events', () => { describe('refresh on events', () => {
beforeEach(() => { beforeEach(() => {
spyOn(contentApi, 'getNode').and.returnValue(of({ entry: node })); spyOn(contentApi, 'getNode').and.returnValue(of({ entry: node }));
spyOn(component.documentList, 'reload'); spyOn(component, 'reload');
fixture.detectChanges(); fixture.detectChanges();
}); });
@ -160,7 +157,7 @@ describe('FilesComponent', () => {
nodeActionsService.contentCopied.next(nodes); nodeActionsService.contentCopied.next(nodes);
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
it('should not call refresh onContentCopied event when parent mismatch', () => { it('should not call refresh onContentCopied event when parent mismatch', () => {
@ -173,37 +170,7 @@ describe('FilesComponent', () => {
nodeActionsService.contentCopied.next(nodes); nodeActionsService.contentCopied.next(nodes);
expect(component.documentList.reload).not.toHaveBeenCalled(); expect(component.reload).not.toHaveBeenCalled();
});
it('should call refresh onCreateFolder event', () => {
contentManagementService.folderCreated.next();
expect(component.documentList.reload).toHaveBeenCalled();
});
it('should call refresh editFolder event', () => {
contentManagementService.folderEdited.next();
expect(component.documentList.reload).toHaveBeenCalled();
});
it('should call refresh deleteNode event', () => {
contentManagementService.nodesDeleted.next();
expect(component.documentList.reload).toHaveBeenCalled();
});
it('should call refresh moveNode event', () => {
contentManagementService.nodesMoved.next();
expect(component.documentList.reload).toHaveBeenCalled();
});
it('should call refresh restoreNode event', () => {
contentManagementService.nodesRestored.next();
expect(component.documentList.reload).toHaveBeenCalled();
}); });
it('should call refresh on fileUploadComplete event if parent node match', fakeAsync(() => { it('should call refresh on fileUploadComplete event if parent node match', fakeAsync(() => {
@ -214,7 +181,7 @@ describe('FilesComponent', () => {
tick(500); tick(500);
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
})); }));
it('should not call refresh on fileUploadComplete event if parent mismatch', fakeAsync(() => { it('should not call refresh on fileUploadComplete event if parent mismatch', fakeAsync(() => {
@ -225,7 +192,7 @@ describe('FilesComponent', () => {
tick(500); tick(500);
expect(component.documentList.reload).not.toHaveBeenCalled(); expect(component.reload).not.toHaveBeenCalled();
})); }));
it('should call refresh on fileUploadDeleted event if parent node match', fakeAsync(() => { it('should call refresh on fileUploadDeleted event if parent node match', fakeAsync(() => {
@ -236,7 +203,7 @@ describe('FilesComponent', () => {
tick(500); tick(500);
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
})); }));
it('should not call refresh on fileUploadDeleted event if parent mismatch', fakeAsync(() => { it('should not call refresh on fileUploadDeleted event if parent mismatch', fakeAsync(() => {
@ -247,7 +214,7 @@ describe('FilesComponent', () => {
tick(500); tick(500);
expect(component.documentList.reload).not.toHaveBeenCalled(); expect(component.reload).not.toHaveBeenCalled();
})); }));
}); });

View File

@ -73,7 +73,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
super.ngOnInit(); super.ngOnInit();
const { route, content, nodeActionsService, uploadService } = this; const { route, nodeActionsService, uploadService } = this;
const { data } = route.snapshot; const { data } = route.snapshot;
this.title = data.title; this.title = data.title;
@ -101,11 +101,6 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
nodeActionsService.contentCopied.subscribe(nodes => nodeActionsService.contentCopied.subscribe(nodes =>
this.onContentCopied(nodes) this.onContentCopied(nodes)
), ),
content.folderCreated.subscribe(() => this.documentList.reload()),
content.folderEdited.subscribe(() => this.documentList.reload()),
content.nodesDeleted.subscribe(() => this.documentList.reload()),
content.nodesMoved.subscribe(() => this.documentList.reload()),
content.nodesRestored.subscribe(() => this.documentList.reload()),
uploadService.fileUploadComplete uploadService.fileUploadComplete
.pipe(debounceTime(300)) .pipe(debounceTime(300))
.subscribe(file => this.onFileUploadedEvent(file)), .subscribe(file => this.onFileUploadedEvent(file)),
@ -178,7 +173,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
// check root and child nodes // check root and child nodes
if (node && node.entry && node.entry.parentId === this.getParentNodeId()) { if (node && node.entry && node.entry.parentId === this.getParentNodeId()) {
this.documentList.reload(); this.reload();
return; return;
} }
@ -215,7 +210,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
if (alreadyDisplayedParentFolder) { if (alreadyDisplayedParentFolder) {
return; return;
} }
this.documentList.reload(); this.reload();
} }
onContentCopied(nodes: MinimalNodeEntity[]) { onContentCopied(nodes: MinimalNodeEntity[]) {
@ -225,7 +220,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
); );
}); });
if (newNode) { if (newNode) {
this.documentList.reload(); this.reload();
} }
} }

View File

@ -35,7 +35,7 @@ import { Observable, Subject, Subscription } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { AppExtensionService } from '../extensions/extension.service'; import { AppExtensionService } from '../extensions/extension.service';
import { ContentManagementService } from '../services/content-management.service'; import { ContentManagementService } from '../services/content-management.service';
import { SetSelectedNodesAction, ViewFileAction } from '../store/actions'; import { ViewFileAction, ReloadDocumentListAction } from '../store/actions';
import { import {
appSelection, appSelection,
currentFolder, currentFolder,
@ -128,11 +128,7 @@ export abstract class PageComponent implements OnInit, OnDestroy {
} }
reload(): void { reload(): void {
if (this.documentList) { this.store.dispatch(new ReloadDocumentListAction());
this.documentList.resetSelection();
this.store.dispatch(new SetSelectedNodesAction([]));
this.documentList.reload();
}
} }
trackByActionId(index: number, action: ContentActionRef) { trackByActionId(index: number, action: ContentActionRef) {

View File

@ -34,8 +34,6 @@ import {
AppConfigPipe AppConfigPipe
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services'; import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../services/content-management.service';
import { RecentFilesComponent } from './recent-files.component'; import { RecentFilesComponent } from './recent-files.component';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
@ -43,7 +41,6 @@ describe('RecentFilesComponent', () => {
let fixture: ComponentFixture<RecentFilesComponent>; let fixture: ComponentFixture<RecentFilesComponent>;
let component: RecentFilesComponent; let component: RecentFilesComponent;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let contentService: ContentManagementService;
let page; let page;
beforeEach(() => { beforeEach(() => {
@ -73,7 +70,6 @@ describe('RecentFilesComponent', () => {
fixture = TestBed.createComponent(RecentFilesComponent); fixture = TestBed.createComponent(RecentFilesComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
contentService = TestBed.get(ContentManagementService);
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
@ -88,44 +84,14 @@ describe('RecentFilesComponent', () => {
); );
}); });
describe('OnInit()', () => {
beforeEach(() => {
spyOn(component, 'reload').and.stub();
});
it('should reload nodes on onDeleteNode event', () => {
fixture.detectChanges();
contentService.nodesDeleted.next();
expect(component.reload).toHaveBeenCalled();
});
it('should reload on onRestoreNode event', () => {
fixture.detectChanges();
contentService.nodesRestored.next();
expect(component.reload).toHaveBeenCalled();
});
it('should reload on move node event', () => {
fixture.detectChanges();
contentService.nodesMoved.next();
expect(component.reload).toHaveBeenCalled();
});
});
describe('refresh', () => { describe('refresh', () => {
it('should call document list reload', () => { it('should call document list reload', () => {
spyOn(component.documentList, 'reload'); spyOn(component, 'reload');
fixture.detectChanges(); fixture.detectChanges();
component.reload(); component.reload();
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
}); });
}); });

View File

@ -31,7 +31,7 @@ import { PageComponent } from '../page.component';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state'; import { AppStore } from '../../store/states/app.state';
import { AppExtensionService } from '../../extensions/extension.service'; import { AppExtensionService } from '../../extensions/extension.service';
import { FileUploadEvent, UploadService } from '@alfresco/adf-core'; import { UploadService } from '@alfresco/adf-core';
import { debounceTime } from 'rxjs/operators'; import { debounceTime } from 'rxjs/operators';
@Component({ @Component({
@ -56,16 +56,12 @@ export class RecentFilesComponent extends PageComponent implements OnInit {
super.ngOnInit(); super.ngOnInit();
this.subscriptions = this.subscriptions.concat([ this.subscriptions = this.subscriptions.concat([
this.content.nodesDeleted.subscribe(() => this.reload()),
this.content.nodesMoved.subscribe(() => this.reload()),
this.content.nodesRestored.subscribe(() => this.reload()),
this.uploadService.fileUploadComplete this.uploadService.fileUploadComplete
.pipe(debounceTime(300)) .pipe(debounceTime(300))
.subscribe(file => this.onFileUploadedEvent(file)), .subscribe(() => this.onFileUploadedEvent()),
this.uploadService.fileUploadDeleted this.uploadService.fileUploadDeleted
.pipe(debounceTime(300)) .pipe(debounceTime(300))
.subscribe(file => this.onFileUploadedEvent(file)), .subscribe(() => this.onFileUploadedEvent()),
this.breakpointObserver this.breakpointObserver
.observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape]) .observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape])
@ -83,7 +79,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit {
} }
} }
private onFileUploadedEvent(event: FileUploadEvent) { private onFileUploadedEvent() {
this.documentList.reload(); this.reload();
} }
} }

View File

@ -34,14 +34,12 @@ import {
AppConfigPipe AppConfigPipe
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services'; import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../services/content-management.service';
import { SharedFilesComponent } from './shared-files.component'; import { SharedFilesComponent } from './shared-files.component';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
describe('SharedFilesComponent', () => { describe('SharedFilesComponent', () => {
let fixture: ComponentFixture<SharedFilesComponent>; let fixture: ComponentFixture<SharedFilesComponent>;
let component: SharedFilesComponent; let component: SharedFilesComponent;
let contentService: ContentManagementService;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let page; let page;
@ -72,7 +70,6 @@ describe('SharedFilesComponent', () => {
fixture = TestBed.createComponent(SharedFilesComponent); fixture = TestBed.createComponent(SharedFilesComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
contentService = TestBed.get(ContentManagementService);
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
@ -81,44 +78,14 @@ describe('SharedFilesComponent', () => {
); );
}); });
describe('OnInit', () => {
beforeEach(() => {
spyOn(component, 'reload').and.callFake(val => val);
});
it('should refresh on deleteNode event', () => {
fixture.detectChanges();
contentService.nodesDeleted.next();
expect(component.reload).toHaveBeenCalled();
});
it('should refresh on restoreNode event', () => {
fixture.detectChanges();
contentService.nodesRestored.next();
expect(component.reload).toHaveBeenCalled();
});
it('should reload on move node event', () => {
fixture.detectChanges();
contentService.nodesMoved.next();
expect(component.reload).toHaveBeenCalled();
});
});
describe('refresh', () => { describe('refresh', () => {
it('should call document list reload', () => { it('should call document list reload', () => {
spyOn(component.documentList, 'reload'); spyOn(component, 'reload');
fixture.detectChanges(); fixture.detectChanges();
component.reload(); component.reload();
expect(component.documentList.reload).toHaveBeenCalled(); expect(component.reload).toHaveBeenCalled();
}); });
}); });
}); });

View File

@ -55,9 +55,6 @@ export class SharedFilesComponent extends PageComponent implements OnInit {
super.ngOnInit(); super.ngOnInit();
this.subscriptions = this.subscriptions.concat([ this.subscriptions = this.subscriptions.concat([
this.content.nodesDeleted.subscribe(() => this.reload()),
this.content.nodesMoved.subscribe(() => this.reload()),
this.content.nodesRestored.subscribe(() => this.reload()),
this.content.linksUnshared this.content.linksUnshared
.pipe(debounceTime(300)) .pipe(debounceTime(300))
.subscribe(() => this.reload()), .subscribe(() => this.reload()),

View File

@ -29,7 +29,7 @@ import { AppStore } from '../../../store/states';
import { appSelection } from '../../../store/selectors/app.selectors'; import { appSelection } from '../../../store/selectors/app.selectors';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { SelectionState } from '@alfresco/adf-extensions'; import { SelectionState } from '@alfresco/adf-extensions';
import { ContentManagementService } from '../../../services/content-management.service'; import { ReloadDocumentListAction } from '../../../store/actions';
@Component({ @Component({
selector: 'app-toggle-favorite', selector: 'app-toggle-favorite',
@ -51,14 +51,11 @@ import { ContentManagementService } from '../../../services/content-management.s
export class ToggleFavoriteComponent { export class ToggleFavoriteComponent {
selection$: Observable<SelectionState>; selection$: Observable<SelectionState>;
constructor( constructor(private store: Store<AppStore>) {
private store: Store<AppStore>,
private content: ContentManagementService
) {
this.selection$ = this.store.select(appSelection); this.selection$ = this.store.select(appSelection);
} }
onToggleEvent() { onToggleEvent() {
this.content.favoriteToggle.next(); this.store.dispatch(new ReloadDocumentListAction());
} }
} }

View File

@ -33,7 +33,6 @@ import {
AppConfigPipe AppConfigPipe
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services'; import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../services/content-management.service';
import { TrashcanComponent } from './trashcan.component'; import { TrashcanComponent } from './trashcan.component';
import { AppTestingModule } from '../../testing/app-testing.module'; import { AppTestingModule } from '../../testing/app-testing.module';
@ -41,7 +40,6 @@ describe('TrashcanComponent', () => {
let fixture: ComponentFixture<TrashcanComponent>; let fixture: ComponentFixture<TrashcanComponent>;
let component: TrashcanComponent; let component: TrashcanComponent;
let alfrescoApi: AlfrescoApiService; let alfrescoApi: AlfrescoApiService;
let contentService: ContentManagementService;
let page; let page;
beforeEach(() => { beforeEach(() => {
@ -73,7 +71,6 @@ describe('TrashcanComponent', () => {
alfrescoApi = TestBed.get(AlfrescoApiService); alfrescoApi = TestBed.get(AlfrescoApiService);
alfrescoApi.reset(); alfrescoApi.reset();
contentService = TestBed.get(ContentManagementService);
component.documentList = <any>{ component.documentList = <any>{
reload: jasmine.createSpy('reload'), reload: jasmine.createSpy('reload'),
@ -86,34 +83,4 @@ describe('TrashcanComponent', () => {
Promise.resolve(page) Promise.resolve(page)
); );
}); });
it('should reload on nodes purged', () => {
component.ngOnInit();
spyOn(component, 'reload').and.stub();
contentService.nodesPurged.next({});
expect(component.reload).toHaveBeenCalled();
});
describe('onRestoreNode()', () => {
it('should call refresh()', () => {
spyOn(component, 'reload');
fixture.detectChanges();
contentService.nodesRestored.next();
expect(component.reload).toHaveBeenCalled();
});
});
describe('refresh()', () => {
it('calls child component to reload', () => {
component.reload();
expect(component.documentList.reload).toHaveBeenCalled();
});
it('calls child component to reset selection', () => {
component.reload();
expect(component.documentList.resetSelection).toHaveBeenCalled();
});
});
}); });

View File

@ -57,9 +57,6 @@ export class TrashcanComponent extends PageComponent implements OnInit {
super.ngOnInit(); super.ngOnInit();
this.subscriptions.push( this.subscriptions.push(
this.content.nodesRestored.subscribe(() => this.reload()),
this.content.nodesPurged.subscribe(() => this.reload()),
this.breakpointObserver this.breakpointObserver
.observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape]) .observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape])
.subscribe(result => { .subscribe(result => {

View File

@ -27,23 +27,27 @@ import { Directive, OnDestroy, OnInit, HostListener } from '@angular/core';
import { DocumentListComponent } from '@alfresco/adf-content-services'; import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { UserPreferencesService } from '@alfresco/adf-core'; import { UserPreferencesService } from '@alfresco/adf-core';
import { Subscription } from 'rxjs'; import { Subject } from 'rxjs';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { SetSelectedNodesAction } from '../store/actions'; import { SetSelectedNodesAction } from '../store/actions';
import { takeUntil } from 'rxjs/operators';
import { ContentManagementService } from '../services/content-management.service';
@Directive({ @Directive({
selector: '[acaDocumentList]' selector: '[acaDocumentList]'
}) })
export class DocumentListDirective implements OnInit, OnDestroy { export class DocumentListDirective implements OnInit, OnDestroy {
private subscriptions: Subscription[] = [];
private isLibrary = false; private isLibrary = false;
onDestroy$ = new Subject<boolean>();
get sortingPreferenceKey(): string { get sortingPreferenceKey(): string {
return this.route.snapshot.data.sortingPreferenceKey; return this.route.snapshot.data.sortingPreferenceKey;
} }
constructor( constructor(
private store: Store<any>, private store: Store<any>,
private content: ContentManagementService,
private documentList: DocumentListComponent, private documentList: DocumentListComponent,
private preferences: UserPreferencesService, private preferences: UserPreferencesService,
private route: ActivatedRoute, private route: ActivatedRoute,
@ -75,14 +79,18 @@ export class DocumentListDirective implements OnInit, OnDestroy {
this.documentList.data.setSorting({ key, direction }); this.documentList.data.setSorting({ key, direction });
} }
this.subscriptions.push( this.documentList.ready
this.documentList.ready.subscribe(() => this.onReady()) .pipe(takeUntil(this.onDestroy$))
); .subscribe(() => this.onReady());
this.content.reload.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.reload();
});
} }
ngOnDestroy() { ngOnDestroy() {
this.subscriptions.forEach(subscription => subscription.unsubscribe()); this.onDestroy$.next(true);
this.subscriptions = []; this.onDestroy$.complete();
} }
@HostListener('sorting-changed', ['$event']) @HostListener('sorting-changed', ['$event'])
@ -123,4 +131,10 @@ export class DocumentListDirective implements OnInit, OnDestroy {
this.store.dispatch(new SetSelectedNodesAction(selection)); this.store.dispatch(new SetSelectedNodesAction(selection));
} }
private reload() {
this.documentList.resetSelection();
this.store.dispatch(new SetSelectedNodesAction([]));
this.documentList.reload();
}
} }

View File

@ -1265,39 +1265,6 @@ describe('ContentManagementService', () => {
).toBe(true); ).toBe(true);
})); }));
describe('refresh()', () => {
it('dispatch event on finish', fakeAsync(done => {
spyOn(contentApi, 'restoreNode').and.returnValue(of({}));
spyOn(contentApi, 'getDeletedNodes').and.returnValue(
of({
list: { entries: [] }
})
);
const path = {
elements: [
{
id: '1-1',
name: 'somewhere-over-the-rainbow'
}
]
};
const selection = [
<any>{
entry: {
id: '1',
path
}
}
];
store.dispatch(new RestoreDeletedNodesAction(selection));
contentManagementService.nodesRestored.subscribe(() => done());
}));
});
describe('notification', () => { describe('notification', () => {
beforeEach(() => { beforeEach(() => {
spyOn(contentApi, 'getDeletedNodes').and.returnValue( spyOn(contentApi, 'getDeletedNodes').and.returnValue(

View File

@ -40,7 +40,8 @@ import {
NavigateToParentFolder, NavigateToParentFolder,
SnackbarUserAction, SnackbarUserAction,
UndoDeleteNodesAction, UndoDeleteNodesAction,
SetSelectedNodesAction SetSelectedNodesAction,
ReloadDocumentListAction
} from '../store/actions'; } from '../store/actions';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppStore } from '../store/states'; import { AppStore } from '../store/states';
@ -76,12 +77,8 @@ interface RestoredNode {
providedIn: 'root' providedIn: 'root'
}) })
export class ContentManagementService { export class ContentManagementService {
nodesMoved = new Subject<any>(); reload = new Subject<any>();
nodesDeleted = new Subject<any>(); nodesDeleted = new Subject<any>();
nodesPurged = new Subject<any>();
nodesRestored = new Subject<any>();
folderEdited = new Subject<any>();
folderCreated = new Subject<any>();
libraryDeleted = new Subject<string>(); libraryDeleted = new Subject<string>();
libraryCreated = new Subject<SiteEntry>(); libraryCreated = new Subject<SiteEntry>();
libraryUpdated = new Subject<SiteEntry>(); libraryUpdated = new Subject<SiteEntry>();
@ -90,9 +87,6 @@ export class ContentManagementService {
library400Error = new Subject<any>(); library400Error = new Subject<any>();
joinLibraryToggle = new Subject<string>(); joinLibraryToggle = new Subject<string>();
linksUnshared = new Subject<any>(); linksUnshared = new Subject<any>();
favoriteAdded = new Subject<Array<MinimalNodeEntity>>();
favoriteRemoved = new Subject<Array<MinimalNodeEntity>>();
favoriteToggle = new Subject<Array<MinimalNodeEntity>>();
favoriteLibraryToggle = new Subject<any>(); favoriteLibraryToggle = new Subject<any>();
constructor( constructor(
@ -113,8 +107,7 @@ export class ContentManagementService {
node.entry.isFavorite = true; node.entry.isFavorite = true;
}); });
this.store.dispatch(new SetSelectedNodesAction(nodes)); this.store.dispatch(new SetSelectedNodesAction(nodes));
this.favoriteAdded.next(nodes); this.store.dispatch(new ReloadDocumentListAction());
this.favoriteToggle.next(nodes);
}); });
} }
} }
@ -126,8 +119,7 @@ export class ContentManagementService {
node.entry.isFavorite = false; node.entry.isFavorite = false;
}); });
this.store.dispatch(new SetSelectedNodesAction(nodes)); this.store.dispatch(new SetSelectedNodesAction(nodes));
this.favoriteRemoved.next(nodes); this.store.dispatch(new ReloadDocumentListAction());
this.favoriteToggle.next(nodes);
}); });
} }
} }
@ -246,7 +238,7 @@ export class ContentManagementService {
dialogInstance.afterClosed().subscribe(node => { dialogInstance.afterClosed().subscribe(node => {
if (node) { if (node) {
this.folderCreated.next(node); this.store.dispatch(new ReloadDocumentListAction());
} }
}); });
} }
@ -267,9 +259,9 @@ export class ContentManagementService {
this.store.dispatch(new SnackbarErrorAction(message)); this.store.dispatch(new SnackbarErrorAction(message));
}); });
dialog.afterClosed().subscribe((node: MinimalNodeEntryEntity) => { dialog.afterClosed().subscribe(node => {
if (node) { if (node) {
this.folderEdited.next(node); this.store.dispatch(new ReloadDocumentListAction());
} }
}); });
} }
@ -420,7 +412,7 @@ export class ContentManagementService {
const failedStatus = this.processStatus([]); const failedStatus = this.processStatus([]);
failedStatus.fail.push(...selection); failedStatus.fail.push(...selection);
this.showRestoreNotification(failedStatus); this.showRestoreNotification(failedStatus);
this.nodesRestored.next(); this.store.dispatch(new ReloadDocumentListAction());
return; return;
} }
@ -439,7 +431,7 @@ export class ContentManagementService {
if (!remainingNodes.length) { if (!remainingNodes.length) {
this.showRestoreNotification(status); this.showRestoreNotification(status);
this.nodesRestored.next(); this.store.dispatch(new ReloadDocumentListAction());
} else { } else {
this.restoreDeletedNodes(remainingNodes); this.restoreDeletedNodes(remainingNodes);
} }
@ -531,6 +523,7 @@ export class ContentManagementService {
forkJoin(...batch).subscribe( forkJoin(...batch).subscribe(
() => { () => {
this.nodesDeleted.next(null); this.nodesDeleted.next(null);
this.store.dispatch(new ReloadDocumentListAction());
}, },
error => { error => {
let i18nMessageString = 'APP.MESSAGES.ERRORS.GENERIC'; let i18nMessageString = 'APP.MESSAGES.ERRORS.GENERIC';
@ -564,7 +557,7 @@ export class ContentManagementService {
const [operationResult, moveResponse] = result; const [operationResult, moveResponse] = result;
this.showMoveMessage(nodes, operationResult, moveResponse); this.showMoveMessage(nodes, operationResult, moveResponse);
this.nodesMoved.next(null); this.store.dispatch(new ReloadDocumentListAction());
}, },
error => { error => {
this.showMoveMessage(nodes, error); this.showMoveMessage(nodes, error);
@ -619,7 +612,7 @@ export class ContentManagementService {
) )
.subscribe( .subscribe(
() => { () => {
this.nodesMoved.next(null); this.store.dispatch(new ReloadDocumentListAction());
}, },
error => { error => {
let message = 'APP.MESSAGES.ERRORS.GENERIC'; let message = 'APP.MESSAGES.ERRORS.GENERIC';
@ -665,6 +658,7 @@ export class ContentManagementService {
if (status.someSucceeded) { if (status.someSucceeded) {
this.nodesDeleted.next(); this.nodesDeleted.next();
this.store.dispatch(new ReloadDocumentListAction());
} }
}); });
} }
@ -685,7 +679,7 @@ export class ContentManagementService {
} }
if (processedData.someSucceeded) { if (processedData.someSucceeded) {
this.nodesRestored.next(); this.store.dispatch(new ReloadDocumentListAction());
} }
}); });
} }
@ -759,7 +753,7 @@ export class ContentManagementService {
const status = this.processStatus(purgedNodes); const status = this.processStatus(purgedNodes);
if (status.success.length) { if (status.success.length) {
this.nodesPurged.next(); this.store.dispatch(new ReloadDocumentListAction());
} }
const message = this.getPurgeMessage(status); const message = this.getPurgeMessage(status);
if (message) { if (message) {

View File

@ -35,6 +35,7 @@ export const SET_USER_PROFILE = 'SET_USER_PROFILE';
export const TOGGLE_INFO_DRAWER = 'TOGGLE_INFO_DRAWER'; export const TOGGLE_INFO_DRAWER = 'TOGGLE_INFO_DRAWER';
export const TOGGLE_DOCUMENT_DISPLAY_MODE = 'TOGGLE_DOCUMENT_DISPLAY_MODE'; export const TOGGLE_DOCUMENT_DISPLAY_MODE = 'TOGGLE_DOCUMENT_DISPLAY_MODE';
export const LOGOUT = 'LOGOUT'; export const LOGOUT = 'LOGOUT';
export const RELOAD_DOCUMENT_LIST = 'RELOAD_DOCUMENT_LIST';
export class SetInitialStateAction implements Action { export class SetInitialStateAction implements Action {
readonly type = SET_INITIAL_STATE; readonly type = SET_INITIAL_STATE;
@ -75,3 +76,8 @@ export class LogoutAction implements Action {
readonly type = LOGOUT; readonly type = LOGOUT;
constructor(public payload?: any) {} constructor(public payload?: any) {}
} }
export class ReloadDocumentListAction implements Action {
readonly type = RELOAD_DOCUMENT_LIST;
constructor(public payload?: any) {}
}

View File

@ -26,18 +26,33 @@
import { Effect, Actions, ofType } from '@ngrx/effects'; import { Effect, Actions, ofType } from '@ngrx/effects';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { LogoutAction, LOGOUT } from '../actions/app.actions'; import {
LogoutAction,
LOGOUT,
ReloadDocumentListAction,
RELOAD_DOCUMENT_LIST
} from '../actions/app.actions';
import { AuthenticationService } from '@alfresco/adf-core'; import { AuthenticationService } from '@alfresco/adf-core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ContentManagementService } from '../../services/content-management.service';
@Injectable() @Injectable()
export class AppEffects { export class AppEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private auth: AuthenticationService, private auth: AuthenticationService,
private router: Router private router: Router,
private content: ContentManagementService
) {} ) {}
@Effect({ dispatch: false })
reload = this.actions$.pipe(
ofType<ReloadDocumentListAction>(RELOAD_DOCUMENT_LIST),
map(action => {
this.content.reload.next(action);
})
);
@Effect({ dispatch: false }) @Effect({ dispatch: false })
logout$ = this.actions$.pipe( logout$ = this.actions$.pipe(
ofType<LogoutAction>(LOGOUT), ofType<LogoutAction>(LOGOUT),