From 4fd8a845beeb39e2923585d43630f8b7c86ea9e3 Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Wed, 19 Nov 2025 20:09:20 +0200 Subject: [PATCH 01/13] fixed --- .../db-table-filters-dialog.component.html | 9 +- .../db-table-filters-dialog.component.ts | 71 +++++- .../db-table-view/db-table-view.component.css | 23 ++ .../db-table-view.component.html | 6 +- .../db-table-view/db-table-view.component.ts | 34 +++ .../saved-filters-dialog.component.css | 13 ++ .../saved-filters-dialog.component.html | 33 ++- .../saved-filters-dialog.component.ts | 16 ++ .../saved-filters-panel.component.css | 217 ++++++++++++++++++ .../saved-filters-panel.component.html | 102 +++++--- .../saved-filters-panel.component.ts | 40 ++++ .../base-record-view-field.component.ts | 20 -- 12 files changed, 517 insertions(+), 67 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.html b/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.html index d6f8fb042..dd2e0e29b 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.html @@ -34,7 +34,8 @@

label: tableWidgets[value.key].name || value.key, value: tableRowFieldsShown[value.key], widgetStructure: tableWidgets[value.key], - relations: tableTypes[value.key] === 'foreign key' ? tableForeignKeys[value.key] : undefined + relations: tableTypes[value.key] === 'foreign key' ? tableForeignKeys[value.key] : undefined, + autofocus: autofocusField === value.key }" [ndcDynamicOutputs]="{ onFieldChange: { handler: updateField, args: ['$event', value.key] } @@ -49,7 +50,8 @@

label: value.key, value: tableRowFieldsShown[value.key], structure: tableRowStructure[value.key], - relations: tableTypes[value.key] === 'foreign key' ? tableForeignKeys[value.key] : undefined + relations: tableTypes[value.key] === 'foreign key' ? tableForeignKeys[value.key] : undefined, + autofocus: autofocusField === value.key }" [ndcDynamicOutputs]="{ onFieldChange: { handler: updateField, args: ['$event', value.key] } @@ -117,7 +119,8 @@

value: tableRowFieldsShown[value.key], readonly: tableRowFieldsComparator[value.key] === 'empty', structure: tableRowStructure[value.key], - relations: tableTypes[value.key] === 'foreign key' ? tableForeignKeys[value.key] : undefined + relations: tableTypes[value.key] === 'foreign key' ? tableForeignKeys[value.key] : undefined, + autofocus: autofocusField === value.key }" [ndcDynamicOutputs]="{ onFieldChange: { handler: updateField, args: ['$event', value.key] } diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts b/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts index 177217d3a..9cf3775b2 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Inject, KeyValueDiffers, KeyValueDiffer } from '@angular/core'; +import { Component, OnInit, AfterViewInit, Inject, KeyValueDiffers, KeyValueDiffer } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { CommonModule } from '@angular/common'; import { ReactiveFormsModule, FormsModule } from '@angular/forms'; @@ -48,7 +48,7 @@ import { Angulartics2OnModule } from 'angulartics2'; ContentLoaderComponent ] }) -export class DbTableFiltersDialogComponent implements OnInit { +export class DbTableFiltersDialogComponent implements OnInit, AfterViewInit { public tableFilters = []; public fieldSearchControl = new FormControl(''); @@ -67,6 +67,7 @@ export class DbTableFiltersDialogComponent implements OnInit { public tableWidgets: object; public tableWidgetsList: string[] = []; public UIwidgets = UIwidgets; + public autofocusField: string | null = null; constructor( @Inject(MAT_DIALOG_DATA) public data: any, @@ -91,6 +92,11 @@ export class DbTableFiltersDialogComponent implements OnInit { return {[field.column_name]: field}; })); + // Set autofocus field if provided + if (this.data.autofocusField) { + this.autofocusField = this.data.autofocusField; + } + const queryParams = this.route.snapshot.queryParams; // If saved_filter is present in queryParams, show empty form without applying filters @@ -124,10 +130,71 @@ export class DbTableFiltersDialogComponent implements OnInit { this.data.structure.widgets.length && this.setWidgets(this.data.structure.widgets); + // If autofocusField is provided, ensure it's in the filters list + if (this.autofocusField && !this.tableFilters.includes(this.autofocusField)) { + this.tableFilters.push(this.autofocusField); + if (!this.tableRowFieldsShown[this.autofocusField]) { + this.tableRowFieldsShown[this.autofocusField] = undefined; + } + if (!this.tableRowFieldsComparator[this.autofocusField]) { + this.tableRowFieldsComparator[this.autofocusField] = 'eq'; + } + } + this.foundFields = this.fieldSearchControl.valueChanges.pipe( startWith(''), map(value => this._filter(value || '')), ); + + } + + ngAfterViewInit(): void { + // Set focus on the autofocus field after view is initialized + if (this.autofocusField) { + setTimeout(() => { + this.focusOnField(this.autofocusField); + }, 200); + } + } + + focusOnField(fieldName: string) { + // Try multiple selectors to find the input field + const selectors = [ + `input[name*="${fieldName}"]`, + `textarea[name*="${fieldName}"]`, + `[data-field="${fieldName}"] input`, + `[data-field="${fieldName}"] textarea`, + `mat-form-field:has([name*="${fieldName}"]) input`, + `mat-form-field:has([name*="${fieldName}"]) textarea` + ]; + + for (const selector of selectors) { + try { + const element = document.querySelector(selector) as HTMLElement; + if (element) { + element.focus(); + element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + return; + } + } catch (e) { + // Continue to next selector if this one fails + } + } + + // Fallback: try to find by key attribute in ndc-dynamic components + const allInputs = document.querySelectorAll('input, textarea'); + for (let i = 0; i < allInputs.length; i++) { + const input = allInputs[i] as HTMLElement; + const formField = input.closest('mat-form-field'); + if (formField) { + const label = formField.querySelector('mat-label'); + if (label && label.textContent && label.textContent.trim() === fieldName) { + input.focus(); + input.scrollIntoView({ behavior: 'smooth', block: 'center' }); + return; + } + } + } } private _filter(value: string): string[] { diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css index ab329f243..f5638d75d 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css @@ -177,6 +177,29 @@ margin-bottom: 12px; } +::ng-deep .active-filters .mat-mdc-chip { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + --mdc-chip-container-shape-radius: 16px !important; + background-color: #E8ECEE !important; + border-radius: 16px !important; +} + +::ng-deep .active-filters .mat-mdc-chip:hover { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; +} + +::ng-deep .active-filters .mdc-evolution-chip__cell { + background-color: #E8ECEE !important; + border-radius: 16px !important; +} + +::ng-deep .active-filters .mdc-evolution-chip__cell:hover { + background-color: #E8ECEE !important; +} + .empty-table-message { display: inline-block; margin-top: 40px; diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html index 936f95c19..cb27f8f7a 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html @@ -176,9 +176,11 @@

{{ displayName }}

+ (removed)="removeFilter.emit(activeFilter.key)" + (click)="handleActiveFilterClick(activeFilter.key)"> {{ getFilter(activeFilter) }} - diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.ts b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.ts index c5279a681..fc2c80272 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.ts @@ -13,6 +13,7 @@ import { CommonModule } from '@angular/common'; import { ConnectionsService } from 'src/app/services/connections.service'; import { DbTableExportDialogComponent } from './db-table-export-dialog/db-table-export-dialog.component'; import { DbTableImportDialogComponent } from './db-table-import-dialog/db-table-import-dialog.component'; +import { DbTableFiltersDialogComponent } from './db-table-filters-dialog/db-table-filters-dialog.component'; import { DragDropModule } from '@angular/cdk/drag-drop'; import { DynamicModule } from 'ng-dynamic-component'; import { ForeignKeyDisplayComponent } from '../../ui-components/table-display-fields/foreign-key/foreign-key.component'; @@ -279,6 +280,39 @@ export class DbTableViewComponent implements OnInit { this.searchString = ''; } + handleActiveFilterClick(filterKey: string) { + const dialogRef = this.dialog.open(DbTableFiltersDialogComponent, { + width: '56em', + data: { + connectionID: this.connectionID, + tableName: this.name, + displayTableName: this.displayName, + structure: { + structure: this.tableData.structure, + foreignKeys: this.tableData.foreignKeys, + foreignKeysList: this.tableData.foreignKeysList, + widgets: this.tableData.widgets + }, + autofocusField: filterKey + } + }); + + dialogRef.afterClosed().subscribe(action => { + if (action === 'filter') { + const filtersFromDialog = {...dialogRef.componentInstance.tableRowFieldsShown}; + const comparators = dialogRef.componentInstance.tableRowFieldsComparator; + this.openFilters.emit({ + structure: this.tableData.structure, + foreignKeysList: this.tableData.foreignKeysList, + foreignKeys: this.tableData.foreignKeys, + widgets: this.tableData.widgets, + filters: filtersFromDialog, + comparators: comparators + }); + } + }); + } + handleSearch() { this.searchString = this.searchString.trim(); this.staticSearchString = this.searchString; diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css index a27ec9c1e..5acd7b4c3 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css @@ -109,3 +109,16 @@ font-style: italic; margin: 16px 0; } + +.comparator-icon { + font-size: 18px; + width: 18px; + height: 18px; + margin-right: 8px; + vertical-align: middle; +} + +::ng-deep .mat-mdc-select-panel .mat-mdc-option { + display: flex; + align-items: center; +} diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html index 843615c44..064783142 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html @@ -80,22 +80,28 @@

Conditions & main column

[(ngModel)]="tableRowFieldsComparator[value.key]" (ngModelChange)="updateComparator($event, value.key)"> - starts with + play_arrow + starts with - ends with + play_arrow + ends with - equal + drag_handle + equal - contains + search + contains - not contains + block + not contains - is empty + space_bar + is empty @@ -106,19 +112,24 @@

Conditions & main column

[(ngModel)]="tableRowFieldsComparator[value.key]" (ngModelChange)="updateComparator($event, value.key)"> - equal + drag_handle + equal - greater than + keyboard_arrow_right + greater than - less than + keyboard_arrow_left + less than - greater than or equal + keyboard_double_arrow_right + greater than or equal - less than or equal + keyboard_double_arrow_left + less than or equal diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts index ecf219811..56e99d4b4 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts @@ -213,6 +213,22 @@ export class SavedFiltersDialogComponent implements OnInit { } } + 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'; + } + removeFilter(field) { delete this.tableRowFieldsShown[field]; delete this.tableRowFieldsComparator[field]; diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css index 4e50b5293..c1565bad9 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css @@ -47,6 +47,94 @@ --mdc-chip-elevated-selected-container-color: var(--color-accentedPalette-500) !important; --mdc-chip-container-height: 32px; --mdc-chip-label-text-color: rgba(0,0,0,0.64); + --mdc-chip-selected-container-shape-leading-width: 0px; + --mdc-chip-with-icon-graphic-selected-container-shape-leading-width: 0px; + --mdc-chip-with-icon-graphic-selected-container-shape-leading-start-width: 0px; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-standard-chip.mdc-evolution-chip--selected { + --mdc-chip-selected-container-elevation-shadow: none; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-standard-chip .mdc-evolution-chip__checkmark { + display: none !important; + width: 0 !important; + min-width: 0 !important; + margin: 0 !important; + padding: 0 !important; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-standard-chip .mdc-evolution-chip__checkmark-svg { + display: none !important; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-standard-chip .mdc-evolution-chip__graphic { + display: none !important; + width: 0 !important; + min-width: 0 !important; + margin: 0 !important; + padding: 0 !important; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-standard-chip .mdc-evolution-chip__action { + padding-left: 16px !important; + padding-right: 8px !important; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-standard-chip.mdc-evolution-chip--selected .mdc-evolution-chip__action { + padding-left: 16px !important; + padding-right: 8px !important; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-standard-chip.mdc-evolution-chip--selected .mdc-evolution-chip__action .mdc-evolution-chip__action__content { + margin-left: 0 !important; + padding-left: 0 !important; + transform: translateX(0) !important; +} + +.saved-filters-tabs ::ng-deep .filter-chip-wrapper { + display: flex; + align-items: center; + gap: 4px; +} + +.saved-filters-tabs ::ng-deep .mat-mdc-chip-action { + display: flex; + align-items: center; +} + +.saved-filters-tabs ::ng-deep .mdc-evolution-chip__action { + display: flex; + align-items: center; + justify-content: flex-start; +} + +.saved-filters-tabs ::ng-deep .mdc-evolution-chip__text-label { + display: flex; + align-items: center; + line-height: 1; +} + +.filter-chip-content { + display: inline-block; + vertical-align: middle; + line-height: 1; +} + +.filter-chip-menu-button { + opacity: 1; + width: 24px; + height: 24px; + line-height: 24px; + flex-shrink: 0; + margin-left: auto; + margin-right: -4px; +} + +.filter-chip-menu-button mat-icon { + font-size: 18px; + width: 18px; + height: 18px; } @media (prefers-color-scheme: light) { @@ -81,6 +169,29 @@ .column-name { margin-top: -8px; + display: flex; + align-items: center; + gap: 4px; +} + +.column-name-icon { + font-size: 16px; + width: 16px; + height: 16px; + line-height: 16px; +} + +.comparator-icon { + font-size: 18px; + width: 18px; + height: 18px; + margin-right: 8px; + vertical-align: middle; +} + +::ng-deep .mat-mdc-select-panel .mat-mdc-option { + display: flex; + align-items: center; } @media (prefers-color-scheme: light) { @@ -120,6 +231,112 @@ .static-filter-chip { cursor: default; + pointer-events: none; +} + +::ng-deep .static-filter-chip .mat-mdc-chip { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + --mdc-chip-container-shape-radius: 16px !important; + background-color: #E8ECEE !important; + border-radius: 16px !important; + pointer-events: none !important; + cursor: default !important; +} + +::ng-deep .static-filter-chip .mat-mdc-chip:hover { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + cursor: default !important; +} + +::ng-deep .static-filter-chip .mat-mdc-chip:active { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + cursor: default !important; +} + +::ng-deep .static-filter-chip .mdc-evolution-chip__cell { + background-color: #E8ECEE !important; + border-radius: 16px !important; +} + +::ng-deep .static-filter-chip .mdc-evolution-chip__cell:hover { + background-color: #E8ECEE !important; +} + +::ng-deep .static-filter-chip .mat-mdc-chip.mdc-evolution-chip--with-primary-icon { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + pointer-events: none !important; +} + +::ng-deep .static-filter-chip .mat-mdc-chip.mdc-evolution-chip--with-primary-icon:hover { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + cursor: default !important; +} + +::ng-deep .static-filter-chip .mat-mdc-chip.mdc-evolution-chip--with-primary-icon:active { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + cursor: default !important; +} + +::ng-deep .static-filter-chip .mdc-evolution-chip__action { + pointer-events: none !important; + cursor: default !important; +} + +@media (prefers-color-scheme: dark) { + ::ng-deep .static-filter-chip .mat-mdc-chip { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + } + + ::ng-deep .static-filter-chip .mat-mdc-chip:hover { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + } + + ::ng-deep .static-filter-chip .mat-mdc-chip:active { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + } + + ::ng-deep .static-filter-chip .mdc-evolution-chip__cell { + background-color: #E8ECEE !important; + } + + ::ng-deep .static-filter-chip .mdc-evolution-chip__cell:hover { + background-color: #E8ECEE !important; + } + + ::ng-deep .static-filter-chip .mat-mdc-chip.mdc-evolution-chip--with-primary-icon { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + } + + ::ng-deep .static-filter-chip .mat-mdc-chip.mdc-evolution-chip--with-primary-icon:hover { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + } + + ::ng-deep .static-filter-chip .mat-mdc-chip.mdc-evolution-chip--with-primary-icon:active { + --mdc-chip-container-color: #E8ECEE !important; + --mdc-chip-elevated-container-color: #E8ECEE !important; + background-color: #E8ECEE !important; + } } /* .dynamic-column-editor + .static-filters { diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html index 3ea37f474..fc7e2e521 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html @@ -13,38 +13,49 @@ - - - - - {{ filter.name }} + (click)="selectFiltersSet(filter.id)" + class="filter-chip-wrapper"> + {{ filter.name }} + + + + +
- where + + subdirectory_arrow_right + where {{ savedFilterMap[selectedFilterSetId]?.dynamicColumn.column }} @@ -53,12 +64,30 @@ - starts with - ends with - equal - contains - not contains - is empty + + play_arrow + starts with + + + play_arrow + ends with + + + drag_handle + equal + + + search + contains + + + block + not contains + + + space_bar + is empty + @@ -66,11 +95,26 @@ - equal - greater than - less than - greater than or equal - less than or equal + + drag_handle + equal + + + keyboard_arrow_right + greater than + + + keyboard_arrow_left + less than + + + keyboard_double_arrow_right + greater than or equal + + + keyboard_double_arrow_left + less than or equal + diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.ts b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.ts index f2eea469e..22e248848 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.ts @@ -69,6 +69,7 @@ export class SavedFiltersPanelComponent implements OnInit, OnDestroy { public selectedFilterSetId: string | null = null; public selectedFilter: any = null; public shouldAutofocus: boolean = false; + public currentFilterForMenu: any = null; public tableStructure: any = null; public tableRowFieldsShown: { [key: string]: any } = {}; @@ -264,6 +265,29 @@ export class SavedFiltersPanelComponent implements OnInit, OnDestroy { // when 'filters set updated' is received } + setCurrentFilter(filter: any) { + this.currentFilterForMenu = filter; + } + + handleEditFilter(filter: any) { + if (filter) { + this.handleOpenSavedFiltersDialog(filter); + } + } + + handleDeleteFilter(filter: any) { + if (filter) { + this._tables.deleteSavedFilter(this.connectionID, this.selectedTableName, filter.id).subscribe({ + next: () => { + // The deletion will trigger 'delete saved filters' event which will refresh the list + }, + error: (error) => { + console.error('Error deleting filter:', error); + } + }); + } + } + getFilterEntries(filters: any): { column: string; operator: string; value: string }[] { if (!filters) return []; @@ -371,6 +395,22 @@ export class SavedFiltersPanelComponent implements OnInit, OnDestroy { this.selectedFilter = entry; } + 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'; + } + getFilter(activeFilter: {column: string, operator: string, value: any}) { const displayedName = normalizeTableName(activeFilter.column); const comparator = activeFilter.operator; diff --git a/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts b/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts index fe8eb408e..e69de29bb 100644 --- a/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts +++ b/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts @@ -1,20 +0,0 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { TableField, WidgetStructure } from 'src/app/models/table'; - -import { CommonModule } from '@angular/common'; - -@Component({ - selector: 'app-base-record-view-field', - templateUrl: './base-record-view-field.component.html', - styleUrls: ['./base-record-view-field.component.css'], - imports: [CommonModule] -}) -export class BaseRecordViewFieldComponent { - @Input() key: string; - @Input() value: any; - @Input() structure: TableField; - @Input() widgetStructure: WidgetStructure; - // @Input() relations: TableForeignKey; - - @Output() onCopyToClipboard = new EventEmitter(); -} From 13b924f963709e300ddfceaa2c086c5a7ceae7f7 Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Wed, 19 Nov 2025 20:10:11 +0200 Subject: [PATCH 02/13] fixed --- .../custom-agent-repository-extension.ts | 2 ++ .../db-table-filters-dialog.component.ts | 6 ++++-- .../db-table-row-view.component.html | 1 - .../db-table-view/db-table-view.component.ts | 4 ++-- .../base-record-view-field.component.ts | 15 +++++++++++++++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/backend/src/entities/agent/repository/custom-agent-repository-extension.ts b/backend/src/entities/agent/repository/custom-agent-repository-extension.ts index ef832a3f4..7e0ea551b 100644 --- a/backend/src/entities/agent/repository/custom-agent-repository-extension.ts +++ b/backend/src/entities/agent/repository/custom-agent-repository-extension.ts @@ -65,6 +65,8 @@ export const customAgentRepositoryExtension = { return 'CASSANDRA-TEST-AGENT-TOKEN'; case ConnectionTypeTestEnum.agent_redis: return 'REDIS-TEST-AGENT-TOKEN'; + default: + throw new Error(`Unsupported connection type for test agent token: ${connectionType}`); } }, }; diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts b/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts index 9cf3775b2..e1573fa28 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-filters-dialog/db-table-filters-dialog.component.ts @@ -128,10 +128,12 @@ export class DbTableFiltersDialogComponent implements OnInit, AfterViewInit { } } - this.data.structure.widgets.length && this.setWidgets(this.data.structure.widgets); + if (this.data.structure.widgets && this.data.structure.widgets.length) { + this.setWidgets(this.data.structure.widgets); + } // If autofocusField is provided, ensure it's in the filters list - if (this.autofocusField && !this.tableFilters.includes(this.autofocusField)) { + if (this.autofocusField && this.tableFilters && !this.tableFilters.includes(this.autofocusField)) { this.tableFilters.push(this.autofocusField); if (!this.tableRowFieldsShown[this.autofocusField]) { this.tableRowFieldsShown[this.autofocusField] = undefined; diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-row-view/db-table-row-view.component.html b/frontend/src/app/components/dashboard/db-table-view/db-table-row-view/db-table-row-view.component.html index f88494d7e..16e0dbbf5 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-row-view/db-table-row-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-row-view/db-table-row-view.component.html @@ -85,7 +85,6 @@

Preview

{ - if (action === 'filter') { + if (action === 'filter' && dialogRef.componentInstance) { const filtersFromDialog = {...dialogRef.componentInstance.tableRowFieldsShown}; const comparators = dialogRef.componentInstance.tableRowFieldsComparator; this.openFilters.emit({ diff --git a/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts b/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts index e69de29bb..b5d157c98 100644 --- a/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts +++ b/frontend/src/app/components/ui-components/record-view-fields/base-record-view-field/base-record-view-field.component.ts @@ -0,0 +1,15 @@ +import { Component, Input } from '@angular/core'; +import { WidgetStructure, TableField } from '../../../../models/table'; + +@Component({ + selector: 'app-base-record-view-field', + template: '', + styles: [] +}) +export class BaseRecordViewFieldComponent { + @Input() value: any; + @Input() key: string; + @Input() widgetStructure: WidgetStructure; + @Input() structure: TableField; +} + From a84e6841bfb9c7508e1060ae50027b62553ad0a2 Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Wed, 19 Nov 2025 20:22:44 +0200 Subject: [PATCH 03/13] =?UTF-8?q?=D1=86=D1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../saved-filters-panel/saved-filters-panel.component.css | 5 ++++- .../saved-filters-panel/saved-filters-panel.component.html | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css index c1565bad9..a018bf04a 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css @@ -7,13 +7,16 @@ .saved-filters-list { display: flex; align-items: center; - gap: 16px; + gap: 8px; } .saved-filters-list__first-time-button { transition: background 0.3s ease; } +.create-filter-button { +} + @media (prefers-color-scheme: light) { .saved-filters-list__first-time-button { background: var(--color-accentedPalette-50); diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html index fc7e2e521..d339f69c3 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html @@ -13,6 +13,7 @@
+ + + + + + @@ -75,7 +89,8 @@

Conditions & editable column

{{value.key}} + appearance="outline" + class="comparator-select-field"> @@ -107,7 +122,8 @@

Conditions & editable column

+ appearance="outline" + class="comparator-select-field"> @@ -161,6 +177,16 @@

Conditions & editable column

close
+ + + diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts index 6beed6692..643efb945 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts @@ -1,7 +1,7 @@ import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { CommonModule } from '@angular/common'; -import { Component, Inject, Input, OnInit, AfterViewInit, ElementRef } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, Inject, Input, OnInit } from '@angular/core'; import { DynamicModule } from 'ng-dynamic-component'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; @@ -69,6 +69,7 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { public tableWidgetsList: string[] = []; public UIwidgets = UIwidgets; public dynamicColumn: string | null = null; + public showAddConditionField = false; constructor( @Inject(MAT_DIALOG_DATA) public data: any, @@ -77,7 +78,7 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { private dialogRef: MatDialogRef, private snackBar: MatSnackBar, private angulartics2: Angulartics2, - private elementRef: ElementRef + private elementRef: ElementRef, ) {} ngOnInit(): void { @@ -139,6 +140,23 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { } } + get hasSelectedFilters(): boolean { + return Object.keys(this.tableRowFieldsShown).length > 0; + } + + handleAddConditionButtonClick(): void { + this.showAddConditionField = true; + setTimeout(() => { + const input = this.elementRef.nativeElement.querySelector('input[name="filter_columns"]') as HTMLInputElement; + input?.focus(); + }, 0); + } + + cancelAddConditionInput(): void { + this.showAddConditionField = false; + this.fieldSearchControl.setValue(''); + } + private _filter(value: string): string[] { return this.fields.filter((field: string) => field.toLowerCase().includes(value.toLowerCase())); } @@ -187,6 +205,20 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { this.tableRowFieldsComparator = {...this.tableRowFieldsComparator, [key]: this.tableRowFieldsComparator[key] || 'eq'}; this.fieldSearchControl.setValue(''); this.updateFiltersCount(); + if (this.hasSelectedFilters) { + this.showAddConditionField = false; + } + } + + handleInputBlur(): void { + // Hide the field if it's empty when it loses focus + if (!this.fieldSearchControl.value || this.fieldSearchControl.value.trim() === '') { + setTimeout(() => { + if (!this.fieldSearchControl.value || this.fieldSearchControl.value.trim() === '') { + this.cancelAddConditionInput(); + } + }, 200); + } } updateComparator(event, fieldName: string) { @@ -249,6 +281,9 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { this.dynamicColumn = null; } this.updateFiltersCount(); + if (!this.hasSelectedFilters) { + this.showAddConditionField = false; + } } updateFiltersCount() { From eb5cf78afcf0eaa1d1695189646e29dd85ee27b8 Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Fri, 19 Dec 2025 13:26:45 +0200 Subject: [PATCH 06/13] 1 --- .../saved-filters-dialog.component.css | 12 ++++ .../saved-filters-dialog.component.html | 64 +++++++++++++++++-- .../saved-filters-dialog.component.ts | 60 ++++++++++++++++- 3 files changed, 130 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css index a11cea502..12a13f5e9 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css @@ -118,6 +118,10 @@ grid-column: 1 / -1; } +.full-width.filter-name-field { + max-width: 400px; +} + .default-filter-checkbox { margin-bottom: 16px; } @@ -202,3 +206,11 @@ min-width: max-content !important; width: max-content !important; } + +.conditions-error-message { + grid-column: 1 / span 6; + color: #f44336; + font-size: 12px; + margin: 8px 0 0 0; + padding-left: 16px; +} diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html index 1b37adbd3..9a9b3ef61 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html @@ -6,12 +6,13 @@

- + Fast filter name - + [(ngModel)]="data.filtersSet.name" + (input)="showNameError = false"> + Fast filter name is required @@ -47,7 +48,32 @@

Conditions & editable column

- + + Click here to add condition + + + + {{field}} + + + + + At least one condition is required + + @@ -183,8 +209,36 @@

Conditions & editable column

add condition - + + Click here to add condition + + + + {{field}} + + + + + At least one condition is required + + +

+ At least one condition is required +

diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts index 643efb945..c2d4978b2 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts @@ -1,7 +1,7 @@ import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { CommonModule } from '@angular/common'; -import { AfterViewInit, Component, ElementRef, Inject, Input, OnInit } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, Inject, Input, OnInit, ViewChild } from '@angular/core'; import { DynamicModule } from 'ng-dynamic-component'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; @@ -70,6 +70,10 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { public UIwidgets = UIwidgets; public dynamicColumn: string | null = null; public showAddConditionField = false; + public showNameError = false; + public showConditionsError = false; + + @ViewChild('tableFiltersForm') tableFiltersForm: any; constructor( @Inject(MAT_DIALOG_DATA) public data: any, @@ -197,6 +201,10 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { updateField = (updatedValue: any, field: string) => { this.tableRowFieldsShown[field] = updatedValue; this.updateFiltersCount(); + // Reset conditions error when a filter is added + if (this.showConditionsError && Object.keys(this.tableRowFieldsShown).length > 0) { + this.showConditionsError = false; + } } addFilter(e) { @@ -205,6 +213,8 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { this.tableRowFieldsComparator = {...this.tableRowFieldsComparator, [key]: this.tableRowFieldsComparator[key] || 'eq'}; this.fieldSearchControl.setValue(''); this.updateFiltersCount(); + // Reset conditions error when a filter is added + this.showConditionsError = false; if (this.hasSelectedFilters) { this.showAddConditionField = false; } @@ -281,6 +291,8 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { this.dynamicColumn = null; } this.updateFiltersCount(); + // Reset conditions error when filters are removed (will be re-validated on save) + this.showConditionsError = false; if (!this.hasSelectedFilters) { this.showAddConditionField = false; } @@ -299,6 +311,52 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { } handleSaveFilters() { + // Reset error flags + this.showNameError = false; + this.showConditionsError = false; + + // Validate filter name + if (!this.data.filtersSet.name || this.data.filtersSet.name.trim() === '') { + this.showNameError = true; + setTimeout(() => { + const nameInput = this.elementRef.nativeElement.querySelector('input[name="filters_set_name"]') as HTMLInputElement; + if (nameInput) { + nameInput.focus(); + nameInput.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + }, 0); + return; + } + + // Validate conditions - check if there are any filters (excluding dynamic column) + // A valid filter must have a comparator defined + const hasFilters = Object.keys(this.tableRowFieldsShown).some(key => { + // Skip dynamic column as it's not a filter condition + if (key === this.dynamicColumn) { + return false; + } + // Check if comparator is defined (even if value is empty/null, comparator must exist) + return this.tableRowFieldsComparator[key] !== undefined && this.tableRowFieldsComparator[key] !== null; + }); + + if (!hasFilters) { + this.showConditionsError = true; + setTimeout(() => { + const conditionInput = this.elementRef.nativeElement.querySelector('input[name="filter_columns"]') as HTMLInputElement; + if (conditionInput) { + conditionInput.focus(); + 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; + if (addButton) { + addButton.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + } + }, 0); + return; + } + let payload; if (Object.keys(this.tableRowFieldsShown).length) { let filters = {}; From 5b6f9a107ff8f7cea54c4aaec656d7662cabaace Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Fri, 19 Dec 2025 22:32:04 +0200 Subject: [PATCH 07/13] arrow and where --- .../saved-filters-dialog.component.css | 180 +++++++++++++++--- .../saved-filters-dialog.component.html | 63 ++---- 2 files changed, 175 insertions(+), 68 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css index 12a13f5e9..a49e52519 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css @@ -1,6 +1,6 @@ .filters-content { display: grid; - grid-template-columns: auto 228px 0 1fr 120px 32px; + grid-template-columns: 32px auto 228px 0 1fr 120px; grid-column-gap: 8px; align-content: flex-start; align-items: flex-start; @@ -8,22 +8,114 @@ } .filters-select { - grid-column: 1 / span 6; + grid-column: 2 / span 5; margin-bottom: 16px; } .filter-line { - grid-column: 1 / span 4; + grid-column: 2 / span 4; +} + +.empty-conditions-container { + grid-column: 1 / span 6; + display: flex; + align-items: center; + gap: 12px; + margin-top: 8px; + margin-bottom: 16px; +} + +.where-label { + font-weight: 500; + color: rgba(0, 0, 0, 0.87); + white-space: nowrap; +} + +@media (prefers-color-scheme: dark) { + .where-label { + color: rgba(255, 255, 255, 0.87); + } +} + +.empty-conditions-container .add-condition-button { + width: auto; + min-width: auto; + min-height: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + text-transform: none; + margin: 0 !important; + padding: 0 16px; + gap: 4px; +} + +.empty-conditions-container .add-condition-button.accent-button { + color: #C177FC; +} + +.empty-conditions-container .add-condition-button.accent-button:hover { + background-color: rgba(193, 119, 252, 0.04); +} + +.empty-conditions-container .add-condition-button.accent-button .add-icon { + font-size: 20px; + width: 20px; + height: 20px; + line-height: 20px; +} + +.empty-conditions-container .column-name-icon { + font-size: 18px; + width: 18px; + height: 18px; + vertical-align: middle; +} + +.empty-condition-input { + width: auto; + min-width: 200px; + max-width: 300px; + margin: 0; + flex-shrink: 0; +} + +.empty-condition-input ::ng-deep .mat-mdc-form-field-infix { + min-height: 36px; + padding-top: 8px; + padding-bottom: 8px; + display: flex; + align-items: center; +} + +.empty-condition-input ::ng-deep .mat-mdc-form-field { + margin: 0; +} + +.empty-condition-input ::ng-deep .mat-mdc-text-field-wrapper { + padding-bottom: 0; + margin-bottom: 0; +} + +.empty-condition-input ::ng-deep .mat-mdc-form-field-subscript-wrapper { + margin-top: 0; + position: absolute; + top: 100%; } .dynamic-column-radio { - grid-column: 5; + grid-column: 6; margin-top: 8px; } +.comparator-select-field { + grid-column: 3; +} + .add-condition-footer { grid-column: 1 / span 6; - margin-top: 16px; + margin-top: 24px; display: flex; flex-direction: column; justify-content: flex-start; @@ -32,22 +124,39 @@ } .add-condition-footer button { - width: 50%; - min-height: 44px; - height: 44px; + width: auto; + min-width: auto; + min-height: 36px; + height: 36px; display: flex; align-items: center; justify-content: center; text-transform: none; - margin: 0 !important; - padding: 0; + margin: 0 0 16px 0 !important; + padding: 0 16px; } .add-condition-footer .filters-select { - width: 50%; + width: auto; + min-width: 200px; + max-width: 300px; margin: 0 !important; - min-height: 44px; + min-height: 36px; margin-top: 0 !important; + flex-shrink: 0; +} + +.add-condition-footer .filters-select ::ng-deep .mat-mdc-form-field-infix { + min-height: 36px; + padding-top: 8px; + padding-bottom: 8px; + display: flex; + align-items: center; +} + +.add-condition-footer .filters-select ::ng-deep .mat-mdc-text-field-wrapper { + padding-bottom: 0; + margin-bottom: 0; } .add-condition-footer ::ng-deep .mat-mdc-form-field { @@ -142,17 +251,16 @@ display: flex; } -.filters-content { - flex: 1 0 auto; -} - .column-name { + grid-column: 2; margin-top: 12px; } .filter-delete-button { + grid-column: 1; margin-top: 4px; - margin-left: 8px; + margin-right: 8px; + align-self: flex-start; } .settings-form__reset-button { @@ -181,25 +289,37 @@ .comparator-select-field { width: auto; - min-width: fit-content; - max-width: fit-content; + min-width: 140px; + max-width: none; } .comparator-select-field ::ng-deep .mat-mdc-form-field-infix { - width: auto !important; + width: 100% !important; min-width: fit-content; - padding-right: 12px; + padding-right: 40px; padding-left: 0; + position: relative; } .comparator-select-field ::ng-deep .mat-mdc-select-trigger { - width: auto; + width: 100%; min-width: fit-content; + display: flex; + justify-content: space-between; + align-items: center; } .comparator-select-field ::ng-deep .mat-mdc-select-value-text { width: auto; min-width: fit-content; + flex: 1; +} + +.comparator-select-field ::ng-deep .mat-mdc-select-arrow-wrapper { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); } .comparator-select-field ::ng-deep .mat-mdc-select-panel { @@ -214,3 +334,19 @@ margin: 8px 0 0 0; padding-left: 16px; } + +/* Add more spacing for multiline textarea inputs (more than 2 rows) */ +.filters-content ::ng-deep .filter-line mat-form-field:has(textarea[rows]):not(:has(textarea[rows="1"])):not(:has(textarea[rows="2"])), +.filters-content ::ng-deep .filter-line mat-form-field:has(textarea.long-textarea), +.filters-content ::ng-deep .filter-line mat-form-field:has(textarea.form-textarea) { + margin-top: 24px !important; + margin-bottom: 24px !important; +} + +/* Add more spacing for foreign key fields */ +.filters-content ::ng-deep .filter-line .foreign-key, +.filters-content ::ng-deep .filter-line app-edit-foreign-key, +.filters-content ::ng-deep .foreign-key { + margin-top: 24px !important; + margin-bottom: 24px !important; +} diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html index 9a9b3ef61..c3d5ec22b 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html @@ -47,8 +47,14 @@

Conditions & editable column

- - +
+ subdirectory_arrow_right + where + + Click here to add condition Conditions & editable column At least one condition is required - +

+ At least one condition is required +

+
+
@@ -197,50 +211,7 @@

Conditions & editable column

Use for editing
- - - - From 8ef3b9cf717e9c50a14e206ddabf28947be6e22b Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Mon, 22 Dec 2025 14:27:58 +0200 Subject: [PATCH 08/13] // --- .../saved-filters-dialog.component.css | 79 ++++++++++++++++-- .../saved-filters-dialog.component.html | 81 ++++++++++--------- .../saved-filters-dialog.component.ts | 2 + .../saved-filters-panel.component.css | 42 +++++++++- .../saved-filters-panel.component.html | 16 ++-- 5 files changed, 163 insertions(+), 57 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css index a49e52519..e5110d361 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css @@ -7,6 +7,11 @@ padding-top: 4px !important; } +::ng-deep mat-dialog-content.filters-content { + padding-left: 24px !important; + padding-right: 24px !important; +} + .filters-select { grid-column: 2 / span 5; margin-bottom: 16px; @@ -25,6 +30,15 @@ margin-bottom: 16px; } +.add-condition-container { + grid-column: 1 / span 6; + display: flex; + align-items: center; + gap: 12px; + margin-top: 8px; + margin-bottom: 16px; +} + .where-label { font-weight: 500; color: rgba(0, 0, 0, 0.87); @@ -37,7 +51,7 @@ } } -.empty-conditions-container .add-condition-button { +.add-condition-button { width: auto; min-width: auto; min-height: 36px; @@ -51,15 +65,15 @@ gap: 4px; } -.empty-conditions-container .add-condition-button.accent-button { +.add-condition-button.accent-button { color: #C177FC; } -.empty-conditions-container .add-condition-button.accent-button:hover { +.add-condition-button.accent-button:hover { background-color: rgba(193, 119, 252, 0.04); } -.empty-conditions-container .add-condition-button.accent-button .add-icon { +.add-condition-button.accent-button .add-icon { font-size: 20px; width: 20px; height: 20px; @@ -247,6 +261,24 @@ flex-direction: column; } +.filters-header-description { + margin: 0 24px 16px 24px; + font-size: 14px; + line-height: 1.5; +} + +@media (prefers-color-scheme: light) { + .filters-header-description { + color: rgba(0, 0, 0, 0.6); + } +} + +@media (prefers-color-scheme: dark) { + .filters-header-description { + color: rgba(255, 255, 255, 0.6); + } +} + ::ng-deep .mat-dialog-container { display: flex; } @@ -256,11 +288,44 @@ margin-top: 12px; } +.conditions-vertical-line { + grid-column: 1; + grid-row: 2 / -1; + width: 1px; + background-color: rgba(0, 0, 0, 0.12); + margin-left: 9px; + margin-top: 0; + margin-bottom: 0; + z-index: 0; +} + +@media (prefers-color-scheme: dark) { + .conditions-vertical-line { + background-color: rgba(255, 255, 255, 0.12); + } +} + .filter-delete-button { grid-column: 1; margin-top: 4px; - margin-right: 8px; + margin-right: 0; + margin-left: 0; align-self: flex-start; + justify-self: center; + position: relative; + z-index: 1; + width: 18px; + height: 18px; + display: flex; + align-items: center; + justify-content: center; +} + +.filter-delete-button ::ng-deep .mat-icon { + font-size: 18px; + width: 18px; + height: 18px; + line-height: 18px; } .settings-form__reset-button { @@ -307,6 +372,7 @@ display: flex; justify-content: space-between; align-items: center; + position: relative; } .comparator-select-field ::ng-deep .mat-mdc-select-value-text { @@ -317,9 +383,10 @@ .comparator-select-field ::ng-deep .mat-mdc-select-arrow-wrapper { position: absolute; - right: 0; + right: 12px; top: 50%; transform: translateY(-50%); + pointer-events: none; } .comparator-select-field ::ng-deep .mat-mdc-select-panel { diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html index c3d5ec22b..431e6f0be 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.html @@ -2,6 +2,9 @@

New fast filter for {{ data.displayTableName }}

+

+ Use conditions to quickly filter {{ data.displayTableName.toLowerCase() }} and optionally edit one column. +

@@ -17,11 +20,6 @@

-

Conditions & editable column

-

- Add conditions and choose one column to use for editing. Only one editable column can be selected. -

- Click here to add condition @@ -50,42 +48,10 @@

Conditions & editable column

subdirectory_arrow_right where - - - Click here to add condition - - - - {{field}} - - - - - At least one condition is required - - -

- At least one condition is required -

+
+ + +
+ + + Click here to add condition + + + + {{field}} + + + + + At least one condition is required + + +

+ At least one condition is required +

+
diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts index c2d4978b2..eb8f9713a 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts @@ -6,6 +6,7 @@ import { DynamicModule } from 'ng-dynamic-component'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatButtonModule } from '@angular/material/button'; import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatRadioModule } from '@angular/material/radio'; import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; @@ -37,6 +38,7 @@ import { Angulartics2, Angulartics2OnModule } from 'angulartics2'; MatIconModule, MatSelectModule, MatCheckboxModule, + MatRadioModule, DynamicModule, RouterModule, MatDialogModule, diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css index a018bf04a..b551f0fcc 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css @@ -158,14 +158,45 @@ .filters-container { display: flex; + align-items: center; gap: 20px; transform: translateX(-10%) scale(0.8); } +.filters-where-label { + display: flex; + align-items: center; + gap: 4px; + font-weight: 500; + white-space: nowrap; + flex-shrink: 0; +} + +.filters-where-label .column-name-icon { + font-size: 18px; + width: 18px; + height: 18px; + line-height: 18px; + vertical-align: middle; +} + +@media (prefers-color-scheme: light) { + .filters-where-label { + color: rgba(0, 0, 0, 0.87); + } +} + +@media (prefers-color-scheme: dark) { + .filters-where-label { + color: rgba(255, 255, 255, 0.87); + } +} + .dynamic-column-editor { display: flex; align-items: center; gap: 16px; + margin-left: 0; /* transform: translateX(-20%) scale(0.8); */ /* transform-origin: center right; */ } @@ -175,13 +206,15 @@ display: flex; align-items: center; gap: 4px; + font-weight: 500; } .column-name-icon { - font-size: 16px; - width: 16px; - height: 16px; - line-height: 16px; + font-size: 18px; + width: 18px; + height: 18px; + line-height: 18px; + vertical-align: middle; } .comparator-icon { @@ -230,6 +263,7 @@ gap: 8px; transform: translateX(5%) scale(1.1); padding-bottom: 16px; + margin-left: 0; } .static-filter-chip { diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html index d339f69c3..25b7748ea 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.html @@ -50,16 +50,16 @@ -
+
+ + subdirectory_arrow_right + where + - - subdirectory_arrow_right - where - - {{ savedFilterMap[selectedFilterSetId]?.dynamicColumn.column }} - + + {{ savedFilterMap[selectedFilterSetId]?.dynamicColumn.column }}
-
+
{{ getFilter(filter) }} From eea5ef9bf80b8dabde7c566005bfb95af4db033b Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Mon, 22 Dec 2025 14:50:54 +0200 Subject: [PATCH 09/13] UI changes for saved filters dialog and environment config --- .../saved-filters-dialog.component.css | 12 +++++++----- frontend/src/environments/environment.dev.ts | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css index e5110d361..23558bf5b 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css @@ -3,7 +3,7 @@ grid-template-columns: 32px auto 228px 0 1fr 120px; grid-column-gap: 8px; align-content: flex-start; - align-items: flex-start; + align-items: center; padding-top: 4px !important; } @@ -120,7 +120,8 @@ .dynamic-column-radio { grid-column: 6; - margin-top: 8px; + margin-top: 0; + align-self: center; } .comparator-select-field { @@ -285,7 +286,8 @@ .column-name { grid-column: 2; - margin-top: 12px; + margin-top: 0; + align-self: center; } .conditions-vertical-line { @@ -307,10 +309,10 @@ .filter-delete-button { grid-column: 1; - margin-top: 4px; + margin-top: 0; margin-right: 0; margin-left: 0; - align-self: flex-start; + align-self: center; justify-self: center; position: relative; z-index: 1; diff --git a/frontend/src/environments/environment.dev.ts b/frontend/src/environments/environment.dev.ts index f01a9c447..72ed7a899 100644 --- a/frontend/src/environments/environment.dev.ts +++ b/frontend/src/environments/environment.dev.ts @@ -1,6 +1,6 @@ export const environment = { production: false, - saas: true, + saas: false, apiRoot: "https://app.rocketadmin.com/api", saasURL: "https://app.rocketadmin.com", saasHostnames: ['localhost'], From ee531d412dee7162d04cb636e19e94814d6b34a2 Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Tue, 23 Dec 2025 15:26:39 +0200 Subject: [PATCH 10/13] Enhance saved filters panel layout and improve validation logic in saved filters dialog --- .../saved-filters-dialog.component.ts | 14 ++++++++++---- .../saved-filters-panel.component.css | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts index eb8f9713a..98348e5d9 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.ts @@ -330,10 +330,11 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { return; } - // Validate conditions - check if there are any filters (excluding dynamic column) + // Validate conditions - check if there are any filters // A valid filter must have a comparator defined - const hasFilters = Object.keys(this.tableRowFieldsShown).some(key => { - // Skip dynamic column as it's not a filter condition + // Either regular filters OR dynamic column with comparator should exist + const hasRegularFilters = Object.keys(this.tableRowFieldsShown).some(key => { + // Skip dynamic column for regular filter check if (key === this.dynamicColumn) { return false; } @@ -341,7 +342,12 @@ export class SavedFiltersDialogComponent implements OnInit, AfterViewInit { return this.tableRowFieldsComparator[key] !== undefined && this.tableRowFieldsComparator[key] !== null; }); - if (!hasFilters) { + // Check if dynamic column has a comparator (it counts as a valid filter condition) + const hasDynamicColumnFilter = this.dynamicColumn && + this.tableRowFieldsComparator[this.dynamicColumn] !== undefined && + this.tableRowFieldsComparator[this.dynamicColumn] !== null; + + if (!hasRegularFilters && !hasDynamicColumnFilter) { this.showConditionsError = true; setTimeout(() => { const conditionInput = this.elementRef.nativeElement.querySelector('input[name="filter_columns"]') as HTMLInputElement; diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css index b551f0fcc..3c66078e6 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css @@ -2,6 +2,7 @@ display: flex; flex-direction: column; gap: 8px; + margin-bottom: 12px; } .saved-filters-list { From 399131d93986674fa1a72e64448a6fc553eebc3b Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Tue, 6 Jan 2026 14:27:30 +0200 Subject: [PATCH 11/13] Update saved filters panel styles: reset margin for column names and add comparator text styling --- .../db-table-view/db-table-view.component.css | 19 +++ .../db-table-view.component.html | 25 ++- .../db-table-view/db-table-view.component.ts | 152 ++++++++++-------- 3 files changed, 128 insertions(+), 68 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css index f5638d75d..63d756181 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css @@ -55,6 +55,25 @@ } } +.dashboard-toggle { + display: flex; + align-items: center; + margin-left: 16px; + margin-right: 8px; +} + +.dashboard-toggle .toggle-label { + margin-left: 8px; + font-size: 14px; +} + +@media (width <= 600px) { + .dashboard-toggle { + margin-left: 0; + margin-top: 8px; + } +} + .table-switcher-option ::ng-deep .mdc-list-item__primary-text { width: 100%; } diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html index cb27f8f7a..8e3542fba 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html @@ -25,6 +25,15 @@

{{ displayName }}

+
+ + Dashboard + +
+ @@ -186,7 +195,7 @@

{{ displayName }}

-{{ displayName }} (filterSelected)="onFilterSelected($event)" > -
+ + + + + +
-
+
", - lt: "<", - gte: ">=", - lte: "<=" - } - public selectedRow: TableRow = null; - public selectedRowType: 'record' | 'foreignKey' = 'record'; - public tableRelatedRecords: any = null; - public displayCellComponents; - public UIwidgets = UIwidgets; - // public tableTypes: object; + // public tablesSwitchControl = new FormControl(''); + public tableData: any; + public filteredTables: TableProperties[]; + // public selection: any; + public columns: Column[]; + public displayedColumns: string[] = []; + public columnsToDisplay: string[] = []; + public searchString: string; + public staticSearchString: string; + public actionsColumnWidth: string; + public bulkActions: CustomAction[]; + public bulkRows: string[]; + public displayedComparators = { + eq: '=', + gt: '>', + lt: '<', + gte: '>=', + lte: '<=', + }; + public selectedRow: TableRow = null; + public selectedRowType: 'record' | 'foreignKey' = 'record'; + public tableRelatedRecords: any = null; + public displayCellComponents; + public UIwidgets = UIwidgets; + // public tableTypes: object; @Input() set table(value){ if (value) this.tableData = value; @@ -628,10 +650,10 @@ export class DbTableViewComponent implements OnInit { const blob = new Blob([csvArray], { type: 'text/csv' }); const url = window.URL.createObjectURL(blob); - a.href = url; - a.download = 'myFile.csv'; - a.click(); - window.URL.revokeObjectURL(url); - a.remove(); - } + a.href = url; + a.download = 'myFile.csv'; + a.click(); + window.URL.revokeObjectURL(url); + a.remove(); + } } From 5ed54a97215e8ff2be65425669bd01ec558c408e Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Tue, 6 Jan 2026 14:46:07 +0200 Subject: [PATCH 12/13] fast filters (new editing) --- .../db-table-view/db-table-view.component.css | 19 -------- .../db-table-view.component.html | 24 ++-------- .../db-table-view/db-table-view.component.ts | 45 ++++++------------- 3 files changed, 16 insertions(+), 72 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css index 63d756181..f5638d75d 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.css @@ -55,25 +55,6 @@ } } -.dashboard-toggle { - display: flex; - align-items: center; - margin-left: 16px; - margin-right: 8px; -} - -.dashboard-toggle .toggle-label { - margin-left: 8px; - font-size: 14px; -} - -@media (width <= 600px) { - .dashboard-toggle { - margin-left: 0; - margin-top: 8px; - } -} - .table-switcher-option ::ng-deep .mdc-list-item__primary-text { width: 100%; } diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html index 8e3542fba..c51e57995 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-view.component.html @@ -25,15 +25,6 @@

{{ displayName }}

-
- - Dashboard - -
- @@ -195,7 +186,7 @@

{{ displayName }}

-{{ displayName }} (filterSelected)="onFilterSelected($event)" > - - - - -
+
-
+
Date: Mon, 26 Jan 2026 14:20:48 +0000 Subject: [PATCH 13/13] fast filters: fix alignment --- .../saved-filters-dialog.component.css | 7 +++---- .../saved-filters-panel.component.css | 10 +++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css index 23558bf5b..765543ebd 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-dialog/saved-filters-dialog.component.css @@ -120,7 +120,7 @@ .dynamic-column-radio { grid-column: 6; - margin-top: 0; + margin-top: -16px; align-self: center; } @@ -286,7 +286,7 @@ .column-name { grid-column: 2; - margin-top: 0; + margin-top: -8px; align-self: center; } @@ -309,7 +309,7 @@ .filter-delete-button { grid-column: 1; - margin-top: 0; + margin-top: -20px; margin-right: 0; margin-left: 0; align-self: center; @@ -363,7 +363,6 @@ .comparator-select-field ::ng-deep .mat-mdc-form-field-infix { width: 100% !important; min-width: fit-content; - padding-right: 40px; padding-left: 0; position: relative; } diff --git a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css index f5f1a55d3..c16ea7a84 100644 --- a/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css +++ b/frontend/src/app/components/dashboard/db-table-view/saved-filters-panel/saved-filters-panel.component.css @@ -1,14 +1,13 @@ .saved-filters-container { display: flex; flex-direction: column; - gap: 8px; - margin-bottom: 12px; } .saved-filters-list { display: flex; align-items: center; gap: 16px; + margin-bottom: 12px; } .saved-filters-list__first-time-button { @@ -167,6 +166,7 @@ display: flex; align-items: center; gap: 20px; + margin-top: -8px; transform: translateX(-10%) scale(0.8); } @@ -178,12 +178,12 @@ } .filters-where-label { + flex-shrink: 0; display: flex; align-items: center; gap: 4px; - font-weight: 500; + margin-top: -2px !important; white-space: nowrap; - flex-shrink: 0; } .filters-where-label .column-name-icon { @@ -216,7 +216,7 @@ } .column-name { - margin-top: -8px; + margin-top: -4px !important; display: flex; align-items: center; gap: 4px;