From 3697c4b97ccb112c7f2c9d8e17be3dcd8e9174da Mon Sep 17 00:00:00 2001 From: ncoronel Date: Fri, 3 Jul 2026 09:00:49 -0300 Subject: [PATCH] feat(modal): add simple modal component with open and close functionality --- src/app/core/services/modal.service.spec.ts | 36 ++++++++ src/app/core/services/modal.service.ts | 43 +++++++++ .../reutilizables-test-page.component.html | 3 + .../reutilizables-test-page.component.ts | 10 +++ .../simple-modal/simple-modal.component.html | 9 ++ .../simple-modal/simple-modal.component.scss | 19 ++++ .../simple-modal.component.spec.ts | 90 +++++++++++++++++++ .../simple-modal/simple-modal.component.ts | 24 +++++ 8 files changed, 234 insertions(+) create mode 100644 src/app/shared/components/simple-modal/simple-modal.component.html create mode 100644 src/app/shared/components/simple-modal/simple-modal.component.scss create mode 100644 src/app/shared/components/simple-modal/simple-modal.component.spec.ts create mode 100644 src/app/shared/components/simple-modal/simple-modal.component.ts diff --git a/src/app/core/services/modal.service.spec.ts b/src/app/core/services/modal.service.spec.ts index f49fb48..0f9a114 100644 --- a/src/app/core/services/modal.service.spec.ts +++ b/src/app/core/services/modal.service.spec.ts @@ -18,6 +18,7 @@ import { firstValueFrom } from 'rxjs'; import { ConfirmDeleteModalComponent } from '../../shared/components/confirm-delete-modal/confirm-delete-modal.component'; import { ConfirmModalComponent } from '../../shared/components/confirm-modal/confirm-modal.component'; +import { SimpleModalComponent } from '../../shared/components/simple-modal/simple-modal.component'; import { MODAL_DATA, ModalRef, @@ -212,6 +213,41 @@ describe('ModalService', () => { showCloseButton: false }); }); + + it('opens the simple modal with default button label', () => { + service.openSimple({ + title: 'Aviso', + content: 'Este es un aviso simple.' + }); + + const activeModal = service.activeModal(); + + expect(activeModal?.component).toBe(SimpleModalComponent); + expect(activeModal?.config).toEqual({ + title: 'Aviso', + data: { + content: 'Este es un aviso simple.', + buttonLabel: 'Entendido' + }, + size: 'md', + closeOnBackdrop: true, + closeOnEscape: true, + showCloseButton: true + }); + }); + + it('maps the simple modal close result to undefined', async () => { + const result$ = service.openSimple({ + title: 'Aviso', + content: 'Este es un aviso simple.' + }); + const activeModal = service.activeModal(); + const resultPromise = firstValueFrom(result$); + + activeModal?.ref.close(); + + await expect(resultPromise).resolves.toBeUndefined(); + }); }); @Component({ diff --git a/src/app/core/services/modal.service.ts b/src/app/core/services/modal.service.ts index 02d1534..98fbe87 100644 --- a/src/app/core/services/modal.service.ts +++ b/src/app/core/services/modal.service.ts @@ -2,6 +2,7 @@ import { InjectionToken, Injectable, Type, signal } from '@angular/core'; import { Observable, Subject, map } from 'rxjs'; import { ConfirmDeleteModalComponent } from '../../shared/components/confirm-delete-modal/confirm-delete-modal.component'; import { ConfirmModalComponent } from '../../shared/components/confirm-modal/confirm-modal.component'; +import { SimpleModalComponent } from '../../shared/components/simple-modal/simple-modal.component'; export type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full'; export type ModalDismissReason = @@ -43,6 +44,17 @@ export interface ConfirmModalConfig cancelLabel?: string; } +export interface SimpleModalData { + content: string; + buttonLabel: string; +} + +export interface SimpleModalConfig + extends Omit, 'data'> { + content: string; + buttonLabel?: string; +} + export interface ActiveModalState { component: Type; config: NormalizedModalConfig; @@ -158,6 +170,19 @@ export class ModalService { ); } + openSimple(config: SimpleModalConfig): Observable { + return this.openSimpleRef(config).afterClosed$.pipe( + map(() => undefined) + ); + } + + openSimpleRef(config: SimpleModalConfig): ModalRef { + return this.open( + SimpleModalComponent, + this.buildSimpleModalConfig(config) + ); + } + private close(ref: ModalRef, result?: TResult): void { if (this.activeModalState()?.ref !== ref) { return; @@ -207,4 +232,22 @@ export class ModalService { } }; } + + private buildSimpleModalConfig( + config: SimpleModalConfig + ): ModalConfig { + const { + content, + buttonLabel = 'Entendido', + ...modalConfig + } = config; + + return { + ...modalConfig, + data: { + content, + buttonLabel + } + }; + } } diff --git a/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html b/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html index c53e29d..6668f5c 100644 --- a/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html +++ b/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html @@ -91,6 +91,9 @@ Abrir modal ancho + + Abrir simple modal +