feat(modal): add confirm and confirm delete modals with tests
- Implemented ConfirmModalComponent and ConfirmDeleteModalComponent for confirmation dialogs. - Added modal service methods to open confirm and confirm delete modals. - Created corresponding HTML and SCSS files for both modal components. - Updated ReutilizablesTestPageComponent to utilize new modals. - Enhanced modal service tests to cover new functionality. - Refactored existing tests to accommodate changes in modal behavior and structure.
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
<div class="confirm-modal">
|
||||
<p class="confirm-modal__content">{{ data.content }}</p>
|
||||
|
||||
<div class="confirm-modal__actions">
|
||||
<app-button variant="danger-secondary" (click)="cancel()">
|
||||
{{ data.cancelLabel }}
|
||||
</app-button>
|
||||
<app-button variant="danger" (click)="confirm()">
|
||||
{{ data.confirmLabel }}
|
||||
</app-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
.confirm-modal {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
justify-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.confirm-modal__content {
|
||||
margin: 0;
|
||||
color: #666666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.confirm-modal__actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import '@angular/compiler';
|
||||
import { TestBed, getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting
|
||||
} from '@angular/platform-browser/testing';
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
ConfirmModalData,
|
||||
MODAL_DATA,
|
||||
ModalRef
|
||||
} from '../../../core/services/modal.service';
|
||||
import { ConfirmDeleteModalComponent } from './confirm-delete-modal.component';
|
||||
|
||||
describe('ConfirmDeleteModalComponent', () => {
|
||||
const data: ConfirmModalData = {
|
||||
content: 'Se eliminara el elemento seleccionado.',
|
||||
confirmLabel: 'Eliminar',
|
||||
cancelLabel: 'Cancelar'
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
try {
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting()
|
||||
);
|
||||
} catch {
|
||||
// Test environment may already be initialized by another setup entrypoint.
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
it('renders the configured content and uses danger for the confirm action', async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ConfirmDeleteModalComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: MODAL_DATA,
|
||||
useValue: data
|
||||
},
|
||||
{
|
||||
provide: ModalRef,
|
||||
useValue: {
|
||||
close: vi.fn()
|
||||
}
|
||||
}
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
const fixture = TestBed.createComponent(ConfirmDeleteModalComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const element = fixture.nativeElement as HTMLElement;
|
||||
const buttons = element.querySelectorAll('button');
|
||||
|
||||
expect(element.textContent).toContain(data.content);
|
||||
expect(element.textContent).toContain(data.confirmLabel);
|
||||
expect(buttons[1].className).toContain('btn-danger');
|
||||
});
|
||||
|
||||
it('closes with false on cancel and true on confirm', async () => {
|
||||
const closeSpy = vi.fn();
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ConfirmDeleteModalComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: MODAL_DATA,
|
||||
useValue: data
|
||||
},
|
||||
{
|
||||
provide: ModalRef,
|
||||
useValue: {
|
||||
close: closeSpy
|
||||
}
|
||||
}
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
const fixture = TestBed.createComponent(ConfirmDeleteModalComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const buttons = fixture.nativeElement.querySelectorAll('button');
|
||||
|
||||
buttons[0].click();
|
||||
buttons[1].click();
|
||||
|
||||
expect(closeSpy).toHaveBeenNthCalledWith(1, false);
|
||||
expect(closeSpy).toHaveBeenNthCalledWith(2, true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
|
||||
import {
|
||||
ConfirmModalData,
|
||||
MODAL_DATA,
|
||||
ModalRef
|
||||
} from '../../../core/services/modal.service';
|
||||
import { ButtonComponent } from '../button/button.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-confirm-delete-modal',
|
||||
imports: [ButtonComponent],
|
||||
templateUrl: './confirm-delete-modal.component.html',
|
||||
styleUrl: './confirm-delete-modal.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ConfirmDeleteModalComponent {
|
||||
protected readonly data = inject<ConfirmModalData>(MODAL_DATA);
|
||||
private readonly modalRef = inject<ModalRef<boolean>>(ModalRef);
|
||||
|
||||
protected cancel(): void {
|
||||
this.modalRef.close(false);
|
||||
}
|
||||
|
||||
protected confirm(): void {
|
||||
this.modalRef.close(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="confirm-modal">
|
||||
<p class="confirm-modal__content">{{ data.content }}</p>
|
||||
|
||||
<div class="confirm-modal__actions">
|
||||
<app-button variant="secondary" (click)="cancel()">
|
||||
{{ data.cancelLabel }}
|
||||
</app-button>
|
||||
<app-button (click)="confirm()">
|
||||
{{ data.confirmLabel }}
|
||||
</app-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
.confirm-modal {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
justify-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.confirm-modal__content {
|
||||
margin: 0;
|
||||
color: #666666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.confirm-modal__actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import '@angular/compiler';
|
||||
import { TestBed, getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting
|
||||
} from '@angular/platform-browser/testing';
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
ConfirmModalData,
|
||||
MODAL_DATA,
|
||||
ModalRef
|
||||
} from '../../../core/services/modal.service';
|
||||
import { ConfirmModalComponent } from './confirm-modal.component';
|
||||
|
||||
describe('ConfirmModalComponent', () => {
|
||||
const data: ConfirmModalData = {
|
||||
content: 'Se confirmara la operacion seleccionada.',
|
||||
confirmLabel: 'Aceptar',
|
||||
cancelLabel: 'Volver'
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
try {
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting()
|
||||
);
|
||||
} catch {
|
||||
// Test environment may already be initialized by another setup entrypoint.
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
it('renders the configured content and labels', async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ConfirmModalComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: MODAL_DATA,
|
||||
useValue: data
|
||||
},
|
||||
{
|
||||
provide: ModalRef,
|
||||
useValue: {
|
||||
close: vi.fn()
|
||||
}
|
||||
}
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
const fixture = TestBed.createComponent(ConfirmModalComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const element = fixture.nativeElement as HTMLElement;
|
||||
|
||||
expect(element.textContent).toContain(data.content);
|
||||
expect(element.textContent).toContain(data.confirmLabel);
|
||||
expect(element.textContent).toContain(data.cancelLabel);
|
||||
});
|
||||
|
||||
it('closes with false on cancel and true on confirm', async () => {
|
||||
const closeSpy = vi.fn();
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ConfirmModalComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: MODAL_DATA,
|
||||
useValue: data
|
||||
},
|
||||
{
|
||||
provide: ModalRef,
|
||||
useValue: {
|
||||
close: closeSpy
|
||||
}
|
||||
}
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
const fixture = TestBed.createComponent(ConfirmModalComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const buttons = fixture.nativeElement.querySelectorAll('button');
|
||||
|
||||
buttons[0].click();
|
||||
buttons[1].click();
|
||||
|
||||
expect(closeSpy).toHaveBeenNthCalledWith(1, false);
|
||||
expect(closeSpy).toHaveBeenNthCalledWith(2, true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
|
||||
import {
|
||||
ConfirmModalData,
|
||||
MODAL_DATA,
|
||||
ModalRef
|
||||
} from '../../../core/services/modal.service';
|
||||
import { ButtonComponent } from '../button/button.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-confirm-modal',
|
||||
imports: [ButtonComponent],
|
||||
templateUrl: './confirm-modal.component.html',
|
||||
styleUrl: './confirm-modal.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ConfirmModalComponent {
|
||||
protected readonly data = inject<ConfirmModalData>(MODAL_DATA);
|
||||
private readonly modalRef = inject<ModalRef<boolean>>(ModalRef);
|
||||
|
||||
protected cancel(): void {
|
||||
this.modalRef.close(false);
|
||||
}
|
||||
|
||||
protected confirm(): void {
|
||||
this.modalRef.close(true);
|
||||
}
|
||||
}
|
||||
@@ -49,16 +49,26 @@
|
||||
}
|
||||
|
||||
.modal-shell__header {
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding: 1.25rem 1.25rem 0.75rem;
|
||||
}
|
||||
|
||||
.modal-shell__title {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
font-size: clamp(1.15rem, 1rem + 0.4vw, 1.5rem);
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
color: #202020;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.modal-shell__header .btn-close {
|
||||
position: absolute;
|
||||
top: 1.25rem;
|
||||
right: 1.25rem;
|
||||
}
|
||||
|
||||
.modal-shell__body {
|
||||
|
||||
Reference in New Issue
Block a user