mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-06-30 18:15:11 +00:00
migrate library directives from ACA (#6861)
This commit is contained in:
parent
7219ff38ac
commit
23264b0068
@ -32,6 +32,8 @@ import { TooltipCardDirective } from './tooltip-card/tooltip-card.directive';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { TooltipCardComponent } from './tooltip-card/tooltip-card.component';
|
||||
import { InfiniteSelectScrollDirective } from './infinite-select-scroll.directive';
|
||||
import { LibraryFavoriteDirective } from './library-favorite.directive';
|
||||
import { LibraryMembershipDirective } from './library-membership.directive';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -51,7 +53,9 @@ import { InfiniteSelectScrollDirective } from './infinite-select-scroll.directiv
|
||||
VersionCompatibilityDirective,
|
||||
TooltipCardDirective,
|
||||
TooltipCardComponent,
|
||||
InfiniteSelectScrollDirective
|
||||
InfiniteSelectScrollDirective,
|
||||
LibraryFavoriteDirective,
|
||||
LibraryMembershipDirective
|
||||
],
|
||||
exports: [
|
||||
HighlightDirective,
|
||||
@ -64,7 +68,9 @@ import { InfiniteSelectScrollDirective } from './infinite-select-scroll.directiv
|
||||
UploadDirective,
|
||||
VersionCompatibilityDirective,
|
||||
TooltipCardDirective,
|
||||
InfiniteSelectScrollDirective
|
||||
InfiniteSelectScrollDirective,
|
||||
LibraryFavoriteDirective,
|
||||
LibraryMembershipDirective
|
||||
]
|
||||
})
|
||||
export class DirectiveModule {}
|
||||
|
121
lib/core/directives/library-favorite.directive.spec.ts
Normal file
121
lib/core/directives/library-favorite.directive.spec.ts
Normal file
@ -0,0 +1,121 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 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 { Component, ViewChild } from '@angular/core';
|
||||
import { LibraryEntity, LibraryFavoriteDirective } from './library-favorite.directive';
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AlfrescoApiService } from '../services/alfresco-api.service';
|
||||
import { CoreModule } from '../core.module';
|
||||
import { AlfrescoApiServiceMock } from '../mock';
|
||||
|
||||
@Component({
|
||||
selector: 'app-test-component',
|
||||
template: ` <button #favoriteLibrary="favoriteLibrary" [adf-favorite-library]="selection">Favorite</button> `
|
||||
})
|
||||
class TestComponent {
|
||||
@ViewChild('favoriteLibrary', { static: true })
|
||||
directive: LibraryFavoriteDirective;
|
||||
|
||||
selection: LibraryEntity = null;
|
||||
}
|
||||
|
||||
describe('LibraryFavoriteDirective', () => {
|
||||
let fixture: ComponentFixture<TestComponent>;
|
||||
let api: AlfrescoApiService;
|
||||
let component: TestComponent;
|
||||
let selection: LibraryEntity;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), CoreModule.forRoot()],
|
||||
providers: [
|
||||
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }
|
||||
],
|
||||
declarations: [TestComponent, LibraryFavoriteDirective]
|
||||
});
|
||||
fixture = TestBed.createComponent(TestComponent);
|
||||
component = fixture.componentInstance;
|
||||
api = TestBed.inject(AlfrescoApiService);
|
||||
selection = { entry: { guid: 'guid', id: 'id', title: 'Site', visibility: 'PUBLIC' }, isLibrary: true, isFavorite: false };
|
||||
component.selection = selection;
|
||||
});
|
||||
|
||||
it('should not check for favorite if no selection exists', () => {
|
||||
spyOn(api.peopleApi, 'getFavoriteSite');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(api.peopleApi.getFavoriteSite).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should mark selection as favorite', async () => {
|
||||
spyOn(api.peopleApi, 'getFavoriteSite').and.returnValue(Promise.resolve(null));
|
||||
|
||||
delete selection.isFavorite;
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(api.peopleApi.getFavoriteSite).toHaveBeenCalled();
|
||||
expect(component.directive.isFavorite()).toBe(true);
|
||||
});
|
||||
|
||||
it('should mark selection not favorite', async () => {
|
||||
spyOn(api.peopleApi, 'getFavoriteSite').and.returnValue(Promise.reject());
|
||||
|
||||
delete selection.isFavorite;
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(api.peopleApi.getFavoriteSite).toHaveBeenCalled();
|
||||
expect(component.directive.isFavorite()).toBe(false);
|
||||
});
|
||||
|
||||
it('should call addFavorite() on click event when selection is not a favorite', async () => {
|
||||
spyOn(api.peopleApi, 'getFavoriteSite').and.returnValue(Promise.reject());
|
||||
spyOn(api.peopleApi, 'addFavorite').and.returnValue(Promise.resolve(null));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(component.directive.isFavorite()).toBeFalsy();
|
||||
|
||||
fixture.nativeElement.querySelector('button').dispatchEvent(new MouseEvent('click'));
|
||||
fixture.detectChanges();
|
||||
expect(api.peopleApi.addFavorite).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call removeFavoriteSite() on click event when selection is favorite', async () => {
|
||||
spyOn(api.peopleApi, 'getFavoriteSite').and.returnValue(Promise.resolve(null));
|
||||
spyOn(api.favoritesApi, 'removeFavoriteSite').and.returnValue(Promise.resolve());
|
||||
|
||||
selection.isFavorite = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(component.directive.isFavorite()).toBeTruthy();
|
||||
|
||||
fixture.nativeElement.querySelector('button').dispatchEvent(new MouseEvent('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(api.favoritesApi.removeFavoriteSite).toHaveBeenCalled();
|
||||
});
|
||||
});
|
107
lib/core/directives/library-favorite.directive.ts
Normal file
107
lib/core/directives/library-favorite.directive.ts
Normal file
@ -0,0 +1,107 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 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, Output, EventEmitter } from '@angular/core';
|
||||
import { SiteBody, FavoriteBody, FavoriteEntry, Site } from '@alfresco/js-api';
|
||||
import { AlfrescoApiService } from '../services/alfresco-api.service';
|
||||
|
||||
export interface LibraryEntity {
|
||||
entry: Site;
|
||||
isLibrary: boolean;
|
||||
isFavorite: boolean;
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-favorite-library]',
|
||||
exportAs: 'favoriteLibrary'
|
||||
})
|
||||
export class LibraryFavoriteDirective implements OnChanges {
|
||||
@Input('adf-favorite-library')
|
||||
library: LibraryEntity = null;
|
||||
|
||||
@Output() toggle = new EventEmitter<any>();
|
||||
// tslint:disable-next-line: no-output-native
|
||||
@Output() error = new EventEmitter<any>();
|
||||
|
||||
private targetLibrary = null;
|
||||
|
||||
@HostListener('click')
|
||||
onClick() {
|
||||
const guid = this.targetLibrary.entry.guid;
|
||||
|
||||
if (this.targetLibrary.isFavorite) {
|
||||
this.removeFavorite(guid);
|
||||
} else {
|
||||
this.addFavorite({
|
||||
target: {
|
||||
site: {
|
||||
guid
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private alfrescoApiService: AlfrescoApiService) {}
|
||||
|
||||
ngOnChanges(changes) {
|
||||
if (!changes.library.currentValue) {
|
||||
this.targetLibrary = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.targetLibrary = changes.library.currentValue;
|
||||
this.markFavoriteLibrary(changes.library.currentValue);
|
||||
}
|
||||
|
||||
isFavorite(): boolean {
|
||||
return this.targetLibrary && this.targetLibrary.isFavorite;
|
||||
}
|
||||
|
||||
private async markFavoriteLibrary(library: LibraryEntity) {
|
||||
if (this.targetLibrary.isFavorite === undefined) {
|
||||
try {
|
||||
await this.alfrescoApiService.peopleApi.getFavoriteSite('-me-', library.entry.id);
|
||||
this.targetLibrary.isFavorite = true;
|
||||
} catch {
|
||||
this.targetLibrary.isFavorite = false;
|
||||
}
|
||||
} else {
|
||||
this.targetLibrary = library;
|
||||
}
|
||||
}
|
||||
|
||||
private addFavorite(favoriteBody: FavoriteBody) {
|
||||
this.alfrescoApiService.peopleApi
|
||||
.addFavorite('-me-', favoriteBody)
|
||||
.then((libraryEntry: FavoriteEntry) => {
|
||||
this.targetLibrary.isFavorite = true;
|
||||
this.toggle.emit(libraryEntry);
|
||||
})
|
||||
.catch((error) => this.error.emit(error));
|
||||
}
|
||||
|
||||
private removeFavorite(favoriteId: string) {
|
||||
this.alfrescoApiService.favoritesApi
|
||||
.removeFavoriteSite('-me-', favoriteId)
|
||||
.then((libraryBody: SiteBody) => {
|
||||
this.targetLibrary.isFavorite = false;
|
||||
this.toggle.emit(libraryBody);
|
||||
})
|
||||
.catch((error) => this.error.emit(error));
|
||||
}
|
||||
}
|
220
lib/core/directives/library-membership.directive.spec.ts
Normal file
220
lib/core/directives/library-membership.directive.spec.ts
Normal file
@ -0,0 +1,220 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 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 { fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { AlfrescoApiService, SitesService } from '../services';
|
||||
import { LibraryMembershipDirective } from './library-membership.directive';
|
||||
import { NO_ERRORS_SCHEMA, SimpleChange } from '@angular/core';
|
||||
import { of, throwError, Subject } from 'rxjs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DirectiveModule } from './directive.module';
|
||||
import { CoreModule } from '../core.module';
|
||||
import { AlfrescoApiServiceMock } from '../mock/alfresco-api.service.mock';
|
||||
|
||||
describe('LibraryMembershipDirective', () => {
|
||||
let alfrescoApiService: AlfrescoApiService;
|
||||
let directive: LibraryMembershipDirective;
|
||||
let peopleApi: any;
|
||||
let sitesService: SitesService;
|
||||
let addMembershipSpy: jasmine.Spy;
|
||||
let getMembershipSpy: jasmine.Spy;
|
||||
let deleteMembershipSpy: jasmine.Spy;
|
||||
let mockSupportedVersion = false;
|
||||
|
||||
let testSiteEntry: any;
|
||||
let requestedMembershipResponse: any;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), DirectiveModule, CoreModule.forRoot()],
|
||||
providers: [
|
||||
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
});
|
||||
|
||||
testSiteEntry = {
|
||||
id: 'id-1',
|
||||
guid: 'site-1',
|
||||
title: 'aa t m',
|
||||
visibility: 'MODERATED'
|
||||
};
|
||||
|
||||
requestedMembershipResponse = {
|
||||
id: testSiteEntry.id,
|
||||
createdAt: '2018-11-14',
|
||||
site: testSiteEntry
|
||||
};
|
||||
|
||||
alfrescoApiService = TestBed.inject(AlfrescoApiService);
|
||||
sitesService = TestBed.inject(SitesService);
|
||||
peopleApi = alfrescoApiService.getInstance().core.peopleApi;
|
||||
directive = new LibraryMembershipDirective(alfrescoApiService, sitesService, {
|
||||
ecmProductInfo$: new Subject(),
|
||||
isVersionSupported: () => mockSupportedVersion
|
||||
} as any);
|
||||
});
|
||||
|
||||
describe('markMembershipRequest', () => {
|
||||
beforeEach(() => {
|
||||
getMembershipSpy = spyOn(peopleApi, 'getSiteMembershipRequest').and.returnValue(Promise.resolve({ entry: requestedMembershipResponse }));
|
||||
});
|
||||
|
||||
it('should not check membership requests if no entry is selected', fakeAsync(() => {
|
||||
const selection = {};
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
expect(getMembershipSpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should check if a membership request exists for the selected library', fakeAsync(() => {
|
||||
const selection = { entry: {} };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
expect(getMembershipSpy.calls.count()).toBe(1);
|
||||
}));
|
||||
|
||||
it('should remember when a membership request exists for selected library', fakeAsync(() => {
|
||||
const selection = { entry: testSiteEntry };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
expect(directive.targetSite.joinRequested).toBe(true);
|
||||
}));
|
||||
|
||||
it('should remember when a membership request is not found for selected library', fakeAsync(() => {
|
||||
getMembershipSpy.and.returnValue(Promise.reject());
|
||||
|
||||
const selection = { entry: testSiteEntry };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
expect(directive.targetSite.joinRequested).toBe(false);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('toggleMembershipRequest', () => {
|
||||
beforeEach(() => {
|
||||
mockSupportedVersion = false;
|
||||
getMembershipSpy = spyOn(peopleApi, 'getSiteMembershipRequest').and.returnValue(Promise.resolve({ entry: requestedMembershipResponse }));
|
||||
addMembershipSpy = spyOn(peopleApi, 'addSiteMembershipRequest').and.returnValue(Promise.resolve({ entry: requestedMembershipResponse }));
|
||||
deleteMembershipSpy = spyOn(peopleApi, 'removeSiteMembershipRequest').and.returnValue(Promise.resolve({}));
|
||||
});
|
||||
|
||||
it('should do nothing if there is no selected library ', fakeAsync(() => {
|
||||
const selection = {};
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
directive.toggleMembershipRequest();
|
||||
tick();
|
||||
expect(addMembershipSpy).not.toHaveBeenCalled();
|
||||
expect(deleteMembershipSpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should delete membership request if there is one', fakeAsync(() => {
|
||||
const selection = { entry: testSiteEntry };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
directive.toggleMembershipRequest();
|
||||
tick();
|
||||
expect(deleteMembershipSpy).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should call API to make a membership request if there is none', fakeAsync(() => {
|
||||
const selection = { entry: { id: 'no-membership-requested' } };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
directive.toggleMembershipRequest();
|
||||
tick();
|
||||
expect(addMembershipSpy).toHaveBeenCalledWith('-me-', { id: 'no-membership-requested' });
|
||||
expect(deleteMembershipSpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it("should add 'workspace' to send appropriate email", fakeAsync(() => {
|
||||
mockSupportedVersion = true;
|
||||
const selection = { entry: { id: 'no-membership-requested' } };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
directive.toggleMembershipRequest();
|
||||
tick();
|
||||
expect(addMembershipSpy).toHaveBeenCalledWith('-me-', { id: 'no-membership-requested', client: 'workspace' });
|
||||
expect(deleteMembershipSpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should call API to add user to library if admin user', fakeAsync(() => {
|
||||
const createSiteMembershipSpy = spyOn(sitesService, 'createSiteMembership').and.returnValue(of({} as any));
|
||||
const selection = { entry: { id: 'no-membership-requested' } };
|
||||
const selectionChange = new SimpleChange(null, selection, true);
|
||||
directive.isAdmin = true;
|
||||
directive.ngOnChanges({ selection: selectionChange });
|
||||
tick();
|
||||
directive.toggleMembershipRequest();
|
||||
tick();
|
||||
expect(createSiteMembershipSpy).toHaveBeenCalled();
|
||||
expect(addMembershipSpy).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should emit error when the request to join a library fails', fakeAsync(() => {
|
||||
spyOn(directive.error, 'emit');
|
||||
addMembershipSpy.and.returnValue(throwError('err'));
|
||||
|
||||
const selection = { entry: { id: 'no-membership-requested' } };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
directive.toggleMembershipRequest();
|
||||
tick();
|
||||
expect(directive.error.emit).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should emit specific error message on invalid email address server error', fakeAsync(() => {
|
||||
const emitErrorSpy = spyOn(directive.error, 'emit');
|
||||
const selection = { entry: { id: 'no-membership-requested' } };
|
||||
const change = new SimpleChange(null, selection, true);
|
||||
directive.ngOnChanges({ selection: change });
|
||||
tick();
|
||||
|
||||
const testData = [
|
||||
{
|
||||
fixture: 'Failed to resolve sender mail address',
|
||||
expected: 'APP.MESSAGES.ERRORS.INVALID_SENDER_EMAIL'
|
||||
},
|
||||
{
|
||||
fixture: 'All recipients for the mail action were invalid',
|
||||
expected: 'APP.MESSAGES.ERRORS.INVALID_RECEIVER_EMAIL'
|
||||
}
|
||||
];
|
||||
|
||||
testData.forEach((data) => {
|
||||
addMembershipSpy.and.returnValue(throwError({ message: data.fixture }));
|
||||
emitErrorSpy.calls.reset();
|
||||
directive.toggleMembershipRequest();
|
||||
tick();
|
||||
expect(emitErrorSpy).toHaveBeenCalledWith({
|
||||
error: { message: data.fixture },
|
||||
i18nKey: data.expected
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
});
|
229
lib/core/directives/library-membership.directive.ts
Normal file
229
lib/core/directives/library-membership.directive.ts
Normal file
@ -0,0 +1,229 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 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, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { SiteEntry, SiteMembershipRequestBody, SiteMemberEntry, SiteMembershipRequestEntry } from '@alfresco/js-api';
|
||||
import { BehaviorSubject, from, Observable } from 'rxjs';
|
||||
import { AlfrescoApiService } from '../services/alfresco-api.service';
|
||||
import { SitesService } from '../services/sites.service';
|
||||
import { VersionCompatibilityService } from '../services/version-compatibility.service';
|
||||
|
||||
export interface LibraryMembershipToggleEvent {
|
||||
updatedEntry?: any;
|
||||
shouldReload: boolean;
|
||||
i18nKey: string;
|
||||
}
|
||||
|
||||
export interface LibraryMembershipErrorEvent {
|
||||
error: any;
|
||||
i18nKey: string;
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-library-membership]',
|
||||
exportAs: 'libraryMembership'
|
||||
})
|
||||
export class LibraryMembershipDirective implements OnChanges {
|
||||
targetSite: any = null;
|
||||
|
||||
isJoinRequested: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
|
||||
/** Site for which to toggle the membership request. */
|
||||
@Input('adf-library-membership')
|
||||
selection: SiteEntry = null;
|
||||
|
||||
/** Site for which to toggle the membership request. */
|
||||
@Input()
|
||||
isAdmin = false;
|
||||
|
||||
@Output()
|
||||
toggle = new EventEmitter<LibraryMembershipToggleEvent>();
|
||||
|
||||
// tslint:disable-next-line: no-output-native
|
||||
@Output()
|
||||
error = new EventEmitter<LibraryMembershipErrorEvent>();
|
||||
|
||||
@HostListener('click')
|
||||
onClick() {
|
||||
this.toggleMembershipRequest();
|
||||
}
|
||||
|
||||
constructor(
|
||||
private alfrescoApiService: AlfrescoApiService,
|
||||
private sitesService: SitesService,
|
||||
private versionCompatibilityService: VersionCompatibilityService
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (!changes.selection.currentValue || !changes.selection.currentValue.entry) {
|
||||
this.targetSite = null;
|
||||
|
||||
return;
|
||||
}
|
||||
this.targetSite = changes.selection.currentValue.entry;
|
||||
this.markMembershipRequest();
|
||||
}
|
||||
|
||||
toggleMembershipRequest() {
|
||||
if (!this.targetSite) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.targetSite.joinRequested) {
|
||||
this.cancelJoinRequest().subscribe(
|
||||
() => {
|
||||
this.targetSite.joinRequested = false;
|
||||
this.isJoinRequested.next(false);
|
||||
const info = {
|
||||
updatedEntry: this.targetSite,
|
||||
shouldReload: false,
|
||||
i18nKey: 'APP.MESSAGES.INFO.JOIN_CANCELED'
|
||||
};
|
||||
this.toggle.emit(info);
|
||||
},
|
||||
(error) => {
|
||||
const errWithMessage = {
|
||||
error,
|
||||
i18nKey: 'APP.MESSAGES.ERRORS.JOIN_CANCEL_FAILED'
|
||||
};
|
||||
this.error.emit(errWithMessage);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.targetSite.joinRequested && !this.isAdmin) {
|
||||
this.joinLibraryRequest().subscribe(
|
||||
(createdMembership) => {
|
||||
this.targetSite.joinRequested = true;
|
||||
this.isJoinRequested.next(true);
|
||||
|
||||
if (createdMembership.entry && createdMembership.entry.site && createdMembership.entry.site.role) {
|
||||
const info = {
|
||||
shouldReload: true,
|
||||
i18nKey: 'APP.MESSAGES.INFO.JOINED'
|
||||
};
|
||||
this.toggle.emit(info);
|
||||
} else {
|
||||
const info = {
|
||||
updatedEntry: this.targetSite,
|
||||
shouldReload: false,
|
||||
i18nKey: 'APP.MESSAGES.INFO.JOIN_REQUESTED'
|
||||
};
|
||||
this.toggle.emit(info);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
const errWithMessage = {
|
||||
error,
|
||||
i18nKey: 'APP.MESSAGES.ERRORS.JOIN_REQUEST_FAILED'
|
||||
};
|
||||
|
||||
const senderEmailCheck = 'Failed to resolve sender mail address';
|
||||
const receiverEmailCheck = 'All recipients for the mail action were invalid';
|
||||
|
||||
if (error.message) {
|
||||
if (error.message.includes(senderEmailCheck)) {
|
||||
errWithMessage.i18nKey = 'APP.MESSAGES.ERRORS.INVALID_SENDER_EMAIL';
|
||||
} else if (error.message.includes(receiverEmailCheck)) {
|
||||
errWithMessage.i18nKey = 'APP.MESSAGES.ERRORS.INVALID_RECEIVER_EMAIL';
|
||||
}
|
||||
}
|
||||
|
||||
this.error.emit(errWithMessage);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isAdmin) {
|
||||
this.joinLibrary().subscribe(
|
||||
(createdMembership: SiteMemberEntry) => {
|
||||
if (createdMembership.entry && createdMembership.entry.role) {
|
||||
const info = {
|
||||
shouldReload: true,
|
||||
i18nKey: 'APP.MESSAGES.INFO.JOINED'
|
||||
};
|
||||
this.toggle.emit(info);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
const errWithMessage = {
|
||||
error,
|
||||
i18nKey: 'APP.MESSAGES.ERRORS.JOIN_REQUEST_FAILED'
|
||||
};
|
||||
|
||||
const senderEmailCheck = 'Failed to resolve sender mail address';
|
||||
const receiverEmailCheck = 'All recipients for the mail action were invalid';
|
||||
|
||||
if (error.message) {
|
||||
if (error.message.includes(senderEmailCheck)) {
|
||||
errWithMessage.i18nKey = 'APP.MESSAGES.ERRORS.INVALID_SENDER_EMAIL';
|
||||
} else if (error.message.includes(receiverEmailCheck)) {
|
||||
errWithMessage.i18nKey = 'APP.MESSAGES.ERRORS.INVALID_RECEIVER_EMAIL';
|
||||
}
|
||||
}
|
||||
|
||||
this.error.emit(errWithMessage);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
markMembershipRequest() {
|
||||
if (!this.targetSite) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.getMembershipRequest().subscribe(
|
||||
(data) => {
|
||||
if (data.entry.id === this.targetSite.id) {
|
||||
this.targetSite.joinRequested = true;
|
||||
this.isJoinRequested.next(true);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
this.targetSite.joinRequested = false;
|
||||
this.isJoinRequested.next(false);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private joinLibraryRequest(): Observable<SiteMembershipRequestEntry> {
|
||||
const memberBody = {
|
||||
id: this.targetSite.id
|
||||
} as SiteMembershipRequestBody;
|
||||
|
||||
if (this.versionCompatibilityService.isVersionSupported('7.0.0')) {
|
||||
memberBody.client = 'workspace';
|
||||
}
|
||||
return from(this.alfrescoApiService.peopleApi.addSiteMembershipRequest('-me-', memberBody));
|
||||
}
|
||||
|
||||
private joinLibrary() {
|
||||
return this.sitesService.createSiteMembership(this.targetSite.id, {
|
||||
role: 'SiteConsumer',
|
||||
id: '-me-'
|
||||
});
|
||||
}
|
||||
|
||||
private cancelJoinRequest() {
|
||||
return from(this.alfrescoApiService.peopleApi.removeSiteMembershipRequest('-me-', this.targetSite.id));
|
||||
}
|
||||
|
||||
private getMembershipRequest() {
|
||||
return from(this.alfrescoApiService.peopleApi.getSiteMembershipRequest('-me-', this.targetSite.id));
|
||||
}
|
||||
}
|
@ -26,5 +26,7 @@ export * from './upload.directive';
|
||||
export * from './version-compatibility.directive';
|
||||
export * from './tooltip-card/tooltip-card.directive';
|
||||
export * from './infinite-select-scroll.directive';
|
||||
export * from './library-favorite.directive';
|
||||
export * from './library-membership.directive';
|
||||
|
||||
export * from './directive.module';
|
||||
|
Loading…
x
Reference in New Issue
Block a user