From a855e79196d9ed6312e67832e56905960179fb3b Mon Sep 17 00:00:00 2001 From: Nino Righi Date: Tue, 18 Nov 2025 10:05:17 +0000 Subject: [PATCH] Merged PR 2030: feat(crm-customer-booking): add loyalty card booking component feat(crm-customer-booking): add loyalty card booking component Implement new component for customer loyalty card credit/debit bookings with booking type selection and real-time transaction updates. Includes automatic reload of transaction history after successful bookings. Key changes: - Add CrmFeatureCustomerBookingComponent with booking form UI - Create CustomerCardBookingFacade for booking API calls - Add CustomerBookingReasonsResource for loading booking types - Extend CrmSearchService with booking methods (addBooking, fetchBookingReasons, fetchCurrentBookingPartnerStore) - Add AddBookingSchema with Zod validation - Integrate component into KundenkarteMainViewComponent - Update CustomerCardTransactionsResource to providedIn: 'root' for shared access - Improve transaction list UX (hide header/center empty state when no data) Technical details: - New library: @isa/crm/feature/customer-booking (Vitest-based) - Signals-based state management with computed properties - Automatic points calculation based on booking type multiplier - Error handling with feedback dialogs - 500ms delay before transaction reload to ensure API consistency - Data attributes for E2E testing (data-what, data-which) Ref: #5315 --- .../kundenkarte-main-view.component.html | 1 + .../kundenkarte-main-view.component.ts | 2 + generated/swagger/crm-api/src/models.ts | 12 +- .../crm-api/src/models/account-balance-dto.ts | 5 + .../crm-api/src/models/account-details-dto.ts | 14 + .../src/models/add-loyalty-card-values.ts | 8 + .../crm-api/src/models/custom-property-dto.ts | 5 + .../crm-api/src/models/identifier-dto.ts | 8 + .../key-value-dtoof-string-and-integer.ts | 12 + .../src/models/membership-details-dto.ts | 19 + .../swagger/crm-api/src/models/optin-dto.ts | 5 + .../response-args-of-account-details-dto.ts | 6 + ...e-of-key-value-dtoof-string-and-integer.ts | 6 + .../response-args-of-ienumerable-of-string.ts | 5 - .../crm-api/src/models/state-level-dto.ts | 10 + .../crm-api/src/services/customer.service.ts | 62 ++ .../src/services/loyalty-card.service.ts | 10 +- .../facades/customer-card-booking.facade.ts | 31 + libs/crm/data-access/src/lib/facades/index.ts | 1 + .../customer-booking-reasons.resource.ts | 29 + .../customer-card-transactions.resource.ts | 5 +- .../data-access/src/lib/resources/index.ts | 1 + .../src/lib/schemas/add-booking.schema.ts | 18 + libs/crm/data-access/src/lib/schemas/index.ts | 1 + .../src/lib/services/crm-search.service.ts | 79 +++ libs/crm/feature/customer-booking/README.md | 7 + .../customer-booking/eslint.config.cjs | 34 ++ .../crm/feature/customer-booking/project.json | 20 + .../crm/feature/customer-booking/src/index.ts | 1 + ...crm-feature-customer-booking.component.css | 15 + ...rm-feature-customer-booking.component.html | 67 +++ ...feature-customer-booking.component.spec.ts | 21 + .../crm-feature-customer-booking.component.ts | 149 +++++ .../customer-booking/src/test-setup.ts | 13 + .../feature/customer-booking/tsconfig.json | 30 + .../customer-booking/tsconfig.lib.json | 27 + .../customer-booking/tsconfig.spec.json | 29 + .../feature/customer-booking/vite.config.mts | 28 + ...-customer-card-transactions.component.html | 13 +- ...re-customer-card-transactions.component.ts | 7 +- package-lock.json | 569 +----------------- tsconfig.base.json | 3 + 42 files changed, 808 insertions(+), 580 deletions(-) create mode 100644 generated/swagger/crm-api/src/models/account-balance-dto.ts create mode 100644 generated/swagger/crm-api/src/models/account-details-dto.ts create mode 100644 generated/swagger/crm-api/src/models/add-loyalty-card-values.ts create mode 100644 generated/swagger/crm-api/src/models/custom-property-dto.ts create mode 100644 generated/swagger/crm-api/src/models/identifier-dto.ts create mode 100644 generated/swagger/crm-api/src/models/key-value-dtoof-string-and-integer.ts create mode 100644 generated/swagger/crm-api/src/models/membership-details-dto.ts create mode 100644 generated/swagger/crm-api/src/models/optin-dto.ts create mode 100644 generated/swagger/crm-api/src/models/response-args-of-account-details-dto.ts create mode 100644 generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-key-value-dtoof-string-and-integer.ts delete mode 100644 generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-string.ts create mode 100644 generated/swagger/crm-api/src/models/state-level-dto.ts create mode 100644 libs/crm/data-access/src/lib/facades/customer-card-booking.facade.ts create mode 100644 libs/crm/data-access/src/lib/resources/customer-booking-reasons.resource.ts create mode 100644 libs/crm/data-access/src/lib/schemas/add-booking.schema.ts create mode 100644 libs/crm/feature/customer-booking/README.md create mode 100644 libs/crm/feature/customer-booking/eslint.config.cjs create mode 100644 libs/crm/feature/customer-booking/project.json create mode 100644 libs/crm/feature/customer-booking/src/index.ts create mode 100644 libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.css create mode 100644 libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.html create mode 100644 libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.spec.ts create mode 100644 libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.ts create mode 100644 libs/crm/feature/customer-booking/src/test-setup.ts create mode 100644 libs/crm/feature/customer-booking/tsconfig.json create mode 100644 libs/crm/feature/customer-booking/tsconfig.lib.json create mode 100644 libs/crm/feature/customer-booking/tsconfig.spec.json create mode 100644 libs/crm/feature/customer-booking/vite.config.mts diff --git a/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html b/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html index 127ec2bc6..3267af977 100644 --- a/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html +++ b/apps/isa-app/src/page/customer/customer-search/kundenkarte-main-view/kundenkarte-main-view.component.html @@ -10,6 +10,7 @@ [tabId]="processId$ | async" class="mt-4" /> + ; + level?: StateLevelDTO; + memberships?: Array; + status?: string; +} diff --git a/generated/swagger/crm-api/src/models/add-loyalty-card-values.ts b/generated/swagger/crm-api/src/models/add-loyalty-card-values.ts new file mode 100644 index 000000000..352340d89 --- /dev/null +++ b/generated/swagger/crm-api/src/models/add-loyalty-card-values.ts @@ -0,0 +1,8 @@ +/* tslint:disable */ +export interface AddLoyaltyCardValues { + + /** + * Card code + */ + cardCode?: string; +} diff --git a/generated/swagger/crm-api/src/models/custom-property-dto.ts b/generated/swagger/crm-api/src/models/custom-property-dto.ts new file mode 100644 index 000000000..1ac3877a6 --- /dev/null +++ b/generated/swagger/crm-api/src/models/custom-property-dto.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +export interface CustomPropertyDTO { + name?: string; + value?: string; +} diff --git a/generated/swagger/crm-api/src/models/identifier-dto.ts b/generated/swagger/crm-api/src/models/identifier-dto.ts new file mode 100644 index 000000000..b520ba200 --- /dev/null +++ b/generated/swagger/crm-api/src/models/identifier-dto.ts @@ -0,0 +1,8 @@ +/* tslint:disable */ +export interface IdentifierDTO { + code?: string; + displayCode?: string; + identifierId?: string; + status?: string; + type?: string; +} diff --git a/generated/swagger/crm-api/src/models/key-value-dtoof-string-and-integer.ts b/generated/swagger/crm-api/src/models/key-value-dtoof-string-and-integer.ts new file mode 100644 index 000000000..ea31e9fff --- /dev/null +++ b/generated/swagger/crm-api/src/models/key-value-dtoof-string-and-integer.ts @@ -0,0 +1,12 @@ +/* tslint:disable */ +export interface KeyValueDTOOfStringAndInteger { + command?: string; + description?: string; + enabled?: boolean; + group?: string; + key?: string; + label?: string; + selected?: boolean; + sort?: number; + value: number; +} diff --git a/generated/swagger/crm-api/src/models/membership-details-dto.ts b/generated/swagger/crm-api/src/models/membership-details-dto.ts new file mode 100644 index 000000000..2cf03e6cf --- /dev/null +++ b/generated/swagger/crm-api/src/models/membership-details-dto.ts @@ -0,0 +1,19 @@ +/* tslint:disable */ +import { CustomPropertyDTO } from './custom-property-dto'; +import { OptinDTO } from './optin-dto'; +export interface MembershipDetailsDTO { + birthDate?: string; + city?: string; + countryCode?: string; + customProperties?: Array; + emailAddress?: string; + familyName?: string; + genderCode?: string; + givenName?: string; + memberRole?: string; + membershipId?: string; + optins?: Array; + streetHouseNo?: string; + userId?: string; + zipCode?: string; +} diff --git a/generated/swagger/crm-api/src/models/optin-dto.ts b/generated/swagger/crm-api/src/models/optin-dto.ts new file mode 100644 index 000000000..946983695 --- /dev/null +++ b/generated/swagger/crm-api/src/models/optin-dto.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +export interface OptinDTO { + flag: boolean; + type?: string; +} diff --git a/generated/swagger/crm-api/src/models/response-args-of-account-details-dto.ts b/generated/swagger/crm-api/src/models/response-args-of-account-details-dto.ts new file mode 100644 index 000000000..b2babdb6b --- /dev/null +++ b/generated/swagger/crm-api/src/models/response-args-of-account-details-dto.ts @@ -0,0 +1,6 @@ +/* tslint:disable */ +import { ResponseArgs } from './response-args'; +import { AccountDetailsDTO } from './account-details-dto'; +export interface ResponseArgsOfAccountDetailsDTO extends ResponseArgs{ + result?: AccountDetailsDTO; +} diff --git a/generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-key-value-dtoof-string-and-integer.ts b/generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-key-value-dtoof-string-and-integer.ts new file mode 100644 index 000000000..9b5631a47 --- /dev/null +++ b/generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-key-value-dtoof-string-and-integer.ts @@ -0,0 +1,6 @@ +/* tslint:disable */ +import { ResponseArgs } from './response-args'; +import { KeyValueDTOOfStringAndInteger } from './key-value-dtoof-string-and-integer'; +export interface ResponseArgsOfIEnumerableOfKeyValueDTOOfStringAndInteger extends ResponseArgs{ + result?: Array; +} diff --git a/generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-string.ts b/generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-string.ts deleted file mode 100644 index 5052347aa..000000000 --- a/generated/swagger/crm-api/src/models/response-args-of-ienumerable-of-string.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* tslint:disable */ -import { ResponseArgs } from './response-args'; -export interface ResponseArgsOfIEnumerableOfString extends ResponseArgs{ - result?: Array; -} diff --git a/generated/swagger/crm-api/src/models/state-level-dto.ts b/generated/swagger/crm-api/src/models/state-level-dto.ts new file mode 100644 index 000000000..bd8c5ecef --- /dev/null +++ b/generated/swagger/crm-api/src/models/state-level-dto.ts @@ -0,0 +1,10 @@ +/* tslint:disable */ +export interface StateLevelDTO { + currentStatePoints?: number; + name?: string; + neededStatePoints?: number; + neededStatePointsNextLevel?: number; + requiredPointsToMaintainLevel?: number; + requiredPointsToReachNextLevel?: number; + validTo?: string; +} diff --git a/generated/swagger/crm-api/src/services/customer.service.ts b/generated/swagger/crm-api/src/services/customer.service.ts index 3e34f1e1c..cf97a38f0 100644 --- a/generated/swagger/crm-api/src/services/customer.service.ts +++ b/generated/swagger/crm-api/src/services/customer.service.ts @@ -17,6 +17,8 @@ import { ResponseArgsOfCustomerDTO } from '../models/response-args-of-customer-d import { SaveCustomerValues } from '../models/save-customer-values'; import { CustomerDTO } from '../models/customer-dto'; import { ResponseArgsOfBoolean } from '../models/response-args-of-boolean'; +import { ResponseArgsOfAccountDetailsDTO } from '../models/response-args-of-account-details-dto'; +import { AddLoyaltyCardValues } from '../models/add-loyalty-card-values'; import { ResponseArgsOfAssignedPayerDTO } from '../models/response-args-of-assigned-payer-dto'; import { ResponseArgsOfIEnumerableOfCustomerInfoDTO } from '../models/response-args-of-ienumerable-of-customer-info-dto'; import { ResponseArgsOfIEnumerableOfBonusCardInfoDTO } from '../models/response-args-of-ienumerable-of-bonus-card-info-dto'; @@ -35,6 +37,7 @@ class CustomerService extends __BaseService { static readonly CustomerUpdateCustomerPath = '/customer/{customerId}'; static readonly CustomerPatchCustomerPath = '/customer/{customerId}'; static readonly CustomerDeleteCustomerPath = '/customer/{customerId}'; + static readonly CustomerAddLoyaltyCardPath = '/customer/{customerId}/loyalty/add-card'; static readonly CustomerCreateCustomerPath = '/customer'; static readonly CustomerAddPayerReferencePath = '/customer/{customerId}/payer'; static readonly CustomerDeactivateCustomerPath = '/customer/{customerId}/deactivate'; @@ -389,6 +392,56 @@ class CustomerService extends __BaseService { ); } + /** + * Kundenkarte hinzufügen + * @param params The `CustomerService.CustomerAddLoyaltyCardParams` containing the following parameters: + * + * - `loyaltyCardValues`: + * + * - `customerId`: + * + * - `locale`: + */ + CustomerAddLoyaltyCardResponse(params: CustomerService.CustomerAddLoyaltyCardParams): __Observable<__StrictHttpResponse> { + let __params = this.newParams(); + let __headers = new HttpHeaders(); + let __body: any = null; + __body = params.loyaltyCardValues; + + if (params.locale != null) __params = __params.set('locale', params.locale.toString()); + let req = new HttpRequest( + 'POST', + this.rootUrl + `/customer/${encodeURIComponent(String(params.customerId))}/loyalty/add-card`, + __body, + { + headers: __headers, + params: __params, + responseType: 'json' + }); + + return this.http.request(req).pipe( + __filter(_r => _r instanceof HttpResponse), + __map((_r) => { + return _r as __StrictHttpResponse; + }) + ); + } + /** + * Kundenkarte hinzufügen + * @param params The `CustomerService.CustomerAddLoyaltyCardParams` containing the following parameters: + * + * - `loyaltyCardValues`: + * + * - `customerId`: + * + * - `locale`: + */ + CustomerAddLoyaltyCard(params: CustomerService.CustomerAddLoyaltyCardParams): __Observable { + return this.CustomerAddLoyaltyCardResponse(params).pipe( + __map(_r => _r.body as ResponseArgsOfAccountDetailsDTO) + ); + } + /** * Anlage eines neuen Kunden * @param payload Kundendaten @@ -861,6 +914,15 @@ module CustomerService { deletionComment?: null | string; } + /** + * Parameters for CustomerAddLoyaltyCard + */ + export interface CustomerAddLoyaltyCardParams { + loyaltyCardValues: AddLoyaltyCardValues; + customerId: number; + locale?: null | string; + } + /** * Parameters for CustomerAddPayerReference */ diff --git a/generated/swagger/crm-api/src/services/loyalty-card.service.ts b/generated/swagger/crm-api/src/services/loyalty-card.service.ts index edf503742..02eba0ec4 100644 --- a/generated/swagger/crm-api/src/services/loyalty-card.service.ts +++ b/generated/swagger/crm-api/src/services/loyalty-card.service.ts @@ -10,7 +10,7 @@ import { map as __map, filter as __filter } from 'rxjs/operators'; import { ResponseArgsOfIQueryResultOfLoyaltyBookingInfoDTO } from '../models/response-args-of-iquery-result-of-loyalty-booking-info-dto'; import { ResponseArgsOfLoyaltyBookingInfoDTO } from '../models/response-args-of-loyalty-booking-info-dto'; import { LoyaltyBookingValues } from '../models/loyalty-booking-values'; -import { ResponseArgsOfIEnumerableOfString } from '../models/response-args-of-ienumerable-of-string'; +import { ResponseArgsOfIEnumerableOfKeyValueDTOOfStringAndInteger } from '../models/response-args-of-ienumerable-of-key-value-dtoof-string-and-integer'; import { ResponseArgsOfKeyValueDTOOfStringAndString } from '../models/response-args-of-key-value-dtoof-string-and-string'; import { ResponseArgsOfBoolean } from '../models/response-args-of-boolean'; import { LoyaltyBonValues } from '../models/loyalty-bon-values'; @@ -133,7 +133,7 @@ class LoyaltyCardService extends __BaseService { /** * Booking reason / Buchungsgründe */ - LoyaltyCardBookingReasonResponse(): __Observable<__StrictHttpResponse> { + LoyaltyCardBookingReasonResponse(): __Observable<__StrictHttpResponse> { let __params = this.newParams(); let __headers = new HttpHeaders(); let __body: any = null; @@ -150,16 +150,16 @@ class LoyaltyCardService extends __BaseService { return this.http.request(req).pipe( __filter(_r => _r instanceof HttpResponse), __map((_r) => { - return _r as __StrictHttpResponse; + return _r as __StrictHttpResponse; }) ); } /** * Booking reason / Buchungsgründe */ - LoyaltyCardBookingReason(): __Observable { + LoyaltyCardBookingReason(): __Observable { return this.LoyaltyCardBookingReasonResponse().pipe( - __map(_r => _r.body as ResponseArgsOfIEnumerableOfString) + __map(_r => _r.body as ResponseArgsOfIEnumerableOfKeyValueDTOOfStringAndInteger) ); } diff --git a/libs/crm/data-access/src/lib/facades/customer-card-booking.facade.ts b/libs/crm/data-access/src/lib/facades/customer-card-booking.facade.ts new file mode 100644 index 000000000..84163c181 --- /dev/null +++ b/libs/crm/data-access/src/lib/facades/customer-card-booking.facade.ts @@ -0,0 +1,31 @@ +import { inject, Injectable } from '@angular/core'; +import { CrmSearchService } from '../services/crm-search.service'; +import { AddBookingInput } from '../schemas'; +import { + KeyValueDTOOfStringAndInteger, + KeyValueDTOOfStringAndString, + LoyaltyBookingInfoDTO, +} from '@generated/swagger/crm-api'; + +@Injectable({ providedIn: 'root' }) +export class CustomerCardBookingFacade { + #crmSearchService = inject(CrmSearchService); + + async fetchBookingReasons( + abortSignal?: AbortSignal, + ): Promise { + return this.#crmSearchService.fetchBookingReasons(abortSignal); + } + + async fetchCurrentBookingPartnerStore( + abortSignal?: AbortSignal, + ): Promise { + return this.#crmSearchService.fetchCurrentBookingPartnerStore(abortSignal); + } + + async addBooking( + params: AddBookingInput, + ): Promise { + return this.#crmSearchService.addBooking(params); + } +} diff --git a/libs/crm/data-access/src/lib/facades/index.ts b/libs/crm/data-access/src/lib/facades/index.ts index 64712ff6a..be887d595 100644 --- a/libs/crm/data-access/src/lib/facades/index.ts +++ b/libs/crm/data-access/src/lib/facades/index.ts @@ -1,2 +1,3 @@ export * from './customer-cards.facade'; export * from './customer.facade'; +export * from './customer-card-booking.facade'; diff --git a/libs/crm/data-access/src/lib/resources/customer-booking-reasons.resource.ts b/libs/crm/data-access/src/lib/resources/customer-booking-reasons.resource.ts new file mode 100644 index 000000000..60e7b8134 --- /dev/null +++ b/libs/crm/data-access/src/lib/resources/customer-booking-reasons.resource.ts @@ -0,0 +1,29 @@ +import { Injectable, inject, resource } from '@angular/core'; +import { logger } from '@isa/core/logging'; +import { CrmSearchService } from '@isa/crm/data-access'; +import { KeyValueDTOOfStringAndInteger } from '@generated/swagger/crm-api'; + +@Injectable() +export class CustomerBookingReasonsResource { + readonly #crmSearchService = inject(CrmSearchService); + readonly #logger = logger(() => ({ + context: 'CustomerBookingReasonsResource', + })); + + readonly resource = resource({ + loader: async ({ + abortSignal, + }): Promise => { + this.#logger.debug('Loading Booking Reasons'); + + const reasons = + await this.#crmSearchService.fetchBookingReasons(abortSignal); + + this.#logger.debug('Booking Reasons loaded', () => ({ + count: reasons.length, + })); + + return reasons; + }, + }); +} diff --git a/libs/crm/data-access/src/lib/resources/customer-card-transactions.resource.ts b/libs/crm/data-access/src/lib/resources/customer-card-transactions.resource.ts index aee66dfb0..e7fdb5471 100644 --- a/libs/crm/data-access/src/lib/resources/customer-card-transactions.resource.ts +++ b/libs/crm/data-access/src/lib/resources/customer-card-transactions.resource.ts @@ -15,9 +15,6 @@ import { LoyaltyBookingInfoDTO } from '@generated/swagger/crm-api'; * * @example * ```typescript - * @Component({ - * providers: [CustomerCardTransactionsResource], - * }) * export class MyFeatureComponent { * #transactionsResource = inject(CustomerCardTransactionsResource); * @@ -30,7 +27,7 @@ import { LoyaltyBookingInfoDTO } from '@generated/swagger/crm-api'; * } * ``` */ -@Injectable() +@Injectable({ providedIn: 'root' }) export class CustomerCardTransactionsResource { readonly #crmSearchService = inject(CrmSearchService); readonly #logger = logger(() => ({ diff --git a/libs/crm/data-access/src/lib/resources/index.ts b/libs/crm/data-access/src/lib/resources/index.ts index cd5e8b7af..8fa1352ba 100644 --- a/libs/crm/data-access/src/lib/resources/index.ts +++ b/libs/crm/data-access/src/lib/resources/index.ts @@ -7,3 +7,4 @@ export * from './customer-shipping-address.resource'; export * from './customer-shipping-addresses.resource'; export * from './customer.resource'; export * from './payer.resource'; +export * from './customer-booking-reasons.resource'; diff --git a/libs/crm/data-access/src/lib/schemas/add-booking.schema.ts b/libs/crm/data-access/src/lib/schemas/add-booking.schema.ts new file mode 100644 index 000000000..4bca607bb --- /dev/null +++ b/libs/crm/data-access/src/lib/schemas/add-booking.schema.ts @@ -0,0 +1,18 @@ +import { z } from 'zod'; + +export const AddBookingSchema = z.object({ + cardCode: z.string().describe('Unique card code identifier'), + booking: z + .object({ + points: z.number().describe('Booking points'), + reason: z.string().optional().describe('Booking Reason'), + storeId: z + .string() + .optional() + .describe('Booking store (convercus store id)'), + }) + .describe('Booking details'), +}); + +export type AddBooking = z.infer; +export type AddBookingInput = z.input; diff --git a/libs/crm/data-access/src/lib/schemas/index.ts b/libs/crm/data-access/src/lib/schemas/index.ts index e8e37ffbd..5f48835e6 100644 --- a/libs/crm/data-access/src/lib/schemas/index.ts +++ b/libs/crm/data-access/src/lib/schemas/index.ts @@ -17,3 +17,4 @@ export * from './payer.schema'; export * from './payment-settings.schema'; export * from './shipping-address.schema'; export * from './user.schema'; +export * from './add-booking.schema'; diff --git a/libs/crm/data-access/src/lib/services/crm-search.service.ts b/libs/crm/data-access/src/lib/services/crm-search.service.ts index 302ce37cb..4e3b3be75 100644 --- a/libs/crm/data-access/src/lib/services/crm-search.service.ts +++ b/libs/crm/data-access/src/lib/services/crm-search.service.ts @@ -3,8 +3,13 @@ import { CustomerService, LoyaltyCardService, LoyaltyBookingInfoDTO, + KeyValueDTOOfStringAndString, + KeyValueDTOOfStringAndInteger, } from '@generated/swagger/crm-api'; import { + AddBooking, + AddBookingInput, + AddBookingSchema, Customer, FetchCustomerCardsInput, FetchCustomerCardsSchema, @@ -14,6 +19,7 @@ import { import { catchResponseArgsErrorPipe, ResponseArgs, + ResponseArgsError, takeUntilAborted, } from '@isa/common/data-access'; import { firstValueFrom } from 'rxjs'; @@ -104,4 +110,77 @@ export class CrmSearchService { return []; } } + + async fetchBookingReasons( + abortSignal?: AbortSignal, + ): Promise { + this.#logger.info('Fetching booking reasons from API'); + + let req$ = this.#loyaltyCardService + .LoyaltyCardBookingReason() + .pipe(catchResponseArgsErrorPipe()); + + if (abortSignal) { + req$ = req$.pipe(takeUntilAborted(abortSignal)); + } + + try { + const res = await firstValueFrom(req$); + this.#logger.debug('Successfully fetched booking reasons'); + + return res?.result || []; + } catch (error) { + this.#logger.error('Error fetching booking reasons', error); + return []; + } + } + + async fetchCurrentBookingPartnerStore( + abortSignal?: AbortSignal, + ): Promise { + this.#logger.info('Fetching current booking partner store from API'); + + let req$ = this.#loyaltyCardService + .LoyaltyCardCurrentBookingPartnerStore() + .pipe(catchResponseArgsErrorPipe()); + + if (abortSignal) { + req$ = req$.pipe(takeUntilAborted(abortSignal)); + } + + try { + const res = await firstValueFrom(req$); + this.#logger.debug('Successfully fetched current booking partner store'); + + return res?.result; + } catch (error) { + this.#logger.error('Error fetching current booking partner store', error); + return undefined; + } + } + + async addBooking( + params: AddBookingInput, + ): Promise { + const parsed = AddBookingSchema.parse(params); + + const req$ = this.#loyaltyCardService.LoyaltyCardAddBooking({ + cardCode: parsed.cardCode, + booking: { + points: parsed.booking.points, + reason: parsed.booking.reason, + storeId: parsed.booking.storeId, + }, + }); + + const res = await firstValueFrom(req$); + + if (res.error) { + const err = new ResponseArgsError(res); + this.#logger.error('Add Booking Failed', err); + throw err; + } + + return res?.result; + } } diff --git a/libs/crm/feature/customer-booking/README.md b/libs/crm/feature/customer-booking/README.md new file mode 100644 index 000000000..c28ab24ee --- /dev/null +++ b/libs/crm/feature/customer-booking/README.md @@ -0,0 +1,7 @@ +# crm-feature-customer-booking + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test crm-feature-customer-booking` to execute the unit tests. diff --git a/libs/crm/feature/customer-booking/eslint.config.cjs b/libs/crm/feature/customer-booking/eslint.config.cjs new file mode 100644 index 000000000..86877dc4b --- /dev/null +++ b/libs/crm/feature/customer-booking/eslint.config.cjs @@ -0,0 +1,34 @@ +const nx = require('@nx/eslint-plugin'); +const baseConfig = require('../../../../eslint.config.js'); + +module.exports = [ + ...baseConfig, + ...nx.configs['flat/angular'], + ...nx.configs['flat/angular-template'], + { + files: ['**/*.ts'], + rules: { + '@angular-eslint/directive-selector': [ + 'error', + { + type: 'attribute', + prefix: 'lib', + style: 'camelCase', + }, + ], + '@angular-eslint/component-selector': [ + 'error', + { + type: 'element', + prefix: 'lib', + style: 'kebab-case', + }, + ], + }, + }, + { + files: ['**/*.html'], + // Override or add rules here + rules: {}, + }, +]; diff --git a/libs/crm/feature/customer-booking/project.json b/libs/crm/feature/customer-booking/project.json new file mode 100644 index 000000000..a98702b12 --- /dev/null +++ b/libs/crm/feature/customer-booking/project.json @@ -0,0 +1,20 @@ +{ + "name": "crm-feature-customer-booking", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/crm/feature/customer-booking/src", + "prefix": "lib", + "projectType": "library", + "tags": [], + "targets": { + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "../../../../coverage/libs/crm/feature/customer-booking" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/libs/crm/feature/customer-booking/src/index.ts b/libs/crm/feature/customer-booking/src/index.ts new file mode 100644 index 000000000..e1ff51eec --- /dev/null +++ b/libs/crm/feature/customer-booking/src/index.ts @@ -0,0 +1 @@ +export * from './lib/crm-feature-customer-booking/crm-feature-customer-booking.component'; diff --git a/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.css b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.css new file mode 100644 index 000000000..cb9a266b0 --- /dev/null +++ b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.css @@ -0,0 +1,15 @@ +:host { + @apply h-[15.5rem] flex flex-col gap-4 rounded-2xl bg-isa-neutral-200 p-8 justify-between; +} + +/* Remove number input arrows */ +input[type='number']::-webkit-outer-spin-button, +input[type='number']::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +input[type='number'] { + -moz-appearance: textfield; + appearance: textfield; +} diff --git a/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.html b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.html new file mode 100644 index 000000000..39bd80162 --- /dev/null +++ b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.html @@ -0,0 +1,67 @@ +@if (cardCode() && !bookingReasonsLoading()) { +
+ Kulanzbuchungen + 1€ entspricht 10 Lesepunkten +
+ +
+
Buchen
+
+
+ @if (selectedReason(); as reason) { + + {{ reason.value > 0 ? '+' : '-' }} + + } + +
+ + @if (bookingReasons(); as reasons) { + @for (reason of reasons; track reason.key) { + + {{ reason.label }} + + } + } + +
+
+ + +} diff --git a/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.spec.ts b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.spec.ts new file mode 100644 index 000000000..f9a26642d --- /dev/null +++ b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CrmFeatureCustomerBookingComponent } from './crm-feature-customer-booking.component'; + +describe('CrmFeatureCustomerBookingComponent', () => { + let component: CrmFeatureCustomerBookingComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CrmFeatureCustomerBookingComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(CrmFeatureCustomerBookingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.ts b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.ts new file mode 100644 index 000000000..1e477c242 --- /dev/null +++ b/libs/crm/feature/customer-booking/src/lib/crm-feature-customer-booking/crm-feature-customer-booking.component.ts @@ -0,0 +1,149 @@ +import { + ChangeDetectionStrategy, + Component, + signal, + computed, + input, + inject, +} from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { ButtonComponent } from '@isa/ui/buttons'; +import { + CustomerBookingReasonsResource, + CustomerCardBookingFacade, + CustomerCardTransactionsResource, +} from '@isa/crm/data-access'; +import { + injectFeedbackDialog, + injectFeedbackErrorDialog, +} from '@isa/ui/dialog'; +import { logger } from '@isa/core/logging'; +import { + DropdownButtonComponent, + DropdownOptionComponent, +} from '@isa/ui/input-controls'; + +@Component({ + selector: 'crm-customer-booking', + imports: [ + FormsModule, + ButtonComponent, + DropdownButtonComponent, + DropdownOptionComponent, + ], + templateUrl: './crm-feature-customer-booking.component.html', + styleUrl: './crm-feature-customer-booking.component.css', + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [CustomerBookingReasonsResource], +}) +export class CrmFeatureCustomerBookingComponent { + #logger = logger(() => ({ + component: 'CrmFeatureCustomerBookingComponent', + })); + #customerCardBookingFacade = inject(CustomerCardBookingFacade); + #bookingReasonsResource = inject(CustomerBookingReasonsResource); + #transactionResource = inject(CustomerCardTransactionsResource); + #errorFeedbackDialog = injectFeedbackErrorDialog(); + #feedbackDialog = injectFeedbackDialog(); + readonly cardCode = input(undefined); + + readonly bookingReasons = this.#bookingReasonsResource.resource.value; + readonly bookingReasonsLoading = + this.#bookingReasonsResource.resource.isLoading; + + points = signal(undefined); + selectedReasonKey = signal(undefined); + isBooking = signal(false); + + selectedReason = computed(() => { + const key = this.selectedReasonKey(); + const reasons = this.bookingReasons(); + return reasons?.find((r) => r.key === key); + }); + + calculatedPoints = computed(() => { + const reason = this.selectedReason(); + const pointsValue = this.points(); + if (!reason || !pointsValue) return 0; + return pointsValue * (reason.value ?? 1); + }); + + disableBooking = computed(() => { + return ( + this.isBooking() || + this.bookingReasonsLoading() || + !this.selectedReasonKey() || + !this.points() || + this.points() === 0 + ); + }); + + dropdownLabel = computed(() => { + const reason = this.selectedReason()?.label; + return reason ?? 'Buchungstyp'; + }); + + async booking() { + this.isBooking.set(true); + try { + const cardCode = this.cardCode(); + const reason = this.selectedReason(); + const calculatedPoints = this.calculatedPoints(); + + if (!cardCode) { + throw new Error('Kein Karten-Code vorhanden'); + } + + if (!reason) { + throw new Error('Kein Buchungsgrund ausgewählt'); + } + + if (calculatedPoints === 0) { + throw new Error('Punktezahl muss größer als 0 sein'); + } + + const currentBookingPartnerStore = + await this.#customerCardBookingFacade.fetchCurrentBookingPartnerStore(); + const storeId = currentBookingPartnerStore?.key; + + await this.#customerCardBookingFacade.addBooking({ + cardCode, + booking: { + points: calculatedPoints, + reason: reason.key, + storeId: storeId, + }, + }); + + this.#feedbackDialog({ + data: { + message: `${reason.label} erfolgreich durchgeführt`, + }, + }); + this.reloadTransactionHistory(); + } catch (error: any) { + this.#logger.error('Booking Failed', () => ({ error })); + this.#errorFeedbackDialog({ + data: { + errorMessage: error?.message ?? 'Buchen/Stornieren fehlgeschlagen', + }, + }); + } finally { + this.isBooking.set(false); + this.resetInputs(); + } + } + + resetInputs() { + this.points.set(undefined); + this.selectedReasonKey.set(undefined); + } + + reloadTransactionHistory() { + // Timeout to ensure that the new booking is available in the transaction history + setTimeout(() => { + this.#transactionResource.params({ cardCode: this.cardCode() }); + this.#transactionResource.resource.reload(); + }, 500); + } +} diff --git a/libs/crm/feature/customer-booking/src/test-setup.ts b/libs/crm/feature/customer-booking/src/test-setup.ts new file mode 100644 index 000000000..cebf5ae72 --- /dev/null +++ b/libs/crm/feature/customer-booking/src/test-setup.ts @@ -0,0 +1,13 @@ +import '@angular/compiler'; +import '@analogjs/vitest-angular/setup-zone'; + +import { + BrowserTestingModule, + platformBrowserTesting, +} from '@angular/platform-browser/testing'; +import { getTestBed } from '@angular/core/testing'; + +getTestBed().initTestEnvironment( + BrowserTestingModule, + platformBrowserTesting(), +); diff --git a/libs/crm/feature/customer-booking/tsconfig.json b/libs/crm/feature/customer-booking/tsconfig.json new file mode 100644 index 000000000..06f8b89a6 --- /dev/null +++ b/libs/crm/feature/customer-booking/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "importHelpers": true, + "moduleResolution": "bundler", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "typeCheckHostBindings": true, + "strictTemplates": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/crm/feature/customer-booking/tsconfig.lib.json b/libs/crm/feature/customer-booking/tsconfig.lib.json new file mode 100644 index 000000000..9259117c2 --- /dev/null +++ b/libs/crm/feature/customer-booking/tsconfig.lib.json @@ -0,0 +1,27 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": [ + "src/**/*.spec.ts", + "src/test-setup.ts", + "jest.config.ts", + "src/**/*.test.ts", + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx" + ], + "include": ["src/**/*.ts"] +} diff --git a/libs/crm/feature/customer-booking/tsconfig.spec.json b/libs/crm/feature/customer-booking/tsconfig.spec.json new file mode 100644 index 000000000..b2f92f3ec --- /dev/null +++ b/libs/crm/feature/customer-booking/tsconfig.spec.json @@ -0,0 +1,29 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ], + "files": ["src/test-setup.ts"] +} diff --git a/libs/crm/feature/customer-booking/vite.config.mts b/libs/crm/feature/customer-booking/vite.config.mts new file mode 100644 index 000000000..de114bc58 --- /dev/null +++ b/libs/crm/feature/customer-booking/vite.config.mts @@ -0,0 +1,28 @@ +/// +import { defineConfig } from 'vite'; +import angular from '@analogjs/vite-plugin-angular'; +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; +import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; + +export default defineConfig(() => ({ + root: __dirname, + cacheDir: '../../../../node_modules/.vite/libs/crm/feature/customer-booking', + plugins: [angular(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + test: { + watch: false, + globals: true, + environment: 'jsdom', + include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + setupFiles: ['src/test-setup.ts'], + reporters: ['default'], + coverage: { + reportsDirectory: + '../../../../coverage/libs/crm/feature/customer-booking', + provider: 'v8' as const, + }, + }, +})); diff --git a/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.html b/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.html index 1b9703243..870e014dc 100644 --- a/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.html +++ b/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.html @@ -1,7 +1,9 @@ -
-

- Letzte Transaktionen des Kunden -

+
+ @if (transactions()?.length) { +

+ Letzte 5 Transaktionen des Kunden +

+ } @if (isLoading()) {
Lade Transaktionen...
@@ -11,9 +13,10 @@
} @else if (!transactions()?.length) { } @else { diff --git a/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.ts b/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.ts index ac3d1085f..37d697d2b 100644 --- a/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.ts +++ b/libs/crm/feature/customer-card-transactions/src/lib/crm-feature-customer-card-transactions/crm-feature-customer-card-transactions.component.ts @@ -24,10 +24,7 @@ import { LoyaltyBookingInfoDTO } from '@generated/swagger/crm-api'; NgIconComponent, EmptyStateComponent, ], - providers: [ - CustomerCardTransactionsResource, - provideIcons({ isaActionPolygonUp, isaActionPolygonDown }), - ], + providers: [provideIcons({ isaActionPolygonUp, isaActionPolygonDown })], templateUrl: './crm-feature-customer-card-transactions.component.html', styleUrl: './crm-feature-customer-card-transactions.component.css', changeDetection: ChangeDetectionStrategy.OnPush, @@ -78,6 +75,8 @@ export class CrmFeatureCustomerCardTransactionsComponent { const code = this.cardCode(); this.#logger.debug('Card code changed', () => ({ cardCode: code })); this.#transactionsResource.params({ cardCode: code }); + + console.log(this.transactions()); }); } } diff --git a/package-lock.json b/package-lock.json index 1d70f8c7a..d45fbe098 100644 --- a/package-lock.json +++ b/package-lock.json @@ -364,7 +364,6 @@ "integrity": "sha512-qEt+M6UAuBUD8lrhmHFFpaKYVeANfVrgZijkebfdDJtQybNL/2bVypJCX7D60XHC2weKHSrp8f18uhmNnvjeGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ts-morph": "^21.0.0", "vfile": "^6.0.3" @@ -429,7 +428,6 @@ "integrity": "sha512-p0GO2H8hiZjRHI9sm4tXTF3OpWaEnkqvB0GBGJfGp8RvpPfDA2t3j2NAUNtd75H+B0xdfyWLmNq9YJGpy6gznA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/core": "20.3.9", "rxjs": "7.8.2" @@ -474,7 +472,6 @@ "integrity": "sha512-DCzHY+EQ98u0h1n8s9add1KVSNWco1RW/Rl8TRkEuGmRQ43MpOfTIZQvlnnqaeMcNH0fZ4zkybVBDj7korJbZg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "2.3.0", "@angular-devkit/architect": "0.2003.9", @@ -708,7 +705,6 @@ "integrity": "sha512-uLRk3865Iz/EO9Zm/mrFfdyoZinJBihXE6HVDYRYjAqsgW14LsD8pkpWy9+LYlOwcH96Ndnev+msxaTJaNXtPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ajv": "8.17.1", "ajv-formats": "3.0.1", @@ -737,7 +733,6 @@ "integrity": "sha512-QD7QS1oR0XcZ9ZI4D1c4JjKmSn2up/ocOU2FS1mMO7S5RtAZMsPv4J3r+6ywHA2ev2sRySOQ0D8OYBcEuYX9Jw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/core": "20.3.6", "jsonc-parser": "3.3.1", @@ -852,7 +847,6 @@ "integrity": "sha512-5Vyo/VJ1DrIsAkudFpZj1f7CpCLYuiTzTQksHTiZE18iYsLKRkEC7y9S6+TiHrdD96rhNxL28Pz9FDU4lIBjkw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-eslint/bundled-angular-compiler": "20.4.0", "eslint-scope": "^8.0.2" @@ -882,7 +876,6 @@ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.6.tgz", "integrity": "sha512-qNaVvEOKvigoCQMg0ABnq44HhiHqKD4WN3KoUcXneklcMYCzFE5nuQxKylfWzCRiI5XqiJ9pqiL1m2D7o+Vdiw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -899,7 +892,6 @@ "integrity": "sha512-Ulimvg6twPSCraaZECEmENfKBlD4M1yqeHlg6dCzFNM4xcwaGUnuG6O3cIQD59DaEvaG73ceM2y8ftYdxAwFow==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "2.3.0", "@angular-devkit/architect": "0.2003.9", @@ -993,18 +985,6 @@ } } }, - "node_modules/@angular/build/node_modules/@types/node": { - "version": "24.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", - "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "undici-types": "~7.16.0" - } - }, "node_modules/@angular/build/node_modules/vite": { "version": "7.1.11", "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", @@ -1118,7 +1098,6 @@ "integrity": "sha512-4eKpRDg96B20yrKJqjA24zgxYy1RiRd70FvF/KG1hqSowsWwtzydtEJ3VM6iFWS9t1D8truuVpKjMEnn1Y274A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/architect": "0.2003.9", "@angular-devkit/core": "20.3.9", @@ -1217,7 +1196,6 @@ "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.6.tgz", "integrity": "sha512-+gHMuFe0wz4f+vfGZ2q+fSQSYaY7KlN7QdDrFqLnA7H2sythzhXvRbXEtp4DkPjihh9gupXg2MeLh1ROy5AfSw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1234,7 +1212,6 @@ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.6.tgz", "integrity": "sha512-OdjXBsAsnn7qiW6fSHClwn9XwjVxhtO9+RbDc6Mf+YPCnJq0s8T78H2fc8VdJFp/Rs+tMZcwwjd9VZPm8+2XWA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1246,8 +1223,8 @@ "version": "20.3.6", "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.6.tgz", "integrity": "sha512-VOFRBx9fBt2jW9I8qD23fwGeKxBI8JssJBAMqnFPl3k59VJWHQi6LlXZCLCBNdfwflTJdKeRvdgT51Q0k6tnFQ==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "7.28.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -1280,7 +1257,6 @@ "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.6.tgz", "integrity": "sha512-sDURQWnjwE4Y750u/5qwkZEYMoI4CrKghnx4aKulxCnohR3//C78wvz6p8MtCuqYfzGkdQZDYFg8tgAz17qgPw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1306,7 +1282,6 @@ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.6.tgz", "integrity": "sha512-tBGo/LBtCtSrClMY4DTm/3UiSjqLLMEYXS/4E0nW1mFDv7ulKnaAQB+KbfBmmTHYxlKLs+SxjKv6GoydMPSurA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1335,7 +1310,6 @@ "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.6.tgz", "integrity": "sha512-isOHiGYHSK+ySK8ry21PGO3jpJpF90E3J2BZ+LUhzpi1SzFBguEVg7j8fvbCLodiwweOnuAiKEHO0F3WpfCQ9Q==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "7.28.3", "@types/babel__core": "7.20.5", @@ -1360,7 +1334,6 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.6.tgz", "integrity": "sha512-gFp1yd+HtRN8XdpMatRLO5w6FLIzsnF31lD2Duo4BUTCoMAMdfaNT6FtcvNdKu7ANo27Ke26fxEEE2bh6FU98A==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1383,7 +1356,6 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.6.tgz", "integrity": "sha512-teO8tBygk6vD1waiLmHGXtXPF/9a9Bw2XI+s550KtJlQqRpr7IUWOFPPQik/uGkppv5Jrv6fP+8mh9QX9zoWnQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1427,7 +1399,6 @@ "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.6.tgz", "integrity": "sha512-fSAYOR9nKpH5PoBYFNdII3nAFl2maUrYiISU33CnGwb7J7Q0s09k231c/P5tVN4URi+jdADVwiBI8cIYk8SVrg==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1446,7 +1417,6 @@ "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-20.3.6.tgz", "integrity": "sha512-utHJCoEO4EKH372BSMnNbcR96yDVkUeV7xcJb+cw9ruTOxGvCG/DUWR1h64xk3Ns6nvFmggTnIVgnBDn+92VpQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1489,7 +1459,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -4419,7 +4388,6 @@ "integrity": "sha512-nqhDw2ZcAUrKNPwhjinJny903bRhI0rQhiDz1LksjeRxqa36i3l75+4iXbOy0rlDpLJGxqtgoPavQjmmyS5UJw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@inquirer/checkbox": "^4.2.1", "@inquirer/confirm": "^5.1.14", @@ -6627,110 +6595,6 @@ "win32" ] }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/@mdx-js/react": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", @@ -7437,7 +7301,6 @@ "integrity": "sha512-YEdHA/rXlydI+ecmsidM0imAhAgyN+fSCOWRJtm72Kx10J6kS2tN1/Zah/hf9C9Msj9OOl0w22aOo7/Sy0qRqg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/bridge-react-webpack-plugin": "0.17.1", "@module-federation/cli": "0.17.1", @@ -7523,7 +7386,6 @@ "integrity": "sha512-2v9ks2caLDJl1wAqVeFLaxKK7oBT6jM1nHzJXsFqgTC0xN2GyRBUz+SHmcXIRcMW5FZKIBBzv8OZrte2/z5PWQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/enhanced": "0.21.4", "@module-federation/runtime": "0.21.4", @@ -7775,7 +7637,6 @@ "integrity": "sha512-RzFKaL0DIjSmkn76KZRfzfB6dD07cvID84950jlNQgdyoQFUGkqD80L6rIpVCJTY/R7LzR3aQjHnoqmq4JPo3w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/runtime": "0.21.4", "@module-federation/webpack-bundler-runtime": "0.21.4" @@ -8023,7 +7884,6 @@ "integrity": "sha512-4kr6zTFFwGywJx6whBtxsc84V+COAuuBpEdEbPZN//YLXhNB0iz2IGsy9r9wDl+06h84bD+3dQ05l9euRLgXzQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/runtime": "0.17.1", "@module-federation/webpack-bundler-runtime": "0.17.1" @@ -8595,7 +8455,6 @@ "resolved": "https://registry.npmjs.org/@ngrx/signals/-/signals-20.1.0.tgz", "integrity": "sha512-ARAHp5yA131Sw6FEtY8XtYcdGcwW5lgpZaJoDIRxc6i12VO3ZDZYp3M/FQhpIDMDXkXHR+pDqoitrqvzI69aQA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -8614,7 +8473,6 @@ "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-20.1.0.tgz", "integrity": "sha512-o8j3CGAGedm+BIb+QDhNXrVaU//n9uF0wH0HZWtXHmW1mjRBaQiUA+ZPMUkDwAeN8KuOcoIEC+2QUXxXGVI7ow==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.0.0" }, @@ -10727,7 +10585,6 @@ "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -11935,7 +11792,6 @@ "integrity": "sha512-hZVrmiZoBTchWUdh/XbeJ5z+GqHW5aPYeufBigmtUeyzul8uJtHlWKmQhpG+lplMf6o1RESTjjxl632TP/Cfhg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@module-federation/runtime-tools": "0.21.2", "@rspack/binding": "1.6.1", @@ -12179,7 +12035,6 @@ "integrity": "sha512-YPIEyKPBOyJYlda5fA49kMThzZ4WidomEMDghshux8xidbjDaPWBZdyVPQj3IXyW0teGlUM/TH0TH2weumMZrg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@angular-devkit/core": "20.3.6", "@angular-devkit/schematics": "20.3.6", @@ -12447,7 +12302,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12863,7 +12717,6 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.23" @@ -13089,7 +12942,6 @@ "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@swc/counter": "^0.1.3" } @@ -13100,7 +12952,6 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -13433,7 +13284,6 @@ "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -13644,8 +13494,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz", "integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/node-forge": { "version": "1.3.14", @@ -13684,17 +13533,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.3.tgz", - "integrity": "sha512-k5dJVszUiNr1DSe8Cs+knKR6IrqhqdhpUwzqhkS8ecQTSf3THNtbfIp/umqHMpX2bv+9dkx3fwDv/86LcSfvSg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "csstype": "^3.0.2" - } - }, "node_modules/@types/retry": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", @@ -13869,7 +13707,6 @@ "integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/types": "8.46.4", @@ -13977,7 +13814,6 @@ "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -14037,7 +13873,6 @@ "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.4", @@ -14539,7 +14374,6 @@ "integrity": "sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/utils": "3.2.4", "fflate": "^0.8.2", @@ -14773,7 +14607,6 @@ "integrity": "sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -14831,7 +14664,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -14951,7 +14783,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -15165,30 +14996,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/aproba": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", - "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -15937,7 +15744,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", @@ -16280,24 +16086,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/canvas": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", - "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "nan": "^2.17.0", - "simple-get": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", @@ -16370,8 +16158,8 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "readdirp": "^4.0.1" }, @@ -16706,17 +16494,6 @@ "dev": true, "license": "MIT" }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "license": "ISC", - "optional": true, - "bin": { - "color-support": "bin.js" - } - }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -16883,14 +16660,6 @@ "node": ">=0.8" } }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true, - "license": "ISC", - "optional": true - }, "node_modules/content-disposition": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", @@ -16918,6 +16687,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, "license": "MIT" }, "node_modules/cookie": { @@ -18371,20 +18141,6 @@ "dev": true, "license": "MIT" }, - "node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dedent": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", @@ -18924,7 +18680,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "iconv-lite": "^0.6.2" @@ -18934,7 +18690,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -19127,7 +18883,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -19169,7 +18924,6 @@ "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -19258,7 +19012,6 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -19319,7 +19072,6 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -19708,7 +19460,6 @@ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", @@ -20310,7 +20061,6 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -20644,72 +20394,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gauge/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/gauge/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/gauge/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/generator-function": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", @@ -21179,14 +20863,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true, - "license": "ISC", - "optional": true - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -21373,7 +21049,6 @@ "integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -22372,7 +22047,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -24032,7 +23706,6 @@ "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -27239,7 +26912,6 @@ "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -27300,7 +26972,6 @@ "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "abab": "^2.0.6", "cssstyle": "^3.0.0", @@ -27853,7 +27524,6 @@ "integrity": "sha512-kdTwsyRuncDfjEs0DlRILWNvxhDG/Zij4YLO4TMJgDLW+8OzpfkdPnRgrsRuY1o+oaxJGWsps5f/RVBgGmmN0w==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -28758,20 +28428,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -29127,14 +28783,6 @@ "thenify-all": "^1.0.0" } }, - "node_modules/nan": { - "version": "2.23.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.1.tgz", - "integrity": "sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -29255,7 +28903,6 @@ "integrity": "sha512-hwPZNeV/6C3pWojK70AHxe6uk1rz2bzoe+WdH+GIWouUcyXrjYQjOFyLfOGD0ia9D+yWVzjsi4CKVK/dQFDQ6Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.3.0", "@rollup/plugin-json": "^6.1.0", @@ -29849,21 +29496,6 @@ "node": ">=8" } }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -29891,7 +29523,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "@napi-rs/wasm-runtime": "0.2.4", "@yarnpkg/lockfile": "^1.1.0", @@ -31140,7 +30771,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -32035,7 +31665,6 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -32388,7 +32017,6 @@ "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -32399,7 +32027,6 @@ "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -32414,17 +32041,6 @@ "dev": true, "license": "MIT" }, - "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -32464,6 +32080,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -32518,6 +32135,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, "license": "Apache-2.0" }, "node_modules/regenerate": { @@ -32912,73 +32530,6 @@ "dev": true, "license": "MIT" }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -33003,7 +32554,6 @@ "integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -33136,7 +32686,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -33184,7 +32733,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/sass": { @@ -33699,7 +33248,6 @@ "resolved": "https://registry.npmjs.org/scandit-web-datacapture-core/-/scandit-web-datacapture-core-6.28.7.tgz", "integrity": "sha512-hcujpTCu7SScqr/8uHITGmudgT9R6hhVv+LCv33nspGBj+DCL2sMHQRUiK3GdXO7Y0c0cEnXekZ/N4LKimtU/g==", "license": "SEE LICENSE IN LICENSE", - "peer": true, "dependencies": { "@types/howler": "^2.2.11", "@types/js-cookie": "^2.2.6", @@ -33803,6 +33351,7 @@ "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -34029,14 +33578,6 @@ "node": ">= 18" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "license": "ISC", - "optional": true - }, "node_modules/set-cookie-parser": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", @@ -34234,19 +33775,6 @@ "license": "MIT", "optional": true }, - "node_modules/simple-get": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", - "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/sirv": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", @@ -34605,7 +34133,6 @@ "integrity": "sha512-339U14K6l46EFyRvaPS2ZlL7v7Pb+LlcXT8KAETrGPxq8v1sAjj2HAOB6zrlAK3M+0+ricssfAwsLCwt7Eg8TQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@storybook/global": "^5.0.0", "@testing-library/jest-dom": "^6.6.3", @@ -34945,7 +34472,6 @@ "integrity": "sha512-ZIdT8eUv8tegmqy1tTIdJv9We2DumkNZFdCF5mz/Kpq3OcTaxSuCAYZge6HKK2CmNC02G1eJig2RV7XTw5hQrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@adobe/css-tools": "~4.3.3", "debug": "^4.3.2", @@ -35176,7 +34702,6 @@ "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -35253,7 +34778,6 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -35497,7 +35021,6 @@ "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.14.0", @@ -36131,7 +35654,6 @@ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -36238,8 +35760,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -36351,9 +35872,8 @@ "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -36368,7 +35888,6 @@ "integrity": "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.4", "@typescript-eslint/parser": "8.46.4", @@ -36427,14 +35946,6 @@ "node": ">=0.8.0" } }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -36804,7 +36315,6 @@ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -36903,7 +36413,6 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", @@ -37058,7 +36567,6 @@ "integrity": "sha512-4JLXU0tD6OZNVqlwzm3HGEhAHufSiyv+skb7q0d2367VDMzrU1Q/ZeepvkcHH0rZie6uqEtTQQe0OEOOluH3Mg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -37701,7 +37209,6 @@ "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-html-community": "0.0.8", "html-entities": "^2.1.0", @@ -37934,52 +37441,6 @@ "node": ">=8" } }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wide-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", @@ -38128,7 +37589,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=8.3.0" }, @@ -38216,7 +37676,6 @@ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -38404,7 +37863,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -38423,8 +37881,7 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", - "license": "MIT", - "peer": true + "license": "MIT" } } } diff --git a/tsconfig.base.json b/tsconfig.base.json index 92ad5779b..ce4de57b6 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -69,6 +69,9 @@ "@isa/core/storage": ["libs/core/storage/src/index.ts"], "@isa/core/tabs": ["libs/core/tabs/src/index.ts"], "@isa/crm/data-access": ["libs/crm/data-access/src/index.ts"], + "@isa/crm/feature/customer-booking": [ + "libs/crm/feature/customer-booking/src/index.ts" + ], "@isa/crm/feature/customer-card-transactions": [ "libs/crm/feature/customer-card-transactions/src/index.ts" ],