Skip to content
Permalink
Browse files
feat(value): refactor boolean value (DEV-98) (#554)
* fix(value): display boolean value even it doesn't exist

* style(boolean value): display checkbox instead of true or false

* refactor(boolean-value): format code

* chore(advanced search): compare boolean value in useful way

* style(search): refactor advanced search

* style(search): refactor advanced search

* style(search): resolve style issue in date picker

* test(search): fix tests

* test(search): fix test in advanced search

* style(value): fixing styling issue in boolean value
  • Loading branch information
kilchenmann committed Oct 20, 2021
1 parent 436c270 commit 7affa5e7c94b35929d795e29380fb31b9906c520
Showing with 178 additions and 92 deletions.
  1. +5 −1 src/app/workspace/resource/properties/properties.component.html
  2. +5 −1 src/app/workspace/resource/properties/properties.component.spec.ts
  3. +2 −0 src/app/workspace/resource/properties/properties.component.ts
  4. +1 −1 ...ource/resource-instance-form/select-properties/switch-properties/switch-properties.component.html
  5. +5 −3 src/app/workspace/resource/values/boolean-value/boolean-value.component.html
  6. +12 −0 src/app/workspace/resource/values/boolean-value/boolean-value.component.scss
  7. +2 −18 src/app/workspace/resource/values/boolean-value/boolean-value.component.spec.ts
  8. +2 −0 src/app/workspace/resource/values/boolean-value/boolean-value.component.ts
  9. +2 −2 src/app/workspace/search/advanced-search/advanced-search.component.html
  10. +14 −1 src/app/workspace/search/advanced-search/advanced-search.component.ts
  11. +22 −18 ...ch/advanced-search/resource-and-property-selection/resource-and-property-selection.component.html
  12. +8 −0 ...ch/advanced-search/resource-and-property-selection/resource-and-property-selection.component.scss
  13. +23 −4 ...arch/resource-and-property-selection/search-select-property/search-select-property.component.html
  14. +20 −2 ...arch/resource-and-property-selection/search-select-property/search-select-property.component.scss
  15. +15 −13 ...h/resource-and-property-selection/search-select-property/search-select-property.component.spec.ts
  16. +1 −1 ...h-select-property/specify-property-value/search-boolean-value/search-boolean-value.component.html
  17. +1 −8 .../search-select-property/specify-property-value/search-date-value/search-date-value.component.html
  18. +1 −1 ...h-select-property/specify-property-value/search-decimal-value/search-decimal-value.component.html
  19. +1 −1 ...on/search-select-property/specify-property-value/search-int-value/search-int-value.component.html
  20. +1 −1 .../search-select-property/specify-property-value/search-link-value/search-link-value.component.html
  21. +1 −1 .../search-select-property/specify-property-value/search-text-value/search-text-value.component.html
  22. +1 −1 ...on/search-select-property/specify-property-value/search-uri-value/search-uri-value.component.html
  23. +4 −4 ...-selection/search-select-property/specify-property-value/specify-property-value.component.spec.ts
  24. +7 −2 ...perty-selection/search-select-property/specify-property-value/specify-property-value.component.ts
  25. +1 −1 ...app/workspace/search/advanced-search/search-select-ontology/search-select-ontology.component.html
  26. +1 −1 .../workspace/search/advanced-search/search-select-ontology/search-select-ontology.component.spec.ts
  27. +7 −0 src/app/workspace/search/advanced-search/search-select-ontology/search-select-ontology.component.ts
  28. +2 −2 src/app/workspace/search/expert-search/expert-search.component.html
  29. +10 −4 src/assets/style/_search.scss
  30. +1 −0 src/assets/style/main.scss
@@ -137,7 +137,11 @@ <h3 class="label mat-title">
</div>
<!-- Add button -->
<div *ngIf="addValueIsAllowed(prop) && project?.status">
<button mat-icon-button type="button" class="value-action create"
<!-- boolen value will always be displayed even if value is not defined (value = false) -->
<span *ngIf="prop.propDef.objectType === booleanValueTypeIri">
<app-boolean-value [mode]="'read'" class="boolean-value"></app-boolean-value>
</span>
<button *ngIf="prop.propDef.objectType !== booleanValueTypeIri" mat-icon-button type="button" class="value-action create"
(click)="showAddValueForm(prop, $event)"
title="Add a new value">
<mat-icon>add_box</mat-icon>
@@ -402,7 +402,11 @@ describe('PropertiesComponent', () => {
// so the amount of add buttons on the page should increase by 1
// standoff links value and has incoming link value are system props and cannot be added: -2
addButtons = propertyViewComponentDe.queryAll(By.css('button.create'));
expect(addButtons.length).toEqual(18);
expect(addButtons.length).toEqual(17);

// in case of boolean value, we do not display the add button, but the boolean value itself
const booleanValue = propertyViewComponentDe.queryAll(By.css('.boolean-value'));
expect(booleanValue.length).toEqual(1);

});

@@ -122,6 +122,8 @@ export class PropertiesComponent implements OnInit, OnChanges, OnDestroy {

representationConstants = RepresentationConstants;

booleanValueTypeIri = Constants.BooleanValue;

hasIncomingLinkIri = Constants.KnoraApiV2 + Constants.HashDelimiter + 'hasIncomingLinkValue';

project: ReadProject;
@@ -2,7 +2,7 @@
<app-text-value-as-string #createVal *ngSwitchCase="'ReadTextValueAsString'" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName" [textArea]="textArea"></app-text-value-as-string>
<app-text-value-as-xml #createVal *ngSwitchCase="'ReadTextValueAsXml'" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName"></app-text-value-as-xml>
<app-int-value #createVal *ngSwitchCase="constants.IntValue" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName"></app-int-value>
<app-boolean-value #createVal *ngSwitchCase="constants.BooleanValue" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName"></app-boolean-value>
<app-boolean-value #createVal *ngSwitchCase="constants.BooleanValue" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName" [moreSpace]="true"></app-boolean-value>
<app-uri-value #createVal *ngSwitchCase="constants.UriValue" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName"></app-uri-value>
<app-decimal-value #createVal *ngSwitchCase="constants.DecimalValue" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName"></app-decimal-value>
<app-color-value #createVal *ngSwitchCase="constants.ColorValue" [mode]="mode" [valueRequiredValidator]="isRequiredProp" [parentForm]="parentForm" [formName]="formName"></app-color-value>
@@ -1,11 +1,13 @@
<span *ngIf="mode === 'read'; else showForm" class="read-mode-view">
<span class="rm-value">{{valueFormControl.value | formattedBoolean:preferredDisplayType}}</span>
<span class="rm-value">
<mat-icon>{{valueFormControl.value ? 'check_box' : 'check_box_outline_blank'}}</mat-icon>
</span>
<span class="rm-comment" *ngIf="shouldShowComment">{{commentFormControl.value}}</span>
</span>
<ng-template #showForm>
<span [formGroup]="form" (ngSubmit)="onSubmit()">
<mat-checkbox [formControlName]="'value'" class="value boolValue child-value-component">
{{valueFormControl.value | formattedBoolean:preferredDisplayType}}

<mat-checkbox [formControlName]="'value'" class="value boolValue child-value-component" [class.more-space]="moreSpace">
</mat-checkbox>
<mat-error *ngIf="valueFormControl.hasError('valueNotChanged') && valueFormControl.dirty">
<span class="custom-error-message">New value must be different than the current value.</span>
@@ -1 +1,13 @@
@import "../../../../../assets/style/viewer";

.read-mode-view .mat-icon,
.boolValue {
margin-top: 4px;
margin-left: 4px;
display: block;

&.more-space {
margin-top: 16px;
}
}

@@ -114,7 +114,7 @@ describe('BooleanValueComponent', () => {

expect(testHostComponent.booleanValueComponent.mode).toEqual('read');

expect(valueReadModeNativeElement.innerText).toEqual('true');
expect(valueReadModeNativeElement.innerText).toEqual('check_box');
});

it('should make an existing value editable', () => {
@@ -127,7 +127,6 @@ describe('BooleanValueComponent', () => {
valueBooleanNativeElement = valueBooleanDebugElement.nativeElement;

checkboxEl = valueBooleanDebugElement.query(By.css('input[type="checkbox"]')).nativeElement;
checkboxLabel = valueBooleanDebugElement.query(By.css('span[class="mat-checkbox-label"]')).nativeElement;

expect(testHostComponent.booleanValueComponent.mode).toEqual('update');

@@ -137,8 +136,6 @@ describe('BooleanValueComponent', () => {

expect(checkboxEl.checked).toBe(true);

expect(checkboxLabel.innerText).toEqual('true');

checkboxEl.click();

testHostFixture.detectChanges();
@@ -155,7 +152,6 @@ describe('BooleanValueComponent', () => {

expect(checkboxEl.disabled).toBe(false);

expect(checkboxLabel.innerText).toEqual('false');
});

it('should validate an existing value with an added comment', () => {
@@ -168,7 +164,6 @@ describe('BooleanValueComponent', () => {
valueBooleanNativeElement = valueBooleanDebugElement.nativeElement;

checkboxEl = valueBooleanDebugElement.query(By.css('input[type="checkbox"]')).nativeElement;
checkboxLabel = valueBooleanDebugElement.query(By.css('span[class="mat-checkbox-label"]')).nativeElement;

commentBooleanDebugElement = valueComponentDe.query(By.css('textarea.comment'));
commentBooleanNativeElement = commentBooleanDebugElement.nativeElement;
@@ -181,8 +176,6 @@ describe('BooleanValueComponent', () => {

expect(checkboxEl.checked).toBe(true);

expect(checkboxLabel.innerText).toEqual('true');

commentBooleanNativeElement.value = 'this is a comment';

commentBooleanNativeElement.dispatchEvent(new Event('input'));
@@ -208,7 +201,6 @@ describe('BooleanValueComponent', () => {
valueBooleanNativeElement = valueBooleanDebugElement.nativeElement;

checkboxEl = valueBooleanDebugElement.query(By.css('input[type="checkbox"]')).nativeElement;
checkboxLabel = valueBooleanDebugElement.query(By.css('span[class="mat-checkbox-label"]')).nativeElement;

expect(testHostComponent.booleanValueComponent.mode).toEqual('update');

@@ -218,16 +210,12 @@ describe('BooleanValueComponent', () => {

expect(checkboxEl.checked).toBe(true);

expect(checkboxLabel.innerText).toEqual('true');

checkboxEl.click();

testHostFixture.detectChanges();

expect(checkboxEl.checked).toBe(false);

expect(checkboxLabel.innerText).toEqual('false');

testHostComponent.booleanValueComponent.resetFormControl();

testHostFixture.detectChanges();
@@ -236,7 +224,6 @@ describe('BooleanValueComponent', () => {

expect(checkboxEl.checked).toBe(true);

expect(checkboxLabel.innerText).toEqual('true');
});

it('should set a new display value', () => {
@@ -250,7 +237,7 @@ describe('BooleanValueComponent', () => {

testHostFixture.detectChanges();

expect(valueReadModeNativeElement.innerText).toEqual('false');
expect(valueReadModeNativeElement.innerText).toEqual('check_box_outline_blank');

expect(testHostComponent.booleanValueComponent.form.valid).toBeTruthy();
});
@@ -273,7 +260,6 @@ describe('BooleanValueComponent', () => {
let valueBooleanDebugElement: DebugElement;
let valueBooleanNativeElement;
let checkboxEl;
let checkboxLabel;
let commentBooleanDebugElement: DebugElement;
let commentBooleanNativeElement;

@@ -292,7 +278,6 @@ describe('BooleanValueComponent', () => {
valueBooleanDebugElement = valueComponentDe.query(By.css('mat-checkbox'));
valueBooleanNativeElement = valueBooleanDebugElement.nativeElement;
checkboxEl = valueBooleanDebugElement.query(By.css('input[type="checkbox"]')).nativeElement;
checkboxLabel = valueBooleanDebugElement.query(By.css('span[class="mat-checkbox-label"]')).nativeElement;

commentBooleanDebugElement = valueComponentDe.query(By.css('textarea.comment'));
commentBooleanNativeElement = commentBooleanDebugElement.nativeElement;
@@ -301,7 +286,6 @@ describe('BooleanValueComponent', () => {
expect(testHostComponent.booleanValueComponent.form.valid).toBeTruthy();
expect(checkboxEl.disabled).toBe(false);
expect(checkboxEl.checked).toBe(false);
expect(checkboxLabel.innerText).toEqual('false');
expect(commentBooleanNativeElement.value).toEqual('');
});

@@ -16,6 +16,8 @@ export class BooleanValueComponent extends BaseValueDirective implements OnInit,

@Input() displayValue?: ReadBooleanValue;

@Input() moreSpace?: boolean;

valueFormControl: FormControl;
commentFormControl: FormControl;

@@ -1,4 +1,4 @@
<form *ngIf="!errorMessage" [formGroup]="form" (ngSubmit)="submit()" class="dsp-form-content">
<form *ngIf="!errorMessage" [formGroup]="form" (ngSubmit)="submit()" class="app-form-content">

<div *ngIf="ontologiesMetadata?.ontologies.length > 0">
<app-search-select-ontology [formGroup]="form" [ontologiesMetadata]="ontologiesMetadata"
@@ -8,7 +8,7 @@
<app-resource-and-property-selection *ngIf="activeOntology !== undefined" #resAndPropSel [formGroup]="form" [activeOntology]="activeOntology" [topLevel]="true">
</app-resource-and-property-selection>

<div class="dsp-form-action">
<div class="app-form-action">
<button class="reset" mat-button type="button" (click)="resourceAndPropertySelection?.resetForm()" [disabled]="this.activeOntology === undefined">
Reset
</button>
@@ -10,7 +10,7 @@ import {
ViewChild
} from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ApiResponseError, Constants, KnoraApiConnection, OntologiesMetadata } from '@dasch-swiss/dsp-js';
import { ApiResponseError, Constants, KnoraApiConnection, OntologiesMetadata, OntologyMetadata } from '@dasch-swiss/dsp-js';
import { Subscription } from 'rxjs';
import { DspApiConnectionToken } from 'src/app/main/declarations/dsp-api-tokens';
import { NotificationService } from 'src/app/main/services/notification.service';
@@ -100,6 +100,9 @@ export class AdvancedSearchComponent implements OnInit, OnDestroy, AfterViewChec
response.ontologies = response.ontologies.filter(onto => onto.attachedToProject !== Constants.SystemProjectIRI);

this.ontologiesMetadata = response;

this.preSelectFirstOntology(this.ontologiesMetadata.ontologies);

},
(error: ApiResponseError) => {
this._notification.openSnackBar(error);
@@ -112,18 +115,28 @@ export class AdvancedSearchComponent implements OnInit, OnDestroy, AfterViewChec
response.ontologies = response.ontologies.filter(onto => onto.attachedToProject !== Constants.SystemProjectIRI);

this.ontologiesMetadata = response;

this.preSelectFirstOntology(this.ontologiesMetadata.ontologies);

},
(error: ApiResponseError) => {
this._notification.openSnackBar(error);
this.errorMessage = error;
});
}

}

setActiveOntology(ontologyIri: string) {
this.activeOntology = ontologyIri;
}

preSelectFirstOntology(ontologies: OntologyMetadata[]) {
if (ontologies.length === 1) {
this.activeOntology = ontologies[0].id;
}
}

submit() {

if (!this.formValid) {
@@ -1,31 +1,35 @@
<div [formGroup]="form">
<div class="form" [formGroup]="form">

<div class="select-resource-class">
<app-search-select-resource-class *ngIf="resourceClasses?.length > 0"
#resourceClass
[formGroup]="form"
[resourceClassDefinitions]="resourceClasses"
(resourceClassSelected)="getPropertiesForResourceClass($event)">
</app-search-select-resource-class>
</div>
<app-search-select-resource-class *ngIf="resourceClasses?.length > 0"
#resourceClass
class="select-resource-class"
[formGroup]="form"
[resourceClassDefinitions]="resourceClasses"
(resourceClassSelected)="getPropertiesForResourceClass($event)">
</app-search-select-resource-class>

<div class="select-property" *ngIf="properties !== undefined">
<div *ngFor="let prop of activeProperties; let i = index">
<div class="select-property" [class.res-pointer-level]="!topLevel" *ngIf="properties !== undefined">

<app-search-select-property #property [activeResourceClass]="activeResourceClass" [formGroup]="form" [index]="i"
[properties]="properties" [topLevel]="topLevel"></app-search-select-property>
<!-- select property -->
<app-search-select-property *ngFor="let prop of activeProperties; let i = index"
#property
[activeResourceClass]="activeResourceClass"
[formGroup]="form"
[index]="i"
[properties]="properties"
[topLevel]="topLevel">
</app-search-select-property>

</div>
</div>

<div class="select-property buttons">
<div class="select-property buttons" [class.res-pointer-level]="!topLevel">
<button mat-mini-fab class="property-button add-property-button" color="primary" type="button"
(click)="addProperty()" [disabled]="activeProperties.length >= 4">
(click)="addProperty()" [disabled]="activeProperties.length >= 4">
<mat-icon aria-label="add a property">add</mat-icon>
</button>

<button mat-mini-fab class="property-button remove-property-button" color="primary" type="button"
(click)="removeProperty()" [disabled]="activeProperties.length == 0">
<button mat-mini-fab class="property-button remove-property-button" color="warn" type="button"
(click)="removeProperty()" [disabled]="!activeProperties.length">
<mat-icon aria-label="remove property">remove</mat-icon>
</button>
</div>
@@ -1,7 +1,15 @@
.form {
display: inherit;
}

.select-property {
margin-left: 16px;

.property-button {
margin: 0 12px 64px 0;
}
}

.res-pointer-level {
margin-left: -160px;
}
@@ -1,12 +1,31 @@
<span *ngIf="properties.length > 0" [formGroup]="form" >
<!-- property header -->
<div *ngIf="index === 0 && topLevel" class="search-property-header">
<span class="fill-remaining-space"></span>
<span class="mat-caption">Sort criterion</span>
</div>

<div *ngIf="properties.length > 0" class="search-property-line" [formGroup]="form">

<!-- select property -->
<mat-form-field class="search-property-field medium-field">
<mat-select placeholder="Select Properties" [formControlName]="'property'" class="select-property">
<mat-option *ngFor="let prop of properties" [value]="prop">{{ prop.label }}</mat-option>
</mat-select>
</mat-form-field>

<!-- comparison operator and property value field -->
<app-specify-property-value #specifyPropertyValue [formGroup]="form" *ngIf="propertySelected !== undefined"
[property]="propertySelected" [topLevel]="topLevel"></app-specify-property-value>
[property]="propertySelected" [topLevel]="topLevel"></app-specify-property-value>

<span class="fill-remaining-space"></span>
<span>
<mat-slide-toggle *ngIf="propertySelected !== undefined && sortCriterion()"
[formControlName]="'isSortCriterion'"
[color]="'primary'"
class="sort-criterion-toggle"
matTooltip="Sort search results by value of this property"
matTooltipPosition="above">
</mat-slide-toggle>
</span>

<mat-checkbox *ngIf="propertySelected !== undefined && sortCriterion()" [formControlName]="'isSortCriterion'" matTooltip="Sort criterion"></mat-checkbox>
</span>
</div>
@@ -1,3 +1,21 @@
.search-property-field {
margin-right: 8px;
:host {
width: 100%;

.search-property-header {
width: 100%;
display: inline-flex;
}

.search-property-line {
display: inline-flex;
width: 100%;

.search-property-field {
margin-right: 8px;
}

.sort-criterion-toggle {
margin: 16px 16px 0 0;
}
}
}
Loading

0 comments on commit 7affa5e

Please sign in to comment.