From a499fe4cd49f673905189df3a3b7cb7d42872d04 Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Tue, 15 Jul 2025 17:27:40 +0200 Subject: [PATCH] frontend: enhance dialog component with force delete option and improved layout --- .../basic-dialog/dialog.component.scss | 126 +++++++++++++++--- .../dialogs/basic-dialog/dialog.component.ts | 66 +++++++-- .../src/lib/models/notification.model.ts | 5 + .../pages/console/rooms/rooms.component.ts | 41 +++++- .../src/lib/services/notification.service.ts | 3 +- 5 files changed, 210 insertions(+), 31 deletions(-) diff --git a/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.scss b/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.scss index 29953d0..ae61849 100644 --- a/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.scss @@ -37,12 +37,19 @@ .dialog-title { @extend .ov-text-center; @include ov-theme-transition; + @include ov-flex-center; + gap: var(--ov-meet-spacing-sm); color: var(--ov-meet-text-primary); font-size: var(--ov-meet-font-size-xl) !important; font-weight: var(--ov-meet-font-weight-medium); margin-bottom: var(--ov-meet-spacing-md); padding: var(--ov-meet-spacing-lg) var(--ov-meet-spacing-lg) 0; line-height: var(--ov-meet-line-height-tight); + + .dialog-icon { + @include ov-icon(md); + color: var(--ov-meet-text-secondary); + } } // === DIALOG CONTENT === @@ -54,6 +61,53 @@ padding: var(--ov-meet-spacing-md) var(--ov-meet-spacing-lg); text-align: center; min-height: auto; + + .dialog-message { + margin-bottom: var(--ov-meet-spacing-md); + } + + .force-checkbox-container { + @include ov-theme-transition; + margin-top: var(--ov-meet-spacing-lg); + padding: var(--ov-meet-spacing-md); + border: 1px solid var(--ov-meet-border-color); + border-radius: var(--ov-meet-radius-md); + background: var(--ov-meet-surface-variant); + text-align: left; + + .force-checkbox { + margin-bottom: var(--ov-meet-spacing-sm); + + .checkbox-text { + font-size: var(--ov-meet-font-size-md); + font-weight: var(--ov-meet-font-weight-medium); + color: var(--ov-meet-text-primary); + } + } + + .checkbox-warning { + display: flex; + align-items: flex-start; + justify-content: flex-start; + gap: var(--ov-meet-spacing-xs); + margin-top: var(--ov-meet-spacing-xs); + + .warning-icon { + @include ov-icon(sm); + color: var(--ov-meet-color-warning); + flex-shrink: 0; + margin-top: 2px; // Align with first line of text + } + + .warning-text { + font-size: var(--ov-meet-font-size-xs); + color: var(--ov-meet-text-secondary); + font-style: italic; + line-height: var(--ov-meet-line-height-relaxed); + flex: 1; + } + } + } } // === DIALOG ACTIONS === @@ -62,52 +116,61 @@ gap: var(--ov-meet-spacing-sm); padding: var(--ov-meet-spacing-lg); margin: 0; + justify-content: center; // Button styling button { @include ov-button-base; @include ov-theme-transition; + @include ov-flex-center; + gap: var(--ov-meet-spacing-xs); min-width: 80px; margin: 0; // Reset default margin + mat-icon { + @include ov-icon(sm); + } + // Cancel/Secondary button - &[mat-button] { + &.cancel-button { color: var(--ov-meet-text-secondary); border: 1px solid var(--ov-meet-border-color); background: transparent; &:hover { @include ov-hover-lift(-1px); - - // background: var(--ov-meet-surface-hover); - // color: var(--ov-meet-text-primary); + background: var(--ov-meet-surface-hover); + color: var(--ov-meet-text-primary); } - - // &:focus { - // outline: 2px solid var(--ov-meet-color-primary); - // outline-offset: 2px; - // } } // Confirm/Primary button - &[mat-flat-button] { - // background: var(--ov-meet-color-primary); + &.confirm-button { color: var(--ov-meet-text-on-primary); &:hover { @include ov-hover-lift(-1px); - // background: var(--ov-meet-color-primary-dark); - // box-shadow: var(--ov-meet-shadow-hover); } - // &:focus { - // outline: 2px solid var(--ov-meet-color-primary-light); - // outline-offset: 2px; - // } - &:active { transform: translateY(0); } + + // Force delete state - changes to warning color + &.force-delete { + background: var(--ov-meet-color-warning) !important; + border-color: var(--ov-meet-color-warning) !important; + + &:hover { + background: var(--ov-meet-color-warning) !important; + filter: brightness(0.9); + } + + &:focus { + outline: 2px solid var(--ov-meet-color-warning); + outline-offset: 2px; + } + } } } } @@ -117,11 +180,35 @@ .dialog-title { font-size: var(--ov-meet-font-size-lg); padding: var(--ov-meet-spacing-md) var(--ov-meet-spacing-md) 0; + flex-direction: column; + gap: var(--ov-meet-spacing-xs); + + .dialog-icon { + @include ov-icon(lg); + } } - mat-dialog-content { + ::ng-deep mat-dialog-content { padding: var(--ov-meet-spacing-sm) var(--ov-meet-spacing-md); font-size: var(--ov-meet-font-size-sm); + + .force-checkbox-container { + margin-top: var(--ov-meet-spacing-md); + padding: var(--ov-meet-spacing-sm); + + .checkbox-warning { + margin-left: 0; // Remove extra margin on mobile + gap: var(--ov-meet-spacing-xs); + + .warning-icon { + margin-top: 1px; // Adjust for smaller text + } + + .warning-text { + font-size: var(--ov-meet-font-size-xs); + } + } + } } .dialog-action { @@ -132,6 +219,7 @@ button { width: 100%; min-width: auto; + justify-content: center; } } } diff --git a/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.ts b/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.ts index 855c8e1..0c0cc2f 100644 --- a/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/components/dialogs/basic-dialog/dialog.component.ts @@ -1,18 +1,50 @@ import { ChangeDetectionStrategy, Component, Inject, inject } from '@angular/core'; +import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; -import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef } from '@angular/material/dialog'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatIconModule } from '@angular/material/icon'; +import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog'; import type { DialogOptions } from '@lib/models'; @Component({ selector: 'ov-dialog', standalone: true, - imports: [MatButtonModule, MatDialogActions, MatDialogContent], + imports: [FormsModule, MatButtonModule, MatIconModule, MatCheckboxModule, MatDialogActions, MatDialogContent, MatDialogTitle], template: `