Skip to content

Commit

Permalink
fix(resource-instance-form): disable "next" button when form is not v…
Browse files Browse the repository at this point in the history
…alid (DEV-803) (#713)

* fix(resource-instance-form): disable "next" button until all information has been entered to proceed to the second step

* test(resource-instance-form): fix unit test

* chore(resource-instance-form): add color input to progress indicator
  • Loading branch information
mdelez committed Apr 13, 2022
1 parent 2d98369 commit 124b953
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 13 deletions.
Expand Up @@ -47,8 +47,10 @@
</span>
<span class="fill-remaining-space"></span>
<span>
<!-- check each 'selected' property in addition to the forms validity because the form is actually valid when fetching ontologies and resource classes -->
<button mat-raised-button type="button" color="primary"
[disabled]="!selectResourceForm.valid || this.errorMessage" (click)="nextStep()" class="form-next">
[disabled]="(!selectedProject || !selectedOntology || !selectedResourceClass || !selectResourceForm.valid) || this.errorMessage" (click)="nextStep()" class="form-next">
<app-progress-indicator *ngIf="loading" [status]="0" [color]="'primary'" class="next-progress"></app-progress-indicator>
Next
</button>
</span>
Expand Down
Expand Up @@ -179,6 +179,10 @@ class MockSelectPropertiesComponent {

@Input() parentForm: FormGroup;

@Input() currentOntoIri: string;

@Input() selectedResourceClass: ResourceClassDefinition;

parentResource = new ReadResource();

constructor(private _valueService: ValueService) { }
Expand Down Expand Up @@ -494,22 +498,32 @@ describe('ResourceInstanceFormComponent', () => {
}
);

const nextButton = await loader.getHarness(MatButtonHarness.with({ selector: '.form-next' }));

const selectProjectComp = resourceInstanceFormComponentDe.query(By.directive(MockSelectProjectComponent));

(selectProjectComp.componentInstance as MockSelectProjectComponent).form.controls.projects.setValue('http://rdfh.ch/projects/0001');

testHostComponent.resourceInstanceFormComponent.selectedProject = 'http://rdfh.ch/projects/0001';

testHostComponent.resourceInstanceFormComponent.ontologiesMetadata = MockOntology.mockOntologiesMetadata();

testHostFixture.detectChanges();

expect(nextButton.isDisabled).toBeTruthy();

const selectOntoComp = resourceInstanceFormComponentDe.query(By.directive(MockSelectOntologyComponent));

(selectOntoComp.componentInstance as MockSelectOntologyComponent).form.controls.ontologies.setValue('http://0.0.0.0:3333/ontology/0001/anything/v2');

(selectOntoComp.componentInstance as MockSelectOntologyComponent).ontologySelected.emit('http://0.0.0.0:3333/ontology/0001/anything/v2');

testHostComponent.resourceInstanceFormComponent.selectedOntology = 'http://0.0.0.0:3333/ontology/0001/anything/v2';

testHostFixture.detectChanges();

expect(nextButton.isDisabled).toBeTruthy();

const selectResourceClassComp = resourceInstanceFormComponentDe.query(By.directive(MockSelectResourceClassComponent));

expect(selectResourceClassComp).toBeTruthy();
Expand All @@ -524,8 +538,6 @@ describe('ResourceInstanceFormComponent', () => {

expect(testHostComponent.resourceInstanceFormComponent.selectResourceForm.valid).toBeTruthy();

const nextButton = await loader.getHarness(MatButtonHarness.with({ selector: '.form-next' }));

await nextButton.click();

const selectPropertiesComp = resourceInstanceFormComponentDe.query(By.directive(MockSelectPropertiesComponent));
Expand Down
Expand Up @@ -262,6 +262,8 @@ export class ResourceInstanceFormComponent implements OnInit, OnDestroy {
// assign the selected iri to selectedProject
this.selectedProject = projectIri;

this.loading = true;

this._dspApiConnection.v2.onto.getOntologiesByProjectIri(projectIri).subscribe(
(response: OntologiesMetadata) => {
// filter out system ontologies
Expand All @@ -273,8 +275,11 @@ export class ResourceInstanceFormComponent implements OnInit, OnDestroy {
if (!this.selectOntologyComponent && response.ontologies.length === 0) {
this.errorMessage = 'No data models defined for the select project.';
}

this.loading = false;
},
(error: ApiResponseError) => {
this.loading = false;
this._errorHandler.showMessage(error);
}
);
Expand Down Expand Up @@ -318,6 +323,8 @@ export class ResourceInstanceFormComponent implements OnInit, OnDestroy {

this.selectedOntology = ontologyIri;

this.loading = true;

this._dspApiConnection.v2.onto.getOntology(ontologyIri).subscribe(
(onto: ReadOntology) => {
this.resourceClasses = onto.getClassDefinitionsByType(ResourceClassDefinition);
Expand All @@ -331,8 +338,11 @@ export class ResourceInstanceFormComponent implements OnInit, OnDestroy {
if ((!this.selectResourceClassComponent || this.selectOntologyComponent.form.controls.ontologies.valueChanges) && this.resourceClasses.length === 0) {
this.errorMessage = 'No resources defined for the selected ontology.';
}

this.loading = false;
},
(error: ApiResponseError) => {
this.loading = false;
this._errorHandler.showMessage(error);
}
);
Expand All @@ -348,14 +358,14 @@ export class ResourceInstanceFormComponent implements OnInit, OnDestroy {
* @param resourceClassIri
*/
selectProperties(resourceClassIri: string) {

// reset errorMessage, it will be reassigned in the else clause if needed
this.errorMessage = undefined;

// if the client undoes the selection of a resource class, use the active ontology as a fallback
if (resourceClassIri === null) {
this.selectResourceClasses(this.selectedOntology);
} else if (resourceClassIri) {
this.loading = true;
this._dspApiConnection.v2.ontologyCache.reloadCachedItem(this.selectedOntology).subscribe(
(res: ReadOntology) => {
this._dspApiConnection.v2.ontologyCache.getResourceClassDefinition(resourceClassIri).subscribe(
Expand Down Expand Up @@ -400,16 +410,11 @@ export class ResourceInstanceFormComponent implements OnInit, OnDestroy {
this.errorMessage = 'No properties defined for the selected resource.';
}

if (this.resourceClasses.length > 1 && !this.userWentBack) {
// automatically go to the next step when a resource class is selected
// but not in case the user went back to previous form
this.nextStep();
} else {
// or update the title because the user select another res class
this.updateParent.emit({ title: this.resourceLabel, subtitle: 'Create new resource' });
}
this.loading = false;

},
(error: ApiResponseError) => {
this.loading = false;
this._errorHandler.showMessage(error);
}
);
Expand Down
3 changes: 2 additions & 1 deletion src/assets/style/_elements.scss
Expand Up @@ -576,7 +576,8 @@ $gc-small: $form-width - $gc-large - 4;
}
}

// progress indicator icon on submit button
// progress indicator icon on next and submit buttons
.next-progress,
.submit-progress {
display: inline-block;
margin-right: 6px;
Expand Down

0 comments on commit 124b953

Please sign in to comment.