diff --git a/e2e/components/dialog/create-library-dialog.ts b/e2e/components/dialog/create-library-dialog.ts
index 074d5beeb..305ccdf70 100755
--- a/e2e/components/dialog/create-library-dialog.ts
+++ b/e2e/components/dialog/create-library-dialog.ts
@@ -30,7 +30,7 @@ import { Utils } from '../../utilities/utils';
export class CreateLibraryDialog extends Component {
private static selectors = {
- root: 'app-library-dialog',
+ root: 'adf-library-dialog',
title: '.mat-dialog-title',
nameInput: 'input[placeholder="Name" i]',
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 2de688991..98391279c 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -39,6 +39,7 @@ import {
TranslateLoaderService
} from '@alfresco/adf-core';
import {
+ LibraryDialogComponent,
ContentModule,
CustomResourcesService
} from '@alfresco/adf-content-services';
@@ -50,7 +51,6 @@ import { FilesComponent } from './components/files/files.component';
import { LibrariesComponent } from './components/libraries/libraries.component';
import { FavoriteLibrariesComponent } from './components/favorite-libraries/favorite-libraries.component';
import { NodeVersionsDialogComponent } from './dialogs/node-versions/node-versions.dialog';
-import { LibraryDialogComponent } from './dialogs/library/library.dialog';
import { AppStoreModule } from './store/app-store.module';
import { MaterialModule } from './material.module';
@@ -118,8 +118,7 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
FilesComponent,
LibrariesComponent,
FavoriteLibrariesComponent,
- NodeVersionsDialogComponent,
- LibraryDialogComponent
+ NodeVersionsDialogComponent
],
providers: [
{ provide: RouteReuseStrategy, useClass: AppRouteReuseStrategy },
diff --git a/src/app/dialogs/library/library.dialog.html b/src/app/dialogs/library/library.dialog.html
deleted file mode 100644
index 20437bcd7..000000000
--- a/src/app/dialogs/library/library.dialog.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
{{ createTitle | translate }}
-
-
-
-
-
-
-
-
-
-
diff --git a/src/app/dialogs/library/library.dialog.scss b/src/app/dialogs/library/library.dialog.scss
deleted file mode 100644
index 5c8abdba9..000000000
--- a/src/app/dialogs/library/library.dialog.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-.app-library-dialog {
- .mat-radio-group {
- display: flex;
- flex-direction: column;
- margin: 0 0 20px 0;
- }
-
- .mat-radio-group .mat-radio-button {
- margin: 10px 0;
- }
-
- .mat-form-field {
- width: 100%;
- }
-
- mat-form-field {
- padding-top: 20px;
- }
-
- .actions-buttons {
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
-
- .mat-button {
- text-transform: uppercase;
- }
- }
-}
diff --git a/src/app/dialogs/library/library.dialog.spec.ts b/src/app/dialogs/library/library.dialog.spec.ts
deleted file mode 100644
index 01808c145..000000000
--- a/src/app/dialogs/library/library.dialog.spec.ts
+++ /dev/null
@@ -1,248 +0,0 @@
-/*!
- * @license
- * Alfresco Example Content Application
- *
- * Copyright (C) 2005 - 2018 Alfresco Software Limited
- *
- * This file is part of the Alfresco Example Content Application.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * The Alfresco Example Content Application is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- */
-
-import { NoopAnimationsModule } from '@angular/platform-browser/animations';
-import { ReactiveFormsModule } from '@angular/forms';
-import { CoreModule } from '@alfresco/adf-core';
-import { LibraryDialogComponent } from './library.dialog';
-import { TestBed, fakeAsync, tick, flush } from '@angular/core/testing';
-import { NO_ERRORS_SCHEMA } from '@angular/core';
-import { MatDialogRef } from '@angular/material';
-import {
- AlfrescoApiService,
- AlfrescoApiServiceMock,
- setupTestBed
-} from '@alfresco/adf-core';
-
-describe('LibraryDialogComponent', () => {
- let fixture;
- let component;
- let alfrescoApi;
- const dialogRef = {
- close: jasmine.createSpy('close')
- };
-
- setupTestBed({
- imports: [NoopAnimationsModule, CoreModule, ReactiveFormsModule],
- declarations: [LibraryDialogComponent],
- providers: [
- {
- provide: AlfrescoApiService,
- useClass: AlfrescoApiServiceMock
- },
- { provide: MatDialogRef, useValue: dialogRef }
- ],
- schemas: [NO_ERRORS_SCHEMA]
- });
-
- beforeEach(() => {
- fixture = TestBed.createComponent(LibraryDialogComponent);
- component = fixture.componentInstance;
- alfrescoApi = TestBed.get(AlfrescoApiService);
-
- spyOn(
- alfrescoApi.getInstance().core.queriesApi,
- 'findSites'
- ).and.returnValue(
- Promise.resolve({
- list: { entries: [] }
- })
- );
- });
-
- it('should set library id automatically on title input', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.title.setValue('libraryTitle');
- tick(500);
- flush();
- fixture.detectChanges();
-
- expect(component.form.controls.id.value).toBe('libraryTitle');
- }));
-
- it('should translate library title space character to dash for library id', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.title.setValue('library title');
- tick(500);
- flush();
- fixture.detectChanges();
-
- expect(component.form.controls.id.value).toBe('library-title');
- }));
-
- it('should not translate library title if value is not a valid id', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.title.setValue('@@@####');
- tick(500);
- flush();
- fixture.detectChanges();
-
- expect(component.form.controls.id.value).toBe(null);
- }));
-
- it('should translate library title partially for library id', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.title.setValue('@@@####library');
- tick(500);
- flush();
- fixture.detectChanges();
-
- expect(component.form.controls.id.value).toBe('library');
- }));
-
- it('should translate library title multiple space character to one dash for library id', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.title.setValue('library title');
- tick(500);
- flush();
- fixture.detectChanges();
-
- expect(component.form.controls.id.value).toBe('library-title');
- }));
-
- it('should not change custom library id on title input', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.id.setValue('custom-id');
- component.form.controls.id.markAsDirty();
- tick(500);
- flush();
- fixture.detectChanges();
-
- component.form.controls.title.setValue('library title');
- tick(500);
- flush();
- fixture.detectChanges();
-
- expect(component.form.controls.id.value).toBe('custom-id');
- }));
-
- it('should invalidate form when library id already exists', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'getSite').and.returnValue(Promise.resolve());
-
- fixture.detectChanges();
- component.form.controls.id.setValue('existingLibrary');
- tick(500);
- flush();
- fixture.detectChanges();
-
- expect(component.form.controls.id.errors).toEqual({
- message: 'LIBRARY.ERRORS.EXISTENT_SITE'
- });
- expect(component.form.valid).toBe(false);
- }));
-
- it('should create site when form is valid', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'createSite').and.returnValue(
- Promise.resolve()
- );
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.title.setValue('library title');
- tick(500);
- flush();
- fixture.detectChanges();
-
- component.submit();
- fixture.detectChanges();
- flush();
-
- expect(alfrescoApi.sitesApi.createSite).toHaveBeenCalledWith({
- id: 'library-title',
- title: 'library title',
- description: '',
- visibility: 'PUBLIC'
- });
- }));
-
- it('should not create site when form is invalid', fakeAsync(() => {
- spyOn(alfrescoApi.sitesApi, 'createSite').and.returnValue(
- Promise.resolve({})
- );
- spyOn(alfrescoApi.sitesApi, 'getSite').and.returnValue(Promise.resolve());
-
- fixture.detectChanges();
- component.form.controls.title.setValue('existingLibrary');
- tick(500);
- flush();
- fixture.detectChanges();
-
- component.submit();
- fixture.detectChanges();
- flush();
-
- expect(alfrescoApi.sitesApi.createSite).not.toHaveBeenCalled();
- }));
-
- it('should notify on 409 conflict error (might be in trash)', fakeAsync(() => {
- const error = { message: '{ "error": { "statusCode": 409 } }' };
- spyOn(alfrescoApi.sitesApi, 'createSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject(error));
- });
- spyOn(alfrescoApi.sitesApi, 'getSite').and.callFake(() => {
- return new Promise((resolve, reject) => reject());
- });
-
- fixture.detectChanges();
- component.form.controls.title.setValue('test');
- tick(500);
- flush();
- fixture.detectChanges();
-
- component.submit();
- fixture.detectChanges();
- flush();
-
- expect(component.form.controls.id.errors).toEqual({
- message: 'LIBRARY.ERRORS.CONFLICT'
- });
- }));
-});
diff --git a/src/app/dialogs/library/library.dialog.ts b/src/app/dialogs/library/library.dialog.ts
deleted file mode 100644
index 7bfcbf8e9..000000000
--- a/src/app/dialogs/library/library.dialog.ts
+++ /dev/null
@@ -1,262 +0,0 @@
-/*!
- * @license
- * Copyright 2016 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 { Observable, Subject, from } from 'rxjs';
-import {
- Component,
- OnInit,
- Output,
- EventEmitter,
- OnDestroy,
- ViewEncapsulation
-} from '@angular/core';
-import {
- FormBuilder,
- FormGroup,
- Validators,
- FormControl,
- AbstractControl
-} from '@angular/forms';
-import { MatDialogRef } from '@angular/material';
-import { SiteBody, SiteEntry, SitePaging } from 'alfresco-js-api';
-import { AlfrescoApiService } from '@alfresco/adf-core';
-import { debounceTime, mergeMap, takeUntil } from 'rxjs/operators';
-
-@Component({
- selector: 'app-library-dialog',
- styleUrls: ['./library.dialog.scss'],
- templateUrl: './library.dialog.html',
- encapsulation: ViewEncapsulation.None,
- host: { class: 'app-library-dialog' }
-})
-export class LibraryDialogComponent implements OnInit, OnDestroy {
- @Output()
- error: EventEmitter = new EventEmitter();
-
- @Output()
- success: EventEmitter = new EventEmitter();
-
- onDestroy$: Subject = new Subject();
-
- createTitle = 'LIBRARY.DIALOG.CREATE_TITLE';
- libraryTitleExists = false;
- form: FormGroup;
- visibilityOption: any;
- visibilityOptions = [
- { value: 'PUBLIC', label: 'LIBRARY.VISIBILITY.PUBLIC', disabled: false },
- { value: 'PRIVATE', label: 'LIBRARY.VISIBILITY.PRIVATE', disabled: false },
- {
- value: 'MODERATED',
- label: 'LIBRARY.VISIBILITY.MODERATED',
- disabled: false
- }
- ];
-
- constructor(
- private alfrescoApiService: AlfrescoApiService,
- private formBuilder: FormBuilder,
- private dialog: MatDialogRef
- ) {}
-
- ngOnInit() {
- const validators = {
- id: [
- Validators.required,
- Validators.maxLength(72),
- this.forbidSpecialCharacters
- ],
- title: [
- Validators.required,
- this.forbidOnlySpaces,
- Validators.maxLength(256)
- ],
- description: [Validators.maxLength(512)]
- };
-
- this.form = this.formBuilder.group({
- title: [null, validators.title],
- id: [null, validators.id, this.createSiteIdValidator()],
- description: ['', validators.description]
- });
-
- this.visibilityOption = this.visibilityOptions[0].value;
-
- this.form.controls['title'].valueChanges
- .pipe(
- debounceTime(300),
- mergeMap(title => this.checkLibraryNameExists(title), title => title),
- takeUntil(this.onDestroy$)
- )
- .subscribe((title: string) => {
- if (!this.form.controls['id'].dirty && this.canGenerateId(title)) {
- this.form.patchValue({ id: this.sanitize(title.trim()) });
- this.form.controls['id'].markAsTouched();
- }
- });
- }
-
- ngOnDestroy() {
- this.onDestroy$.next(true);
- this.onDestroy$.complete();
- }
-
- get title(): string {
- const { title } = this.form.value;
-
- return (title || '').trim();
- }
-
- get id(): string {
- const { id } = this.form.value;
-
- return (id || '').trim();
- }
-
- get description(): string {
- const { description } = this.form.value;
-
- return (description || '').trim();
- }
-
- get visibility(): string {
- return this.visibilityOption || '';
- }
-
- submit() {
- const { form, dialog } = this;
-
- if (!form.valid) {
- return;
- }
-
- this.create().subscribe(
- (node: SiteEntry) => {
- this.success.emit(node);
- dialog.close(node);
- },
- error => this.handleError(error)
- );
- }
-
- visibilityChangeHandler(event) {
- this.visibilityOption = event.value;
- }
-
- private create(): Observable {
- const { title, id, description, visibility } = this;
- const siteBody = {
- id,
- title,
- description,
- visibility
- };
-
- return from(this.alfrescoApiService.sitesApi.createSite(siteBody));
- }
-
- private sanitize(input: string) {
- return input.replace(/[\s\s]+/g, '-').replace(/[^A-Za-z0-9-]/g, '');
- }
-
- private canGenerateId(title) {
- return Boolean(title.replace(/[^A-Za-z0-9-]/g, '').length);
- }
-
- private handleError(error: any): any {
- const {
- error: { statusCode }
- } = JSON.parse(error.message);
-
- if (statusCode === 409) {
- this.form.controls['id'].setErrors({
- message: 'LIBRARY.ERRORS.CONFLICT'
- });
- }
-
- return error;
- }
-
- private async checkLibraryNameExists(libraryTitle: string) {
- const { entries } = (await this.findLibraryByTitle(libraryTitle)).list;
-
- if (entries.length) {
- this.libraryTitleExists = entries[0].entry.title === libraryTitle;
- } else {
- this.libraryTitleExists = false;
- }
- }
-
- private findLibraryByTitle(libraryTitle: string): Promise {
- return this.alfrescoApiService
- .getInstance()
- .core.queriesApi.findSites(libraryTitle, {
- maxItems: 1,
- fields: ['title']
- })
- .catch(() => ({ list: { entries: [] } }));
- }
-
- private forbidSpecialCharacters({ value }: FormControl) {
- if (value === null || value.length === 0) {
- return null;
- }
-
- const validCharacters: RegExp = /[^A-Za-z0-9-]/;
- const isValid: boolean = !validCharacters.test(value);
-
- return isValid
- ? null
- : {
- message: 'LIBRARY.ERRORS.ILLEGAL_CHARACTERS'
- };
- }
-
- private forbidOnlySpaces({ value }: FormControl) {
- if (value === null || value.length === 0) {
- return null;
- }
-
- const isValid: boolean = !!(value || '').trim();
-
- return isValid
- ? null
- : {
- message: 'LIBRARY.ERRORS.ONLY_SPACES'
- };
- }
-
- private createSiteIdValidator() {
- let timer;
-
- return (control: AbstractControl) => {
- if (timer) {
- clearTimeout(timer);
- }
-
- return new Promise(resolve => {
- timer = setTimeout(() => {
- return from(
- this.alfrescoApiService.sitesApi.getSite(control.value)
- ).subscribe(
- () => resolve({ message: 'LIBRARY.ERRORS.EXISTENT_SITE' }),
- () => resolve(null)
- );
- }, 300);
- });
- };
- }
-}
diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts
index 31c02520c..f8aa5a146 100644
--- a/src/app/services/content-management.service.ts
+++ b/src/app/services/content-management.service.ts
@@ -28,9 +28,9 @@ import { Injectable } from '@angular/core';
import { MatDialog, MatSnackBar } from '@angular/material';
import {
FolderDialogComponent,
- ConfirmDialogComponent
+ ConfirmDialogComponent,
+ LibraryDialogComponent
} from '@alfresco/adf-content-services';
-import { LibraryDialogComponent } from '../dialogs/library/library.dialog';
import {
SnackbarErrorAction,
SnackbarInfoAction,