diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html
index f41910ec0..4ea4e8c28 100644
--- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html
+++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.html
@@ -85,6 +85,7 @@
+ {{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }}
{{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }}
diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts
index 9b54f8c65..ab7652fb6 100644
--- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts
+++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.spec.ts
@@ -23,16 +23,23 @@
* along with Alfresco. If not, see .
*/
import { LibraryMetadataFormComponent } from './library-metadata-form.component';
-import { TestBed, ComponentFixture } from '@angular/core/testing';
+import {
+ TestBed,
+ ComponentFixture,
+ fakeAsync,
+ tick
+} from '@angular/core/testing';
import { Store } from '@ngrx/store';
import { UpdateLibraryAction } from '../../../store/actions';
import { AppTestingModule } from '../../../testing/app-testing.module';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Site, SiteBody } from 'alfresco-js-api';
+import { AlfrescoApiService, AlfrescoApiServiceMock } from '@alfresco/adf-core';
describe('LibraryMetadataFormComponent', () => {
let fixture: ComponentFixture;
let component: LibraryMetadataFormComponent;
+ let alfrescoApiService: AlfrescoApiService;
const storeMock = {
dispatch: jasmine.createSpy('dispatch')
};
@@ -41,12 +48,16 @@ describe('LibraryMetadataFormComponent', () => {
TestBed.configureTestingModule({
imports: [AppTestingModule],
declarations: [LibraryMetadataFormComponent],
- providers: [{ provide: Store, useValue: storeMock }],
+ providers: [
+ { provide: Store, useValue: storeMock },
+ { provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }
+ ],
schemas: [NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(LibraryMetadataFormComponent);
component = fixture.componentInstance;
+ alfrescoApiService = TestBed.get(AlfrescoApiService);
});
afterEach(() => {
@@ -211,4 +222,98 @@ describe('LibraryMetadataFormComponent', () => {
expect(component.form.value).toEqual(siteEntryModel);
});
+
+ it('should warn if library name input is used by another library', fakeAsync(() => {
+ const title = 'some-title';
+ spyOn(
+ alfrescoApiService.getInstance().core.queriesApi,
+ 'findSites'
+ ).and.returnValue(
+ Promise.resolve({
+ list: { entries: [{ entry: { title } }] }
+ })
+ );
+
+ const siteEntryModel = {
+ title: 'libraryTitle',
+ description: 'description',
+ visibility: 'PRIVATE'
+ };
+
+ component.node = {
+ entry: {
+ id: 'libraryId',
+ ...siteEntryModel
+ }
+ };
+
+ fixture.detectChanges();
+ component.form.controls.title.setValue(title);
+ fixture.detectChanges();
+
+ tick(500);
+ expect(component.libraryTitleExists).toBe(true);
+ }));
+
+ it('should not warn if library name input is the same with library node data', fakeAsync(() => {
+ spyOn(
+ alfrescoApiService.getInstance().core.queriesApi,
+ 'findSites'
+ ).and.returnValue(
+ Promise.resolve({
+ list: { entries: [{ entry: { title: 'libraryTitle' } }] }
+ })
+ );
+
+ const siteEntryModel = {
+ title: 'libraryTitle',
+ description: 'description',
+ visibility: 'PRIVATE'
+ };
+
+ component.node = {
+ entry: {
+ id: 'libraryId',
+ ...siteEntryModel
+ }
+ };
+
+ fixture.detectChanges();
+ component.form.controls.title.setValue('libraryTitle');
+ fixture.detectChanges();
+
+ tick(500);
+ expect(component.libraryTitleExists).toBe(false);
+ }));
+
+ it('should not warn if library name is unique', fakeAsync(() => {
+ spyOn(
+ alfrescoApiService.getInstance().core.queriesApi,
+ 'findSites'
+ ).and.returnValue(
+ Promise.resolve({
+ list: { entries: [] }
+ })
+ );
+
+ const siteEntryModel = {
+ title: 'libraryTitle',
+ description: 'description',
+ visibility: 'PRIVATE'
+ };
+
+ component.node = {
+ entry: {
+ id: 'libraryId',
+ ...siteEntryModel
+ }
+ };
+
+ fixture.detectChanges();
+ component.form.controls.title.setValue('some-name');
+ fixture.detectChanges();
+
+ tick(500);
+ expect(component.libraryTitleExists).toBe(false);
+ }));
});
diff --git a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts
index e687bb8f1..c9a707d9e 100644
--- a/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts
+++ b/src/app/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts
@@ -23,22 +23,27 @@
* along with Alfresco. If not, see .
*/
-import { Component, Input, OnInit, OnChanges } from '@angular/core';
+import { Component, Input, OnInit, OnChanges, OnDestroy } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
-import { SiteEntry } from 'alfresco-js-api';
+import { SiteEntry, SitePaging } from 'alfresco-js-api';
import { Store } from '@ngrx/store';
import { UpdateLibraryAction } from '../../../store/actions';
import { AppStore } from '../../../store/states/app.state';
+import { debounceTime, mergeMap, takeUntil } from 'rxjs/operators';
+import { AlfrescoApiService } from '@alfresco/adf-core';
+import { Observable, from, Subject } from 'rxjs';
@Component({
selector: 'app-library-metadata-form',
templateUrl: './library-metadata-form.component.html'
})
-export class LibraryMetadataFormComponent implements OnInit, OnChanges {
+export class LibraryMetadataFormComponent
+ implements OnInit, OnChanges, OnDestroy {
@Input()
node: SiteEntry;
edit: boolean;
+ libraryTitleExists = false;
libraryType = [
{ value: 'PUBLIC', label: 'LIBRARY.VISIBILITY.PUBLIC' },
@@ -56,7 +61,12 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
visibility: new FormControl(this.libraryType[0].value)
});
- constructor(protected store: Store) {}
+ onDestroy$: Subject = new Subject();
+
+ constructor(
+ private alfrescoApiService: AlfrescoApiService,
+ protected store: Store
+ ) {}
get canUpdateLibrary() {
return (
@@ -79,6 +89,32 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
ngOnInit() {
this.updateForm(this.node);
+
+ this.form.controls['title'].valueChanges
+ .pipe(
+ debounceTime(300),
+ mergeMap(title => this.findLibraryByTitle(title)),
+ takeUntil(this.onDestroy$)
+ )
+ .subscribe(result => {
+ const { entries } = result.list;
+
+ if (entries.length) {
+ if (this.form.controls.title.value === this.node.entry.title) {
+ this.libraryTitleExists = false;
+ } else {
+ this.libraryTitleExists =
+ this.form.controls.title.value === entries[0].entry.title;
+ }
+ } else {
+ this.libraryTitleExists = false;
+ }
+ });
+ }
+
+ ngOnDestroy() {
+ this.onDestroy$.next(true);
+ this.onDestroy$.complete();
}
ngOnChanges() {
@@ -101,4 +137,16 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
visibility: entry.visibility
});
}
+
+ private findLibraryByTitle(libraryTitle: string): Observable {
+ return from(
+ this.alfrescoApiService
+ .getInstance()
+ .core.queriesApi.findSites(libraryTitle, {
+ maxItems: 1,
+ fields: ['title']
+ })
+ .catch(() => ({ list: { entries: [] } }))
+ );
+ }
}