mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Merged PR 2060: feature(checkout-reward, core-tabs): Added back button and configured it so i...
feature(checkout-reward, core-tabs): Added back button and configured it so it can accept optional route to navigate. Added orderNumber and orderDate to reward order confirmation Ref: #5456
This commit is contained in:
committed by
Lorenz Hilpert
parent
41630d5d7c
commit
c0cc0e1bbc
@@ -1,3 +1,7 @@
|
||||
:host {
|
||||
@apply w-full flex flex-row items-center justify-between;
|
||||
}
|
||||
|
||||
ui-item-row-data-label {
|
||||
width: 12.4rem;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
<h1 class="text-isa-neutral-900 isa-text-subtitle-1-regular">
|
||||
Prämienausgabe abgeschlossen
|
||||
</h1>
|
||||
<div class="flex flex-col gap-4">
|
||||
<h1 class="text-isa-neutral-900 isa-text-subtitle-1-regular">
|
||||
Prämienausgabe abgeschlossen
|
||||
</h1>
|
||||
<ui-item-row-data>
|
||||
<ui-item-row-data-row>
|
||||
<ui-item-row-data-label>Vorgangs-ID</ui-item-row-data-label>
|
||||
<ui-item-row-data-value>{{ orderNumbers() }}</ui-item-row-data-value>
|
||||
</ui-item-row-data-row>
|
||||
<ui-item-row-data-row>
|
||||
<ui-item-row-data-label>Bestelldatum</ui-item-row-data-label>
|
||||
<ui-item-row-data-value>{{ orderDates() }}</ui-item-row-data-value>
|
||||
</ui-item-row-data-row>
|
||||
</ui-item-row-data>
|
||||
</div>
|
||||
|
||||
<common-print-button
|
||||
class="self-start"
|
||||
*ifNotRole="Role.CallCenter"
|
||||
printerType="label"
|
||||
[printFn]="printFn"
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
inject,
|
||||
computed,
|
||||
} from '@angular/core';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { CheckoutPrintFacade } from '@isa/checkout/data-access';
|
||||
import { PrintButtonComponent, Printer } from '@isa/common/print';
|
||||
import { OrderConfiramtionStore } from '../reward-order-confirmation.store';
|
||||
import { IfRoleDirective, Role } from '@isa/core/auth';
|
||||
import { ItemRowDataImports } from '@isa/ui/item-rows';
|
||||
|
||||
@Component({
|
||||
selector: 'checkout-order-confirmation-header',
|
||||
templateUrl: './order-confirmation-header.component.html',
|
||||
styleUrls: ['./order-confirmation-header.component.css'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [PrintButtonComponent, IfRoleDirective],
|
||||
imports: [PrintButtonComponent, IfRoleDirective, ItemRowDataImports],
|
||||
})
|
||||
export class OrderConfirmationHeaderComponent {
|
||||
protected readonly Role = Role;
|
||||
#checkoutPrintFacade = inject(CheckoutPrintFacade);
|
||||
#store = inject(OrderConfiramtionStore);
|
||||
#datePipe = new DatePipe('de-DE');
|
||||
|
||||
orderIds = this.#store.orderIds;
|
||||
|
||||
@@ -24,4 +32,35 @@ export class OrderConfirmationHeaderComponent {
|
||||
data: this.orderIds() ?? [],
|
||||
});
|
||||
};
|
||||
|
||||
orderNumbers = computed(() => {
|
||||
const orders = this.#store.orders();
|
||||
if (!orders || orders.length === 0) {
|
||||
return '';
|
||||
}
|
||||
return orders
|
||||
.map((order) => order.orderNumber)
|
||||
.filter(Boolean)
|
||||
.join('; ');
|
||||
});
|
||||
|
||||
orderDates = computed(() => {
|
||||
const orders = this.#store.orders();
|
||||
if (!orders || orders.length === 0) {
|
||||
return '';
|
||||
}
|
||||
return orders
|
||||
.map((order) => {
|
||||
if (!order.orderDate) {
|
||||
return null;
|
||||
}
|
||||
const formatted = this.#datePipe.transform(
|
||||
order.orderDate,
|
||||
'dd.MM.yyyy | HH:mm',
|
||||
);
|
||||
return formatted ? `${formatted} Uhr` : null;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join('; ');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
HandleCommandService,
|
||||
HandleCommand,
|
||||
getMainActions,
|
||||
DisplayOrdersResource,
|
||||
} from '@isa/oms/data-access';
|
||||
import { ButtonComponent } from '@isa/ui/buttons';
|
||||
import { NgIcon } from '@ng-icons/core';
|
||||
@@ -61,6 +62,7 @@ export class ConfirmationListItemActionCardComponent {
|
||||
#orderRewardCollectFacade = inject(OrderRewardCollectFacade);
|
||||
#store = inject(OrderConfiramtionStore);
|
||||
#orderItemSubsetResource = inject(OrderItemSubsetResource);
|
||||
#displayOrdersResource = inject(DisplayOrdersResource);
|
||||
#handleCommandFacade = inject(HandleCommandFacade);
|
||||
|
||||
item = input.required<DisplayOrderItem>();
|
||||
@@ -165,7 +167,7 @@ export class ConfirmationListItemActionCardComponent {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.#orderItemSubsetResource.refresh();
|
||||
this.reloadResources();
|
||||
}
|
||||
} finally {
|
||||
this.isLoading.set(false);
|
||||
@@ -175,4 +177,9 @@ export class ConfirmationListItemActionCardComponent {
|
||||
async handleCommand(params: HandleCommand) {
|
||||
await this.#handleCommandFacade.handle(params);
|
||||
}
|
||||
|
||||
reloadResources() {
|
||||
this.#orderItemSubsetResource.refresh();
|
||||
this.#displayOrdersResource.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
:host {
|
||||
@apply block w-full text-isa-neutral-900 mt-[1.42rem];
|
||||
@apply flex flex-col w-full text-isa-neutral-900 mt-[1.42rem] gap-4;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
@if (!hasPendingActions()) {
|
||||
<tabs-navigate-back-button [navigateTo]="rewardCatalogRoute()" />
|
||||
}
|
||||
<div
|
||||
class="bg-isa-white p-6 rounded-2xl flex flex-col gap-6 items-start self-stretch"
|
||||
>
|
||||
|
||||
@@ -12,9 +12,21 @@ import { OrderConfirmationAddressesComponent } from './order-confirmation-addres
|
||||
import { OrderConfirmationHeaderComponent } from './order-confirmation-header/order-confirmation-header.component';
|
||||
import { OrderConfirmationItemListComponent } from './order-confirmation-item-list/order-confirmation-item-list.component';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { TabService } from '@isa/core/tabs';
|
||||
import {
|
||||
NavigateBackButtonComponent,
|
||||
TabService,
|
||||
injectTabId,
|
||||
} from '@isa/core/tabs';
|
||||
import { OrderConfiramtionStore } from './reward-order-confirmation.store';
|
||||
import { DisplayOrdersResource } from '@isa/oms/data-access';
|
||||
import {
|
||||
DisplayOrdersResource,
|
||||
getProcessingStatusState,
|
||||
ProcessingStatusState,
|
||||
} from '@isa/oms/data-access';
|
||||
import {
|
||||
hasOrderTypeFeature,
|
||||
hasLoyaltyCollectCommand,
|
||||
} from '@isa/checkout/data-access';
|
||||
|
||||
@Component({
|
||||
selector: 'checkout-reward-order-confirmation',
|
||||
@@ -25,13 +37,14 @@ import { DisplayOrdersResource } from '@isa/oms/data-access';
|
||||
OrderConfirmationHeaderComponent,
|
||||
OrderConfirmationAddressesComponent,
|
||||
OrderConfirmationItemListComponent,
|
||||
NavigateBackButtonComponent,
|
||||
],
|
||||
providers: [OrderConfiramtionStore, DisplayOrdersResource],
|
||||
})
|
||||
export class RewardOrderConfirmationComponent {
|
||||
#store = inject(OrderConfiramtionStore);
|
||||
#displayOrdersResource = inject(DisplayOrdersResource);
|
||||
#tabId = inject(TabService).activatedTabId;
|
||||
#tabId = injectTabId();
|
||||
#activatedRoute = inject(ActivatedRoute);
|
||||
|
||||
params = toSignal(this.#activatedRoute.paramMap);
|
||||
@@ -49,6 +62,43 @@ export class RewardOrderConfirmationComponent {
|
||||
orderIds = this.displayOrderIds;
|
||||
orders = this.#store.orders;
|
||||
|
||||
/**
|
||||
* Checks if there are any items with pending actions (Rücklage items that still need to be collected).
|
||||
* Returns true if at least one item requires action.
|
||||
*/
|
||||
hasPendingActions = computed(() => {
|
||||
const orders = this.#store.orders();
|
||||
if (!orders) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const allItems = orders.flatMap((order) => order.items ?? []);
|
||||
|
||||
return allItems.some((item) => {
|
||||
const isRuecklage = hasOrderTypeFeature(item.features, ['Rücklage']);
|
||||
if (!isRuecklage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const hasCollectCommand = hasLoyaltyCollectCommand(item.subsetItems);
|
||||
const statuses = item.subsetItems?.map(
|
||||
(subset) => subset.processingStatus,
|
||||
);
|
||||
const processingStatus = getProcessingStatusState(statuses);
|
||||
const isComplete =
|
||||
processingStatus !== undefined &&
|
||||
processingStatus !== ProcessingStatusState.Ordered;
|
||||
|
||||
// Item has pending action if it has collect command and is not complete
|
||||
return hasCollectCommand && !isComplete;
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Route to the reward catalog for the current tab.
|
||||
*/
|
||||
rewardCatalogRoute = computed(() => `/${this.#tabId()}/reward`);
|
||||
|
||||
constructor() {
|
||||
// Update store state
|
||||
effect(() => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, inject, computed } from '@angular/core';
|
||||
import { Component, inject, computed, input } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { NgIcon, provideIcons } from '@ng-icons/core';
|
||||
import { isaActionChevronLeft } from '@isa/icons';
|
||||
@@ -33,7 +33,18 @@ export class NavigateBackButtonComponent {
|
||||
#tabService = inject(TabService);
|
||||
#router = inject(Router);
|
||||
|
||||
/**
|
||||
* Optional URL to navigate to instead of using browser history.
|
||||
* Pass a complete URL string (e.g. '/123/reward').
|
||||
*/
|
||||
navigateTo = input<string>();
|
||||
|
||||
canNavigateBack = computed(() => {
|
||||
// If navigateTo is set, always allow navigation
|
||||
if (this.navigateTo()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const tabId = this.#tabService.activatedTabId();
|
||||
if (tabId === null) {
|
||||
return false;
|
||||
@@ -49,10 +60,18 @@ export class NavigateBackButtonComponent {
|
||||
});
|
||||
|
||||
back() {
|
||||
const navigateTo = this.navigateTo();
|
||||
if (navigateTo) {
|
||||
this.#router.navigateByUrl(navigateTo);
|
||||
return;
|
||||
}
|
||||
|
||||
// Default behavior: use browser history
|
||||
const tabId = this.#tabService.activatedTabId();
|
||||
if (tabId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const location = this.#tabService.navigateBack(tabId);
|
||||
|
||||
if (!location) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</ui-item-row-data-value>
|
||||
</ui-item-row-data-row>
|
||||
<ui-item-row-data-row>
|
||||
<ui-item-row-data-label>Vorgang-ID:</ui-item-row-data-label>
|
||||
<ui-item-row-data-label>Vorgangs-ID:</ui-item-row-data-label>
|
||||
<ui-item-row-data-value>
|
||||
{{ r.order?.data?.orderNumber }}
|
||||
</ui-item-row-data-value>
|
||||
|
||||
Reference in New Issue
Block a user