diff --git a/src/app/dialogs/library/library.dialog.html b/src/app/dialogs/library/library.dialog.html
index 80e51e982..2314c585b 100644
--- a/src/app/dialogs/library/library.dialog.html
+++ b/src/app/dialogs/library/library.dialog.html
@@ -14,9 +14,15 @@
{{
'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate
}}
+
{{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }}
+
+
+ {{ form.controls['title'].errors?.message | translate }}
+
+
diff --git a/src/app/dialogs/library/library.dialog.spec.ts b/src/app/dialogs/library/library.dialog.spec.ts
index 2b1a223bb..01808c145 100644
--- a/src/app/dialogs/library/library.dialog.spec.ts
+++ b/src/app/dialogs/library/library.dialog.spec.ts
@@ -100,6 +100,48 @@ describe('LibraryDialogComponent', () => {
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());
diff --git a/src/app/dialogs/library/library.dialog.ts b/src/app/dialogs/library/library.dialog.ts
index 9519d3a03..7bfcbf8e9 100644
--- a/src/app/dialogs/library/library.dialog.ts
+++ b/src/app/dialogs/library/library.dialog.ts
@@ -79,13 +79,17 @@ export class LibraryDialogComponent implements OnInit, OnDestroy {
Validators.maxLength(72),
this.forbidSpecialCharacters
],
- title: [Validators.required, Validators.maxLength(256)],
+ title: [
+ Validators.required,
+ this.forbidOnlySpaces,
+ Validators.maxLength(256)
+ ],
description: [Validators.maxLength(512)]
};
this.form = this.formBuilder.group({
- title: ['', validators.title],
- id: ['', validators.id, this.createSiteIdValidator()],
+ title: [null, validators.title],
+ id: [null, validators.id, this.createSiteIdValidator()],
description: ['', validators.description]
});
@@ -98,11 +102,7 @@ export class LibraryDialogComponent implements OnInit, OnDestroy {
takeUntil(this.onDestroy$)
)
.subscribe((title: string) => {
- if (!title.trim().length) {
- return;
- }
-
- if (!this.form.controls['id'].dirty) {
+ if (!this.form.controls['id'].dirty && this.canGenerateId(title)) {
this.form.patchValue({ id: this.sanitize(title.trim()) });
this.form.controls['id'].markAsTouched();
}
@@ -169,7 +169,11 @@ export class LibraryDialogComponent implements OnInit, OnDestroy {
}
private sanitize(input: string) {
- return input.replace(/[\s]/g, '-').replace(/[^A-Za-z0-9-]/g, '');
+ 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 {
@@ -207,6 +211,10 @@ export class LibraryDialogComponent implements OnInit, OnDestroy {
}
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);
@@ -217,6 +225,20 @@ export class LibraryDialogComponent implements OnInit, OnDestroy {
};
}
+ 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;
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index b916f3fc5..222f80bc9 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -406,6 +406,7 @@
"DESCRIPTION_TOO_LONG": "Use 512 characters or less for description",
"TITLE_TOO_LONG": "Use 256 characters or less for title",
"ILLEGAL_CHARACTERS": "Use numbers and letters only",
+ "ONLY_SPACES": "Library name can't contain only spaces",
"LIBRARY_UPDATE_ERROR": "There was an error updating library properties"
},
"SUCCESS": {