diff --git a/src/app/common/common.module.ts b/src/app/common/common.module.ts index a31010d56..31ce023a4 100644 --- a/src/app/common/common.module.ts +++ b/src/app/common/common.module.ts @@ -29,7 +29,6 @@ import { NodeMoveDirective } from './directives/node-move.directive'; import { DownloadFileDirective } from './directives/node-download.directive'; import { NodeRestoreDirective } from './directives/node-restore.directive'; import { NodePermanentDeleteDirective } from './directives/node-permanent-delete.directive'; -import { NodeFavoriteDirective } from './directives/node-favorite.directive'; import { ContentManagementService } from './services/content-management.service'; import { BrowsingFilesService } from './services/browsing-files.service'; @@ -52,8 +51,7 @@ export function declarations() { NodeMoveDirective, DownloadFileDirective, NodeRestoreDirective, - NodePermanentDeleteDirective, - NodeFavoriteDirective + NodePermanentDeleteDirective ]; } diff --git a/src/app/common/directives/node-favorite.directive.spec.ts b/src/app/common/directives/node-favorite.directive.spec.ts deleted file mode 100644 index 3ddd6490a..000000000 --- a/src/app/common/directives/node-favorite.directive.spec.ts +++ /dev/null @@ -1,331 +0,0 @@ -/*! - * @license - * Copyright 2017 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { AlfrescoApiService, CoreModule, TranslationService, NodesApiService } from '@alfresco/adf-core'; -import { Component, DebugElement } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; - -import { ContentManagementService } from '../services/content-management.service'; -import { NodeFavoriteDirective } from './node-favorite.directive'; - -@Component({ - template: '
' -}) -class TestComponent { - selection; -} - -describe('NodeFavoriteDirective', () => { - let component: TestComponent; - let fixture: ComponentFixture; - let element: DebugElement; - let directiveInstance; - let apiService; - let contentService; - let favoritesApi; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [ - CoreModule - ], - declarations: [ - TestComponent, - NodeFavoriteDirective - ], - providers: [ - ContentManagementService, - AlfrescoApiService - ] - }); - - fixture = TestBed.createComponent(TestComponent); - component = fixture.componentInstance; - element = fixture.debugElement.query(By.directive(NodeFavoriteDirective)); - directiveInstance = element.injector.get(NodeFavoriteDirective); - - contentService = TestBed.get(ContentManagementService); - apiService = TestBed.get(AlfrescoApiService); - favoritesApi = apiService.getInstance().core.favoritesApi; - }); - - describe('selection input change event', () => { - it('does not call markFavoritesNodes() if input list is empty', () => { - spyOn(directiveInstance, 'markFavoritesNodes'); - - component.selection = []; - - fixture.detectChanges(); - - expect(directiveInstance.markFavoritesNodes).not.toHaveBeenCalledWith(); - }); - - it('calls markFavoritesNodes() on input change', () => { - spyOn(directiveInstance, 'markFavoritesNodes'); - - component.selection = [{ entry: { id: '1', name: 'name1' } }]; - - fixture.detectChanges(); - - expect(directiveInstance.markFavoritesNodes).toHaveBeenCalledWith(component.selection); - - component.selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '1', name: 'name1' } } - ]; - - fixture.detectChanges(); - - expect(directiveInstance.markFavoritesNodes).toHaveBeenCalledWith(component.selection); - }); - }); - - describe('markFavoritesNodes()', () => { - let favoritesApiSpy; - - beforeEach(() => { - favoritesApiSpy = spyOn(favoritesApi, 'getFavorite'); - }); - - it('check each selected node if it is a favorite', fakeAsync(() => { - favoritesApiSpy.and.returnValue(Promise.resolve()); - - component.selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } - ]; - - fixture.detectChanges(); - tick(); - - expect(favoritesApiSpy.calls.count()).toBe(2); - })); - - it('it does not check processed node when another is unselected', fakeAsync(() => { - favoritesApiSpy.and.returnValue(Promise.resolve()); - - component.selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } - ]; - - fixture.detectChanges(); - tick(); - - expect(directiveInstance.favorites.length).toBe(2); - expect(favoritesApiSpy.calls.count()).toBe(2); - - favoritesApiSpy.calls.reset(); - - component.selection = [ - { entry: { id: '2', name: 'name2' } } - ]; - - fixture.detectChanges(); - tick(); - - expect(directiveInstance.favorites.length).toBe(1); - expect(favoritesApiSpy).not.toHaveBeenCalled(); - })); - - it('it does not check processed nodes when another is selected', fakeAsync(() => { - favoritesApiSpy.and.returnValue(Promise.resolve()); - - component.selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } } - ]; - - fixture.detectChanges(); - tick(); - - expect(directiveInstance.favorites.length).toBe(2); - expect(favoritesApiSpy.calls.count()).toBe(2); - - favoritesApiSpy.calls.reset(); - - component.selection = [ - { entry: { id: '1', name: 'name1' } }, - { entry: { id: '2', name: 'name2' } }, - { entry: { id: '3', name: 'name3' } } - ]; - - fixture.detectChanges(); - tick(); - - expect(directiveInstance.favorites.length).toBe(3); - expect(favoritesApiSpy.calls.count()).toBe(1); - })); - }); - - describe('toggleFavorite()', () => { - let removeFavoriteSpy; - let addFavoriteSpy; - - beforeEach(() => { - removeFavoriteSpy = spyOn(favoritesApi, 'removeFavoriteSite'); - addFavoriteSpy = spyOn(favoritesApi, 'addFavorite'); - }); - - it('does not perform action if favorites collection is empty', () => { - component.selection = []; - - fixture.detectChanges(); - element.triggerEventHandler('click', null); - - expect(removeFavoriteSpy).not.toHaveBeenCalled(); - expect(addFavoriteSpy).not.toHaveBeenCalled(); - }); - - it('calls addFavorite() if none is a favorite', fakeAsync(() => { - addFavoriteSpy.and.returnValue(Promise.resolve()); - - directiveInstance.favorites = [ - { entry: { id: '1', name: 'name1', isFavorite: false } }, - { entry: { id: '2', name: 'name2', isFavorite: false } } - ]; - - element.triggerEventHandler('click', null); - tick(); - - expect(addFavoriteSpy.calls.argsFor(0)[1].length).toBe(2); - })); - - it('calls addFavorite() on the node that is not a favorite in selection', fakeAsync(() => { - addFavoriteSpy.and.returnValue(Promise.resolve()); - - directiveInstance.favorites = [ - { entry: { id: '1', name: 'name1', isFile: true, isFolder: false, isFavorite: false } }, - { entry: { id: '2', name: 'name2', isFile: true, isFolder: false, isFavorite: true } } - ]; - - element.triggerEventHandler('click', null); - tick(); - - const callArgs = addFavoriteSpy.calls.argsFor(0)[1]; - const callParameter = callArgs[0]; - - expect(callArgs.length).toBe(1); - expect(callParameter.target.file.guid).toBe('1'); - })); - - it('calls removeFavoriteSite() if all are favorites', fakeAsync(() => { - addFavoriteSpy.and.returnValue(Promise.resolve()); - - directiveInstance.favorites = [ - { entry: { id: '1', name: 'name1', isFavorite: true } }, - { entry: { id: '2', name: 'name2', isFavorite: true } } - ]; - - element.triggerEventHandler('click', null); - tick(); - - expect(removeFavoriteSpy.calls.count()).toBe(2); - })); - }); - - describe('getFavorite()', () => { - it('process node as favorite', fakeAsync(() => { - spyOn(favoritesApi, 'getFavorite').and.returnValue(Promise.resolve()); - - component.selection = [ - { entry: { id: '1', name: 'name1' } } - ]; - - fixture.detectChanges(); - tick(); - - expect(directiveInstance.favorites[0].entry.isFavorite).toBe(true); - })); - - it('process node as not a favorite', fakeAsync(() => { - spyOn(favoritesApi, 'getFavorite').and.returnValue(Promise.reject(null)); - - component.selection = [ - { entry: { id: '1', name: 'name1' } } - ]; - - fixture.detectChanges(); - tick(); - - expect(directiveInstance.favorites[0].entry.isFavorite).toBe(false); - })); - }); - - describe('reset()', () => { - beforeEach(() => { - spyOn(favoritesApi, 'removeFavoriteSite').and.returnValue(Promise.resolve()); - spyOn(favoritesApi, 'addFavorite').and.returnValue(Promise.resolve()); - }); - - it('reset favorite collection after addFavorite()', fakeAsync(() => { - directiveInstance.favorites = [ - { entry: { id: '1', name: 'name1', isFavorite: true } } - ]; - - element.triggerEventHandler('click', null); - tick(); - - expect(directiveInstance.favorites.length).toBe(0); - })); - - it('reset favorite collection after removeFavoriteSite()', fakeAsync(() => { - directiveInstance.favorites = [ - { entry: { id: '1', name: 'name1', isFavorite: false } } - ]; - - element.triggerEventHandler('click', null); - tick(); - - expect(directiveInstance.favorites.length).toBe(0); - })); - }); - - describe('hasFavorites()', () => { - it('returns false if favorites collection is empty', () => { - directiveInstance.favorites = []; - - const hasFavorites = directiveInstance.hasFavorites(); - - expect(hasFavorites).toBe(false); - }); - - it('returns false if some are not favorite', () => { - directiveInstance.favorites = [ - { entry: { id: '1', name: 'name1', isFavorite: true } }, - { entry: { id: '2', name: 'name2', isFavorite: false } } - ]; - - const hasFavorites = directiveInstance.hasFavorites(); - - expect(hasFavorites).toBe(false); - }); - - it('returns true if all are favorite', () => { - directiveInstance.favorites = [ - { entry: { id: '1', name: 'name1', isFavorite: true } }, - { entry: { id: '2', name: 'name2', isFavorite: true } } - ]; - - const hasFavorites = directiveInstance.hasFavorites(); - - expect(hasFavorites).toBe(true); - }); - }); -}); diff --git a/src/app/common/directives/node-favorite.directive.ts b/src/app/common/directives/node-favorite.directive.ts deleted file mode 100644 index 8e09a0072..000000000 --- a/src/app/common/directives/node-favorite.directive.ts +++ /dev/null @@ -1,181 +0,0 @@ -/*! - * @license - * Copyright 2017 Alfresco Software, Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Directive, HostListener, Input, OnChanges } from '@angular/core'; -import { AlfrescoApiService } from '@alfresco/adf-core'; - -import { MinimalNodeEntity, FavoriteBody } from 'alfresco-js-api'; -import { Observable } from 'rxjs/Rx'; - -import { ContentManagementService } from '../services/content-management.service'; - -@Directive({ - selector: '[app-favorite-node]', - exportAs: 'favorite' -}) -export class NodeFavoriteDirective implements OnChanges { - private favorites: any[] = []; - - @Input('app-favorite-node') - selection: any[]; - - @HostListener('click') - onClick() { - this.toggleFavorite(); - } - - constructor( - public content: ContentManagementService, - private alfrescoApiService: AlfrescoApiService - ) {} - - ngOnChanges(changes) { - if (!changes.selection.currentValue.length) { - return; - } - - this.markFavoritesNodes(changes.selection.currentValue); - } - - toggleFavorite() { - if (!this.favorites.length) { - return; - } - - const every = this.favorites.every((selected) => selected.entry.isFavorite); - - if (every) { - const batch = this.favorites.map((selected) => { - // shared files have nodeId - const id = selected.entry.nodeId || selected.entry.id; - - return Observable.of(this.alfrescoApiService.getInstance().core.favoritesApi.removeFavoriteSite('-me-', id)); - }); - - Observable.forkJoin(batch) - .subscribe(() => { - this.content.toggleFavorite.next(); - this.reset(); - }); - } - - if (!every) { - const notFavorite = this.favorites.filter((node) => !node.entry.isFavorite); - const body: FavoriteBody[] = notFavorite.map((node) => this.createFavoriteBody(node)); - - Observable.from(this.alfrescoApiService.getInstance().core.favoritesApi.addFavorite('-me-', body)) - .subscribe(() => { - this.content.toggleFavorite.next(); - this.reset(); - }); - } - } - - markFavoritesNodes(selection) { - if (selection.length < this.favorites.length) { - const newFavorites = this.reduce(this.favorites, selection); - this.favorites = newFavorites; - } - - const result = this.diff(selection, this.favorites); - const batch = this.getProcessBatch(result); - - Observable.forkJoin(batch).subscribe((data) => this.favorites.push(...data)); - } - - hasFavorites(): boolean { - if (this.favorites && !this.favorites.length) { - return false; - } - - return this.favorites.every((selected) => selected.entry.isFavorite); - } - - private reset() { - this.favorites = []; - } - - private getProcessBatch(selection): any[] { - return selection.map((selected) => this.getFavorite(selected)); - } - - private getFavorite(selected): Observable { - const { name, isFile, isFolder } = selected.entry; - // shared files have nodeId - const id = selected.entry.nodeId || selected.entry.id; - - const promise = this.alfrescoApiService.getInstance() - .core.favoritesApi.getFavorite('-me-', id); - - return Observable.from(promise) - .map(() => ({ - entry: { - id, - isFolder, - isFile, - name, - isFavorite: true - } - })) - .catch(() => { - return Observable.of({ - entry: { - id, - isFolder, - isFile, - name, - isFavorite: false - } - }); - }); - } - - private createFavoriteBody(node): FavoriteBody { - const type = this.getNodeType(node); - // shared files have nodeId - const id = node.entry.nodeId || node.entry.id; - - return { - target: { - [type]: { - guid: id - } - } - }; - } - - private getNodeType(node): string { - // shared could only be files - if (!node.entry.isFile && !node.entry.isFolder) { - return 'file'; - } - - return node.entry.isFile ? 'file' : 'folder'; - } - - private diff(list, patch): any[] { - const ids = patch.map(item => item.entry.id); - - return list.filter(item => ids.includes(item.entry.id) ? null : item); - } - - private reduce(patch, comparator): any[] { - const ids = comparator.map(item => item.entry.id); - - return patch.filter(item => ids.includes(item.entry.id) ? item : null); - } -} diff --git a/src/app/common/services/content-management.service.ts b/src/app/common/services/content-management.service.ts index 7aa324d71..81099f07f 100644 --- a/src/app/common/services/content-management.service.ts +++ b/src/app/common/services/content-management.service.ts @@ -23,5 +23,4 @@ export class ContentManagementService { deleteNode = new Subject(); moveNode = new Subject(); restoreNode = new Subject(); - toggleFavorite = new Subject(); } diff --git a/src/app/components/favorites/favorites.component.html b/src/app/components/favorites/favorites.component.html index 5233e3aca..323786641 100644 --- a/src/app/components/favorites/favorites.component.html +++ b/src/app/components/favorites/favorites.component.html @@ -41,10 +41,10 @@ class="secondary-options"> diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index 5c57cfaa9..ec43b3ce3 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -110,15 +110,6 @@ describe('Favorites Routed Component', () => { expect(component.refresh).toHaveBeenCalled(); }); - - it('should fetch nodes on favorite toggle', () => { - spyOn(component, 'refresh'); - fixture.detectChanges(); - - contentService.toggleFavorite.next(null); - - expect(component.refresh).toHaveBeenCalled(); - }); }); describe('Node navigation', () => { diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 6216a8e3a..683688bc1 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -50,8 +50,7 @@ export class FavoritesComponent extends PageComponent implements OnInit, OnDestr this.content.deleteNode.subscribe(() => this.refresh()), this.content.restoreNode.subscribe(() => this.refresh()), this.contentService.folderEdit.subscribe(() => this.refresh()), - this.content.moveNode.subscribe(() => this.refresh()), - this.content.toggleFavorite.debounceTime(300).subscribe(() => this.refresh()) + this.content.moveNode.subscribe(() => this.refresh()) ]); } diff --git a/src/app/components/files/files.component.html b/src/app/components/files/files.component.html index df2f826b1..6ea76a7a9 100644 --- a/src/app/components/files/files.component.html +++ b/src/app/components/files/files.component.html @@ -44,10 +44,10 @@ class="secondary-options"> diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts index 14df0f50f..2d5580834 100644 --- a/src/app/components/files/files.component.spec.ts +++ b/src/app/components/files/files.component.spec.ts @@ -137,12 +137,6 @@ describe('FilesComponent', () => { fixture.detectChanges(); }); - it('reset favorites colection onToggleFavorite event', () => { - contentManagementService.toggleFavorite.next(null); - - expect(component.load).toHaveBeenCalled(); - }); - it('calls refresh onContentCopied event if parent is the same', () => { const nodes = [ { entry: { parentId: '1' } }, diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 03862efab..298a9209b 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -92,7 +92,6 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { contentManagementService.deleteNode.subscribe(() => this.load(false, this.pagination)), contentManagementService.moveNode.subscribe(() => this.load(false, this.pagination)), contentManagementService.restoreNode.subscribe(() => this.load(false, this.pagination)), - contentManagementService.toggleFavorite.subscribe(() => this.load(false, this.pagination)), uploadService.fileUploadComplete.subscribe(file => this.onFileUploadedEvent(file)), uploadService.fileUploadDeleted.subscribe((file) => this.onFileUploadedEvent(file)) ]); diff --git a/src/app/components/recent-files/recent-files.component.html b/src/app/components/recent-files/recent-files.component.html index 6715e5e19..b41966666 100644 --- a/src/app/components/recent-files/recent-files.component.html +++ b/src/app/components/recent-files/recent-files.component.html @@ -33,10 +33,10 @@ class="secondary-options"> diff --git a/src/app/components/recent-files/recent-files.component.spec.ts b/src/app/components/recent-files/recent-files.component.spec.ts index b7d44ff00..6ddaf63f0 100644 --- a/src/app/components/recent-files/recent-files.component.spec.ts +++ b/src/app/components/recent-files/recent-files.component.spec.ts @@ -98,14 +98,6 @@ describe('RecentFiles Routed Component', () => { expect(component.refresh).toHaveBeenCalled(); }); - it('should reload on toggleFavorite event', () => { - fixture.detectChanges(); - - contentService.toggleFavorite.next(); - - expect(component.refresh).toHaveBeenCalled(); - }); - it('should reload on move node event', () => { fixture.detectChanges(); diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index 4444fe829..b2e3dea74 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -46,8 +46,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit, OnDes this.subscriptions = this.subscriptions.concat([ this.content.deleteNode.subscribe(() => this.refresh()), this.content.moveNode.subscribe(() => this.refresh()), - this.content.restoreNode.subscribe(() => this.refresh()), - this.content.toggleFavorite.subscribe(() => this.refresh()) + this.content.restoreNode.subscribe(() => this.refresh()) ]); } diff --git a/src/app/components/shared-files/shared-files.component.html b/src/app/components/shared-files/shared-files.component.html index 6e9b51ff2..e7eb1481d 100644 --- a/src/app/components/shared-files/shared-files.component.html +++ b/src/app/components/shared-files/shared-files.component.html @@ -33,10 +33,10 @@ class="secondary-options"> diff --git a/src/app/components/shared-files/shared-files.component.spec.ts b/src/app/components/shared-files/shared-files.component.spec.ts index e78c77122..525acfe86 100644 --- a/src/app/components/shared-files/shared-files.component.spec.ts +++ b/src/app/components/shared-files/shared-files.component.spec.ts @@ -94,14 +94,6 @@ describe('SharedFilesComponent', () => { expect(component.refresh).toHaveBeenCalled(); }); - it('should refresh on favorite toggle event', () => { - fixture.detectChanges(); - - contentService.toggleFavorite.next(); - - expect(component.refresh).toHaveBeenCalled(); - }); - it('should reload on move node event', () => { fixture.detectChanges(); diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index 47079bb0e..94004ec68 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -47,8 +47,7 @@ export class SharedFilesComponent extends PageComponent implements OnInit, OnDes this.subscriptions = this.subscriptions.concat([ this.content.deleteNode.subscribe(() => this.refresh()), this.content.moveNode.subscribe(() => this.refresh()), - this.content.restoreNode.subscribe(() => this.refresh()), - this.content.toggleFavorite.subscribe(() => this.refresh()) + this.content.restoreNode.subscribe(() => this.refresh()) ]); }