-
Notifications
You must be signed in to change notification settings - Fork 161
Query Builder
- Overview
- User Stories
- Functionality
- Test Scenarios
- Accessibility
- Assumptions and Limitations
- References
CodeX
Developer Name
- Dimitar Dimitrov
- Mike Cherkasov
- Teodosia Hristodorova
- Ivan Petrov
Designer Name
- Simeon Simeonov
- Marin Popov
- Dimitar Dimitrov | Date:
- Mike Cherkasov | Date:
- Simeon Simeonov | Date:
- Radoslav Mirchev | Date: 10-Oct-2024
- Damyan Petev | Date:
- Radoslav Karaivanov | Date:
- Stamen Stoychev | Date:
Version | Users | Date | Notes |
---|---|---|---|
1 | Names of Developers and Designers | Date | |
1.1 | Teodosia Hristodorova | Aug 20, 2024 | Add test scenarios |
1.2 | Galina Edinakova | Aug 27, 2024 | Update spec to reflect the addition of features required to support queries and subqueries. |
1.3 | Ivan Petrov | Jan 17, 2025 | Updated test plan with drag & drop tests. |
1.4 | Teodosia Hristodorova | Jan 22, 2025 | Remove selection and modify editing tests. |
Query Builder provides means for operating with complex filters by creating or editing conditions and grouping them using AND/OR logic. The set of operands depends on the type of data that the filter is applied on. It outputs an object which could be serialized to JSON.
- Have query builder that shows filtering options.
- The query builder should load predetermined filter expressions.
- The filter expressions must be set/edit by user interaction.
- The query builder must support adding/removing conditions and group filters.
- The filter operands must correspond to the type of data being filtered.
- The query builder must show whether AND or OR logic is applied to a group.
- The query builder must output an object representing the currently applied expression.
- (NEW) The query builder should allow selecting from multiple entities (tables).
Developer stories:
- As a developer, I want to be able to define the initial state of the Query Builder expression tree.
- As a developer, I want to be able to clear the applied filtering expression programmatically.
- As a developer, I want to be able to specify the operands applicable for a field corresponding to the type of data of that field.
- As a developer, I want to have preset option for the type of filters that I can apply on data (numeric, string, boolean, date).
- As a developer, I want to create custom filtering conditions.
- As a developer, I want to be able to set display density for the Query Builder.
- As a developer, I want to change the title and show/hide the legend, so that I can customize the header of the component.
- (NEW) As a developer, I want to have the option to pass fields from different entities to the Query Builder.
- (NEW) As a developer, I want to choose which fields from a selected entity should be returned by the query.
- (NEW) As a developer, I want to be able to customize/template the search value input.
End-user stories:
- As an end user, I want to be able to create groups of filters (expression). I want to be able to add interactively group of filters having predefined logical operation (AND, OR).
- As an end user, I want to be able to edit a filter condition: specifying field, filtering operand and value for each filter. All this should be achieved interactively.
- As an end user, I want to be able to choose the type of operand based on the field type.
- As an end user, I want to be provided with a convenient end-user interface for creating and editing complex filtering expressions that contain multiple filters, spreading across and combining different data fields.
- As an end user, I want to be able to interactively select the logical operation (AND, OR) that will define the connection between filters and filter expressions.
- As an end user, I want to be able to add or remove filters interactively.
- As an end user, I want to be able to add or remove group of filters interactively.
- As an end user, I want to be able to group filters interactively.
- As an end user, I want to be able to ungroup filters that have been grouped before.
- As an end user, I want to have always exposed the name of the field on which the filter is applied on, the name of the filter operand applied and the typed filter value.
- As an end user, I want to have always exposed the logical operation (AND, OR) applied for group of filters.
- As an end user, I want to be able to perform selection on condition and group of conditions.
- As an end user, I want to have exposed color code indication about the logical operation (AND, OR) applied for group of filters.
- As an end user, I want to be be able to insert filter or group of filters after selected filter or group of filters.
- As an end user, I want to be able to select multiple filter conditions.
- As an end user, I want to have exposed contextual menu having meaningful actions when more than one filtering conditions are selected.
- As an end user, I want to be able to clear all created filters.
- As an end user, I want to be able to apply all created filters.
- As an end user, I want to be able to quickly remove a filter condition using a clear icon in the filter chip.
- (NEW) As an end user, I want to be able to select the entity whose fields I want to apply filtering on.
- (NEW) As an end user, I want to be able to select which fields the query should return.
- (NEW) As an end user, I want to be able to easily select to return all fields.
- (NEW) As an end user, I want to be warned that all conditions would be cleared on switching the selected entity and be provided with an option to cancel/confirm this change.
- (NEW) As an end user, I want to be able to easily create sub-queries.
- (NEW) As an end user, I want to be able to identify subqueries without having to put the condition in edit mode.
- (NEW) As an end user, I want to be able to show & hide sub-queries' inner conditions.
3.1. End-User Experience
** Integration scenarios or functionality with other features/components prototype ** End-to-end user experienceprototype ** Prepared design files for styling e.g. interplay with features and light/dark variants design hand-off
3.2. Developer Experience (UPDATED)
The simple Query Builder component could be defined like this:
<igx-query-builder
[entities]="this.entities">
</igx-query-builder>
The developer could customize the header by specifying a different title and/or hiding the legend using the IgxQueryBuilderHeaderComponent.
<igx-query-builder [entities]="this.entities">
<!-- Custom header -->
<igx-query-builder-header [title]="'Custom title'"
[showLegend]="false">
</igx-query-builder-header>
</igx-query-builder>
The developer could customize the search value input using the IgxQueryBuilderSearchValueTemplateDirective.
<igx-query-builder [entities]="this.entities">
<ng-template igxQueryBuilderSearchValue>
<span>Custom Search Value</span>
</ng-template>
</igx-query-builder>
The developer can define the entities whose fields all further operations would be applied on via the Query Builder's entities input. An entity is represented by its name and its collection of fields.
export interface EntityType {
name: string;
fields: FieldType[];
}
The developer can define the fields to be filtered as well as their data type, label, filtering operands. If not specified, default filtering operands are set based on the data type.
This can be done via the fields
property with the following interface:
export interface FieldType { (UPDATED)
/** The label of the data field */
label?: string;
/** The name of the data field */
field: string;
/** The displayed text for the field. If not set, the field is used. */
header?: string;
/** The field data type */
dataType: DataType;
/** Provides filtering operations. If not set, default ones are used based on data type */
filters: IgxFilteringOperand;
/** Sets the format pipe arguments for the field */
pipeArgs: IFieldPipeArgs;
/** The default time format */
defaultTimeFormat: string;
/** The default date time format */
defaultDateTimeFormat: string;
/** Applies custom formatter to the displayed values */
formatter(value: any, rowData?: any): any;
}
The developer can set the initial expressions tree, or get the one modified by the user, by the expressionsTree property with the following interface:
export interface IExpressionTree { (UPDATED)
filteringOperands: (IExpressionTree | IFilteringExpression)[];
operator: FilteringLogic;
field?: string;
entity?: string;
returnFields?: string[];
}
export declare interface IFilteringExpression { (UPDATED)
field: string;
condition?: IFilteringOperation;
conditionName: string;
searchVal?: Serializable;
searchTree?: IExpressionTree;
ignoreCase?: boolean;
}
export interface IFilteringOperation {
name: string;
isUnary: boolean;
iconName: string;
hidden?: boolean;
logic: (value: any, searchVal?: any, ignoreCase?: boolean) => boolean;
}
3.3. Globalization/Localization
3.4. Keyboard Navigation
Keys | Description |
---|---|
Tab/Shift+Tab | Navigates through buttons for adding new groups or conditions, buttons and fields of a condition in edit mode and chips of already set conditions and their corresponding remove, edit and add buttons. |
Enter/Space | Enters edit mode for a field. Selects specified value for a field. Applies the action of an active button. Selects/Deselects a chip. |
Arrow Up/Down | Navigates up/down through the dropdown menu items. |
Esc | Closes the drop down menu. |
3.5. API
Name | Description | Type |
---|---|---|
entities | An array of entities to select fields from. Contains information about the entity's name and fields. | EntityType[] |
expressionTree | Gets/Sets the displayed expressions tree. | IExpressionTree |
locale | Locale settings for the component. If this locale is not set, its value to be determined based on the global Angular application LOCALE_ID. | string |
resourceStrings | Gets/sets the resource strings. | IQueryBuilderResourceStrings |
Name | Description | Cancelable | Parameters |
---|---|---|---|
expressionTreeChange | Emitted when entity, return fields, condition, field, operand, value is changed. | no | - |
Name | Description | Type |
---|---|---|
title | Sets the title displayed in the header. | string |
showLegend | Determines whether the legend items are displayed or not. Defaults to true. | boolean |
resourceStrings | Gets/sets the resource strings. | IQueryBuilderResourceStrings |
Name | Description | Type |
---|---|---|
entities | An array of entities to select fields from. Contains information about the entity's name and fields. | EntityType[] |
parentExpression | ||
fields | An array of fields to be filtered. Contains information about label, field, type, operands. | FieldType[] |
expressionTree | Gets/Sets the displayed tree. | IExpressionTree |
locale | Locale settings for the component. If this locale is not set, its value to be determined based on the global Angular application LOCALE_ID. | string |
resourceStrings | Gets/sets the resource strings. | IQueryBuilderResourceStrings |
Name | Description | Cancelable | Parameters |
---|---|---|---|
expressionTreeChange | Emitted when entity, condition, field, operand, value is changed. | no | - |
inEditModeChange | Emitted when the expression item's inEditMode changes. | no | - |
4.1. Automation
- Should render empty Query Builder properly.
- Should render Query Builder with initially set expression tree properly.
- Should render combo for main entity return fields and select for nested entity return field.
- Should correctly initialize a newly added 'And' group.
- Should add a new condition to existing group by using add buttons.
- Should be able to add and define a new group through initial adding button.
- Value input should be disabled for unary operator.
- Fields dropdown should contain proper fields based on the entity.
- Column dropdown should contain proper fields based on the entity.
- Operator dropdown should contain operators based on the column's datatype ('string' or 'number' or 'date').
- Operator dropdown should contain operators based on the column's datatype ('boolean').
- Should correctly apply a 'string' column condition through UI.
- Should correctly apply a 'Greater Than' with 'number' column condition through UI.
- Should correctly apply a 'Equals' with 'number' column condition through UI.
- Should correctly apply a 'boolean' column condition through UI.
- Should correctly apply a 'date' column condition through UI with unary operator.
- Should correctly apply a 'date' column condition through UI with value from calendar.
- Should correctly apply an 'in' column condition through UI.
- Should correctly apply a 'not-in' column condition through UI.
- Should disable value fields when isNestedQuery condition is selected.
- Should correctly focus the search value input when editing the filtering expression.
- Should display add button when hovering a chip.
- Should have disabled adding buttons when an expression is in edit mode.
- Clicking a condition should put it in edit mode.
- Should switch edit mode on click on chip on the same level.
- Should exit edit mode on add, change group buttons, entity and fields select click.
- Should show add expression button when there is an expression in add mode.
- Should display an alert dialog when the entity is changed and showEntityChangeDialog is true.
- Should not display an alert dialog when the entity changed once showEntityChangeDialog is disabled.
- Initially should not display an alert dialog when the entity is changed if hideEntityChangeDialog is disabled through API.
- Should reset all inputs when the entity is changed.
- Should NOT reset all inputs when the entity is not changed.
- Should collapse nested query when it is committed.
- Should be able to open edit mode on click, close the edited condition on "close" button click and not commit it.
- Should focus added through group add buttons expression chip if it is committed.
- Should NOT focus an expression chip if added expression is discarded.
- Should not make bug where existing inner query is leaking to a newly created one.
- canCommit should return the correct validity state of currently edited condition.
- canCommit should return the correct validity state of currently added condition.
- Should be able to commit nested query without where condition.
- Should disable changing a selected entity when "disableEntityChange"=true.
- Should disable changing a selected entity when "disableEntityChange"=true only after initial selection.
-
Should properly commit/discard changes in nested query.
-
Should NOT throw errors when an invalid condition is committed through API.
-
Should navigate with Tab/Shift+Tab through entity and fields inputs, chips, their respective drop & delete icons and operator drop-down button.
-
Should navigate with Tab/Shift+Tab through chips "edit", "cancel" buttons, fields of a condition in edit mode.
-
Should start editing a condition when pressing 'Enter' on its respective chip.
-
Should remove a chip in when pressing 'Enter' on its 'remove' icon.
- Should render custom header properly.
- Should render custom input template properly.
- Should apply field formatter properly.
- Should correctly change resource strings for Query Builder.
- Should render ghost when mouse drag operation starts.
- Should collapse the condition when mouse drag operation starts.
- Should render drop ghost properly when mouse dragged.
- Should position drop ghost below the target condition on dragging down.
- Should position drop ghost above the target condition on dragging up.
- Should position drop ghost at the top inside the inner group when dragged over the first inner level condition.
- Should position drop ghost outside the inner group aligned with the outer level conditions when the top inner level condition is dragged up.
- Should position drop ghost below the inner group aligned with the outer level conditions when the bottom inner level condition is dragged down.
- Should hide drop ghost on dragging the mouse far down outside the query builder.
- Should drop the condition above the target condition on dragging up.
- Should drop the condition below the target condition on dragging down.
- Should drop the condition inside the inner group when dropped over the group.
- Should drop the condition outside the inner group aligned with the outer level conditions when dropped above the inner group.
- Should drop the condition at the last position of the root group when dropped above the buttons.
- Should remove the inner group when the last condition is dragged out.
- Should drop the condition above the currently edited condition on dragging up.
- Should be able to drag a top-level condition while a sub-query is expanded.
- Should allow dragging a sub-query condition while a sub-query is expanded.
- Should successfully rearrange sub-query conditions via mouse drag.
- Should not allow dragging a sub-query condition outside the sub-query.
- Should successfully drop a condition inside a newly created group.
- Should render drop ghost properly when keyboard dragged.
- Should commit drop upon hitting 'Enter' when keyboard dragged.
- Should cancel drop upon hitting 'Escape' when keyboard dragged.
4.2. Manual testing
- Should navigate with Tab/Shift+Tab through chips' 'adding' button.
- Should not exit edit mode Tab/Shift+Tab through chips.