Filter predicate dynamic value
This commit is contained in:
parent
faee8e6bf0
commit
cf6824cf22
@ -44,6 +44,7 @@ import org.thingsboard.server.common.data.query.EntityDataSortOrder;
|
|||||||
import org.thingsboard.server.common.data.query.EntityKey;
|
import org.thingsboard.server.common.data.query.EntityKey;
|
||||||
import org.thingsboard.server.common.data.query.EntityKeyType;
|
import org.thingsboard.server.common.data.query.EntityKeyType;
|
||||||
import org.thingsboard.server.common.data.query.EntityListFilter;
|
import org.thingsboard.server.common.data.query.EntityListFilter;
|
||||||
|
import org.thingsboard.server.common.data.query.FilterPredicateValue;
|
||||||
import org.thingsboard.server.common.data.query.KeyFilter;
|
import org.thingsboard.server.common.data.query.KeyFilter;
|
||||||
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
|
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
|
||||||
import org.thingsboard.server.common.data.security.Authority;
|
import org.thingsboard.server.common.data.security.Authority;
|
||||||
@ -259,7 +260,7 @@ public abstract class BaseEntityQueryControllerTest extends AbstractControllerTe
|
|||||||
KeyFilter highTemperatureFilter = new KeyFilter();
|
KeyFilter highTemperatureFilter = new KeyFilter();
|
||||||
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
||||||
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
||||||
predicate.setValue(45);
|
predicate.setValue(FilterPredicateValue.fromDouble(45));
|
||||||
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||||
highTemperatureFilter.setPredicate(predicate);
|
highTemperatureFilter.setPredicate(predicate);
|
||||||
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
||||||
|
|||||||
@ -26,9 +26,9 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
@RunWith(ClasspathSuite.class)
|
@RunWith(ClasspathSuite.class)
|
||||||
@ClasspathSuite.ClassnameFilters({
|
@ClasspathSuite.ClassnameFilters({
|
||||||
"org.thingsboard.server.controller.sql.WebsocketApiSqlTest",
|
// "org.thingsboard.server.controller.sql.WebsocketApiSqlTest",
|
||||||
// "org.thingsboard.server.controller.sql.EntityQueryControllerSqlTest",
|
// "org.thingsboard.server.controller.sql.EntityQueryControllerSqlTest",
|
||||||
// "org.thingsboard.server.controller.sql.*Test",
|
"org.thingsboard.server.controller.sql.*Test",
|
||||||
})
|
})
|
||||||
public class ControllerSqlTestSuite {
|
public class ControllerSqlTestSuite {
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import lombok.Data;
|
|||||||
public class BooleanFilterPredicate implements KeyFilterPredicate {
|
public class BooleanFilterPredicate implements KeyFilterPredicate {
|
||||||
|
|
||||||
private BooleanOperation operation;
|
private BooleanOperation operation;
|
||||||
private boolean value;
|
private FilterPredicateValue<Boolean> value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FilterPredicateType getType() {
|
public FilterPredicateType getType() {
|
||||||
|
|||||||
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DynamicValue<T> {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private T resolvedValue;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final DynamicValueSourceType sourceType;
|
||||||
|
@Getter
|
||||||
|
private final String sourceAttribute;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.query;
|
||||||
|
|
||||||
|
public enum DynamicValueSourceType {
|
||||||
|
CURRENT_TENANT,
|
||||||
|
CURRENT_CUSTOMER,
|
||||||
|
CURRENT_USER
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.query;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FilterPredicateValue<T> {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final T defaultValue;
|
||||||
|
@Getter
|
||||||
|
private final DynamicValue<T> dynamicValue;
|
||||||
|
|
||||||
|
public FilterPredicateValue(T defaultValue) {
|
||||||
|
this(defaultValue, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public FilterPredicateValue(@JsonProperty("defaultValue") T defaultValue,
|
||||||
|
@JsonProperty("dynamicValue") DynamicValue<T> dynamicValue) {
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.dynamicValue = dynamicValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public T getValue() {
|
||||||
|
if (this.dynamicValue != null && this.dynamicValue.getResolvedValue() != null) {
|
||||||
|
return this.dynamicValue.getResolvedValue();
|
||||||
|
} else {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterPredicateValue<Double> fromDouble(double value) {
|
||||||
|
return new FilterPredicateValue<>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterPredicateValue<String> fromString(String value) {
|
||||||
|
return new FilterPredicateValue<>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterPredicateValue<Boolean> fromBoolean(boolean value) {
|
||||||
|
return new FilterPredicateValue<>(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,7 +21,7 @@ import lombok.Data;
|
|||||||
public class NumericFilterPredicate implements KeyFilterPredicate {
|
public class NumericFilterPredicate implements KeyFilterPredicate {
|
||||||
|
|
||||||
private NumericOperation operation;
|
private NumericOperation operation;
|
||||||
private double value;
|
private FilterPredicateValue<Double> value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FilterPredicateType getType() {
|
public FilterPredicateType getType() {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import lombok.Data;
|
|||||||
public class StringFilterPredicate implements KeyFilterPredicate {
|
public class StringFilterPredicate implements KeyFilterPredicate {
|
||||||
|
|
||||||
private StringOperation operation;
|
private StringOperation operation;
|
||||||
private String value;
|
private FilterPredicateValue<String> value;
|
||||||
private boolean ignoreCase;
|
private boolean ignoreCase;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -440,7 +440,7 @@ public class EntityKeyMapping {
|
|||||||
private String buildStringPredicateQuery(QueryContext ctx, String field, StringFilterPredicate stringFilterPredicate) {
|
private String buildStringPredicateQuery(QueryContext ctx, String field, StringFilterPredicate stringFilterPredicate) {
|
||||||
String operationField = field;
|
String operationField = field;
|
||||||
String paramName = getNextParameterName(field);
|
String paramName = getNextParameterName(field);
|
||||||
String value = stringFilterPredicate.getValue();
|
String value = stringFilterPredicate.getValue().getValue();
|
||||||
String stringOperationQuery = "";
|
String stringOperationQuery = "";
|
||||||
if (stringFilterPredicate.isIgnoreCase()) {
|
if (stringFilterPredicate.isIgnoreCase()) {
|
||||||
value = value.toLowerCase();
|
value = value.toLowerCase();
|
||||||
@ -476,7 +476,7 @@ public class EntityKeyMapping {
|
|||||||
|
|
||||||
private String buildNumericPredicateQuery(QueryContext ctx, String field, NumericFilterPredicate numericFilterPredicate) {
|
private String buildNumericPredicateQuery(QueryContext ctx, String field, NumericFilterPredicate numericFilterPredicate) {
|
||||||
String paramName = getNextParameterName(field);
|
String paramName = getNextParameterName(field);
|
||||||
ctx.addDoubleParameter(paramName, numericFilterPredicate.getValue());
|
ctx.addDoubleParameter(paramName, numericFilterPredicate.getValue().getValue());
|
||||||
String numericOperationQuery = "";
|
String numericOperationQuery = "";
|
||||||
switch (numericFilterPredicate.getOperation()) {
|
switch (numericFilterPredicate.getOperation()) {
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
@ -504,7 +504,7 @@ public class EntityKeyMapping {
|
|||||||
private String buildBooleanPredicateQuery(QueryContext ctx, String field,
|
private String buildBooleanPredicateQuery(QueryContext ctx, String field,
|
||||||
BooleanFilterPredicate booleanFilterPredicate) {
|
BooleanFilterPredicate booleanFilterPredicate) {
|
||||||
String paramName = getNextParameterName(field);
|
String paramName = getNextParameterName(field);
|
||||||
ctx.addBooleanParameter(paramName, booleanFilterPredicate.isValue());
|
ctx.addBooleanParameter(paramName, booleanFilterPredicate.getValue().getValue());
|
||||||
String booleanOperationQuery = "";
|
String booleanOperationQuery = "";
|
||||||
switch (booleanFilterPredicate.getOperation()) {
|
switch (booleanFilterPredicate.getOperation()) {
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
|
|||||||
@ -49,6 +49,7 @@ import org.thingsboard.server.common.data.query.EntityDataSortOrder;
|
|||||||
import org.thingsboard.server.common.data.query.EntityKey;
|
import org.thingsboard.server.common.data.query.EntityKey;
|
||||||
import org.thingsboard.server.common.data.query.EntityKeyType;
|
import org.thingsboard.server.common.data.query.EntityKeyType;
|
||||||
import org.thingsboard.server.common.data.query.EntityListFilter;
|
import org.thingsboard.server.common.data.query.EntityListFilter;
|
||||||
|
import org.thingsboard.server.common.data.query.FilterPredicateValue;
|
||||||
import org.thingsboard.server.common.data.query.KeyFilter;
|
import org.thingsboard.server.common.data.query.KeyFilter;
|
||||||
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
|
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
|
||||||
import org.thingsboard.server.common.data.query.RelationsQueryFilter;
|
import org.thingsboard.server.common.data.query.RelationsQueryFilter;
|
||||||
@ -239,7 +240,7 @@ public abstract class BaseEntityServiceTest extends AbstractServiceTest {
|
|||||||
KeyFilter highTemperatureFilter = new KeyFilter();
|
KeyFilter highTemperatureFilter = new KeyFilter();
|
||||||
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
||||||
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
||||||
predicate.setValue(45);
|
predicate.setValue(FilterPredicateValue.fromDouble(45));
|
||||||
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||||
highTemperatureFilter.setPredicate(predicate);
|
highTemperatureFilter.setPredicate(predicate);
|
||||||
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
||||||
@ -311,7 +312,7 @@ public abstract class BaseEntityServiceTest extends AbstractServiceTest {
|
|||||||
KeyFilter highTemperatureFilter = new KeyFilter();
|
KeyFilter highTemperatureFilter = new KeyFilter();
|
||||||
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
||||||
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
||||||
predicate.setValue(45);
|
predicate.setValue(FilterPredicateValue.fromDouble(45));
|
||||||
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||||
highTemperatureFilter.setPredicate(predicate);
|
highTemperatureFilter.setPredicate(predicate);
|
||||||
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
||||||
@ -382,7 +383,7 @@ public abstract class BaseEntityServiceTest extends AbstractServiceTest {
|
|||||||
KeyFilter highTemperatureFilter = new KeyFilter();
|
KeyFilter highTemperatureFilter = new KeyFilter();
|
||||||
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "consumption"));
|
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "consumption"));
|
||||||
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
||||||
predicate.setValue(50);
|
predicate.setValue(FilterPredicateValue.fromDouble(50));
|
||||||
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||||
highTemperatureFilter.setPredicate(predicate);
|
highTemperatureFilter.setPredicate(predicate);
|
||||||
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
||||||
@ -584,7 +585,7 @@ public abstract class BaseEntityServiceTest extends AbstractServiceTest {
|
|||||||
KeyFilter highTemperatureFilter = new KeyFilter();
|
KeyFilter highTemperatureFilter = new KeyFilter();
|
||||||
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
|
||||||
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
NumericFilterPredicate predicate = new NumericFilterPredicate();
|
||||||
predicate.setValue(45);
|
predicate.setValue(FilterPredicateValue.fromDouble(45));
|
||||||
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||||
highTemperatureFilter.setPredicate(predicate);
|
highTemperatureFilter.setPredicate(predicate);
|
||||||
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
|
||||||
|
|||||||
@ -396,7 +396,9 @@ export class EntityService {
|
|||||||
type: FilterPredicateType.STRING,
|
type: FilterPredicateType.STRING,
|
||||||
operation: StringOperation.STARTS_WITH,
|
operation: StringOperation.STARTS_WITH,
|
||||||
ignoreCase: true,
|
ignoreCase: true,
|
||||||
value: searchText
|
value: {
|
||||||
|
defaultValue: searchText
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
] : null
|
] : null
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" [formGroup]="booleanFilterPredicateFormGroup">
|
<div fxFlex fxLayout="row" fxLayoutAlign="start start" fxLayoutGap="8px" [formGroup]="booleanFilterPredicateFormGroup">
|
||||||
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex="40" class="mat-block">
|
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex="40" class="mat-block">
|
||||||
<mat-label></mat-label>
|
<mat-label></mat-label>
|
||||||
<mat-select required formControlName="operation" placeholder="{{'filter.operation.operation' | translate}}">
|
<mat-select required formControlName="operation" placeholder="{{'filter.operation.operation' | translate}}">
|
||||||
@ -24,7 +24,8 @@
|
|||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-checkbox fxFlex="60" formControlName="value">
|
<tb-filter-predicate-value fxFlex="60"
|
||||||
{{ (booleanFilterPredicateFormGroup.get('value').value ? 'value.true' : 'value.false') | translate }}
|
[valueType]="valueTypeEnum.BOOLEAN"
|
||||||
</mat-checkbox>
|
formControlName="value">
|
||||||
|
</tb-filter-predicate-value>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -18,10 +18,10 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core';
|
|||||||
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
BooleanFilterPredicate,
|
BooleanFilterPredicate,
|
||||||
BooleanOperation, booleanOperationTranslationMap,
|
BooleanOperation,
|
||||||
|
booleanOperationTranslationMap, EntityKeyValueType,
|
||||||
FilterPredicateType
|
FilterPredicateType
|
||||||
} from '@shared/models/query/query.models';
|
} from '@shared/models/query/query.models';
|
||||||
import { isDefined } from '@core/utils';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-boolean-filter-predicate',
|
selector: 'tb-boolean-filter-predicate',
|
||||||
@ -39,6 +39,8 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On
|
|||||||
|
|
||||||
@Input() disabled: boolean;
|
@Input() disabled: boolean;
|
||||||
|
|
||||||
|
valueTypeEnum = EntityKeyValueType;
|
||||||
|
|
||||||
booleanFilterPredicateFormGroup: FormGroup;
|
booleanFilterPredicateFormGroup: FormGroup;
|
||||||
|
|
||||||
booleanOperations = Object.keys(BooleanOperation);
|
booleanOperations = Object.keys(BooleanOperation);
|
||||||
@ -53,7 +55,7 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.booleanFilterPredicateFormGroup = this.fb.group({
|
this.booleanFilterPredicateFormGroup = this.fb.group({
|
||||||
operation: [BooleanOperation.EQUAL, [Validators.required]],
|
operation: [BooleanOperation.EQUAL, [Validators.required]],
|
||||||
value: [false]
|
value: [null, [Validators.required]]
|
||||||
});
|
});
|
||||||
this.booleanFilterPredicateFormGroup.valueChanges.subscribe(() => {
|
this.booleanFilterPredicateFormGroup.valueChanges.subscribe(() => {
|
||||||
this.updateModel();
|
this.updateModel();
|
||||||
@ -78,16 +80,13 @@ export class BooleanFilterPredicateComponent implements ControlValueAccessor, On
|
|||||||
|
|
||||||
writeValue(predicate: BooleanFilterPredicate): void {
|
writeValue(predicate: BooleanFilterPredicate): void {
|
||||||
this.booleanFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
|
this.booleanFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
|
||||||
this.booleanFilterPredicateFormGroup.get('value').patchValue(isDefined(predicate.value) ? predicate.value : false, {emitEvent: false});
|
this.booleanFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateModel() {
|
private updateModel() {
|
||||||
let predicate: BooleanFilterPredicate = null;
|
let predicate: BooleanFilterPredicate = null;
|
||||||
if (this.booleanFilterPredicateFormGroup.valid) {
|
if (this.booleanFilterPredicateFormGroup.valid) {
|
||||||
predicate = this.booleanFilterPredicateFormGroup.getRawValue();
|
predicate = this.booleanFilterPredicateFormGroup.getRawValue();
|
||||||
if (!isDefined(predicate.value)) {
|
|
||||||
predicate.value = false;
|
|
||||||
}
|
|
||||||
predicate.type = FilterPredicateType.BOOLEAN;
|
predicate.type = FilterPredicateType.BOOLEAN;
|
||||||
}
|
}
|
||||||
this.propagateChange(predicate);
|
this.propagateChange(predicate);
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
<div class="predicate-list">
|
<div class="predicate-list">
|
||||||
<div fxLayout="row" fxLayoutAlign="start center" style="height: 40px;"
|
<div fxLayout="row" fxLayoutAlign="start center" style="height: 45px;"
|
||||||
formArrayName="predicates"
|
formArrayName="predicates"
|
||||||
*ngFor="let predicateControl of predicatesFormArray().controls; let $index = index">
|
*ngFor="let predicateControl of predicatesFormArray().controls; let $index = index">
|
||||||
<div fxFlex="8" fxLayout="row" fxLayoutAlign="center" class="filters-operation">
|
<div fxFlex="8" fxLayout="row" fxLayoutAlign="center" class="filters-operation">
|
||||||
|
|||||||
@ -0,0 +1,48 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
|
||||||
|
Licensed 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 fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" [formGroup]="filterPredicateValueFormGroup">
|
||||||
|
<div fxFlex fxLayout="column">
|
||||||
|
<div fxFlex fxLayout="column" [ngSwitch]="valueType">
|
||||||
|
<ng-template [ngSwitchCase]="valueTypeEnum.STRING">
|
||||||
|
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex class="mat-block">
|
||||||
|
<mat-label></mat-label>
|
||||||
|
<input matInput formControlName="defaultValue" placeholder="{{'filter.value' | translate}}">
|
||||||
|
</mat-form-field>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template [ngSwitchCase]="valueTypeEnum.NUMERIC">
|
||||||
|
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex class="mat-block">
|
||||||
|
<mat-label></mat-label>
|
||||||
|
<input required type="number" matInput formControlName="defaultValue"
|
||||||
|
placeholder="{{'filter.value' | translate}}">
|
||||||
|
</mat-form-field>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template [ngSwitchCase]="valueTypeEnum.DATE_TIME">
|
||||||
|
<tb-datetime fxFlex formControlName="defaultValue"
|
||||||
|
dateText="filter.date"
|
||||||
|
timeText="filter.time"
|
||||||
|
required [showLabel]="false"></tb-datetime>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template [ngSwitchCase]="valueTypeEnum.BOOLEAN">
|
||||||
|
<mat-checkbox fxFlex formControlName="defaultValue">
|
||||||
|
{{ (filterPredicateValueFormGroup.get('defaultValue').value ? 'value.true' : 'value.false') | translate }}
|
||||||
|
</mat-checkbox>
|
||||||
|
</ng-template>
|
||||||
|
</div>
|
||||||
|
<div class="tb-hint">Default value</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,126 @@
|
|||||||
|
///
|
||||||
|
/// Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
///
|
||||||
|
/// Licensed 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, forwardRef, Input, OnInit } from '@angular/core';
|
||||||
|
import {
|
||||||
|
ControlValueAccessor,
|
||||||
|
FormBuilder,
|
||||||
|
FormGroup,
|
||||||
|
NG_VALUE_ACCESSOR,
|
||||||
|
ValidatorFn,
|
||||||
|
Validators
|
||||||
|
} from '@angular/forms';
|
||||||
|
import { EntityKeyValueType, FilterPredicateValue } from '@shared/models/query/query.models';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'tb-filter-predicate-value',
|
||||||
|
templateUrl: './filter-predicate-value.component.html',
|
||||||
|
styleUrls: ['./filter-predicate.scss'],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => FilterPredicateValueComponent),
|
||||||
|
multi: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class FilterPredicateValueComponent implements ControlValueAccessor, OnInit {
|
||||||
|
|
||||||
|
@Input() disabled: boolean;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
valueType: EntityKeyValueType;
|
||||||
|
|
||||||
|
valueTypeEnum = EntityKeyValueType;
|
||||||
|
|
||||||
|
filterPredicateValueFormGroup: FormGroup;
|
||||||
|
|
||||||
|
private propagateChange = null;
|
||||||
|
|
||||||
|
constructor(private fb: FormBuilder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
let defaultValue: string | number | boolean;
|
||||||
|
let defaultValueValidators: ValidatorFn[];
|
||||||
|
switch (this.valueType) {
|
||||||
|
case EntityKeyValueType.STRING:
|
||||||
|
defaultValue = '';
|
||||||
|
defaultValueValidators = [];
|
||||||
|
break;
|
||||||
|
case EntityKeyValueType.NUMERIC:
|
||||||
|
defaultValue = 0;
|
||||||
|
defaultValueValidators = [Validators.required];
|
||||||
|
break;
|
||||||
|
case EntityKeyValueType.BOOLEAN:
|
||||||
|
defaultValue = false;
|
||||||
|
defaultValueValidators = [];
|
||||||
|
break;
|
||||||
|
case EntityKeyValueType.DATE_TIME:
|
||||||
|
defaultValue = Date.now();
|
||||||
|
defaultValueValidators = [Validators.required];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.filterPredicateValueFormGroup = this.fb.group({
|
||||||
|
defaultValue: [defaultValue, defaultValueValidators],
|
||||||
|
dynamicValue: this.fb.group(
|
||||||
|
{
|
||||||
|
sourceType: [null],
|
||||||
|
sourceAttribute: [null]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
this.filterPredicateValueFormGroup.valueChanges.subscribe(() => {
|
||||||
|
this.updateModel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.propagateChange = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
setDisabledState?(isDisabled: boolean): void {
|
||||||
|
this.disabled = isDisabled;
|
||||||
|
if (this.disabled) {
|
||||||
|
this.filterPredicateValueFormGroup.disable({emitEvent: false});
|
||||||
|
} else {
|
||||||
|
this.filterPredicateValueFormGroup.enable({emitEvent: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(predicateValue: FilterPredicateValue<string | number | boolean>): void {
|
||||||
|
this.filterPredicateValueFormGroup.get('defaultValue').patchValue(predicateValue.defaultValue, {emitEvent: false});
|
||||||
|
this.filterPredicateValueFormGroup.get('dynamicValue').patchValue(predicateValue.dynamicValue ?
|
||||||
|
predicateValue.dynamicValue : { sourceType: null, sourceAttribute: null }, {emitEvent: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateModel() {
|
||||||
|
let predicateValue: FilterPredicateValue<string | number | boolean> = null;
|
||||||
|
if (this.filterPredicateValueFormGroup.valid) {
|
||||||
|
predicateValue = this.filterPredicateValueFormGroup.getRawValue();
|
||||||
|
if (predicateValue.dynamicValue) {
|
||||||
|
if (!predicateValue.dynamicValue.sourceType || !predicateValue.dynamicValue.sourceAttribute) {
|
||||||
|
predicateValue.dynamicValue = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.propagateChange(predicateValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -13,6 +13,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
:host {
|
||||||
|
.tb-hint {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
:host ::ng-deep {
|
:host ::ng-deep {
|
||||||
mat-form-field {
|
mat-form-field {
|
||||||
.mat-form-field-wrapper {
|
.mat-form-field-wrapper {
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" [formGroup]="numericFilterPredicateFormGroup">
|
<div fxFlex fxLayout="row" fxLayoutAlign="start start" fxLayoutGap="8px" [formGroup]="numericFilterPredicateFormGroup">
|
||||||
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex="40" class="mat-block">
|
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex="40" class="mat-block">
|
||||||
<mat-label></mat-label>
|
<mat-label></mat-label>
|
||||||
<mat-select required formControlName="operation" placeholder="{{'filter.operation.operation' | translate}}">
|
<mat-select required formControlName="operation" placeholder="{{'filter.operation.operation' | translate}}">
|
||||||
@ -24,19 +24,8 @@
|
|||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<div fxFlex="60" fxLayout="column" [ngSwitch]="valueType">
|
<tb-filter-predicate-value fxFlex="60"
|
||||||
<ng-template [ngSwitchCase]="valueTypeEnum.NUMERIC">
|
[valueType]="valueType"
|
||||||
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex class="mat-block">
|
formControlName="value">
|
||||||
<mat-label></mat-label>
|
</tb-filter-predicate-value>
|
||||||
<input required type="number" matInput formControlName="value"
|
|
||||||
placeholder="{{'filter.value' | translate}}">
|
|
||||||
</mat-form-field>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template [ngSwitchCase]="valueTypeEnum.DATE_TIME">
|
|
||||||
<tb-datetime fxFlex formControlName="value"
|
|
||||||
dateText="filter.date"
|
|
||||||
timeText="filter.time"
|
|
||||||
required [showLabel]="false"></tb-datetime>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -18,9 +18,11 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core';
|
|||||||
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
EntityKeyValueType,
|
EntityKeyValueType,
|
||||||
FilterPredicateType, NumericFilterPredicate, NumericOperation, numericOperationTranslationMap,
|
FilterPredicateType,
|
||||||
|
NumericFilterPredicate,
|
||||||
|
NumericOperation,
|
||||||
|
numericOperationTranslationMap,
|
||||||
} from '@shared/models/query/query.models';
|
} from '@shared/models/query/query.models';
|
||||||
import { isDefined } from '@core/utils';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-numeric-filter-predicate',
|
selector: 'tb-numeric-filter-predicate',
|
||||||
@ -56,7 +58,7 @@ export class NumericFilterPredicateComponent implements ControlValueAccessor, On
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.numericFilterPredicateFormGroup = this.fb.group({
|
this.numericFilterPredicateFormGroup = this.fb.group({
|
||||||
operation: [NumericOperation.EQUAL, [Validators.required]],
|
operation: [NumericOperation.EQUAL, [Validators.required]],
|
||||||
value: [0, [Validators.required]]
|
value: [null, [Validators.required]]
|
||||||
});
|
});
|
||||||
this.numericFilterPredicateFormGroup.valueChanges.subscribe(() => {
|
this.numericFilterPredicateFormGroup.valueChanges.subscribe(() => {
|
||||||
this.updateModel();
|
this.updateModel();
|
||||||
@ -81,16 +83,13 @@ export class NumericFilterPredicateComponent implements ControlValueAccessor, On
|
|||||||
|
|
||||||
writeValue(predicate: NumericFilterPredicate): void {
|
writeValue(predicate: NumericFilterPredicate): void {
|
||||||
this.numericFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
|
this.numericFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
|
||||||
this.numericFilterPredicateFormGroup.get('value').patchValue(isDefined(predicate.value) ? predicate.value : 0, {emitEvent: false});
|
this.numericFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateModel() {
|
private updateModel() {
|
||||||
let predicate: NumericFilterPredicate = null;
|
let predicate: NumericFilterPredicate = null;
|
||||||
if (this.numericFilterPredicateFormGroup.valid) {
|
if (this.numericFilterPredicateFormGroup.valid) {
|
||||||
predicate = this.numericFilterPredicateFormGroup.getRawValue();
|
predicate = this.numericFilterPredicateFormGroup.getRawValue();
|
||||||
if (!predicate.value) {
|
|
||||||
predicate.value = 0;
|
|
||||||
}
|
|
||||||
predicate.type = FilterPredicateType.NUMERIC;
|
predicate.type = FilterPredicateType.NUMERIC;
|
||||||
}
|
}
|
||||||
this.propagateChange(predicate);
|
this.propagateChange(predicate);
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px" [formGroup]="stringFilterPredicateFormGroup">
|
<div fxFlex fxLayout="row" fxLayoutAlign="start start" fxLayoutGap="8px" [formGroup]="stringFilterPredicateFormGroup">
|
||||||
<div fxFlex="40" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
|
<div fxFlex="40" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
|
||||||
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex class="mat-block">
|
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex class="mat-block">
|
||||||
<mat-label></mat-label>
|
<mat-label></mat-label>
|
||||||
@ -28,8 +28,8 @@
|
|||||||
<mat-checkbox fxLayout="row" fxLayoutAlign="center" formControlName="ignoreCase" style="min-width: 70px;">
|
<mat-checkbox fxLayout="row" fxLayoutAlign="center" formControlName="ignoreCase" style="min-width: 70px;">
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field floatLabel="always" hideRequiredMarker fxFlex="60" class="mat-block">
|
<tb-filter-predicate-value fxFlex="60"
|
||||||
<mat-label></mat-label>
|
[valueType]="valueTypeEnum.STRING"
|
||||||
<input matInput formControlName="value" placeholder="{{'filter.value' | translate}}">
|
formControlName="value">
|
||||||
</mat-form-field>
|
</tb-filter-predicate-value>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
import { Component, forwardRef, Input, OnInit } from '@angular/core';
|
import { Component, forwardRef, Input, OnInit } from '@angular/core';
|
||||||
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
|
EntityKeyValueType,
|
||||||
FilterPredicateType,
|
FilterPredicateType,
|
||||||
StringFilterPredicate,
|
StringFilterPredicate,
|
||||||
StringOperation,
|
StringOperation,
|
||||||
@ -39,6 +40,8 @@ export class StringFilterPredicateComponent implements ControlValueAccessor, OnI
|
|||||||
|
|
||||||
@Input() disabled: boolean;
|
@Input() disabled: boolean;
|
||||||
|
|
||||||
|
valueTypeEnum = EntityKeyValueType;
|
||||||
|
|
||||||
stringFilterPredicateFormGroup: FormGroup;
|
stringFilterPredicateFormGroup: FormGroup;
|
||||||
|
|
||||||
stringOperations = Object.keys(StringOperation);
|
stringOperations = Object.keys(StringOperation);
|
||||||
@ -53,7 +56,7 @@ export class StringFilterPredicateComponent implements ControlValueAccessor, OnI
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.stringFilterPredicateFormGroup = this.fb.group({
|
this.stringFilterPredicateFormGroup = this.fb.group({
|
||||||
operation: [StringOperation.STARTS_WITH, [Validators.required]],
|
operation: [StringOperation.STARTS_WITH, [Validators.required]],
|
||||||
value: [''],
|
value: [null, [Validators.required]],
|
||||||
ignoreCase: [false]
|
ignoreCase: [false]
|
||||||
});
|
});
|
||||||
this.stringFilterPredicateFormGroup.valueChanges.subscribe(() => {
|
this.stringFilterPredicateFormGroup.valueChanges.subscribe(() => {
|
||||||
@ -79,7 +82,7 @@ export class StringFilterPredicateComponent implements ControlValueAccessor, OnI
|
|||||||
|
|
||||||
writeValue(predicate: StringFilterPredicate): void {
|
writeValue(predicate: StringFilterPredicate): void {
|
||||||
this.stringFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
|
this.stringFilterPredicateFormGroup.get('operation').patchValue(predicate.operation, {emitEvent: false});
|
||||||
this.stringFilterPredicateFormGroup.get('value').patchValue(predicate.value ? predicate.value : '', {emitEvent: false});
|
this.stringFilterPredicateFormGroup.get('value').patchValue(predicate.value, {emitEvent: false});
|
||||||
this.stringFilterPredicateFormGroup.get('ignoreCase').patchValue(predicate.ignoreCase, {emitEvent: false});
|
this.stringFilterPredicateFormGroup.get('ignoreCase').patchValue(predicate.ignoreCase, {emitEvent: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +90,6 @@ export class StringFilterPredicateComponent implements ControlValueAccessor, OnI
|
|||||||
let predicate: StringFilterPredicate = null;
|
let predicate: StringFilterPredicate = null;
|
||||||
if (this.stringFilterPredicateFormGroup.valid) {
|
if (this.stringFilterPredicateFormGroup.valid) {
|
||||||
predicate = this.stringFilterPredicateFormGroup.getRawValue();
|
predicate = this.stringFilterPredicateFormGroup.getRawValue();
|
||||||
if (!predicate.value) {
|
|
||||||
predicate.value = '';
|
|
||||||
}
|
|
||||||
predicate.type = FilterPredicateType.STRING;
|
predicate.type = FilterPredicateType.STRING;
|
||||||
}
|
}
|
||||||
this.propagateChange(predicate);
|
this.propagateChange(predicate);
|
||||||
|
|||||||
@ -84,12 +84,12 @@ export class UserFilterDialogComponent extends DialogComponent<UserFilterDialogC
|
|||||||
const userInputControl = this.fb.group({
|
const userInputControl = this.fb.group({
|
||||||
label: [userInput.label],
|
label: [userInput.label],
|
||||||
valueType: [userInput.valueType],
|
valueType: [userInput.valueType],
|
||||||
value: [(userInput.info.keyFilterPredicate as any).value,
|
value: [(userInput.info.keyFilterPredicate as any).value.defaultValue,
|
||||||
userInput.valueType === EntityKeyValueType.NUMERIC ||
|
userInput.valueType === EntityKeyValueType.NUMERIC ||
|
||||||
userInput.valueType === EntityKeyValueType.DATE_TIME ? [Validators.required] : []]
|
userInput.valueType === EntityKeyValueType.DATE_TIME ? [Validators.required] : []]
|
||||||
});
|
});
|
||||||
userInputControl.get('value').valueChanges.subscribe(value => {
|
userInputControl.get('value').valueChanges.subscribe(value => {
|
||||||
(userInput.info.keyFilterPredicate as any).value = value;
|
(userInput.info.keyFilterPredicate as any).value.defaultValue = value;
|
||||||
});
|
});
|
||||||
return userInputControl;
|
return userInputControl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,6 +83,7 @@ import { FiltersEditPanelComponent } from '@home/components/filter/filters-edit-
|
|||||||
import { UserFilterDialogComponent } from '@home/components/filter/user-filter-dialog.component';
|
import { UserFilterDialogComponent } from '@home/components/filter/user-filter-dialog.component';
|
||||||
import { FilterUserInfoComponent } from './filter/filter-user-info.component';
|
import { FilterUserInfoComponent } from './filter/filter-user-info.component';
|
||||||
import { FilterUserInfoDialogComponent } from './filter/filter-user-info-dialog.component';
|
import { FilterUserInfoDialogComponent } from './filter/filter-user-info-dialog.component';
|
||||||
|
import { FilterPredicateValueComponent } from './filter/filter-predicate-value.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations:
|
declarations:
|
||||||
@ -148,7 +149,8 @@ import { FilterUserInfoDialogComponent } from './filter/filter-user-info-dialog.
|
|||||||
FiltersEditPanelComponent,
|
FiltersEditPanelComponent,
|
||||||
UserFilterDialogComponent,
|
UserFilterDialogComponent,
|
||||||
FilterUserInfoComponent,
|
FilterUserInfoComponent,
|
||||||
FilterUserInfoDialogComponent
|
FilterUserInfoDialogComponent,
|
||||||
|
FilterPredicateValueComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
|||||||
@ -138,16 +138,22 @@ export function createDefaultFilterPredicate(valueType: EntityKeyValueType, comp
|
|||||||
switch (predicate.type) {
|
switch (predicate.type) {
|
||||||
case FilterPredicateType.STRING:
|
case FilterPredicateType.STRING:
|
||||||
predicate.operation = StringOperation.STARTS_WITH;
|
predicate.operation = StringOperation.STARTS_WITH;
|
||||||
predicate.value = '';
|
predicate.value = {
|
||||||
|
defaultValue: ''
|
||||||
|
};
|
||||||
predicate.ignoreCase = false;
|
predicate.ignoreCase = false;
|
||||||
break;
|
break;
|
||||||
case FilterPredicateType.NUMERIC:
|
case FilterPredicateType.NUMERIC:
|
||||||
predicate.operation = NumericOperation.EQUAL;
|
predicate.operation = NumericOperation.EQUAL;
|
||||||
predicate.value = valueType === EntityKeyValueType.DATE_TIME ? Date.now() : 0;
|
predicate.value = {
|
||||||
|
defaultValue: valueType === EntityKeyValueType.DATE_TIME ? Date.now() : 0
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case FilterPredicateType.BOOLEAN:
|
case FilterPredicateType.BOOLEAN:
|
||||||
predicate.operation = BooleanOperation.EQUAL;
|
predicate.operation = BooleanOperation.EQUAL;
|
||||||
predicate.value = false;
|
predicate.value = {
|
||||||
|
defaultValue: false
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case FilterPredicateType.COMPLEX:
|
case FilterPredicateType.COMPLEX:
|
||||||
predicate.operation = ComplexOperation.AND;
|
predicate.operation = ComplexOperation.AND;
|
||||||
@ -228,23 +234,47 @@ export const complexOperationTranslationMap = new Map<ComplexOperation, string>(
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export enum DynamicValueSourceType {
|
||||||
|
CURRENT_TENANT = 'CURRENT_TENANT',
|
||||||
|
CURRENT_CUSTOMER = 'CURRENT_CUSTOMER',
|
||||||
|
CURRENT_USER = 'CURRENT_USER'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dynamicValueSourceTypeTranslationMap = new Map<DynamicValueSourceType, string>(
|
||||||
|
[
|
||||||
|
[DynamicValueSourceType.CURRENT_TENANT, 'filter.current-tenant'],
|
||||||
|
[DynamicValueSourceType.CURRENT_CUSTOMER, 'filter.current-customer'],
|
||||||
|
[DynamicValueSourceType.CURRENT_USER, 'filter.current-user']
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
export interface DynamicValue<T> {
|
||||||
|
sourceType: DynamicValueSourceType;
|
||||||
|
sourceAttribute: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterPredicateValue<T> {
|
||||||
|
defaultValue: T;
|
||||||
|
dynamicValue?: DynamicValue<T>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StringFilterPredicate {
|
export interface StringFilterPredicate {
|
||||||
type: FilterPredicateType.STRING,
|
type: FilterPredicateType.STRING,
|
||||||
operation: StringOperation;
|
operation: StringOperation;
|
||||||
value: string;
|
value: FilterPredicateValue<string>;
|
||||||
ignoreCase: boolean;
|
ignoreCase: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NumericFilterPredicate {
|
export interface NumericFilterPredicate {
|
||||||
type: FilterPredicateType.NUMERIC,
|
type: FilterPredicateType.NUMERIC,
|
||||||
operation: NumericOperation;
|
operation: NumericOperation;
|
||||||
value: number;
|
value: FilterPredicateValue<number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BooleanFilterPredicate {
|
export interface BooleanFilterPredicate {
|
||||||
type: FilterPredicateType.BOOLEAN,
|
type: FilterPredicateType.BOOLEAN,
|
||||||
operation: BooleanOperation;
|
operation: BooleanOperation;
|
||||||
value: boolean;
|
value: FilterPredicateValue<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BaseComplexFilterPredicate<T extends KeyFilterPredicate | KeyFilterPredicateInfo> {
|
export interface BaseComplexFilterPredicate<T extends KeyFilterPredicate | KeyFilterPredicateInfo> {
|
||||||
|
|||||||
@ -1227,7 +1227,10 @@
|
|||||||
"remove-key-filter": "Remove key filter",
|
"remove-key-filter": "Remove key filter",
|
||||||
"edit-key-filter": "Edit key filter",
|
"edit-key-filter": "Edit key filter",
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"time": "Time"
|
"time": "Time",
|
||||||
|
"current-tenant": "Current tenant",
|
||||||
|
"current-customer": "Current customer",
|
||||||
|
"current-user": "Current user"
|
||||||
},
|
},
|
||||||
"fullscreen": {
|
"fullscreen": {
|
||||||
"expand": "Expand to fullscreen",
|
"expand": "Expand to fullscreen",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user