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": {