alirezanet/Gridify

JavaScript client library

MoienTajik opened this issue ยท 3 comments

Details

The consumers of the endpoints for "GridifyQuery" are primarily frontends (JavaScript).
While it falls outside the scope of this project, it is logical to have a client library that aligns with the query syntax of this project. Additionally, there can be builders in the frontend library that can create Filter/Sort/Order expressions in JavaScript, allowing for easy appending to the URL and transmission to a backend that uses Gridify internally.

Hi @MoienTajik,

Thank you for your feedback. I did consider the possibility of a JavaScript library, but I encountered some challenges in finding a suitable and reusable solution, particularly because each JavaScript library (mainly data Grids) can handle queries differently.

Nonetheless, we remain enthusiastic about embracing new ideas and contributions. If you or anyone else has specific ideas or is interested in contributing to this effort, please don't hesitate to send a pull request. Your assistance and insights would be highly valued and greatly appreciated! ๐Ÿ˜Š

...because each JavaScript library (mainly data Grids) can handle queries differently.

I believe that the package I'm considering should not manage the integration with data grid libraries directly. The Core package (e.g., Gridify.Client) should merely provide a simple, fluent builder to create a query string that meets Gridify's backend requirements, including Paging<T> and other fundamental models.

For integration with third-party data grid libraries, separate packages should be created on top of the Core package for each vendor, such as Gridify.Client.Telerik.

I'm requesting this because most Gridify consumers currently have to manually implement these features in their frontend. This process could instead be streamlined and published as a standard library by the author.

Below is a quick pseudo-example of what I have in mind (certainly, there's much room for improvement):

class GridifyQueryBuilder {
    private queryParts: string[] = [];

    equal(field: string, value: string): QueryBuilder {
        return this.addCondition(field, '=', value);
    }

    notEqual(field: string, value: string): QueryBuilder {
        return this.addCondition(field, '!=', value);
    }

    lessThan(field: string, value: string): QueryBuilder {
        return this.addCondition(field, '<', value);
    }

    and(): QueryBuilder {
        this.queryParts.push(',');
        return this;
    }

    or(): QueryBuilder {
        this.queryParts.push('|');
        return this;
    }

    private addCondition(field: string, operator: string, value: string, caseInsensitive: boolean = false): QueryBuilder {
        const escapedValue = this.escapeValue(value);
        this.queryParts.push(`${field}${operator}${escapedValue}${caseInsensitive ? '/i' : ''}`);
        return this;
    }

    private escapeValue(value: string): string {
        return value.replace(/([(),|]|\/i)/g, '\\$1');
    }

    build(): string {
        return this.queryParts.join('');
    }
}

// Usage example
const query = new GridifyQueryBuilder()
    .equal('FirstName', 'John')
    .and()
    .lessThan('Age', '30')
    .or()
    .equal('LastName', 'Doe')
    .build();

Hi @MoienTajik ,
I agree, very good suggestion. I've just started working on it. It's still a work in progress but I've opened a draft PR here for visibility and to facilitate discussion.

While I continue to refine the implementation, I'm very open to any suggestions or feedback that could help improve it. If you have specific ideas or concerns, please feel free to share them either here in the issue or directly on the PR. Your input is invaluable to ensure that the end result is as robust and user-friendly as possible.