feat: introduce loading context management across services
- Refactor AuthService, CartService, CatalogService, CheckoutService, TenantService, and TicketService to extend BaseApiService for consistent loading context handling.
- Implement loading modes ('global', 'custom', 'none') using HttpContext for API requests.
- Update existing service methods to accept loading mode parameters and propagate them to HTTP requests.
- Enhance global loading interceptor to respect loading modes and prevent global loading for specific requests.
- Add unit tests to verify loading mode propagation in services and interceptors.
- Update component interactions to utilize the new loading mode functionality.
This commit is contained in:
@@ -29,7 +29,9 @@ export class PurchaseList implements OnInit {
|
||||
try {
|
||||
const tenantCode = this.tenantService.tenant()?.codigo || '';
|
||||
|
||||
const response = await this.checkoutService.getPurchases(tenantCode, 'paid');
|
||||
const response = await this.checkoutService
|
||||
.withCustomLoading()
|
||||
.getPurchases(tenantCode, 'paid');
|
||||
const mappedPurchases = response.data.map((purchase: PurchaseSummaryResponse) => ({
|
||||
id: purchase.id,
|
||||
date: this.formatDate(purchase.created_at),
|
||||
|
||||
@@ -44,7 +44,9 @@ export class PurchaseDetailPage implements OnInit {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await this.checkoutService.getPurchase(tenant.codigo, purchaseId);
|
||||
const response = await this.checkoutService
|
||||
.withCustomLoading()
|
||||
.getPurchase(tenant.codigo, purchaseId);
|
||||
|
||||
this.purchase.set({
|
||||
id: response.id,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
|
||||
import { BaseApiService } from '../../../../../../core/services/base-api.service';
|
||||
import { TenantService } from '../../../../../../core/services/tenant.service';
|
||||
|
||||
export interface TicketResponse {
|
||||
@@ -21,13 +21,14 @@ export interface TicketResponse {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class TicketService {
|
||||
private readonly http = inject(HttpClient);
|
||||
export class TicketService extends BaseApiService {
|
||||
private readonly tenantService = inject(TenantService);
|
||||
|
||||
getTickets(): Promise<TicketResponse[]> {
|
||||
return firstValueFrom(
|
||||
this.http.get<{ data: TicketResponse[] }>(`${this.tenantService.getTenantApiUrl()}/tickets`),
|
||||
this.http.get<{ data: TicketResponse[] }>(
|
||||
`${this.tenantService.getTenantApiUrl()}/tickets`,
|
||||
),
|
||||
).then((response) => response.data ?? []);
|
||||
}
|
||||
|
||||
@@ -36,7 +37,9 @@ export class TicketService {
|
||||
this.http.post(
|
||||
`${this.tenantService.getTenantApiUrl()}/tickets/pdf`,
|
||||
{ ticket_ids: ticketIds },
|
||||
{ responseType: 'blob' },
|
||||
{
|
||||
responseType: 'blob',
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,14 @@ import { TicketComponent } from './components/ticket/ticket.component';
|
||||
import { TicketResponse, TicketService } from './ticket.service';
|
||||
import { TicketsPage } from './tickets-page';
|
||||
|
||||
function withCustomLoading<T extends object>(
|
||||
service: T,
|
||||
): T & { withCustomLoading: () => T } {
|
||||
return Object.assign(service, {
|
||||
withCustomLoading: () => service,
|
||||
});
|
||||
}
|
||||
|
||||
const ticket = (overrides: Partial<TicketResponse>): TicketResponse => ({
|
||||
id: 1,
|
||||
tenant_code: 'tenant',
|
||||
@@ -40,10 +48,10 @@ describe('TicketsPage', () => {
|
||||
providers: [
|
||||
{
|
||||
provide: TicketService,
|
||||
useValue: {
|
||||
useValue: withCustomLoading({
|
||||
getTickets: () => Promise.resolve([ticket({})]),
|
||||
downloadPdf: () => Promise.resolve(new Blob(['pdf-content'])),
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -99,10 +107,10 @@ describe('TicketsPage', () => {
|
||||
providers: [
|
||||
{
|
||||
provide: TicketService,
|
||||
useValue: {
|
||||
useValue: withCustomLoading({
|
||||
getTickets: () => Promise.resolve([ticket({})]),
|
||||
downloadPdf,
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -150,7 +158,10 @@ describe('TicketsPage', () => {
|
||||
.overrideComponent(TicketsPage, {
|
||||
set: {
|
||||
providers: [
|
||||
{ provide: TicketService, useValue: { getTickets: () => Promise.resolve([]) } },
|
||||
{
|
||||
provide: TicketService,
|
||||
useValue: withCustomLoading({ getTickets: () => Promise.resolve([]) }),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
@@ -183,7 +194,10 @@ describe('TicketsPage', () => {
|
||||
.overrideComponent(TicketsPage, {
|
||||
set: {
|
||||
providers: [
|
||||
{ provide: TicketService, useValue: { getTickets: () => Promise.resolve(tickets) } },
|
||||
{
|
||||
provide: TicketService,
|
||||
useValue: withCustomLoading({ getTickets: () => Promise.resolve(tickets) }),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
@@ -236,7 +250,9 @@ describe('TicketsPage', () => {
|
||||
providers: [
|
||||
{
|
||||
provide: TicketService,
|
||||
useValue: { getTickets: () => Promise.resolve([ticket({})]) },
|
||||
useValue: withCustomLoading({
|
||||
getTickets: () => Promise.resolve([ticket({})]),
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ export class TicketsPage implements OnInit {
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
try {
|
||||
this.tickets.set(await this.ticketService.getTickets());
|
||||
this.tickets.set(await this.ticketService.withCustomLoading().getTickets());
|
||||
} catch {
|
||||
this.toastService.danger('Hubo un error al cargar los tickets');
|
||||
} finally {
|
||||
@@ -151,7 +151,9 @@ export class TicketsPage implements OnInit {
|
||||
this.isGeneratingPdf.set(true);
|
||||
|
||||
try {
|
||||
return await this.ticketService.downloadPdf(tickets.map((ticket) => ticket.id));
|
||||
return await this.ticketService
|
||||
.withCustomLoading()
|
||||
.downloadPdf(tickets.map((ticket) => ticket.id));
|
||||
} catch {
|
||||
this.toastService.danger('No se pudo generar el PDF de los tickets.');
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user