Merged PR 2034: feat(crm): set selected customer when navigating to Prämienshop

 feat(crm): set selected customer when navigating to Prämienshop

Implements autoTriggerContinueFn pattern to properly set customer context
before navigating to reward shop from customer loyalty cards view.

Changes:
- Add output event to customer-loyalty-cards component (library layer)
- Handle navigation at app layer (kundenkarte-main-view) to respect module boundaries
- Use existing autoTriggerContinueFn pattern from details-main-view
- Inject NavigationStateService and CustomerSearchNavigation services
- Preserve context with returnUrl and autoTriggerContinueFn flag

This ensures customer selection logic (_setCustomer, _setBuyer, _setSelectedCustomerIdInTab)
executes before navigating to the reward shop, matching the behavior of the
continue() method in CustomerDetailsViewMainComponent.

Refs: #5485

Related work items: #5485
This commit is contained in:
Lorenz Hilpert
2025-11-20 15:15:32 +00:00
committed by Nino Righi
parent f3d5466f81
commit c873546160
3 changed files with 47 additions and 9 deletions

View File

@@ -8,6 +8,7 @@
<crm-customer-loyalty-cards
[customerId]="customerId$ | async"
[tabId]="processId$ | async"
(navigateToPraemienshop)="onNavigateToPraemienshop()"
class="mt-4"
/>
@let cardCode = firstActiveCardCode();

View File

@@ -8,8 +8,10 @@ import {
OnDestroy,
} from '@angular/core';
import { CustomerSearchStore } from '../store';
import { ActivatedRoute } from '@angular/router';
import { ActivatedRoute, Router } from '@angular/router';
import { map } from 'rxjs/operators';
import { NavigationStateService } from '@isa/core/navigation';
import { CustomerSearchNavigation } from '@shared/services/navigation';
import { AsyncPipe } from '@angular/common';
import { CustomerMenuComponent } from '../../components/customer-menu';
import { CustomerLoyaltyCardsComponent } from '@isa/crm/feature/customer-loyalty-cards';
@@ -48,6 +50,9 @@ export class KundenkarteMainViewComponent implements OnDestroy {
private _bonusCardsResource = inject(CustomerBonusCardsResource);
#cardTransactionsResource = inject(CustomerCardTransactionsResource);
elementRef = inject(ElementRef);
#router = inject(Router);
#navigationState = inject(NavigationStateService);
#customerNavigationService = inject(CustomerSearchNavigation);
get hostElement() {
return this.elementRef.nativeElement;
@@ -89,6 +94,36 @@ export class KundenkarteMainViewComponent implements OnDestroy {
}, 500);
}
/**
* Handle navigation to Prämienshop with proper customer selection.
* Uses autoTriggerContinueFn pattern to auto-select customer via details view.
*/
async onNavigateToPraemienshop(): Promise<void> {
const tabId = this._store.processId;
const customerId = this.customerId();
if (!customerId || !tabId) {
return;
}
// Preserve context for auto-triggering continue() in details view
this.#navigationState.preserveContext(
{
returnUrl: `/${tabId}/reward`,
autoTriggerContinueFn: true,
},
'select-customer',
);
// Navigate to customer details - will auto-trigger continue()
await this.#router.navigate(
this.#customerNavigationService.detailsRoute({
processId: tabId,
customerId: Number(customerId),
}).path,
);
}
ngOnDestroy(): void {
if (this.#reloadTimeoutId) {
clearTimeout(this.#reloadTimeoutId);

View File

@@ -1,11 +1,9 @@
import { Component, effect, inject, input } from '@angular/core';
import { Component, effect, inject, input, output } from '@angular/core';
import { CustomerBonusCardsResource } from '@isa/crm/data-access';
import { logger } from '@isa/core/logging';
import { CustomerCardPointsSummaryComponent } from './components/customer-card-points-summary';
import { CustomerCardsCarouselComponent } from './components/customer-cards-carousel';
import { coerceNumberProperty, NumberInput } from '@angular/cdk/coercion';
import { TextButtonComponent } from '@isa/ui/buttons';
import { Router } from '@angular/router';
import { AddCustomerCardComponent } from './components/add-customer-card/add-customer-card.component';
/**
@@ -30,15 +28,12 @@ import { AddCustomerCardComponent } from './components/add-customer-card/add-cus
imports: [
CustomerCardPointsSummaryComponent,
CustomerCardsCarouselComponent,
TextButtonComponent,
AddCustomerCardComponent,
],
templateUrl: './customer-loyalty-cards.component.html',
styleUrl: './customer-loyalty-cards.component.css',
})
export class CustomerLoyaltyCardsComponent {
#router = inject(Router);
#bonusCardsResource = inject(CustomerBonusCardsResource);
#logger = logger(() => ({
@@ -61,6 +56,12 @@ export class CustomerLoyaltyCardsComponent {
transform: coerceNumberProperty,
});
/**
* Event emitted when user requests navigation to Prämienshop.
* Parent must handle navigation using autoTriggerContinueFn pattern.
*/
readonly navigateToPraemienshop = output<void>();
/**
* All bonus cards for the selected customer.
*/
@@ -89,9 +90,10 @@ export class CustomerLoyaltyCardsComponent {
/**
* Handle navigation to Prämienshop.
* Emits event for parent to handle navigation with proper customer selection.
*/
onNavigateToPraemienshop(): void {
this.#logger.info('Navigate to Prämienshop requested');
this.#router.navigate([`${this.tabId()}/reward`]);
this.#logger.info('Emit navigate to Prämienshop event');
this.navigateToPraemienshop.emit();
}
}