From 31a77d7638e8123873826a2c480fcd6ab9eaad58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Agneray?= <francois.agneray@lam.fr>
Date: Wed, 17 Aug 2022 11:45:40 +0200
Subject: [PATCH] Fixed: Multiple bugs search types criteria

---
 .../search-type/between-date.component.ts     | 19 +++++++++----
 .../criteria/search-type/between.component.ts | 12 ++++++--
 .../search-type/checkbox.component.ts         | 15 +++++++---
 .../criteria/search-type/date.component.ts    |  5 +++-
 .../criteria/search-type/json.component.ts    | 13 +++++++--
 .../criteria/search-type/list.component.ts    | 13 +++++++--
 .../search-type/select-multiple.component.ts  | 15 +++++++---
 .../criteria/search-type/select.component.ts  |  4 ++-
 .../search-type/svom-json-kw.component.ts     | 11 +++++++-
 .../instance/store/models/criterion.model.ts  | 28 ++++++++++++++-----
 10 files changed, 104 insertions(+), 31 deletions(-)

diff --git a/client/src/app/instance/search/components/criteria/search-type/between-date.component.ts b/client/src/app/instance/search/components/criteria/search-type/between-date.component.ts
index 2706a27e..0ac5dfb1 100644
--- a/client/src/app/instance/search/components/criteria/search-type/between-date.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/between-date.component.ts
@@ -11,7 +11,7 @@ import { Component } from '@angular/core';
 import { FormGroup, FormControl, Validators } from '@angular/forms';
 
 import { AbstractSearchTypeComponent } from './abstract-search-type.component';
-import { Criterion, BetweenCriterion } from 'src/app/instance/store/models';
+import { Criterion, BetweenCriterion, FieldCriterion } from 'src/app/instance/store/models';
 
 @Component({
     selector: 'app-between-date',
@@ -36,11 +36,17 @@ export class BetweenDateComponent extends AbstractSearchTypeComponent {
     setCriterion(criterion: Criterion) {
         super.setCriterion(criterion);
         if (criterion) {
-            const betweenCriterion = criterion as BetweenCriterion;
-            this.form.controls.dateRange.setValue([
-                new Date(betweenCriterion.min),
-                new Date(betweenCriterion.max)
-            ]);
+            if (criterion.type === 'between') {
+                const betweenCriterion = criterion as BetweenCriterion;
+                this.form.controls.dateRange.setValue([
+                    new Date(betweenCriterion.min),
+                    new Date(betweenCriterion.max)
+                ]);
+                this.form.controls.label.setValue('bw');
+            } else {
+                const fieldCriterion = criterion as FieldCriterion;
+                this.form.controls.label.setValue(fieldCriterion.operator);
+            }
         } else {
             this.form.controls.label.setValue('bw');
         }
@@ -81,6 +87,7 @@ export class BetweenDateComponent extends AbstractSearchTypeComponent {
             this.nullOrNotNull = this.form.controls.label.value;
             this.form.controls.dateRange.disable();
         } else {
+            this.nullOrNotNull = '';
             this.form.controls.dateRange.enable();
         }
     }
diff --git a/client/src/app/instance/search/components/criteria/search-type/between.component.ts b/client/src/app/instance/search/components/criteria/search-type/between.component.ts
index 0aeeb599..61e50847 100644
--- a/client/src/app/instance/search/components/criteria/search-type/between.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/between.component.ts
@@ -11,7 +11,7 @@ import { Component } from '@angular/core';
 import { FormGroup, FormControl, Validators } from '@angular/forms';
 
 import { AbstractSearchTypeComponent } from './abstract-search-type.component';
-import { Criterion, BetweenCriterion } from 'src/app/instance/store/models';
+import { Criterion, BetweenCriterion, FieldCriterion } from 'src/app/instance/store/models';
 
 @Component({
     selector: 'app-between',
@@ -35,7 +35,14 @@ export class BetweenComponent extends AbstractSearchTypeComponent {
 
     setCriterion(criterion: Criterion): void {
         super.setCriterion(criterion);
-        if (!criterion) {
+        if (criterion) {
+            if (criterion.type === 'between') {
+                this.form.controls.label.setValue('bw');
+            } else {
+                const fieldCriterion = criterion as FieldCriterion;
+                this.form.controls.label.setValue(fieldCriterion.operator);
+            }
+        } else {
             this.form.controls.label.setValue('bw');
         }
     }
@@ -89,6 +96,7 @@ export class BetweenComponent extends AbstractSearchTypeComponent {
             this.form.controls.min.disable();
             this.form.controls.max.disable();
         } else {
+            this.nullOrNotNull = '';
             this.form.controls.max.enable();
             this.form.controls.min.enable();
         }
diff --git a/client/src/app/instance/search/components/criteria/search-type/checkbox.component.ts b/client/src/app/instance/search/components/criteria/search-type/checkbox.component.ts
index 9fe0de55..5d334eb9 100644
--- a/client/src/app/instance/search/components/criteria/search-type/checkbox.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/checkbox.component.ts
@@ -11,7 +11,7 @@ import { Component } from '@angular/core';
 import { FormGroup, FormControl, FormArray } from '@angular/forms';
 
 import { AbstractSearchTypeComponent } from './abstract-search-type.component';
-import { Criterion, SelectMultipleCriterion } from 'src/app/instance/store/models';
+import { Criterion, SelectMultipleCriterion, FieldCriterion } from 'src/app/instance/store/models';
 import { Attribute } from 'src/app/metamodel/models';
 
 @Component({
@@ -47,10 +47,16 @@ export class CheckboxComponent extends AbstractSearchTypeComponent {
         super.setCriterion(criterion);
         
         if (criterion) {
-            for (let i = 0; i < this.attribute.options.length; i++) {
-                if ((criterion as SelectMultipleCriterion).options.find(o => o.label === this.attribute.options[i].label)) {
-                    this.getCheckboxes().controls[i].setValue(true);
+            if (criterion.type === 'multiple') {
+                for (let i = 0; i < this.attribute.options.length; i++) {
+                    if ((criterion as SelectMultipleCriterion).options.find(o => o.label === this.attribute.options[i].label)) {
+                        this.getCheckboxes().controls[i].setValue(true);
+                    }
                 }
+                this.form.controls.label.setValue('in');
+            } else {
+                const fieldCriterion = criterion as FieldCriterion;
+                this.form.controls.label.setValue(fieldCriterion.operator);
             }
         } else {
             this.form.controls.label.setValue('in');
@@ -105,6 +111,7 @@ export class CheckboxComponent extends AbstractSearchTypeComponent {
                 value.disable();
             });
         } else {
+            this.nullOrNotNull = '';
             this.getCheckboxes().controls.map((value, index) => {
                 value.enable();
             });
diff --git a/client/src/app/instance/search/components/criteria/search-type/date.component.ts b/client/src/app/instance/search/components/criteria/search-type/date.component.ts
index 9a5ea568..11abc84c 100644
--- a/client/src/app/instance/search/components/criteria/search-type/date.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/date.component.ts
@@ -30,7 +30,10 @@ export class DateComponent extends AbstractSearchTypeComponent {
     setCriterion(criterion: Criterion) {
         super.setCriterion(criterion);
         if (criterion) {
-            this.form.controls.date.setValue(new Date((criterion as FieldCriterion).value));
+            const fieldCriterion = criterion as FieldCriterion;
+            if (fieldCriterion.value) {
+                this.form.controls.date.setValue(new Date(fieldCriterion.value));
+            }
         } else {
             this.form.controls.operator.setValue(this.attribute.operator);
             if (!this.attribute.dynamic_operator) {
diff --git a/client/src/app/instance/search/components/criteria/search-type/json.component.ts b/client/src/app/instance/search/components/criteria/search-type/json.component.ts
index 1399230f..bb4346ee 100644
--- a/client/src/app/instance/search/components/criteria/search-type/json.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/json.component.ts
@@ -11,7 +11,7 @@ import { Component } from '@angular/core';
 import { FormGroup, FormControl, Validators } from '@angular/forms';
 
 import { AbstractSearchTypeComponent } from './abstract-search-type.component';
-import { Criterion, JsonCriterion } from 'src/app/instance/store/models';
+import { Criterion, JsonCriterion, FieldCriterion } from 'src/app/instance/store/models';
 
 @Component({
     selector: 'app-json',
@@ -36,7 +36,15 @@ export class JsonComponent extends AbstractSearchTypeComponent {
 
     setCriterion(criterion: Criterion) {
         super.setCriterion(criterion);
-        if (!criterion) {
+        if (criterion) {
+            if (criterion.type === 'json') {
+                this.form.controls.label.setValue('js');
+            } else {
+                const fieldCriterion = criterion as FieldCriterion;
+                this.form.controls.label.setValue(fieldCriterion.operator);
+                this.form.controls.operator.setValue('');
+            }
+        } else {
             this.form.controls.label.setValue('js');
         }
     }
@@ -61,6 +69,7 @@ export class JsonComponent extends AbstractSearchTypeComponent {
             this.form.controls.path.disable();
             this.form.controls.value.disable();
         } else {
+            this.nullOrNotNull = '';
             this.form.controls.operator.enable();
             this.form.controls.path.enable();
             this.form.controls.value.enable();
diff --git a/client/src/app/instance/search/components/criteria/search-type/list.component.ts b/client/src/app/instance/search/components/criteria/search-type/list.component.ts
index 4383525e..3970c7a1 100644
--- a/client/src/app/instance/search/components/criteria/search-type/list.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/list.component.ts
@@ -11,7 +11,7 @@ import { Component } from '@angular/core';
 import { FormGroup, FormControl, Validators } from '@angular/forms';
 
 import { AbstractSearchTypeComponent } from './abstract-search-type.component';
-import { Criterion, ListCriterion } from 'src/app/instance/store/models';
+import { Criterion, ListCriterion, FieldCriterion } from 'src/app/instance/store/models';
 
 @Component({
     selector: 'app-list',
@@ -35,8 +35,14 @@ export class ListComponent extends AbstractSearchTypeComponent {
     setCriterion(criterion: Criterion) {
         super.setCriterion(criterion);
         if (criterion) {
-            this.form.controls.list.setValue((criterion as ListCriterion).values.join('\n'));
-            this.form.disable();
+            if (criterion.type === 'list') {
+                const listCriterion = criterion as ListCriterion;
+                this.form.controls.list.setValue(listCriterion.values.join('\n'));
+                this.form.controls.label.setValue('in');
+            } else {
+                const fieldCriterion = criterion as FieldCriterion;
+                this.form.controls.label.setValue(fieldCriterion.operator);
+            }
         } else {
             this.form.controls.label.setValue('in');
         }
@@ -73,6 +79,7 @@ export class ListComponent extends AbstractSearchTypeComponent {
             this.nullOrNotNull = this.form.controls.label.value;
             this.form.controls.list.disable();
         } else {
+            this.nullOrNotNull = '';
             this.form.controls.list.enable();
         }
     }
diff --git a/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts b/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts
index e514d086..87a4cd57 100644
--- a/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/select-multiple.component.ts
@@ -11,7 +11,7 @@ import { Component } from '@angular/core';
 import { FormGroup, FormControl, Validators } from '@angular/forms';
 
 import { AbstractSearchTypeComponent } from './abstract-search-type.component';
-import { Criterion, SelectMultipleCriterion } from 'src/app/instance/store/models';
+import { Criterion, SelectMultipleCriterion, FieldCriterion } from 'src/app/instance/store/models';
 
 @Component({
     selector: 'app-select-multiple',
@@ -35,9 +35,15 @@ export class SelectMultipleComponent extends AbstractSearchTypeComponent {
     setCriterion(criterion: Criterion) {
         super.setCriterion(criterion);
         if (criterion) {
-            const multipleCriterion = criterion as SelectMultipleCriterion;
-            const values = multipleCriterion.options.map(option => option.value);
-            this.form.controls.select.setValue(values);
+            if (criterion.type === 'multiple') {
+                const multipleCriterion = criterion as SelectMultipleCriterion;
+                const values = multipleCriterion.options.map(option => option.value);
+                this.form.controls.select.setValue(values);
+                this.form.controls.label.setValue('in');
+            } else {
+                const fieldCriterion = criterion as FieldCriterion;
+                this.form.controls.label.setValue(fieldCriterion.operator);
+            }
         } else {
             this.form.controls.label.setValue('in');
         }
@@ -64,6 +70,7 @@ export class SelectMultipleComponent extends AbstractSearchTypeComponent {
             this.nullOrNotNull = this.form.controls.label.value;
             this.form.controls.select.disable();
         } else {
+            this.nullOrNotNull = '';
             this.form.controls.select.enable();
         }
     }
diff --git a/client/src/app/instance/search/components/criteria/search-type/select.component.ts b/client/src/app/instance/search/components/criteria/search-type/select.component.ts
index 28b82635..8f09d008 100644
--- a/client/src/app/instance/search/components/criteria/search-type/select.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/select.component.ts
@@ -29,7 +29,9 @@ export class SelectComponent extends AbstractSearchTypeComponent {
     
     setCriterion(criterion: Criterion) {
         super.setCriterion(criterion);
-        if (!criterion) {
+        if (criterion) {
+            this.form.controls.select.setValue((criterion as FieldCriterion).value);
+        } else {
             this.form.controls.operator.setValue(this.attribute.operator);
             if (!this.attribute.dynamic_operator) {
                 this.operators = searchTypeOperators.filter(
diff --git a/client/src/app/instance/search/components/criteria/search-type/svom-json-kw.component.ts b/client/src/app/instance/search/components/criteria/search-type/svom-json-kw.component.ts
index 399e1ef2..dfc22ca5 100644
--- a/client/src/app/instance/search/components/criteria/search-type/svom-json-kw.component.ts
+++ b/client/src/app/instance/search/components/criteria/search-type/svom-json-kw.component.ts
@@ -41,7 +41,15 @@ export class SvomJsonKwComponent extends AbstractSearchTypeComponent {
 
     setCriterion(criterion: Criterion) {
         super.setCriterion(criterion);
-        if (!criterion) {
+        if (criterion) {
+            if (criterion.type === 'json') {
+                this.form.controls.label.setValue('js');
+            } else {
+                const fieldCriterion = criterion as FieldCriterion;
+                this.form.controls.label.setValue(fieldCriterion.operator);
+                this.form.controls.operator.setValue('');
+            }
+        } else {
             this.form.controls.label.setValue('js');
         }
     }
@@ -93,6 +101,7 @@ export class SvomJsonKwComponent extends AbstractSearchTypeComponent {
             this.form.controls.path.disable();
             this.form.controls.value.disable();
         } else {
+            this.nullOrNotNull = '';
             this.form.controls.operator.enable();
             this.form.controls.path.enable();
             this.form.controls.value.enable();
diff --git a/client/src/app/instance/store/models/criterion.model.ts b/client/src/app/instance/store/models/criterion.model.ts
index cade405a..3abcabaf 100644
--- a/client/src/app/instance/store/models/criterion.model.ts
+++ b/client/src/app/instance/store/models/criterion.model.ts
@@ -105,14 +105,20 @@ export const stringToCriterion = (attribute: Attribute, params: string[] = null)
             }
         case 'list':
             if (params) {
-                return { id: attribute.id, type: 'list', values: params[2].split('|') } as ListCriterion;
+                if (params[1] === 'nl' || params[1] === 'nnl') {
+                    return { id: attribute.id, type: 'field', operator: params[1], value: null } as FieldCriterion;
+                } else {
+                    return { id: attribute.id, type: 'list', values: params[2].split('|') } as ListCriterion;
+                }
             } else {
                 return { id: attribute.id, type: 'list', values: attribute.min.toString().split('|') } as ListCriterion;
             }
         case 'between':
         case 'between-date':
             if (params) {
-                if (params[1] === 'bw') {
+                if (params[1] === 'nl' || params[1] === 'nnl') {
+                    return { id: attribute.id, type: 'field', operator: params[1], value: null } as FieldCriterion;
+                } else if (params[1] === 'bw') {
                     const bwValues = params[2].split('|');
                     return { id: attribute.id, type: 'between', min: bwValues[0], max: bwValues[1] } as BetweenCriterion;
                 } else if (params[1] === 'gte') {
@@ -126,9 +132,13 @@ export const stringToCriterion = (attribute: Attribute, params: string[] = null)
         case 'select-multiple':
         case 'checkbox':
             if (params) {
-                const msValues = params[2].split('|');
-                const options = attribute.options.filter(option => msValues.includes(option.value));
-                return { id: attribute.id, type: 'multiple', options } as SelectMultipleCriterion;
+                if (params[1] === 'nl' || params[1] === 'nnl') {
+                    return { id: attribute.id, type: 'field', operator: params[1], value: null } as FieldCriterion;
+                } else {
+                    const msValues = params[2].split('|');
+                    const options = attribute.options.filter(option => msValues.includes(option.value));
+                    return { id: attribute.id, type: 'multiple', options } as SelectMultipleCriterion;
+                }
             } else {
                 const msValues = attribute.min.toString().split('|');
                 const options = attribute.options.filter(option => msValues.includes(option.value));
@@ -137,8 +147,12 @@ export const stringToCriterion = (attribute: Attribute, params: string[] = null)
         case 'json':
         case 'svom_json_kw':
             if (params) {
-                const [path, operator, value] = params[2].split('|');
-                return { id: attribute.id, type: 'json', path, operator, value } as JsonCriterion;
+                if (params[1] === 'nl' || params[1] === 'nnl') {
+                    return { id: attribute.id, type: 'field', operator: params[1], value: null } as FieldCriterion;
+                } else {
+                    const [path, operator, value] = params[2].split('|');
+                    return { id: attribute.id, type: 'json', path, operator, value } as JsonCriterion;
+                }
             } else {
                 const [path, operator, value] = attribute.min.toString().split('|');
                 return { id: attribute.id, type: 'json', path, operator, value } as JsonCriterion;
-- 
GitLab