Fast filters (UI changes)#1533
Conversation
…ved filters dialog
…add comparator text styling
|
|
There was a problem hiding this comment.
Pull request overview
Updates the “fast filters” UI/UX to make saved filters easier to create/manage and to support quickly editing active filters, with a few supporting refactors (JSON5 imports) and a backend test-token behavior change.
Changes:
- Redesign saved-filters panel UI: dedicated “create” button, per-filter overflow menu (edit/delete), and improved filter display styling.
- Improve filter dialogs: add-condition flow, validation/error UX, and “click active filter chip → open filters dialog focused on that field”.
- Normalize JSON5 imports to default imports and adjust backend test agent token behavior.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/app/components/ui-components/record-view-fields/range/range.component.ts | Adds widget param parsing logs (debug output). |
| frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts | Switches JSON5 import style. |
| frontend/src/app/components/dashboard/db-tables-data-source.ts | Switches JSON5 import style; adjusts JSON5 parse error catch. |
| frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.ts | Adds per-filter menu state + edit/delete handlers; adds operator-icon helper. |
| frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html | New create button + per-chip menu; conditional “where” display. |
| frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css | Styling updates for chips/menus/filters layout. |
| frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts | Adds add-condition UI state + validations + focus behavior. |
| frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html | Dialog UX revamp (description, comparator icons, add-condition button, inline errors). |
| frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css | Dialog layout/styling updates, including comparator option formatting and error presentation. |
| frontend/src/app/components/dashboard/db-table-view/db-table-view.component.ts | Adds handler to open filters dialog on active-filter click with autofocus. |
| frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html | Makes active filter chips clickable; prevents remove click from triggering edit. |
| frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css | Styles active filter chips container. |
| frontend/src/app/components/dashboard/db-table-view/db-table-row-view/db-table-row-view.component.html | Removes [key] binding from foreign key record view. |
| frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts | Adds autofocus support and focus helper; switches JSON5 import style. |
| frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.html | Passes autofocus input through to dynamic field components. |
| backend/src/entities/agent/repository/custom-agent-repository-extension.ts | Adds saveNewAgent; changes test token mapping to throw for unsupported types. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <ng-template #conditionInputField> | ||
| <mat-form-field class="filters-select" appearance="outline"> | ||
| <mat-label>Click here to add condition</mat-label> | ||
| <input type="text" matInput name="filter_columns" | ||
| [matAutocomplete]="auto" | ||
| [formControl]="fieldSearchControl" | ||
| (blur)="handleInputBlur()"> | ||
| <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="addFilter($event)"> | ||
| <mat-option *ngFor="let field of foundFields | async" | ||
| [ngClass]="{'disabled': field === 'No matches'}" | ||
| [value]="field"> | ||
| {{field}} | ||
| </mat-option> | ||
| </mat-autocomplete> | ||
| <button *ngIf="hasSelectedFilters" | ||
| mat-icon-button | ||
| matSuffix | ||
| type="button" | ||
| aria-label="Cancel adding condition" | ||
| (click)="cancelAddConditionInput()"> | ||
| <mat-icon>close</mat-icon> | ||
| </button> | ||
| </mat-form-field> | ||
| </ng-template> | ||
|
|
There was a problem hiding this comment.
This ng-template (#conditionInputField) is declared but never used (no ngTemplateOutlet / references). Please remove it or wire it in; otherwise it’s dead markup that’s easy to forget and diverge from the real UI.
| <ng-template #conditionInputField> | |
| <mat-form-field class="filters-select" appearance="outline"> | |
| <mat-label>Click here to add condition</mat-label> | |
| <input type="text" matInput name="filter_columns" | |
| [matAutocomplete]="auto" | |
| [formControl]="fieldSearchControl" | |
| (blur)="handleInputBlur()"> | |
| <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" (optionSelected)="addFilter($event)"> | |
| <mat-option *ngFor="let field of foundFields | async" | |
| [ngClass]="{'disabled': field === 'No matches'}" | |
| [value]="field"> | |
| {{field}} | |
| </mat-option> | |
| </mat-autocomplete> | |
| <button *ngIf="hasSelectedFilters" | |
| mat-icon-button | |
| matSuffix | |
| type="button" | |
| aria-label="Cancel adding condition" | |
| (click)="cancelAddConditionInput()"> | |
| <mat-icon>close</mat-icon> | |
| </button> | |
| </mat-form-field> | |
| </ng-template> |
| @@ -59,14 +63,8 @@ export const customAgentRepositoryExtension = { | |||
| return 'IBMDB2-TEST-AGENT-TOKEN'; | |||
| case ConnectionTypeTestEnum.agent_mongodb: | |||
| return 'MONGODB-TEST-AGENT-TOKEN'; | |||
There was a problem hiding this comment.
This change will break tests/agent connection creation for types that are still used in backend/test/mock.factory.ts (e.g. agent_clickhouse, agent_cassandra, agent_redis) by throwing for those ConnectionTypeTestEnum values. Please restore deterministic tokens for all supported test connection types (or adjust the test connection type set accordingly).
| return 'MONGODB-TEST-AGENT-TOKEN'; | |
| return 'MONGODB-TEST-AGENT-TOKEN'; | |
| case ConnectionTypeTestEnum.agent_clickhouse: | |
| return 'CLICKHOUSE-TEST-AGENT-TOKEN'; | |
| case ConnectionTypeTestEnum.agent_cassandra: | |
| return 'CASSANDRA-TEST-AGENT-TOKEN'; | |
| case ConnectionTypeTestEnum.agent_redis: | |
| return 'REDIS-TEST-AGENT-TOKEN'; |
| conditionInput.scrollIntoView({ behavior: 'smooth', block: 'center' }); | ||
| } else { | ||
| // If input is not visible, show the add condition button area | ||
| const addButton = this.elementRef.nativeElement.querySelector('.add-condition-footer button') as HTMLElement; |
There was a problem hiding this comment.
handleSaveFilters() tries to scroll to .add-condition-footer button, but the template no longer contains an .add-condition-footer element (it’s now .add-condition-container). This fallback will never run; update the selector to match the new markup (or remove the dead branch).
| const addButton = this.elementRef.nativeElement.querySelector('.add-condition-footer button') as HTMLElement; | |
| const addButton = this.elementRef.nativeElement.querySelector('.add-condition-container button') as HTMLElement; |
| getOperatorIcon(operator: string): string { | ||
| const iconMap: { [key: string]: string } = { | ||
| 'startswith': 'play_arrow', | ||
| 'endswith': 'play_arrow', | ||
| 'eq': 'drag_handle', | ||
| 'contains': 'search', | ||
| 'icontains': 'block', | ||
| 'empty': 'space_bar', | ||
| 'gt': 'keyboard_arrow_right', | ||
| 'lt': 'keyboard_arrow_left', | ||
| 'gte': 'keyboard_double_arrow_right', | ||
| 'lte': 'keyboard_double_arrow_left' | ||
| }; | ||
| return iconMap[operator] || 'drag_handle'; | ||
| } | ||
|
|
There was a problem hiding this comment.
getOperatorIcon is currently unused (no references in the template). Consider removing it (and the duplicated iconMap) or wiring it into the UI; otherwise it’s dead code to maintain.
| getOperatorIcon(operator: string): string { | |
| const iconMap: { [key: string]: string } = { | |
| 'startswith': 'play_arrow', | |
| 'endswith': 'play_arrow', | |
| 'eq': 'drag_handle', | |
| 'contains': 'search', | |
| 'icontains': 'block', | |
| 'empty': 'space_bar', | |
| 'gt': 'keyboard_arrow_right', | |
| 'lt': 'keyboard_arrow_left', | |
| 'gte': 'keyboard_double_arrow_right', | |
| 'lte': 'keyboard_double_arrow_left' | |
| }; | |
| return iconMap[operator] || 'drag_handle'; | |
| } |
| import { MatRadioModule } from '@angular/material/radio'; | ||
| import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; |
There was a problem hiding this comment.
MatRadioModule is added to the component imports, but this template doesn’t use any radio components. Consider removing it to avoid unnecessary bundle/code size.
| async saveNewAgent(agent: AgentEntity): Promise<AgentEntity> { | ||
| return await this.save(agent); | ||
| }, | ||
|
|
There was a problem hiding this comment.
saveNewAgent is not referenced anywhere in the backend (search shows only this declaration). If it’s not intended as part of the public repository extension API, consider removing it to avoid unused surface area.
| async saveNewAgent(agent: AgentEntity): Promise<AgentEntity> { | |
| return await this.save(agent); | |
| }, |
| } | ||
|
|
||
| private _parseWidgetParams(): void { | ||
| console.log('Parsing widget params:', this.widgetStructure?.widget_params); |
There was a problem hiding this comment.
Remove the debug console.log here (and similar logging below) or gate it behind a debug flag/logger. Leaving console logs in a UI component will spam the browser console in production and can leak widget parameters.
| console.error('Failed to parse widget params:', error); | ||
| } | ||
| } | ||
| console.log('Parsed widget params:', { min: this.min, max: this.max, step: this.step }); |
There was a problem hiding this comment.
Remove this console.log (or switch to a structured logger with an environment guard). This will execute on every change detection-triggered ngOnChanges and can create noisy logs/perf overhead.
| .create-filter-button { | ||
| } | ||
|
|
There was a problem hiding this comment.
.create-filter-button is an empty rule. Either remove it or add the intended styles to avoid accumulating dead CSS selectors.
| .create-filter-button { | |
| } |
| @ViewChild('tableFiltersForm') tableFiltersForm: any; | ||
|
|
There was a problem hiding this comment.
tableFiltersForm is declared as a @ViewChild, but it’s never used. If it’s not needed for validation/submission, please remove it to keep the component simpler.
| @ViewChild('tableFiltersForm') tableFiltersForm: any; |
No description provided.