From 078bd417fc21b9d73a21618430c7e1a5f2366cb9 Mon Sep 17 00:00:00 2001 From: Ondrej Zizka Date: Wed, 5 Apr 2017 23:27:55 +0200 Subject: [PATCH 1/4] T667 Creating a project with a duplicate title should validate before save is clicked - REST --- .../web/services/rest/MigrationProjectEndpoint.java | 9 +++++++++ .../services/rest/MigrationProjectEndpointImpl.java | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpoint.java b/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpoint.java index 7ea5ee92f..ec3e53158 100644 --- a/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpoint.java +++ b/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpoint.java @@ -59,6 +59,15 @@ public interface MigrationProjectEndpoint @Path("delete") void deleteProject(MigrationProject migration); + /** + * Look up a project ID by name. + */ + @GET + @Path("id-by-name/{title}") + Long getProjectIdByName(@PathParam("title") String title); + + + /** * Adds app count to MigrationProject solely for the purpose of this REST API. */ diff --git a/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpointImpl.java b/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpointImpl.java index f5005b9c3..ae25740f3 100644 --- a/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpointImpl.java +++ b/services/src/main/java/org/jboss/windup/web/services/rest/MigrationProjectEndpointImpl.java @@ -12,12 +12,12 @@ import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; import javax.ws.rs.NotFoundException; +import javax.ws.rs.PathParam; import org.jboss.windup.util.exception.WindupException; import org.jboss.windup.web.addons.websupport.WebPathUtil; import org.jboss.windup.web.furnaceserviceprovider.FromFurnace; -import org.jboss.windup.web.services.model.AnalysisContext; import org.jboss.windup.web.services.model.MigrationProject; import org.jboss.windup.web.services.service.AnalysisContextService; import org.jboss.windup.web.services.service.MigrationProjectService; @@ -95,4 +95,12 @@ public void deleteProject(MigrationProject migrationProject) this.migrationProjectService.deleteProject(project); } + @Override + public Long getProjectIdByName(String title){ + String jql = "SELECT id FROM MigrationProject p WHERE LOWER(p.title) = LOWER(:title)"; + List ids = this.entityManager.createQuery(jql, Long.class) + .setParameter("title", title) + .getResultList(); + return ids.isEmpty() ? null : ids.get(0); + } } From c1657d3566b1f97172a5b7e01f0f08d262e81cb0 Mon Sep 17 00:00:00 2001 From: Ondrej Zizka Date: Wed, 5 Apr 2017 23:29:13 +0200 Subject: [PATCH 2/4] T667 Creating a project with a duplicate title should validate before save - service --- .../webapp/src/app/project/migration-project.service.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ui/src/main/webapp/src/app/project/migration-project.service.ts b/ui/src/main/webapp/src/app/project/migration-project.service.ts index 231cafe95..4bcfbec7d 100644 --- a/ui/src/main/webapp/src/app/project/migration-project.service.ts +++ b/ui/src/main/webapp/src/app/project/migration-project.service.ts @@ -21,6 +21,7 @@ export class MigrationProjectService extends AbstractService { private CREATE_MIGRATION_PROJECT_URL = "/migrationProjects/create"; private UPDATE_MIGRATION_PROJECT_URL = "/migrationProjects/update"; private DELETE_MIGRATION_PROJECT_URL = '/migrationProjects/delete'; + private GET_ID_BY_NAME_URL = '/migrationProjects/id-by-name'; private monitoredProjects = new Map(); @@ -138,6 +139,12 @@ export class MigrationProjectService extends AbstractService { stopMonitoringProject(project: MigrationProject) { this.monitoredProjects.delete(project.id); } + + getIdByName(name: string): Observable | null { + return this._http.get(Constants.REST_BASE + this.GET_ID_BY_NAME_URL + "/" + encodeURIComponent(name)) + .map(res => res.json()) + .catch(this.handleError); + } } export interface HasAppCount{ applicationCount: number; } From 33dcfe56f578d47e5d3d627fab6776764775d2b1 Mon Sep 17 00:00:00 2001 From: Ondrej Zizka Date: Wed, 5 Apr 2017 23:30:42 +0200 Subject: [PATCH 3/4] T667 Creating a project with a duplicate title should validate before save - validator WIP --- ui/src/main/webapp/src/app/app.module.ts | 2 ++ .../migration-project-form.component.html | 10 ++----- .../project-name-not-exists.validator.ts | 27 +++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts diff --git a/ui/src/main/webapp/src/app/app.module.ts b/ui/src/main/webapp/src/app/app.module.ts index e4cfd19fb..03b35d95e 100644 --- a/ui/src/main/webapp/src/app/app.module.ts +++ b/ui/src/main/webapp/src/app/app.module.ts @@ -125,6 +125,7 @@ import {ExecutionApplicationListComponent} from "./reports/execution-application import {SourceResolve} from "./reports/source/source.resolve"; import {ExecutionResolve} from "./executions/execution.resolve"; import {CacheService, CacheServiceInstance} from "./shared/cache.service"; +import {ProjectNameNotExistsValidator} from "./shared/validators/project-name-not-exists.validator"; /** * Load all mapping data from the generated files. @@ -151,6 +152,7 @@ initializeModelMappingData(); declarations: [ // Directives InViewport, + ProjectNameNotExistsValidator, // pages AppComponent, diff --git a/ui/src/main/webapp/src/app/project/migration-project-form.component.html b/ui/src/main/webapp/src/app/project/migration-project-form.component.html index 67d0fda27..903c430c7 100644 --- a/ui/src/main/webapp/src/app/project/migration-project-form.component.html +++ b/ui/src/main/webapp/src/app/project/migration-project-form.component.html @@ -11,14 +11,8 @@

{{title}}

-
diff --git a/ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts b/ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts new file mode 100644 index 000000000..7570c8706 --- /dev/null +++ b/ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts @@ -0,0 +1,27 @@ +import {AbstractControl, AsyncValidatorFn} from "@angular/forms"; +import {FileService} from "../../services/file.service"; +import {MigrationProjectService} from "../../project/migration-project.service"; +import { Directive } from '@angular/core'; + +/** + * Fails validation if the name in the given control already exists as a project name. + */ +@Directive({ + selector: '[projectNameNotUsed]' +}) +export class ProjectNameNotExistsValidator { + + static create(projectService: MigrationProjectService): AsyncValidatorFn { + return function (control: AbstractControl): {[key: string]: any} { + return new Promise(resolve => { + projectService.getIdByName(control.value).subscribe(result => { + if (result === null) + resolve(null); + else + resolve({isNameFree: false}); + }); + }); + }; + }; + +} From 39ef5255f59a29e8c3748dd14d20ecb07dbb31f7 Mon Sep 17 00:00:00 2001 From: Jess Sightler Date: Wed, 5 Apr 2017 18:33:48 -0400 Subject: [PATCH 4/4] Added to validators and added a separate message --- .../migration-project-form.component.html | 7 +++- .../migration-project-form.component.ts | 6 +++ .../project-name-not-exists.validator.ts | 39 +++++++++++-------- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/ui/src/main/webapp/src/app/project/migration-project-form.component.html b/ui/src/main/webapp/src/app/project/migration-project-form.component.html index 903c430c7..7a1071837 100644 --- a/ui/src/main/webapp/src/app/project/migration-project-form.component.html +++ b/ui/src/main/webapp/src/app/project/migration-project-form.component.html @@ -12,10 +12,13 @@

{{title}}

- + + The title must be unique + + The title must be greater than 3 characters long and fewer than 128 characters.
diff --git a/ui/src/main/webapp/src/app/project/migration-project-form.component.ts b/ui/src/main/webapp/src/app/project/migration-project-form.component.ts index 5af03d6c2..3eb981b7f 100644 --- a/ui/src/main/webapp/src/app/project/migration-project-form.component.ts +++ b/ui/src/main/webapp/src/app/project/migration-project-form.component.ts @@ -6,6 +6,7 @@ import {MigrationProjectService} from "./migration-project.service"; import {FormComponent} from "../shared/form.component"; import {Subscription} from "rxjs"; import {RouteFlattenerService} from "../core/routing/route-flattener.service"; +import {FormControl} from "@angular/forms"; @Component({ templateUrl: './migration-project-form.component.html', @@ -56,6 +57,11 @@ export class MigrationProjectFormComponent extends FormComponent implements OnIn return Math.min(4 + (this.model.description ? this.model.description.length : 0) / 80, 25) } + titleIsDuplicated(control:FormControl):boolean { + let touched = control.touched == null ? false : control.touched; + return control.hasError('nameIsTaken') && touched; + } + save() { if (this.editMode) { this._migrationProjectService.update(this.model).subscribe( diff --git a/ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts b/ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts index 7570c8706..6762657b2 100644 --- a/ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts +++ b/ui/src/main/webapp/src/app/shared/validators/project-name-not-exists.validator.ts @@ -1,27 +1,34 @@ -import {AbstractControl, AsyncValidatorFn} from "@angular/forms"; -import {FileService} from "../../services/file.service"; +import {Directive, forwardRef} from '@angular/core'; +import {FormControl, NG_ASYNC_VALIDATORS, Validator} from "@angular/forms"; import {MigrationProjectService} from "../../project/migration-project.service"; -import { Directive } from '@angular/core'; /** * Fails validation if the name in the given control already exists as a project name. */ @Directive({ - selector: '[projectNameNotUsed]' + selector: '[wuProjectNameNotUsed]', + providers: [ + { provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => ProjectNameNotExistsValidator), multi: true } + ] }) -export class ProjectNameNotExistsValidator { +export class ProjectNameNotExistsValidator implements Validator { - static create(projectService: MigrationProjectService): AsyncValidatorFn { - return function (control: AbstractControl): {[key: string]: any} { - return new Promise(resolve => { - projectService.getIdByName(control.value).subscribe(result => { - if (result === null) - resolve(null); - else - resolve({isNameFree: false}); - }); + constructor(private projectService: MigrationProjectService) + { + } + + validate(control: FormControl):Promise<{[key: string] : boolean}> { + let projectService = this.projectService; + + return new Promise(resolve => { + projectService.getIdByName(control.value).subscribe(result => { + if (result == null) { + resolve(null); + } else { + resolve({['nameIsTaken']: true}); + } }); - }; - }; + }); + } }