This is an automated email from the ASF dual-hosted git repository.
zehnder pushed a commit to branch
3430-filtering-for-numerical-dimension-properties-in-data-explorer
in repository https://gitbox.apache.org/repos/asf/streampipes.git
The following commit(s) were added to
refs/heads/3430-filtering-for-numerical-dimension-properties-in-data-explorer
by this push:
new f40022c7e8 fix(#3430): Refactor filter selection panel row and filter
operator according to data type
f40022c7e8 is described below
commit f40022c7e8860ce098d0f844f836f5eb108d95cd
Author: Philipp Zehnder <[email protected]>
AuthorDate: Wed Jan 22 15:54:20 2025 +0100
fix(#3430): Refactor filter selection panel row and filter operator
according to data type
---
.../param/model/WhereClauseParams.java | 8 +-
ui/angular.json | 3 +-
ui/cypress/support/utils/datalake/DataLakeUtils.ts | 45 ++++++-
.../datalake/widgetDataConfiguration.smoke.spec.ts | 6 +
...on-panel-row-operation-selection.component.html | 46 +++++++
...tion-panel-row-operation-selection.component.ts | 36 ++++++
...ion-panel-row-property-selection.component.html | 31 +++++
...ction-panel-row-property-selection.component.ts | 43 +++++++
...nel-row-value-input-autocomplete.component.html | 42 ++++++
...panel-row-value-input-autocomplete.component.ts | 39 ++++++
...-selection-panel-row-value-input.component.html | 29 +++++
...er-selection-panel-row-value-input.component.ts | 35 +++++
.../filter-selection-panel-row.component.html | 58 +++++++++
.../filter-selection-panel-row.component.ts | 51 ++++++++
.../filter-selection-panel.component.html | 143 ++-------------------
.../filter-selection-panel.component.ts | 9 +-
ui/src/app/data-explorer/data-explorer.module.ts | 10 ++
17 files changed, 494 insertions(+), 140 deletions(-)
diff --git
a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/WhereClauseParams.java
b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/WhereClauseParams.java
index 3381983268..6bf5589d99 100644
---
a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/WhereClauseParams.java
+++
b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/param/model/WhereClauseParams.java
@@ -98,7 +98,9 @@ public class WhereClauseParams implements IQueryStatement {
}
private Object returnCondition(String inputCondition) {
- if (NumberUtils.isParsable(inputCondition)) {
+ if (isQuotedString(inputCondition)) {
+ return inputCondition.substring(1, inputCondition.length() - 1);
+ } else if (NumberUtils.isParsable(inputCondition)) {
return Double.parseDouble(inputCondition);
} else if (isBoolean(inputCondition)) {
return Boolean.parseBoolean(inputCondition);
@@ -107,6 +109,10 @@ public class WhereClauseParams implements IQueryStatement {
}
}
+ private boolean isQuotedString(String input) {
+ return input.startsWith("\"") && input.endsWith("\"");
+ }
+
private boolean isBoolean(String input) {
return "true".equalsIgnoreCase(input) || "false".equalsIgnoreCase(input);
}
diff --git a/ui/angular.json b/ui/angular.json
index 17b7a423cc..384b9b88b4 100644
--- a/ui/angular.json
+++ b/ui/angular.json
@@ -189,7 +189,8 @@
},
"schematics": {
"@schematics/angular:component": {
- "style": "scss"
+ "style": "scss",
+ "standalone": false
}
},
"cli": {
diff --git a/ui/cypress/support/utils/datalake/DataLakeUtils.ts
b/ui/cypress/support/utils/datalake/DataLakeUtils.ts
index dc45a8cc42..e9b87103d5 100644
--- a/ui/cypress/support/utils/datalake/DataLakeUtils.ts
+++ b/ui/cypress/support/utils/datalake/DataLakeUtils.ts
@@ -181,7 +181,9 @@ export class DataLakeUtils {
}
public static saveDataViewConfiguration() {
- cy.dataCy('save-data-view-btn', { timeout: 10000 }).click();
+ cy.dataCy('save-data-view-btn', { timeout: 10000 }).click({
+ force: true,
+ });
}
public static saveDashboardConfiguration() {
@@ -278,6 +280,43 @@ export class DataLakeUtils {
}
}
+ /**
+ * This method validates that the defined filter options are available in
the UI
+ * @param expectedFilterOptions
+ */
+ public static validateFilterOptions(
+ expectedFilterOptions: ('=' | '<' | '<=' | '>=' | '>' | '!=')[],
+ ) {
+ cy.dataCy('design-panel-data-settings-filter-operator')
+ .click()
+ .dataCy('operator-', {}, true)
+ .should('have.length', expectedFilterOptions.length);
+
+ expectedFilterOptions.forEach(option => {
+ const escapedOption = option.replace(/([=<>!])/g, '\\$1');
+ cy.dataCy('operator-' + escapedOption).should('be.visible');
+ });
+
+ cy.dataCy('design-panel-data-settings-filter-operator').click({
+ force: true,
+ });
+ }
+
+ public static validateAutoCompleteOptions(options: string[]) {
+ cy.dataCy('design-panel-data-settings-filter-value')
+ .click({ force: true })
+ .dataCy('autocomplete-value-', {}, true)
+ .should('have.length', options.length);
+
+ options.forEach(option => {
+ cy.dataCy('autocomplete-value-' + option).should('be.visible');
+ });
+
+ cy.dataCy('design-panel-data-settings-filter-value').click({
+ force: true,
+ });
+ }
+
/**
* In the data set panel select all property fields
*/
@@ -309,7 +348,9 @@ export class DataLakeUtils {
}
public static dataConfigRemoveFilter() {
- cy.dataCy('design-panel-data-settings-remove-filter').first().click();
+ cy.dataCy('design-panel-data-settings-remove-filter')
+ .first()
+ .click({ force: true });
}
public static clickGroupBy(propertyName: string) {
diff --git a/ui/cypress/tests/datalake/widgetDataConfiguration.smoke.spec.ts
b/ui/cypress/tests/datalake/widgetDataConfiguration.smoke.spec.ts
index 1a21da1559..3b9eb2f858 100644
--- a/ui/cypress/tests/datalake/widgetDataConfiguration.smoke.spec.ts
+++ b/ui/cypress/tests/datalake/widgetDataConfiguration.smoke.spec.ts
@@ -45,6 +45,7 @@ describe('Test Table View in Data Explorer', () => {
let filterConfig = new DataLakeFilterConfig('randomnumber', '22', '=');
DataLakeUtils.dataConfigAddFilter(filterConfig);
DataLakeWidgetTableUtils.checkAmountOfRows(2);
+ DataLakeUtils.validateFilterOptions(['=', '<', '<=', '>=', '>', '!=']);
DataLakeUtils.dataConfigRemoveFilter();
DataLakeWidgetTableUtils.checkAmountOfRows(10);
@@ -52,6 +53,7 @@ describe('Test Table View in Data Explorer', () => {
filterConfig = new DataLakeFilterConfig('randomnumber', '50', '>');
DataLakeUtils.dataConfigAddFilter(filterConfig);
DataLakeWidgetTableUtils.checkAmountOfRows(5);
+ DataLakeUtils.validateFilterOptions(['=', '<', '<=', '>=', '>', '!=']);
DataLakeUtils.dataConfigRemoveFilter();
// Test number smaller then
@@ -64,6 +66,8 @@ describe('Test Table View in Data Explorer', () => {
filterConfig = new DataLakeFilterConfig('randombool', 'true', '=');
DataLakeUtils.dataConfigAddFilter(filterConfig);
DataLakeWidgetTableUtils.checkAmountOfRows(6);
+ DataLakeUtils.validateFilterOptions(['=', '!=']);
+ DataLakeUtils.validateAutoCompleteOptions(['true', 'false']);
DataLakeUtils.dataConfigRemoveFilter();
// Test string & if filter is persisted correctly
@@ -72,6 +76,8 @@ describe('Test Table View in Data Explorer', () => {
DataLakeUtils.dataConfigAddFilter(filterConfig);
DataLakeUtils.checkIfFilterIsSet(1);
DataLakeWidgetTableUtils.checkAmountOfRows(4);
+ DataLakeUtils.validateFilterOptions(['=', '!=']);
+ DataLakeUtils.validateAutoCompleteOptions(['a', 'b', 'c']);
DataLakeUtils.saveAndReEditWidget('NewWidget');
DataLakeUtils.checkIfFilterIsSet(1);
DataLakeWidgetTableUtils.checkAmountOfRows(4);
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-operation-selection/filter-selection-panel-row-operation-selection.component.html
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-operation-selection/filter-selection-panel-row-operation-selection.compo
[...]
new file mode 100644
index 0000000000..3af11dd781
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-operation-selection/filter-selection-panel-row-operation-selection.component.html
@@ -0,0 +1,46 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+<mat-form-field color="accent" class="w-80-px mr-5" appearance="outline">
+ <mat-select
+ [(value)]="filter.operator"
+ panelClass="form-field-small min-w-100"
+ (selectionChange)="updateParentComponent()"
+ data-cy="design-panel-data-settings-filter-operator"
+ >
+ <mat-option [value]="'='" data-cy="operator-=">
+ <span class="pipeline-name">=</span>
+ </mat-option>
+ @if (filter.field && filter.field['numeric']) {
+ <mat-option [value]="'<'" data-cy="operator-<">
+ <span class="pipeline-name"><</span>
+ </mat-option>
+ <mat-option [value]="'<='" data-cy="operator-<=">
+ <span class="pipeline-name"><=</span>
+ </mat-option>
+ <mat-option [value]="'>='" data-cy="operator->=">
+ <span class="pipeline-name">>=</span>
+ </mat-option>
+ <mat-option [value]="'>'" data-cy="operator->">
+ <span class="pipeline-name">></span>
+ </mat-option>
+ }
+ <mat-option [value]="'!='" data-cy="operator-!=">
+ <span class="pipeline-name">!=</span>
+ </mat-option>
+ </mat-select>
+</mat-form-field>
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-operation-selection/filter-selection-panel-row-operation-selection.component.ts
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-operation-selection/filter-selection-panel-row-operation-selection.component.ts
new file mode 100644
index 0000000000..1ba9c766a1
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-operation-selection/filter-selection-panel-row-operation-selection.component.ts
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { SelectedFilter } from '@streampipes/platform-services';
+
+@Component({
+ selector: 'sp-filter-selection-panel-row-operation-selection',
+ templateUrl:
+ './filter-selection-panel-row-operation-selection.component.html',
+})
+export class FilterSelectionPanelRowOperationSelectionComponent {
+ @Input()
+ public filter: SelectedFilter;
+
+ @Output()
+ public update = new EventEmitter<void>();
+
+ updateParentComponent() {
+ this.update.emit();
+ }
+}
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-property-selection/filter-selection-panel-row-property-selection.component.html
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-property-selection/filter-selection-panel-row-property-selection.component.html
new file mode 100644
index 0000000000..23c7ba5c26
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-property-selection/filter-selection-panel-row-property-selection.component.html
@@ -0,0 +1,31 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+<mat-form-field color="accent" class="w-140-px mr-5" appearance="outline">
+ <mat-label>Field</mat-label>
+ <mat-select
+ [(value)]="filter.field"
+ (selectionChange)="updateParentComponent()"
+ [compareWith]="compare"
+ panelClass="form-field-small min-w-200"
+ data-cy="design-panel-data-settings-filter-field"
+ >
+ @for (field of possibleFields; track field) {
+ <mat-option [value]="field">{{ field.runtimeName }} </mat-option>
+ }
+ </mat-select>
+</mat-form-field>
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-property-selection/filter-selection-panel-row-property-selection.component.ts
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-property-selection/filter-selection-panel-row-property-selection.component.ts
new file mode 100644
index 0000000000..f1f874cfb3
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-property-selection/filter-selection-panel-row-property-selection.component.ts
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { FieldConfig, SelectedFilter } from '@streampipes/platform-services';
+
+@Component({
+ selector: 'sp-filter-selection-panel-row-property-selection',
+ templateUrl:
+ './filter-selection-panel-row-property-selection.component.html',
+})
+export class FilterSelectionPanelRowPropertySelectionComponent {
+ @Input()
+ public filter: SelectedFilter;
+
+ @Input()
+ public possibleFields: FieldConfig[];
+
+ @Output()
+ public update = new EventEmitter<void>();
+
+ updateParentComponent() {
+ this.update.emit();
+ }
+
+ compare(available: FieldConfig, selected: FieldConfig) {
+ return available.runtimeName === selected.runtimeName;
+ }
+}
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input-autocomplete/filter-selection-panel-row-value-input-autocomplete.component.html
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input-autocomplete/filter-selection-panel-row-value-inpu
[...]
new file mode 100644
index 0000000000..9ff3259aca
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input-autocomplete/filter-selection-panel-row-value-input-autocomplete.component.html
@@ -0,0 +1,42 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+<mat-form-field color="accent" appearance="outline" class="w-140-px mr-5">
+ <input
+ type="text"
+ placeholder="Value"
+ aria-label="Number"
+ matInput
+ [(ngModel)]="filter.value"
+ (change)="updateParentComponent()"
+ data-cy="design-panel-data-settings-filter-value"
+ [matAutocomplete]="auto"
+ />
+ <mat-autocomplete
+ #auto="matAutocomplete"
+ (optionSelected)="updateParentComponent()"
+ >
+ @for (value of tagValues.get(filter.field.runtimeName); track value) {
+ <mat-option
+ [attr.data-cy]="'autocomplete-value-' + value"
+ [value]="value"
+ >
+ {{ value }}
+ </mat-option>
+ }
+ </mat-autocomplete>
+</mat-form-field>
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input-autocomplete/filter-selection-panel-row-value-input-autocomplete.component.ts
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input-autocomplete/filter-selection-panel-row-value-input-
[...]
new file mode 100644
index 0000000000..e02ca4b998
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input-autocomplete/filter-selection-panel-row-value-input-autocomplete.component.ts
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { SelectedFilter } from '@streampipes/platform-services';
+
+@Component({
+ selector: 'sp-filter-selection-panel-row-value-input-autocomplete',
+ templateUrl:
+ './filter-selection-panel-row-value-input-autocomplete.component.html',
+})
+export class FilterSelectionPanelRowValueInputAutocompleteComponent {
+ @Input()
+ public filter: SelectedFilter;
+
+ @Input()
+ public tagValues: Map<string, string[]>;
+
+ @Output()
+ public update = new EventEmitter<void>();
+
+ updateParentComponent() {
+ this.update.emit();
+ }
+}
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input/filter-selection-panel-row-value-input.component.html
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input/filter-selection-panel-row-value-input.component.html
new file mode 100644
index 0000000000..38614ea5b1
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input/filter-selection-panel-row-value-input.component.html
@@ -0,0 +1,29 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+<mat-form-field color="accent" appearance="outline" class="w-140-px mr-5">
+ <mat-label>Value</mat-label>
+ <input
+ type="text"
+ placeholder="Value"
+ aria-label="Number"
+ matInput
+ [(ngModel)]="filter.value"
+ (change)="updateParentComponent()"
+ data-cy="design-panel-data-settings-filter-value"
+ />
+</mat-form-field>
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input/filter-selection-panel-row-value-input.component.ts
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input/filter-selection-panel-row-value-input.component.ts
new file mode 100644
index 0000000000..4e52a4bf97
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input/filter-selection-panel-row-value-input.component.ts
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { SelectedFilter } from '@streampipes/platform-services';
+
+@Component({
+ selector: 'sp-filter-selection-panel-row-value-input',
+ templateUrl: './filter-selection-panel-row-value-input.component.html',
+})
+export class FilterSelectionPanelRowValueInputComponent {
+ @Input()
+ public filter: SelectedFilter;
+
+ @Output()
+ public update = new EventEmitter<void>();
+
+ updateParentComponent() {
+ this.update.emit();
+ }
+}
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row.component.html
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row.component.html
new file mode 100644
index 0000000000..5d617b6dd4
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row.component.html
@@ -0,0 +1,58 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<div fxFlex="100" fxLayout="column" class="form-field-small">
+ <div fxFlex="100" fxLayout="row" fxLayoutAlign="start center">
+ <sp-filter-selection-panel-row-property-selection
+ [filter]="filter"
+ [possibleFields]="possibleFields"
+ (update)="updateParentComponent()"
+ >
+ </sp-filter-selection-panel-row-property-selection>
+
+ <sp-filter-selection-panel-row-operation-selection
+ [filter]="filter"
+ (update)="updateParentComponent()"
+ >
+ </sp-filter-selection-panel-row-operation-selection>
+
+ @if (!filter.field || !tagValues.has(filter.field.runtimeName)) {
+ <sp-filter-selection-panel-row-value-input
+ [filter]="filter"
+ (update)="updateParentComponent()"
+ >
+ </sp-filter-selection-panel-row-value-input>
+ } @else {
+ <sp-filter-selection-panel-row-value-input-autocomplete
+ [filter]="filter"
+ [tagValues]="tagValues"
+ (update)="updateParentComponent()"
+ >
+ </sp-filter-selection-panel-row-value-input-autocomplete>
+ }
+
+ <button
+ mat-icon-button
+ color="accent"
+ (click)="remove()"
+ data-cy="design-panel-data-settings-remove-filter"
+ >
+ <i class="material-icons">remove</i>
+ </button>
+ </div>
+</div>
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row.component.ts
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row.component.ts
new file mode 100644
index 0000000000..9e7cc75810
--- /dev/null
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row.component.ts
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { FieldConfig, SelectedFilter } from '@streampipes/platform-services';
+
+@Component({
+ selector: 'sp-filter-selection-panel-row',
+ templateUrl: './filter-selection-panel-row.component.html',
+})
+export class FilterSelectionPanelRowComponent {
+ @Input()
+ public filter: SelectedFilter;
+
+ @Input()
+ public possibleFields: FieldConfig[];
+
+ @Input()
+ public tagValues: Map<string, string[]>;
+
+ @Output()
+ public update = new EventEmitter<void>();
+
+ @Output()
+ public removeFilter = new EventEmitter<number>();
+
+ constructor() {}
+
+ updateParentComponent() {
+ this.update.emit();
+ }
+
+ remove() {
+ this.removeFilter.emit();
+ }
+}
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html
index 2d5242eaf3..f2dd8b0d27 100644
---
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.html
@@ -31,134 +31,19 @@
</button>
</div>
<div fxLayout="column">
- <div
- *ngFor="
- let filter of sourceConfig.queryConfig.selectedFilters;
- let i = index
- "
- fxFlex="100"
- fxLayout="column"
- >
- <div fxFlex="100" fxLayout="column" class="form-field-small">
- <div fxFlex="100" fxLayout="row" fxLayoutAlign="start center">
- <mat-form-field
- color="accent"
- class="w-140-px mr-5"
- appearance="outline"
- >
- <mat-label>Field</mat-label>
- <mat-select
- [(value)]="filter.field"
- (selectionChange)="updateWidget()"
- [compareWith]="compare"
- panelClass="form-field-small min-w-200"
- data-cy="design-panel-data-settings-filter-field"
- >
- <mat-option
- *ngFor="
- let field of
sourceConfig.queryConfig.fields
- "
- [value]="field"
- >{{ field.runtimeName }}
- </mat-option>
- </mat-select>
- </mat-form-field>
- <mat-form-field
- color="accent"
- class="w-80-px mr-5"
- appearance="outline"
- >
- <mat-select
- [(value)]="filter.operator"
- panelClass="form-field-small min-w-100"
- (selectionChange)="updateWidget()"
-
data-cy="design-panel-data-settings-filter-operator"
- >
- <mat-option [value]="'='">
- <span class="pipeline-name">=</span>
- </mat-option>
- <mat-option [value]="'<'">
- <span class="pipeline-name"><</span>
- </mat-option>
- <mat-option [value]="'<='">
- <span class="pipeline-name"><=</span>
- </mat-option>
- <mat-option [value]="'>='">
- <span class="pipeline-name">>=</span>
- </mat-option>
- <mat-option [value]="'>'">
- <span class="pipeline-name">></span>
- </mat-option>
- <mat-option [value]="'!='">
- <span class="pipeline-name">!=</span>
- </mat-option>
- </mat-select>
- </mat-form-field>
- <mat-form-field
- color="accent"
- appearance="outline"
- class="w-140-px mr-5"
- *ngIf="
- !filter.field ||
- !tagValues.has(filter.field.runtimeName)
- "
- >
- <mat-label>Value</mat-label>
- <input
- type="text"
- placeholder="Value"
- aria-label="Number"
- matInput
- [(ngModel)]="filter.value"
- (change)="updateWidget()"
- data-cy="design-panel-data-settings-filter-value"
- />
- </mat-form-field>
- <mat-form-field
- color="accent"
- appearance="outline"
- class="w-140-px mr-5"
- *ngIf="
- filter.field &&
- tagValues.has(filter.field.runtimeName)
- "
- >
- <input
- type="text"
- placeholder="Value"
- aria-label="Number"
- matInput
- [(ngModel)]="filter.value"
- (change)="updateWidget()"
- data-cy="design-panel-data-settings-filter-value"
- [matAutocomplete]="auto"
- />
- <mat-autocomplete
- #auto="matAutocomplete"
- (optionSelected)="updateWidget()"
- >
- <mat-option
- *ngFor="
- let value of tagValues.get(
- filter.field.runtimeName
- )
- "
- [value]="value"
- >
- {{ value }}
- </mat-option>
- </mat-autocomplete>
- </mat-form-field>
- <button
- mat-icon-button
- color="accent"
- (click)="remove(sourceConfig, i)"
- data-cy="design-panel-data-settings-remove-filter"
- >
- <i class="material-icons">remove</i>
- </button>
- </div>
- </div>
- </div>
+ @for (
+ filter of sourceConfig.queryConfig.selectedFilters;
+ track filter;
+ let i = $index
+ ) {
+ <sp-filter-selection-panel-row
+ [filter]="filter"
+ [possibleFields]="sourceConfig.queryConfig.fields"
+ [tagValues]="tagValues"
+ (update)="updateWidget()"
+ (removeFilter)="remove(i)"
+ >
+ </sp-filter-selection-panel-row>
+ }
</div>
</sp-configuration-box>
diff --git
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts
index 042d2515e2..fc251508c5 100644
---
a/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts
+++
b/ui/src/app/data-explorer/components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel.component.ts
@@ -19,7 +19,6 @@
import { Component, Input, OnInit } from '@angular/core';
import {
DatalakeRestService,
- FieldConfig,
SelectedFilter,
SourceConfig,
} from '@streampipes/platform-services';
@@ -88,8 +87,8 @@ export class FilterSelectionPanelComponent implements OnInit {
this.updateWidget();
}
- remove(sourceConfig: any, index: number) {
- sourceConfig.queryConfig.selectedFilters.splice(index, 1);
+ remove(index: number) {
+ this.sourceConfig.queryConfig.selectedFilters.splice(index, 1);
this.widgetConfigService.notify({
refreshData: true,
@@ -113,8 +112,4 @@ export class FilterSelectionPanelComponent implements
OnInit {
});
}
}
-
- compare(available: FieldConfig, selected: FieldConfig) {
- return available.runtimeName === selected.runtimeName;
- }
}
diff --git a/ui/src/app/data-explorer/data-explorer.module.ts
b/ui/src/app/data-explorer/data-explorer.module.ts
index 32991008ed..c3edd8cf6c 100644
--- a/ui/src/app/data-explorer/data-explorer.module.ts
+++ b/ui/src/app/data-explorer/data-explorer.module.ts
@@ -125,6 +125,11 @@ import { DataExplorerDataViewPreviewComponent } from
'./components/dashboard/das
import { DataExplorerDashboardToolbarComponent } from
'./components/dashboard/dashboard-toolbar/dashboard-toolbar.component';
import { OrderSelectionPanelComponent } from
'./components/data-view/data-view-designer-panel/data-settings/order-selection-panel/order-selection-panel.component';
import { GaugeWidgetConfigComponent } from
'./components/widgets/gauge/config/gauge-widget-config.component';
+import { FilterSelectionPanelRowComponent } from
'./components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row.component';
+import { FilterSelectionPanelRowPropertySelectionComponent } from
'./components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-property-selection/filter-selection-panel-row-property-selection.component';
+import { FilterSelectionPanelRowOperationSelectionComponent } from
'./components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-operation-selection/filter-selection-panel-row-operation-selection.component';
+import { FilterSelectionPanelRowValueInputComponent } from
'./components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input/filter-selection-panel-row-value-input.component';
+import { FilterSelectionPanelRowValueInputAutocompleteComponent } from
'./components/data-view/data-view-designer-panel/data-settings/filter-selection-panel/filter-selection-panel-row/filter-selection-panel-row-value-input-autocomplete/filter-selection-panel-row-value-input-autocomplete.component';
@NgModule({
imports: [
@@ -224,6 +229,7 @@ import { GaugeWidgetConfigComponent } from
'./components/widgets/gauge/config/ga
FieldSelectionPanelComponent,
FieldSelectionComponent,
FilterSelectionPanelComponent,
+ FilterSelectionPanelRowComponent,
GaugeWidgetConfigComponent,
GroupConfigurationComponent,
ImageWidgetComponent,
@@ -268,6 +274,10 @@ import { GaugeWidgetConfigComponent } from
'./components/widgets/gauge/config/ga
SpEchartsWidgetAppearanceConfigComponent,
SpTimeSeriesAppearanceConfigComponent,
SpDataZoomConfigComponent,
+ FilterSelectionPanelRowPropertySelectionComponent,
+ FilterSelectionPanelRowOperationSelectionComponent,
+ FilterSelectionPanelRowValueInputComponent,
+ FilterSelectionPanelRowValueInputAutocompleteComponent,
],
exports: [],
})