From c3defe731bf8f5ee8f2365e06e38ace62bb3613c Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Thu, 5 Feb 2026 16:07:22 +0200 Subject: [PATCH 1/2] feat: improve UX for editable field in fast filters dialog - Replace checkbox with slide toggle for better visual feedback - Add "Quick edit" column header aligned with "where" label - Add info icon with tooltip explaining the feature - Show quick edit column only when conditions exist - Support dark theme styling Co-Authored-By: Claude Opus 4.5 --- .../saved-filters-dialog.component.css | 52 +++++++++++++++---- .../saved-filters-dialog.component.html | 18 +++++-- .../saved-filters-dialog.component.ts | 6 ++- 3 files changed, 59 insertions(+), 17 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 765543ebd..05fc9262a 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 @@ -22,7 +22,7 @@ } .empty-conditions-container { - grid-column: 1 / span 6; + grid-column: 1 / span 5; display: flex; align-items: center; gap: 12px; @@ -118,10 +118,49 @@ top: 100%; } -.dynamic-column-radio { +.quick-edit-header { + grid-column: 6; + display: flex; + align-items: center; + gap: 4px; + justify-content: center; + margin-top: 8px; + margin-bottom: 16px; +} + +.quick-edit-title { + font-size: 11px; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.5px; + color: rgba(0, 0, 0, 0.5); + white-space: nowrap; +} + +.quick-edit-info-icon { + font-size: 14px; + width: 14px; + height: 14px; + color: rgba(0, 0, 0, 0.35); + cursor: help; +} + +.quick-edit-toggle { grid-column: 6; margin-top: -16px; align-self: center; + display: flex; + justify-content: center; +} + +@media (prefers-color-scheme: dark) { + .quick-edit-title { + color: rgba(255, 255, 255, 0.5); + } + + .quick-edit-info-icon { + color: rgba(255, 255, 255, 0.35); + } } .comparator-select-field { @@ -185,15 +224,6 @@ padding-bottom: 0; } -.dynamic-column-radio ::ng-deep .mdc-form-field { - display: flex; - align-items: center; - gap: 4px; -} - -.dynamic-column-radio ::ng-deep .mdc-form-field>label { - white-space: nowrap; -} .filter-save-form { grid-column: 1 / span 6; 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 431e6f0be..7e376b852 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 @@ -49,6 +49,14 @@

subdirectory_arrow_right where +
+ Quick edit + + info_outline + +
@@ -170,12 +178,12 @@

}" > -
- + - Editable - + (change)="toggleDynamicColumn(value.key)" + color="primary"> +
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 dfe60c1e4..85648eb00 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 @@ -13,6 +13,8 @@ import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { RouterModule } from '@angular/router'; import { ContentLoaderComponent } from 'src/app/components/ui-components/content-loader/content-loader.component'; import { Observable, map, startWith } from 'rxjs'; @@ -43,7 +45,9 @@ import { Angulartics2, Angulartics2OnModule } from 'angulartics2'; MatDialogModule, MatSnackBarModule, ContentLoaderComponent, - Angulartics2OnModule + Angulartics2OnModule, + MatSlideToggleModule, + MatTooltipModule ], templateUrl: './saved-filters-dialog.component.html', styleUrl: './saved-filters-dialog.component.css' From 7ffa0a2ad44f755028346078e971bfd68125a3fa Mon Sep 17 00:00:00 2001 From: Karina Kharchenko Date: Thu, 5 Feb 2026 17:18:35 +0200 Subject: [PATCH 2/2] feat: add slide toggle with lock/edit icons and animated help tooltip - Replace checkbox with slide toggle showing lock/edit icons inside - Add animated help popup showing chip vs editable input comparison - Toggle animation shows text being typed to demonstrate editability - Reduce quick edit column width for better layout Co-Authored-By: Claude Opus 4.5 --- .../saved-filters-dialog.component.css | 272 +++++++++++++++++- .../saved-filters-dialog.component.html | 41 ++- .../saved-filters-dialog.component.ts | 6 +- 3 files changed, 306 insertions(+), 13 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 05fc9262a..1e3b4f0de 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: 32px auto 228px 0 1fr 120px; + grid-template-columns: 32px auto 228px 0 1fr 100px; grid-column-gap: 8px; align-content: flex-start; align-items: center; @@ -142,17 +142,285 @@ width: 14px; height: 14px; color: rgba(0, 0, 0, 0.35); - cursor: help; + cursor: pointer; +} + +/* Quick edit help menu styles */ +::ng-deep .quick-edit-help-menu { + max-width: none !important; +} + +.quick-edit-help-content { + padding: 16px; + cursor: default; +} + +.quick-edit-help-text { + margin: 0 0 12px 0; + font-size: 13px; + color: rgba(0, 0, 0, 0.7); + line-height: 1.4; +} + +/* Animated example */ +.quick-edit-animated-example { + display: flex; + align-items: center; + gap: 16px; +} + +.example-toggle-animated { + flex-shrink: 0; +} + +.toggle-track { + width: 36px; + height: 20px; + border-radius: 10px; + background-color: rgba(0, 0, 0, 0.25); + position: relative; + animation: toggleTrack 3s ease-in-out infinite; +} + +.toggle-thumb { + width: 16px; + height: 16px; + border-radius: 50%; + background-color: #fff; + position: absolute; + top: 2px; + left: 2px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + animation: toggleThumb 3s ease-in-out infinite; +} + +@keyframes toggleTrack { + 0%, 40% { + background-color: rgba(0, 0, 0, 0.25); + } + 50%, 90% { + background-color: #C177FC; + } + 100% { + background-color: rgba(0, 0, 0, 0.25); + } +} + +@keyframes toggleThumb { + 0%, 40% { + left: 2px; + } + 50%, 90% { + left: 18px; + } + 100% { + left: 2px; + } +} + +.example-filter-animated { + position: relative; + height: 36px; + min-width: 110px; + margin-top: 4px; +} + +.example-chip-animated { + position: absolute; + top: 0; + left: 0; + background-color: rgba(0, 0, 0, 0.08); + border-radius: 16px; + padding: 5px 12px; + font-size: 12px; + color: rgba(0, 0, 0, 0.7); + white-space: nowrap; + animation: chipFade 3s ease-in-out infinite; +} + +.example-editable-animated { + position: absolute; + top: 0; + left: 0; + display: flex; + align-items: center; + gap: 4px; + background-color: transparent; + border: 1px solid #C177FC; + border-radius: 4px; + padding: 8px 8px 4px 8px; + opacity: 0; + animation: editableFade 3s ease-in-out infinite; +} + +.example-editable-label { + position: absolute; + top: -8px; + left: 8px; + font-size: 10px; + color: #C177FC; + background-color: #fff; + padding: 0 4px; +} + +.example-editable-value { + font-size: 12px; + color: rgba(0, 0, 0, 0.87); + display: flex; + align-items: center; +} + +.typing-text::after { + content: 'active'; + animation: typeText 3s ease-in-out infinite; +} + +@keyframes typeText { + 0%, 40% { + content: ''; + } + 45% { + content: 'p'; + } + 50% { + content: 'pe'; + } + 55% { + content: 'pen'; + } + 60% { + content: 'pend'; + } + 65% { + content: 'pendi'; + } + 70%, 90% { + content: 'pending'; + } + 100% { + content: ''; + } +} + +.example-typing-cursor { + font-size: 12px; + color: #C177FC; + font-weight: 300; + animation: cursorBlink 0.5s step-end infinite; +} + +@keyframes cursorBlink { + 0%, 50% { + opacity: 1; + } + 51%, 100% { + opacity: 0; + } +} + +@keyframes chipFade { + 0%, 40% { + opacity: 1; + } + 50%, 90% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes editableFade { + 0%, 40% { + opacity: 0; + } + 50%, 90% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +@media (prefers-color-scheme: dark) { + .quick-edit-help-text { + color: rgba(255, 255, 255, 0.7); + } + + .toggle-track { + animation: toggleTrackDark 3s ease-in-out infinite; + } + + @keyframes toggleTrackDark { + 0%, 40% { + background-color: rgba(255, 255, 255, 0.3); + } + 50%, 90% { + background-color: #C177FC; + } + 100% { + background-color: rgba(255, 255, 255, 0.3); + } + } + + .example-chip-animated { + background-color: rgba(255, 255, 255, 0.12); + color: rgba(255, 255, 255, 0.7); + } + + .example-editable-animated { + background-color: transparent; + } + + .example-editable-label { + color: #C177FC; + background-color: #424242; + } + + .example-editable-value { + color: rgba(255, 255, 255, 0.87); + } + + .example-typing-cursor { + color: #C177FC; + } } .quick-edit-toggle { grid-column: 6; margin-top: -16px; align-self: center; + justify-self: center; +} + +/* Hide default icons */ +.quick-edit-toggle ::ng-deep .mdc-switch__icons { + display: none; +} + +/* Style the thumb to contain our icon */ +.quick-edit-toggle ::ng-deep .mdc-switch__handle { display: flex; + align-items: center; justify-content: center; } +/* Add lock icon when unchecked */ +.quick-edit-toggle ::ng-deep .mdc-switch__handle::after { + font-family: 'Material Icons'; + content: 'lock'; + font-size: 16px; + position: absolute; + color: #fff; +} + +/* Add edit icon when checked */ +.quick-edit-toggle.mat-mdc-slide-toggle-checked ::ng-deep .mdc-switch__handle::after { + content: 'edit'; + font-size: 16px; + color: #fff; +} + @media (prefers-color-scheme: dark) { .quick-edit-title { color: rgba(255, 255, 255, 0.5); 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 7e376b852..58ccbba8c 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 @@ -52,10 +52,33 @@

Quick edit + [matMenuTriggerFor]="quickEditHelpMenu"> info_outline + +
+

Enable to change this value
directly from the table view

+
+
+
+
+
+
+
+
+ status = active +
+
+ status: + + + | + +
+
+
+
+
@@ -178,13 +201,13 @@

}" > -
- - -
+ + 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 85648eb00..dec7218e5 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 @@ -11,9 +11,10 @@ import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/materia import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; +import { MatMenuModule } from '@angular/material/menu'; import { MatSelectModule } from '@angular/material/select'; -import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { MatTooltipModule } from '@angular/material/tooltip'; import { RouterModule } from '@angular/router'; import { ContentLoaderComponent } from 'src/app/components/ui-components/content-loader/content-loader.component'; @@ -38,6 +39,8 @@ import { Angulartics2, Angulartics2OnModule } from 'angulartics2'; MatButtonModule, MatIconModule, MatSelectModule, + MatSlideToggleModule, + MatMenuModule, MatCheckboxModule, MatRadioModule, DynamicModule, @@ -46,7 +49,6 @@ import { Angulartics2, Angulartics2OnModule } from 'angulartics2'; MatSnackBarModule, ContentLoaderComponent, Angulartics2OnModule, - MatSlideToggleModule, MatTooltipModule ], templateUrl: './saved-filters-dialog.component.html',