diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html index 459ec8b8da..2cc49fea9a 100644 --- a/demo-shell/src/app/components/files/files.component.html +++ b/demo-shell/src/app/components/files/files.component.html @@ -29,7 +29,7 @@
- +
diff --git a/docs/sites-dropdown.component.md b/docs/sites-dropdown.component.md index 2c57598042..103c3f7dc8 100644 --- a/docs/sites-dropdown.component.md +++ b/docs/sites-dropdown.component.md @@ -24,6 +24,7 @@ Displays a dropdown menu to show and interact with the sites of the current user | siteList | [SitePaging](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/SitePaging.md) | null | A custom list of sites to be displayed by the dropdown. If no value is given, the sites of the current user are displayed by default. A list of objects only with properties 'title' and 'guid' is enough to be able to display the dropdown. | | placeholder | string | 'DROPDOWN.PLACEHOLDER_LABEL' | The placeholder text/the key from translation files for the placeholder text to be shown by default | | value | string | null | Id of the select site | +| relations | string | null | This parameter will allow to perform sites query filtering the results.It could have two possible values: **members** and **containers**. When **members** is used the site list will be filtered with only the sites where the user is a member of. | ### Events diff --git a/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts b/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts index d1a6758611..c1cf5dc65e 100644 --- a/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts +++ b/lib/content-services/site-dropdown/sites-dropdown.component.spec.ts @@ -18,7 +18,9 @@ import { DebugElement } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { DropdownSitesComponent } from './sites-dropdown.component'; +import { DropdownSitesComponent, Relations } from './sites-dropdown.component'; +import { SitesService, LogService } from '@alfresco/adf-core'; +import { Observable } from 'rxjs/Observable'; declare let jasmine: any; @@ -29,13 +31,16 @@ describe('DropdownSitesComponent', () => { let debug: DebugElement; let element: HTMLElement; let sitesList: any; + let siteListWitMembers: any; + let siteService: SitesService; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ DropdownSitesComponent - ] + ], + providers: [SitesService, LogService] }).compileComponents(); })); @@ -44,6 +49,7 @@ describe('DropdownSitesComponent', () => { debug = fixture.debugElement; element = fixture.nativeElement; component = fixture.componentInstance; + siteService = TestBed.get(SitesService); sitesList = { 'list': { @@ -80,6 +86,126 @@ describe('DropdownSitesComponent', () => { ] } }; + + siteListWitMembers = { + 'list': { + 'entries': [{ + 'entry': { + 'visibility': 'MODERATED', + 'guid': 'b4cff62a-664d-4d45-9302-98723eac1319', + 'description': 'This is a Sample Alfresco Team site.', + 'id': 'MODERATED-SITE', + 'preset': 'site-dashboard', + 'title': 'FAKE-MODERATED-SITE' + }, + 'relations': { + 'members': { + 'list': { + 'pagination': { + 'count': 3, + 'hasMoreItems': false, + 'skipCount': 0, + 'maxItems': 100 + }, + 'entries': [ + { + 'entry': { + 'role': 'SiteManager', + 'person': { + 'firstName': 'Administrator', + 'emailNotificationsEnabled': true, + 'company': {}, + 'id': 'admin', + 'enabled': true, + 'email': 'admin@alfresco.com' + }, + 'id': 'admin' + } + }, + { + 'entry': { + 'role': 'SiteCollaborator', + 'person': { + 'lastName': 'Beecher', + 'userStatus': 'Helping to design the look and feel of the new web site', + 'jobTitle': 'Graphic Designer', + 'statusUpdatedAt': '2011-02-15T20:20:13.432+0000', + 'mobile': '0112211001100', + 'emailNotificationsEnabled': true, + 'description': 'Alice is a demo user for the sample Alfresco Team site.', + 'telephone': '0112211001100', + 'enabled': false, + 'firstName': 'Alice', + 'skypeId': 'abeecher', + 'avatarId': '198500fc-1e99-4f5f-8926-248cea433366', + 'location': 'Tilbury, UK', + 'company': { + 'organization': 'Moresby, Garland and Wedge', + 'address1': '200 Butterwick Street', + 'address2': 'Tilbury', + 'address3': 'UK', + 'postcode': 'ALF1 SAM1' + }, + 'id': 'abeecher', + 'email': 'abeecher@example.com' + }, + 'id': 'abeecher' + } + } + ] + } + } + } + }, { + 'entry': { + 'visibility': 'PUBLIC', + 'guid': 'b4cff62a-664d-4d45-9302-98723eac1319', + 'description': 'This is a Sample Alfresco Team site.', + 'id': 'PUBLIC-SITE', + 'preset': 'site-dashboard', + 'title': 'FAKE-SITE-PUBLIC' + } + }, { + 'entry': { + 'visibility': 'PRIVATE', + 'guid': 'b4cff62a-664d-4d45-9302-98723eac1319', + 'description': 'This is a Sample Alfresco Team site.', + 'id': 'MEMBER-SITE', + 'preset': 'site-dashboard', + 'title': 'FAKE-PRIVATE-SITE-MEMBER' + }, + 'relations': { + 'members': { + 'list': { + 'pagination': { + 'count': 3, + 'hasMoreItems': false, + 'skipCount': 0, + 'maxItems': 100 + }, + 'entries': [ + { + 'entry': { + 'role': 'SiteManager', + 'person': { + 'firstName': 'Administrator', + 'emailNotificationsEnabled': true, + 'company': {}, + 'id': 'admin', + 'enabled': true, + 'email': 'admin@alfresco.com' + }, + 'id': 'test' + } + } + ] + } + } + } + } + ] + } + }; }); describe('Rendering tests', () => { @@ -280,5 +406,43 @@ describe('DropdownSitesComponent', () => { }); }); + it('should show only sites which logged user is member of when member relation is set', async(() => { + spyOn(siteService, 'getEcmCurrentLoggedUserName').and.returnValue('test'); + spyOn(siteService, 'getSites').and.returnValue(Observable.of(siteListWitMembers)); + component.relations = Relations.Members; + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let options: any = debug.queryAll(By.css('mat-option')); + expect(options[1].nativeElement.innerText).toContain('FAKE-SITE-PUBLIC'); + expect(options[2].nativeElement.innerText).toContain('FAKE-PRIVATE-SITE-MEMBER'); + expect(options[3]).toBeUndefined(); + }); + }); + })); + + it('should show all the sites if no relation is set', async(() => { + spyOn(siteService, 'getEcmCurrentLoggedUserName').and.returnValue('test'); + spyOn(siteService, 'getSites').and.returnValue(Observable.of(siteListWitMembers)); + component.siteList = null; + component.relations = null; + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + debug.query(By.css('.mat-select-trigger')).triggerEventHandler('click', null); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let options: any = debug.queryAll(By.css('mat-option')); + expect(options[1].nativeElement.innerText).toContain('FAKE-MODERATED-SITE'); + expect(options[2].nativeElement.innerText).toContain('FAKE-SITE-PUBLIC'); + expect(options[3].nativeElement.innerText).toContain('FAKE-PRIVATE-SITE-MEMBER'); + }); + }); + })); + }); }); diff --git a/lib/content-services/site-dropdown/sites-dropdown.component.ts b/lib/content-services/site-dropdown/sites-dropdown.component.ts index e57964c7da..e5052eb42e 100644 --- a/lib/content-services/site-dropdown/sites-dropdown.component.ts +++ b/lib/content-services/site-dropdown/sites-dropdown.component.ts @@ -16,9 +16,14 @@ */ import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; -import { SitesService } from '@alfresco/adf-core'; +import { SitesService, LogService } from '@alfresco/adf-core'; import { SitePaging, SiteEntry } from 'alfresco-js-api'; +export enum Relations { + Members = 'members', + Containers = 'containers' +} + @Component({ selector: 'adf-sites-dropdown', styleUrls: ['./sites-dropdown.component.scss'], @@ -48,6 +53,9 @@ export class DropdownSitesComponent implements OnInit { @Input() placeholder: string = 'DROPDOWN.PLACEHOLDER_LABEL'; + @Input() + relations: string; + /** Emitted when the user selects a site. When the default option is selected, * an empty model is emitted. */ @@ -58,14 +66,14 @@ export class DropdownSitesComponent implements OnInit { public MY_FILES_VALUE = '-my-'; - constructor(private sitesService: SitesService) { + constructor(private sitesService: SitesService, + private logService: LogService) { } ngOnInit() { if (!this.siteList) { this.setDefaultSiteList(); } - } selectedSite(event: any) { @@ -73,24 +81,42 @@ export class DropdownSitesComponent implements OnInit { } private setDefaultSiteList() { - this.sitesService.getSites().subscribe((result) => { - this.siteList = result; + let extendedOptions = null; + if (this.relations) { + extendedOptions = { relations: [this.relations] }; + } + this.sitesService.getSites(extendedOptions).subscribe((result) => { - if (!this.hideMyFiles) { - let myItem = { entry: { id: '-my-', guid: '-my-', title: 'DROPDOWN.MY_FILES_OPTION' } }; + this.siteList = this.relations === Relations.Members ? this.filteredResultsByMember(result) : result; - this.siteList.list.entries.unshift(myItem); + if (!this.hideMyFiles) { + let myItem = { entry: { id: '-my-', guid: '-my-', title: 'DROPDOWN.MY_FILES_OPTION' } }; - if (!this.value) { - this.value = '-my-'; - } + this.siteList.list.entries.unshift(myItem); + + if (!this.value) { + this.value = '-my-'; } + } - this.selected = this.siteList.list.entries.find(site => site.entry.id === this.value); - }, - (error) => { + this.selected = this.siteList.list.entries.find(site => site.entry.id === this.value); + }, + (error) => { + this.logService.error(error); + }); + } + + private filteredResultsByMember(sites: SitePaging): SitePaging { + const loggedUserName = this.sitesService.getEcmCurrentLoggedUserName(); + sites.list.entries = sites.list.entries.filter( (site) => this.isCurrentUserMember(site, loggedUserName)); + return sites; + } + + private isCurrentUserMember(site, loggedUserName): boolean { + return site.entry.visibility === 'PUBLIC' || + !!site.relations.members.list.entries.find((member) => { + return member.entry.id === loggedUserName; }); - } } diff --git a/lib/content-services/version-manager/version-manager.component.ts b/lib/content-services/version-manager/version-manager.component.ts index 5a29e2fd33..85e6868cbe 100644 --- a/lib/content-services/version-manager/version-manager.component.ts +++ b/lib/content-services/version-manager/version-manager.component.ts @@ -48,4 +48,3 @@ export class VersionManagerComponent { this.uploadError.emit(event); } } - diff --git a/lib/content-services/version-manager/version-upload.component.ts b/lib/content-services/version-manager/version-upload.component.ts index 0538382e35..58e01d0da9 100644 --- a/lib/content-services/version-manager/version-upload.component.ts +++ b/lib/content-services/version-manager/version-upload.component.ts @@ -46,4 +46,3 @@ export class VersionUploadComponent { } } - diff --git a/lib/core/services/sites.service.ts b/lib/core/services/sites.service.ts index 071a5e5437..feaa6b3db6 100644 --- a/lib/core/services/sites.service.ts +++ b/lib/core/services/sites.service.ts @@ -81,6 +81,10 @@ export class SitesService { return this.getSite(siteId, { relations: ['members'] }); } + getEcmCurrentLoggedUserName(): string { + return this.apiService.getInstance().ecmAuth.username; + } + private handleError(error: Response): any { console.error(error); return Observable.throw(error || 'Server error');