Skip to content

[feat] Modelo de condicional profundo en consultas #13

@wrsbyte

Description

@wrsbyte

Hola @CodelyTV, Wilmer desde Colombia. Felicidades y gracias por todas las contribuciones al desarrollo de software y la comunidad en español 🥳.

[Problema] Entiendo que el modelo Criteria se propone como una generalización de consultas complejas a través de REST API. Muchos de los frontends que requieren este tipo de consultas requieren concatenar condiciones más profundas que permitan un filtrado preciso.

Aquí un ejemplo del frontal de odoo v15.

image

[Propuesta] Un modelado de Filtro recursivo que permita seleccionar la relación entre operaciones (AND, OR).

Dejo esbozo de la idea.

import { FilterField } from "./FilterField";
import { FilterOperator, Operator } from "./FilterOperator";
import { FilterValue } from "./FilterValue";

export type Relation = 'AND' | 'OR';

export class Condition {
    readonly field: FilterField;
    readonly operator: FilterOperator;
    readonly value: FilterValue;

    constructor(field: FilterField, operator: FilterOperator, value: FilterValue) {
        this.field = field;
        this.operator = operator;
        this.value = value;
    }

    static fromPrimitives(field: string, operator: string, value: string): Condition {
        return new Condition(
            new FilterField(field),
            new FilterOperator(Operator[operator as keyof typeof Operator]),
            new FilterValue(value),
        );
    }

    toPrimitives(): FiltersPrimitives {
        return {
            field: this.field.value,
            operator: this.operator.value,
            value: this.value.value,
        };
    }
}

export class Filter {
    readonly relation: Relation;
    readonly filters: Array<Condition | Filter>;

    constructor(relation: Relation, filters: Array<Condition | Filter>) {
        this.relation = relation;
        this.filters = filters;
    }

    static fromPrimitives(relation: Relation, filters: Array<FiltersPrimitives>): Filter {
        return new Filter(
            relation,
            filters.map((filter) => {
                const isConditionFilter = 'field' in filter;
                if (isConditionFilter ) {
                    return Condition.fromPrimitives(filter.field, filter.operator, filter.value);
                }
                
                return Filter.fromPrimitives(filter.relation, filter.filters);
            })
        );
    }

    toPrimitives(): any {
        return {
            relation: this.relation,
            filters: this.filters.map((filter) => {
                eturn filter.toPrimitives();
            }),
        };
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions